mirror of https://github.com/python/cpython
SF patch #1007189, multi-line imports, for instance:
"from blah import (foo, bar baz, bongo)"
This commit is contained in:
parent
876032e570
commit
1a4ddaecc7
|
@ -623,6 +623,9 @@ It continues with the next cycle of the nearest enclosing loop.
|
||||||
\productioncont{| "from" \token{module} "import" \token{identifier}
|
\productioncont{| "from" \token{module} "import" \token{identifier}
|
||||||
["as" \token{name}]}
|
["as" \token{name}]}
|
||||||
\productioncont{ ( "," \token{identifier} ["as" \token{name}] )*}
|
\productioncont{ ( "," \token{identifier} ["as" \token{name}] )*}
|
||||||
|
\productioncont{| "from" \token{module} "import" "(" \token{identifier}
|
||||||
|
["as" \token{name}]}
|
||||||
|
\productioncont{ ( "," \token{identifier} ["as" \token{name}] )* [","] ")"}
|
||||||
\productioncont{| "from" \token{module} "import" "*"}
|
\productioncont{| "from" \token{module} "import" "*"}
|
||||||
\production{module}
|
\production{module}
|
||||||
{(\token{identifier} ".")* \token{identifier}}
|
{(\token{identifier} ".")* \token{identifier}}
|
||||||
|
@ -744,8 +747,8 @@ before the release in which the feature becomes standard.
|
||||||
|
|
||||||
\begin{productionlist}[*]
|
\begin{productionlist}[*]
|
||||||
\production{future_statement}
|
\production{future_statement}
|
||||||
{"from" "__future__" "import" feature ["as" name]}
|
{"from" "__future__" "import" feature ["as" name] ("," feature ["as" name])*}
|
||||||
\productioncont{("," feature ["as" name])*}
|
\productioncont{| "from" "__future__" "import" "(" feature ["as" name] ("," feature ["as" name])* [","] ")"}
|
||||||
\production{feature}{identifier}
|
\production{feature}{identifier}
|
||||||
\production{name}{identifier}
|
\production{name}{identifier}
|
||||||
\end{productionlist}
|
\end{productionlist}
|
||||||
|
|
|
@ -51,9 +51,13 @@ continue_stmt: 'continue'
|
||||||
return_stmt: 'return' [testlist]
|
return_stmt: 'return' [testlist]
|
||||||
yield_stmt: 'yield' testlist
|
yield_stmt: 'yield' testlist
|
||||||
raise_stmt: 'raise' [test [',' test [',' test]]]
|
raise_stmt: 'raise' [test [',' test [',' test]]]
|
||||||
import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
|
import_stmt: import_name | import_from
|
||||||
|
import_name: 'import' dotted_as_names
|
||||||
|
import_from: 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
|
||||||
import_as_name: NAME [NAME NAME]
|
import_as_name: NAME [NAME NAME]
|
||||||
dotted_as_name: dotted_name [NAME NAME]
|
dotted_as_name: dotted_name [NAME NAME]
|
||||||
|
import_as_names: import_as_name (',' import_as_name)* [',']
|
||||||
|
dotted_as_names: dotted_as_name (',' dotted_as_name)*
|
||||||
dotted_name: NAME ('.' NAME)*
|
dotted_name: NAME ('.' NAME)*
|
||||||
global_stmt: 'global' NAME (',' NAME)*
|
global_stmt: 'global' NAME (',' NAME)*
|
||||||
exec_stmt: 'exec' expr ['in' test [',' test]]
|
exec_stmt: 'exec' expr ['in' test [',' test]]
|
||||||
|
|
|
@ -23,52 +23,56 @@
|
||||||
#define yield_stmt 278
|
#define yield_stmt 278
|
||||||
#define raise_stmt 279
|
#define raise_stmt 279
|
||||||
#define import_stmt 280
|
#define import_stmt 280
|
||||||
#define import_as_name 281
|
#define import_name 281
|
||||||
#define dotted_as_name 282
|
#define import_from 282
|
||||||
#define dotted_name 283
|
#define import_as_name 283
|
||||||
#define global_stmt 284
|
#define dotted_as_name 284
|
||||||
#define exec_stmt 285
|
#define import_as_names 285
|
||||||
#define assert_stmt 286
|
#define dotted_as_names 286
|
||||||
#define compound_stmt 287
|
#define dotted_name 287
|
||||||
#define if_stmt 288
|
#define global_stmt 288
|
||||||
#define while_stmt 289
|
#define exec_stmt 289
|
||||||
#define for_stmt 290
|
#define assert_stmt 290
|
||||||
#define try_stmt 291
|
#define compound_stmt 291
|
||||||
#define except_clause 292
|
#define if_stmt 292
|
||||||
#define suite 293
|
#define while_stmt 293
|
||||||
#define test 294
|
#define for_stmt 294
|
||||||
#define and_test 295
|
#define try_stmt 295
|
||||||
#define not_test 296
|
#define except_clause 296
|
||||||
#define comparison 297
|
#define suite 297
|
||||||
#define comp_op 298
|
#define test 298
|
||||||
#define expr 299
|
#define and_test 299
|
||||||
#define xor_expr 300
|
#define not_test 300
|
||||||
#define and_expr 301
|
#define comparison 301
|
||||||
#define shift_expr 302
|
#define comp_op 302
|
||||||
#define arith_expr 303
|
#define expr 303
|
||||||
#define term 304
|
#define xor_expr 304
|
||||||
#define factor 305
|
#define and_expr 305
|
||||||
#define power 306
|
#define shift_expr 306
|
||||||
#define atom 307
|
#define arith_expr 307
|
||||||
#define listmaker 308
|
#define term 308
|
||||||
#define testlist_gexp 309
|
#define factor 309
|
||||||
#define lambdef 310
|
#define power 310
|
||||||
#define trailer 311
|
#define atom 311
|
||||||
#define subscriptlist 312
|
#define listmaker 312
|
||||||
#define subscript 313
|
#define testlist_gexp 313
|
||||||
#define sliceop 314
|
#define lambdef 314
|
||||||
#define exprlist 315
|
#define trailer 315
|
||||||
#define testlist 316
|
#define subscriptlist 316
|
||||||
#define testlist_safe 317
|
#define subscript 317
|
||||||
#define dictmaker 318
|
#define sliceop 318
|
||||||
#define classdef 319
|
#define exprlist 319
|
||||||
#define arglist 320
|
#define testlist 320
|
||||||
#define argument 321
|
#define testlist_safe 321
|
||||||
#define list_iter 322
|
#define dictmaker 322
|
||||||
#define list_for 323
|
#define classdef 323
|
||||||
#define list_if 324
|
#define arglist 324
|
||||||
#define gen_iter 325
|
#define argument 325
|
||||||
#define gen_for 326
|
#define list_iter 326
|
||||||
#define gen_if 327
|
#define list_for 327
|
||||||
#define testlist1 328
|
#define list_if 328
|
||||||
#define encoding_decl 329
|
#define gen_iter 329
|
||||||
|
#define gen_for 330
|
||||||
|
#define gen_if 331
|
||||||
|
#define testlist1 332
|
||||||
|
#define encoding_decl 333
|
||||||
|
|
|
@ -438,28 +438,28 @@ class Transformer:
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def import_stmt(self, nodelist):
|
def import_stmt(self, nodelist):
|
||||||
# import_stmt: 'import' dotted_as_name (',' dotted_as_name)* |
|
# import_stmt: import_name | import_from
|
||||||
# from: 'from' dotted_name 'import'
|
assert len(nodelist) == 1
|
||||||
# ('*' | import_as_name (',' import_as_name)*)
|
return self.com_node(nodelist[0])
|
||||||
if nodelist[0][1] == 'from':
|
|
||||||
names = []
|
def import_name(self, nodelist):
|
||||||
if nodelist[3][0] == token.NAME:
|
# import_name: 'import' dotted_as_names
|
||||||
for i in range(3, len(nodelist), 2):
|
n = Import(self.com_dotted_as_names(nodelist[1]))
|
||||||
names.append((nodelist[i][1], None))
|
|
||||||
else:
|
|
||||||
for i in range(3, len(nodelist), 2):
|
|
||||||
names.append(self.com_import_as_name(nodelist[i]))
|
|
||||||
n = From(self.com_dotted_name(nodelist[1]), names)
|
|
||||||
n.lineno = nodelist[0][2]
|
n.lineno = nodelist[0][2]
|
||||||
return n
|
return n
|
||||||
|
|
||||||
if nodelist[1][0] == symbol.dotted_name:
|
def import_from(self, nodelist):
|
||||||
names = [(self.com_dotted_name(nodelist[1][1:]), None)]
|
# import_from: 'from' dotted_name 'import' ('*' |
|
||||||
|
# '(' import_as_names ')' | import_as_names)
|
||||||
|
assert nodelist[0][1] == 'from'
|
||||||
|
assert nodelist[1][0] == symbol.dotted_name
|
||||||
|
assert nodelist[2][1] == 'import'
|
||||||
|
fromname = self.com_dotted_name(nodelist[1])
|
||||||
|
if nodelist[3][0] == token.STAR:
|
||||||
|
n = From(fromname, [('*', None)])
|
||||||
else:
|
else:
|
||||||
names = []
|
node = nodelist[3 + (nodelist[3][0] == token.LPAR)]
|
||||||
for i in range(1, len(nodelist), 2):
|
n = From(fromname, self.com_import_as_names(node))
|
||||||
names.append(self.com_dotted_as_name(nodelist[i]))
|
|
||||||
n = Import(names)
|
|
||||||
n.lineno = nodelist[0][2]
|
n.lineno = nodelist[0][2]
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
@ -895,29 +895,41 @@ class Transformer:
|
||||||
return name[:-1]
|
return name[:-1]
|
||||||
|
|
||||||
def com_dotted_as_name(self, node):
|
def com_dotted_as_name(self, node):
|
||||||
dot = self.com_dotted_name(node[1])
|
assert node[0] == symbol.dotted_as_name
|
||||||
if len(node) <= 2:
|
node = node[1:]
|
||||||
|
dot = self.com_dotted_name(node[0][1:])
|
||||||
|
if len(node) == 1:
|
||||||
return dot, None
|
return dot, None
|
||||||
if node[0] == symbol.dotted_name:
|
assert node[1][1] == 'as'
|
||||||
pass
|
assert node[2][0] == token.NAME
|
||||||
else:
|
return dot, node[2][1]
|
||||||
assert node[2][1] == 'as'
|
|
||||||
assert node[3][0] == token.NAME
|
def com_dotted_as_names(self, node):
|
||||||
return dot, node[3][1]
|
assert node[0] == symbol.dotted_as_names
|
||||||
|
node = node[1:]
|
||||||
|
names = [self.com_dotted_as_name(node[0])]
|
||||||
|
for i in range(2, len(node), 2):
|
||||||
|
names.append(self.com_dotted_as_name(node[i]))
|
||||||
|
return names
|
||||||
|
|
||||||
def com_import_as_name(self, node):
|
def com_import_as_name(self, node):
|
||||||
if node[0] == token.STAR:
|
|
||||||
return '*', None
|
|
||||||
assert node[0] == symbol.import_as_name
|
assert node[0] == symbol.import_as_name
|
||||||
node = node[1:]
|
node = node[1:]
|
||||||
if len(node) == 1:
|
|
||||||
assert node[0][0] == token.NAME
|
assert node[0][0] == token.NAME
|
||||||
|
if len(node) == 1:
|
||||||
return node[0][1], None
|
return node[0][1], None
|
||||||
|
|
||||||
assert node[1][1] == 'as', node
|
assert node[1][1] == 'as', node
|
||||||
assert node[2][0] == token.NAME
|
assert node[2][0] == token.NAME
|
||||||
return node[0][1], node[2][1]
|
return node[0][1], node[2][1]
|
||||||
|
|
||||||
|
def com_import_as_names(self, node):
|
||||||
|
assert node[0] == symbol.import_as_names
|
||||||
|
node = node[1:]
|
||||||
|
names = [self.com_import_as_name(node[0])]
|
||||||
|
for i in range(2, len(node), 2):
|
||||||
|
names.append(self.com_import_as_name(node[i]))
|
||||||
|
return names
|
||||||
|
|
||||||
def com_bases(self, node):
|
def com_bases(self, node):
|
||||||
bases = []
|
bases = []
|
||||||
for i in range(1, len(node), 2):
|
for i in range(1, len(node), 2):
|
||||||
|
|
102
Lib/symbol.py
102
Lib/symbol.py
|
@ -35,55 +35,59 @@ return_stmt = 277
|
||||||
yield_stmt = 278
|
yield_stmt = 278
|
||||||
raise_stmt = 279
|
raise_stmt = 279
|
||||||
import_stmt = 280
|
import_stmt = 280
|
||||||
import_as_name = 281
|
import_name = 281
|
||||||
dotted_as_name = 282
|
import_from = 282
|
||||||
dotted_name = 283
|
import_as_name = 283
|
||||||
global_stmt = 284
|
dotted_as_name = 284
|
||||||
exec_stmt = 285
|
import_as_names = 285
|
||||||
assert_stmt = 286
|
dotted_as_names = 286
|
||||||
compound_stmt = 287
|
dotted_name = 287
|
||||||
if_stmt = 288
|
global_stmt = 288
|
||||||
while_stmt = 289
|
exec_stmt = 289
|
||||||
for_stmt = 290
|
assert_stmt = 290
|
||||||
try_stmt = 291
|
compound_stmt = 291
|
||||||
except_clause = 292
|
if_stmt = 292
|
||||||
suite = 293
|
while_stmt = 293
|
||||||
test = 294
|
for_stmt = 294
|
||||||
and_test = 295
|
try_stmt = 295
|
||||||
not_test = 296
|
except_clause = 296
|
||||||
comparison = 297
|
suite = 297
|
||||||
comp_op = 298
|
test = 298
|
||||||
expr = 299
|
and_test = 299
|
||||||
xor_expr = 300
|
not_test = 300
|
||||||
and_expr = 301
|
comparison = 301
|
||||||
shift_expr = 302
|
comp_op = 302
|
||||||
arith_expr = 303
|
expr = 303
|
||||||
term = 304
|
xor_expr = 304
|
||||||
factor = 305
|
and_expr = 305
|
||||||
power = 306
|
shift_expr = 306
|
||||||
atom = 307
|
arith_expr = 307
|
||||||
listmaker = 308
|
term = 308
|
||||||
testlist_gexp = 309
|
factor = 309
|
||||||
lambdef = 310
|
power = 310
|
||||||
trailer = 311
|
atom = 311
|
||||||
subscriptlist = 312
|
listmaker = 312
|
||||||
subscript = 313
|
testlist_gexp = 313
|
||||||
sliceop = 314
|
lambdef = 314
|
||||||
exprlist = 315
|
trailer = 315
|
||||||
testlist = 316
|
subscriptlist = 316
|
||||||
testlist_safe = 317
|
subscript = 317
|
||||||
dictmaker = 318
|
sliceop = 318
|
||||||
classdef = 319
|
exprlist = 319
|
||||||
arglist = 320
|
testlist = 320
|
||||||
argument = 321
|
testlist_safe = 321
|
||||||
list_iter = 322
|
dictmaker = 322
|
||||||
list_for = 323
|
classdef = 323
|
||||||
list_if = 324
|
arglist = 324
|
||||||
gen_iter = 325
|
argument = 325
|
||||||
gen_for = 326
|
list_iter = 326
|
||||||
gen_if = 327
|
list_for = 327
|
||||||
testlist1 = 328
|
list_if = 328
|
||||||
encoding_decl = 329
|
gen_iter = 329
|
||||||
|
gen_for = 330
|
||||||
|
gen_if = 331
|
||||||
|
testlist1 = 332
|
||||||
|
encoding_decl = 333
|
||||||
#--end constants--
|
#--end constants--
|
||||||
|
|
||||||
sym_name = {}
|
sym_name = {}
|
||||||
|
|
|
@ -35,7 +35,8 @@ continue + try/finally ok
|
||||||
testing continue and break in try/except in loop
|
testing continue and break in try/except in loop
|
||||||
return_stmt
|
return_stmt
|
||||||
raise_stmt
|
raise_stmt
|
||||||
import_stmt
|
import_name
|
||||||
|
import_from
|
||||||
global_stmt
|
global_stmt
|
||||||
exec_stmt
|
exec_stmt
|
||||||
assert_stmt
|
assert_stmt
|
||||||
|
|
|
@ -211,6 +211,47 @@ if 1:
|
||||||
self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
|
self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
|
||||||
self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
|
self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
|
||||||
|
|
||||||
|
def test_import(self):
|
||||||
|
succeed = [
|
||||||
|
'import sys',
|
||||||
|
'import os, sys',
|
||||||
|
'from __future__ import nested_scopes, generators',
|
||||||
|
'from __future__ import (nested_scopes,\ngenerators)',
|
||||||
|
'from __future__ import (nested_scopes,\ngenerators,)',
|
||||||
|
'from sys import stdin, stderr, stdout',
|
||||||
|
'from sys import (stdin, stderr,\nstdout)',
|
||||||
|
'from sys import (stdin, stderr,\nstdout,)',
|
||||||
|
'from sys import (stdin\n, stderr, stdout)',
|
||||||
|
'from sys import (stdin\n, stderr, stdout,)',
|
||||||
|
'from sys import stdin as si, stdout as so, stderr as se',
|
||||||
|
'from sys import (stdin as si, stdout as so, stderr as se)',
|
||||||
|
'from sys import (stdin as si, stdout as so, stderr as se,)',
|
||||||
|
]
|
||||||
|
fail = [
|
||||||
|
'import (os, sys)',
|
||||||
|
'import (os), (sys)',
|
||||||
|
'import ((os), (sys))',
|
||||||
|
'import (sys',
|
||||||
|
'import sys)',
|
||||||
|
'import (os,)',
|
||||||
|
'from (sys) import stdin',
|
||||||
|
'from __future__ import (nested_scopes',
|
||||||
|
'from __future__ import nested_scopes)',
|
||||||
|
'from __future__ import nested_scopes,\ngenerators',
|
||||||
|
'from sys import (stdin',
|
||||||
|
'from sys import stdin)',
|
||||||
|
'from sys import stdin, stdout,\nstderr',
|
||||||
|
'from sys import stdin si',
|
||||||
|
'from sys import stdin,'
|
||||||
|
'from sys import (*)',
|
||||||
|
'from sys import (stdin,, stdout, stderr)',
|
||||||
|
'from sys import (stdin, stdout),',
|
||||||
|
]
|
||||||
|
for stmt in succeed:
|
||||||
|
compile(stmt, 'tmp', 'exec')
|
||||||
|
for stmt in fail:
|
||||||
|
self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(TestSpecifics)
|
test_support.run_unittest(TestSpecifics)
|
||||||
|
|
||||||
|
|
|
@ -417,12 +417,16 @@ except RuntimeError: pass
|
||||||
try: raise KeyboardInterrupt
|
try: raise KeyboardInterrupt
|
||||||
except KeyboardInterrupt: pass
|
except KeyboardInterrupt: pass
|
||||||
|
|
||||||
print 'import_stmt' # 'import' NAME (',' NAME)* | 'from' NAME 'import' ('*' | NAME (',' NAME)*)
|
print 'import_name' # 'import' dotted_as_names
|
||||||
import sys
|
import sys
|
||||||
import time, sys
|
import time, sys
|
||||||
|
print 'import_from' # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
|
||||||
from time import time
|
from time import time
|
||||||
|
from time import (time)
|
||||||
from sys import *
|
from sys import *
|
||||||
from sys import path, argv
|
from sys import path, argv
|
||||||
|
from sys import (path, argv)
|
||||||
|
from sys import (path, argv,)
|
||||||
|
|
||||||
print 'global_stmt' # 'global' NAME (',' NAME)*
|
print 'global_stmt' # 'global' NAME (',' NAME)*
|
||||||
def f():
|
def f():
|
||||||
|
|
|
@ -130,12 +130,26 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
|
||||||
def test_import_from_statement(self):
|
def test_import_from_statement(self):
|
||||||
self.check_suite("from sys.path import *")
|
self.check_suite("from sys.path import *")
|
||||||
self.check_suite("from sys.path import dirname")
|
self.check_suite("from sys.path import dirname")
|
||||||
|
self.check_suite("from sys.path import (dirname)")
|
||||||
|
self.check_suite("from sys.path import (dirname,)")
|
||||||
self.check_suite("from sys.path import dirname as my_dirname")
|
self.check_suite("from sys.path import dirname as my_dirname")
|
||||||
|
self.check_suite("from sys.path import (dirname as my_dirname)")
|
||||||
|
self.check_suite("from sys.path import (dirname as my_dirname,)")
|
||||||
self.check_suite("from sys.path import dirname, basename")
|
self.check_suite("from sys.path import dirname, basename")
|
||||||
|
self.check_suite("from sys.path import (dirname, basename)")
|
||||||
|
self.check_suite("from sys.path import (dirname, basename,)")
|
||||||
self.check_suite(
|
self.check_suite(
|
||||||
"from sys.path import dirname as my_dirname, basename")
|
"from sys.path import dirname as my_dirname, basename")
|
||||||
|
self.check_suite(
|
||||||
|
"from sys.path import (dirname as my_dirname, basename)")
|
||||||
|
self.check_suite(
|
||||||
|
"from sys.path import (dirname as my_dirname, basename,)")
|
||||||
self.check_suite(
|
self.check_suite(
|
||||||
"from sys.path import dirname, basename as my_basename")
|
"from sys.path import dirname, basename as my_basename")
|
||||||
|
self.check_suite(
|
||||||
|
"from sys.path import (dirname, basename as my_basename)")
|
||||||
|
self.check_suite(
|
||||||
|
"from sys.path import (dirname, basename as my_basename,)")
|
||||||
|
|
||||||
def test_basic_import_statement(self):
|
def test_basic_import_statement(self):
|
||||||
self.check_suite("import sys")
|
self.check_suite("import sys")
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.4 alpha 3?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- SF patch #1007189: ``from ... import ...`` statements now allow the name
|
||||||
|
list to be surrounded by parentheses.
|
||||||
|
|
||||||
- Some speedups for long arithmetic, thanks to Trevor Perrin. Gradeschool
|
- Some speedups for long arithmetic, thanks to Trevor Perrin. Gradeschool
|
||||||
multiplication was sped a little by optimizing the C code. Gradeschool
|
multiplication was sped a little by optimizing the C code. Gradeschool
|
||||||
squaring was sped by about a factor of 2, by exploiting that about half
|
squaring was sped by about a factor of 2, by exploiting that about half
|
||||||
|
@ -889,7 +892,7 @@ Library
|
||||||
API matches math.log().
|
API matches math.log().
|
||||||
|
|
||||||
- Bug #957381: distutils bdist_rpm no longer fails on recent RPM versions
|
- Bug #957381: distutils bdist_rpm no longer fails on recent RPM versions
|
||||||
that generate a *-debuginfo.rpm.
|
that generate a -debuginfo.rpm
|
||||||
|
|
||||||
- os.path.devnull has been added for all supported platforms.
|
- os.path.devnull has been added for all supported platforms.
|
||||||
|
|
||||||
|
|
|
@ -839,6 +839,7 @@ VALIDATER(expr_stmt); VALIDATER(power);
|
||||||
VALIDATER(print_stmt); VALIDATER(del_stmt);
|
VALIDATER(print_stmt); VALIDATER(del_stmt);
|
||||||
VALIDATER(return_stmt); VALIDATER(list_iter);
|
VALIDATER(return_stmt); VALIDATER(list_iter);
|
||||||
VALIDATER(raise_stmt); VALIDATER(import_stmt);
|
VALIDATER(raise_stmt); VALIDATER(import_stmt);
|
||||||
|
VALIDATER(import_name); VALIDATER(import_from);
|
||||||
VALIDATER(global_stmt); VALIDATER(list_if);
|
VALIDATER(global_stmt); VALIDATER(list_if);
|
||||||
VALIDATER(assert_stmt); VALIDATER(list_for);
|
VALIDATER(assert_stmt); VALIDATER(list_for);
|
||||||
VALIDATER(exec_stmt); VALIDATER(compound_stmt);
|
VALIDATER(exec_stmt); VALIDATER(compound_stmt);
|
||||||
|
@ -1714,55 +1715,100 @@ validate_dotted_as_name(node *tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* import_stmt:
|
/* dotted_as_name (',' dotted_as_name)* */
|
||||||
*
|
static int
|
||||||
* 'import' dotted_as_name (',' dotted_as_name)*
|
validate_dotted_as_names(node *tree)
|
||||||
* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
|
{
|
||||||
|
int nch = NCH(tree);
|
||||||
|
int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0));
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; res && (i < nch); i += 2)
|
||||||
|
res = (validate_comma(CHILD(tree, i))
|
||||||
|
&& validate_dotted_as_name(CHILD(tree, i + 1)));
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* import_as_name (',' import_as_name)* [','] */
|
||||||
|
static int
|
||||||
|
validate_import_as_names(node *tree)
|
||||||
|
{
|
||||||
|
int nch = NCH(tree);
|
||||||
|
int res = validate_import_as_name(CHILD(tree, 0));
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; res && (i + 1 < nch); i += 2)
|
||||||
|
res = (validate_comma(CHILD(tree, i))
|
||||||
|
&& validate_import_as_name(CHILD(tree, i + 1)));
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 'import' dotted_as_names */
|
||||||
|
static int
|
||||||
|
validate_import_name(node *tree)
|
||||||
|
{
|
||||||
|
return (validate_ntype(tree, import_name)
|
||||||
|
&& validate_numnodes(tree, 2, "import_name")
|
||||||
|
&& validate_name(CHILD(tree, 0), "import")
|
||||||
|
&& validate_dotted_as_names(CHILD(tree, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 'from' dotted_name 'import' ('*' | '(' import_as_names ')' |
|
||||||
|
* import_as_names
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
validate_import_from(node *tree)
|
||||||
|
{
|
||||||
|
int nch = NCH(tree);
|
||||||
|
int res = validate_ntype(tree, import_from)
|
||||||
|
&& (nch >= 4)
|
||||||
|
&& validate_name(CHILD(tree, 0), "from")
|
||||||
|
&& validate_dotted_name(CHILD(tree, 1))
|
||||||
|
&& validate_name(CHILD(tree, 2), "import");
|
||||||
|
|
||||||
|
if (res && TYPE(CHILD(tree, 3)) == LPAR)
|
||||||
|
res = ((nch == 6)
|
||||||
|
&& validate_lparen(CHILD(tree, 3))
|
||||||
|
&& validate_import_as_names(CHILD(tree, 4))
|
||||||
|
&& validate_rparen(CHILD(tree, 5)));
|
||||||
|
else if (res && TYPE(CHILD(tree, 3)) != STAR)
|
||||||
|
res = validate_import_as_names(CHILD(tree, 3));
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* import_stmt: import_name | import_from */
|
||||||
|
static int
|
||||||
validate_import_stmt(node *tree)
|
validate_import_stmt(node *tree)
|
||||||
{
|
{
|
||||||
int nch = NCH(tree);
|
int nch = NCH(tree);
|
||||||
int res = (validate_ntype(tree, import_stmt)
|
int res = validate_numnodes(tree, 1, "import_stmt");
|
||||||
&& (nch >= 2) && is_even(nch)
|
|
||||||
&& validate_ntype(CHILD(tree, 0), NAME));
|
|
||||||
|
|
||||||
if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
|
if (res) {
|
||||||
int j;
|
int ntype = TYPE(CHILD(tree, 0));
|
||||||
|
|
||||||
res = validate_dotted_as_name(CHILD(tree, 1));
|
if (ntype == import_name || ntype == import_from)
|
||||||
for (j = 2; res && (j < nch); j += 2)
|
res = validate_node(CHILD(tree, 0));
|
||||||
res = (validate_comma(CHILD(tree, j))
|
|
||||||
&& validate_dotted_as_name(CHILD(tree, j + 1)));
|
|
||||||
}
|
|
||||||
else if (res && (res = validate_name(CHILD(tree, 0), "from"))) {
|
|
||||||
res = ((nch >= 4) && is_even(nch)
|
|
||||||
&& validate_dotted_name(CHILD(tree, 1))
|
|
||||||
&& validate_name(CHILD(tree, 2), "import"));
|
|
||||||
if (nch == 4) {
|
|
||||||
if (TYPE(CHILD(tree, 3)) == import_as_name)
|
|
||||||
res = validate_import_as_name(CHILD(tree, 3));
|
|
||||||
else
|
|
||||||
res = validate_star(CHILD(tree, 3));
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
/* 'from' dotted_name 'import' import_as_name
|
|
||||||
* (',' import_as_name)+
|
|
||||||
*/
|
|
||||||
int j;
|
|
||||||
res = validate_import_as_name(CHILD(tree, 3));
|
|
||||||
for (j = 4; res && (j < nch); j += 2)
|
|
||||||
res = (validate_comma(CHILD(tree, j))
|
|
||||||
&& validate_import_as_name(CHILD(tree, j + 1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = 0;
|
res = 0;
|
||||||
|
err_string("illegal import_stmt child type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nch == 1) {
|
||||||
|
res = 0;
|
||||||
|
PyErr_Format(parser_error,
|
||||||
|
"Unrecognized child node of import_stmt: %d.",
|
||||||
|
TYPE(CHILD(tree, 0)));
|
||||||
|
}
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
validate_global_stmt(node *tree)
|
validate_global_stmt(node *tree)
|
||||||
{
|
{
|
||||||
|
@ -2823,6 +2869,12 @@ validate_node(node *tree)
|
||||||
case import_stmt:
|
case import_stmt:
|
||||||
res = validate_import_stmt(tree);
|
res = validate_import_stmt(tree);
|
||||||
break;
|
break;
|
||||||
|
case import_name:
|
||||||
|
res = validate_import_name(tree);
|
||||||
|
break;
|
||||||
|
case import_from:
|
||||||
|
res = validate_import_from(tree);
|
||||||
|
break;
|
||||||
case global_stmt:
|
case global_stmt:
|
||||||
res = validate_global_stmt(tree);
|
res = validate_global_stmt(tree);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3490,42 +3490,53 @@ com_from_import(struct compiling *c, node *n)
|
||||||
static void
|
static void
|
||||||
com_import_stmt(struct compiling *c, node *n)
|
com_import_stmt(struct compiling *c, node *n)
|
||||||
{
|
{
|
||||||
|
node *nn;
|
||||||
int i;
|
int i;
|
||||||
REQ(n, import_stmt);
|
REQ(n, import_stmt);
|
||||||
/* 'import' dotted_name (',' dotted_name)* |
|
n = CHILD(n, 0);
|
||||||
'from' dotted_name 'import' ('*' | NAME (',' NAME)*) */
|
/* import_stmt: import_name | import_from */
|
||||||
if (STR(CHILD(n, 0))[0] == 'f') {
|
if (TYPE(n) == import_from) {
|
||||||
|
/* 'from' dotted_name 'import' ('*' |
|
||||||
|
'(' import_as_names ')' | import_as_names) */
|
||||||
PyObject *tup;
|
PyObject *tup;
|
||||||
/* 'from' dotted_name 'import' ... */
|
|
||||||
REQ(CHILD(n, 1), dotted_name);
|
REQ(CHILD(n, 1), dotted_name);
|
||||||
|
nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
|
||||||
if (TYPE(CHILD(n, 3)) == STAR) {
|
if (TYPE(nn) == STAR)
|
||||||
tup = Py_BuildValue("(s)", "*");
|
tup = Py_BuildValue("(s)", "*");
|
||||||
} else {
|
else {
|
||||||
tup = PyTuple_New((NCH(n) - 2)/2);
|
if (TYPE(CHILD(nn, NCH(nn) - 1)) == COMMA &&
|
||||||
for (i = 3; i < NCH(n); i += 2) {
|
TYPE(CHILD(n, 3)) != LPAR) {
|
||||||
PyTuple_SET_ITEM(tup, (i-3)/2,
|
com_error(c, PyExc_SyntaxError,
|
||||||
PyString_FromString(STR(
|
"trailing comma not allowed "
|
||||||
CHILD(CHILD(n, i), 0))));
|
"without surrounding parentheses");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
REQ(nn, import_as_names);
|
||||||
|
tup = PyTuple_New((NCH(nn) + 1) / 2);
|
||||||
|
for (i = 0; i < NCH(nn); i += 2)
|
||||||
|
PyTuple_SET_ITEM(tup, i / 2,
|
||||||
|
PyString_FromString(STR(
|
||||||
|
CHILD(CHILD(nn, i), 0))));
|
||||||
}
|
}
|
||||||
com_addoparg(c, LOAD_CONST, com_addconst(c, tup));
|
com_addoparg(c, LOAD_CONST, com_addconst(c, tup));
|
||||||
Py_DECREF(tup);
|
Py_DECREF(tup);
|
||||||
com_push(c, 1);
|
com_push(c, 1);
|
||||||
com_addopname(c, IMPORT_NAME, CHILD(n, 1));
|
com_addopname(c, IMPORT_NAME, CHILD(n, 1));
|
||||||
if (TYPE(CHILD(n, 3)) == STAR)
|
if (TYPE(nn) == STAR)
|
||||||
com_addbyte(c, IMPORT_STAR);
|
com_addbyte(c, IMPORT_STAR);
|
||||||
else {
|
else {
|
||||||
for (i = 3; i < NCH(n); i += 2)
|
for (i = 0; i < NCH(nn); i += 2)
|
||||||
com_from_import(c, CHILD(n, i));
|
com_from_import(c, CHILD(nn, i));
|
||||||
com_addbyte(c, POP_TOP);
|
com_addbyte(c, POP_TOP);
|
||||||
}
|
}
|
||||||
com_pop(c, 1);
|
com_pop(c, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* 'import' ... */
|
/* 'import' dotted_as_names */
|
||||||
for (i = 1; i < NCH(n); i += 2) {
|
nn = CHILD(n, 1);
|
||||||
node *subn = CHILD(n, i);
|
REQ(nn, dotted_as_names);
|
||||||
|
for (i = 0; i < NCH(nn); i += 2) {
|
||||||
|
node *subn = CHILD(nn, i);
|
||||||
REQ(subn, dotted_as_name);
|
REQ(subn, dotted_as_name);
|
||||||
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
|
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
|
||||||
com_push(c, 1);
|
com_push(c, 1);
|
||||||
|
@ -6291,14 +6302,15 @@ symtable_gen_iter(struct symtable *st, node *n)
|
||||||
static void
|
static void
|
||||||
symtable_import(struct symtable *st, node *n)
|
symtable_import(struct symtable *st, node *n)
|
||||||
{
|
{
|
||||||
|
node *nn;
|
||||||
int i;
|
int i;
|
||||||
/* import_stmt: 'import' dotted_as_name (',' dotted_as_name)*
|
/* import_stmt: import_name | import_from */
|
||||||
| 'from' dotted_name 'import'
|
n = CHILD(n, 0);
|
||||||
('*' | import_as_name (',' import_as_name)*)
|
if (TYPE(n) == import_from) {
|
||||||
import_as_name: NAME [NAME NAME]
|
/* import_from: 'from' dotted_name 'import' ('*' |
|
||||||
*/
|
| '(' import_as_names ')' | import_as_names) */
|
||||||
if (STR(CHILD(n, 0))[0] == 'f') { /* from */
|
|
||||||
node *dotname = CHILD(n, 1);
|
node *dotname = CHILD(n, 1);
|
||||||
|
REQ(dotname, dotted_name);
|
||||||
if (strcmp(STR(CHILD(dotname, 0)), "__future__") == 0) {
|
if (strcmp(STR(CHILD(dotname, 0)), "__future__") == 0) {
|
||||||
/* check for bogus imports */
|
/* check for bogus imports */
|
||||||
if (n->n_lineno >= st->st_future->ff_last_lineno) {
|
if (n->n_lineno >= st->st_future->ff_last_lineno) {
|
||||||
|
@ -6308,7 +6320,8 @@ symtable_import(struct symtable *st, node *n)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TYPE(CHILD(n, 3)) == STAR) {
|
nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
|
||||||
|
if (TYPE(nn) == STAR) {
|
||||||
if (st->st_cur->ste_type != TYPE_MODULE) {
|
if (st->st_cur->ste_type != TYPE_MODULE) {
|
||||||
if (symtable_warn(st,
|
if (symtable_warn(st,
|
||||||
"import * only allowed at module level") < 0)
|
"import * only allowed at module level") < 0)
|
||||||
|
@ -6317,8 +6330,9 @@ symtable_import(struct symtable *st, node *n)
|
||||||
st->st_cur->ste_optimized |= OPT_IMPORT_STAR;
|
st->st_cur->ste_optimized |= OPT_IMPORT_STAR;
|
||||||
st->st_cur->ste_opt_lineno = n->n_lineno;
|
st->st_cur->ste_opt_lineno = n->n_lineno;
|
||||||
} else {
|
} else {
|
||||||
for (i = 3; i < NCH(n); i += 2) {
|
REQ(nn, import_as_names);
|
||||||
node *c = CHILD(n, i);
|
for (i = 0; i < NCH(nn); i += 2) {
|
||||||
|
node *c = CHILD(nn, i);
|
||||||
if (NCH(c) > 1) /* import as */
|
if (NCH(c) > 1) /* import as */
|
||||||
symtable_assign(st, CHILD(c, 2),
|
symtable_assign(st, CHILD(c, 2),
|
||||||
DEF_IMPORT);
|
DEF_IMPORT);
|
||||||
|
@ -6328,9 +6342,11 @@ symtable_import(struct symtable *st, node *n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 1; i < NCH(n); i += 2) {
|
/* 'import' dotted_as_names */
|
||||||
symtable_assign(st, CHILD(n, i), DEF_IMPORT);
|
nn = CHILD(n, 1);
|
||||||
}
|
REQ(nn, dotted_as_names);
|
||||||
|
for (i = 0; i < NCH(nn); i += 2)
|
||||||
|
symtable_assign(st, CHILD(nn, i), DEF_IMPORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,18 @@ future_check_features(PyFutureFeatures *ff, node *n, const char *filename)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *feature;
|
char *feature;
|
||||||
node *ch;
|
node *ch, *nn;
|
||||||
|
|
||||||
REQ(n, import_stmt); /* must by from __future__ import ... */
|
REQ(n, import_from);
|
||||||
|
nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
|
||||||
for (i = 3; i < NCH(n); i += 2) {
|
if (TYPE(nn) == STAR) {
|
||||||
ch = CHILD(n, i);
|
PyErr_SetString(PyExc_SyntaxError, FUTURE_IMPORT_STAR);
|
||||||
if (TYPE(ch) == STAR) {
|
PyErr_SyntaxLocation(filename, nn->n_lineno);
|
||||||
PyErr_SetString(PyExc_SyntaxError,
|
|
||||||
FUTURE_IMPORT_STAR);
|
|
||||||
PyErr_SyntaxLocation(filename, ch->n_lineno);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
REQ(nn, import_as_names);
|
||||||
|
for (i = 0; i < NCH(nn); i += 2) {
|
||||||
|
ch = CHILD(nn, i);
|
||||||
REQ(ch, import_as_name);
|
REQ(ch, import_as_name);
|
||||||
feature = STR(CHILD(ch, 0));
|
feature = STR(CHILD(ch, 0));
|
||||||
if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
|
if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
|
||||||
|
@ -188,7 +188,8 @@ future_parse(PyFutureFeatures *ff, node *n, const char *filename)
|
||||||
case import_stmt: {
|
case import_stmt: {
|
||||||
node *name;
|
node *name;
|
||||||
|
|
||||||
if (STR(CHILD(n, 0))[0] != 'f') { /* from */
|
n = CHILD(n, 0);
|
||||||
|
if (TYPE(n) != import_from) {
|
||||||
ff->ff_last_lineno = n->n_lineno;
|
ff->ff_last_lineno = n->n_lineno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
1990
Python/graminit.c
1990
Python/graminit.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue