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}
|
||||
["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" "*"}
|
||||
\production{module}
|
||||
{(\token{identifier} ".")* \token{identifier}}
|
||||
|
@ -744,8 +747,8 @@ before the release in which the feature becomes standard.
|
|||
|
||||
\begin{productionlist}[*]
|
||||
\production{future_statement}
|
||||
{"from" "__future__" "import" feature ["as" name]}
|
||||
\productioncont{("," feature ["as" name])*}
|
||||
{"from" "__future__" "import" feature ["as" name] ("," feature ["as" name])*}
|
||||
\productioncont{| "from" "__future__" "import" "(" feature ["as" name] ("," feature ["as" name])* [","] ")"}
|
||||
\production{feature}{identifier}
|
||||
\production{name}{identifier}
|
||||
\end{productionlist}
|
||||
|
|
|
@ -51,9 +51,13 @@ continue_stmt: 'continue'
|
|||
return_stmt: 'return' [testlist]
|
||||
yield_stmt: 'yield' testlist
|
||||
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]
|
||||
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)*
|
||||
global_stmt: 'global' NAME (',' NAME)*
|
||||
exec_stmt: 'exec' expr ['in' test [',' test]]
|
||||
|
|
|
@ -23,52 +23,56 @@
|
|||
#define yield_stmt 278
|
||||
#define raise_stmt 279
|
||||
#define import_stmt 280
|
||||
#define import_as_name 281
|
||||
#define dotted_as_name 282
|
||||
#define dotted_name 283
|
||||
#define global_stmt 284
|
||||
#define exec_stmt 285
|
||||
#define assert_stmt 286
|
||||
#define compound_stmt 287
|
||||
#define if_stmt 288
|
||||
#define while_stmt 289
|
||||
#define for_stmt 290
|
||||
#define try_stmt 291
|
||||
#define except_clause 292
|
||||
#define suite 293
|
||||
#define test 294
|
||||
#define and_test 295
|
||||
#define not_test 296
|
||||
#define comparison 297
|
||||
#define comp_op 298
|
||||
#define expr 299
|
||||
#define xor_expr 300
|
||||
#define and_expr 301
|
||||
#define shift_expr 302
|
||||
#define arith_expr 303
|
||||
#define term 304
|
||||
#define factor 305
|
||||
#define power 306
|
||||
#define atom 307
|
||||
#define listmaker 308
|
||||
#define testlist_gexp 309
|
||||
#define lambdef 310
|
||||
#define trailer 311
|
||||
#define subscriptlist 312
|
||||
#define subscript 313
|
||||
#define sliceop 314
|
||||
#define exprlist 315
|
||||
#define testlist 316
|
||||
#define testlist_safe 317
|
||||
#define dictmaker 318
|
||||
#define classdef 319
|
||||
#define arglist 320
|
||||
#define argument 321
|
||||
#define list_iter 322
|
||||
#define list_for 323
|
||||
#define list_if 324
|
||||
#define gen_iter 325
|
||||
#define gen_for 326
|
||||
#define gen_if 327
|
||||
#define testlist1 328
|
||||
#define encoding_decl 329
|
||||
#define import_name 281
|
||||
#define import_from 282
|
||||
#define import_as_name 283
|
||||
#define dotted_as_name 284
|
||||
#define import_as_names 285
|
||||
#define dotted_as_names 286
|
||||
#define dotted_name 287
|
||||
#define global_stmt 288
|
||||
#define exec_stmt 289
|
||||
#define assert_stmt 290
|
||||
#define compound_stmt 291
|
||||
#define if_stmt 292
|
||||
#define while_stmt 293
|
||||
#define for_stmt 294
|
||||
#define try_stmt 295
|
||||
#define except_clause 296
|
||||
#define suite 297
|
||||
#define test 298
|
||||
#define and_test 299
|
||||
#define not_test 300
|
||||
#define comparison 301
|
||||
#define comp_op 302
|
||||
#define expr 303
|
||||
#define xor_expr 304
|
||||
#define and_expr 305
|
||||
#define shift_expr 306
|
||||
#define arith_expr 307
|
||||
#define term 308
|
||||
#define factor 309
|
||||
#define power 310
|
||||
#define atom 311
|
||||
#define listmaker 312
|
||||
#define testlist_gexp 313
|
||||
#define lambdef 314
|
||||
#define trailer 315
|
||||
#define subscriptlist 316
|
||||
#define subscript 317
|
||||
#define sliceop 318
|
||||
#define exprlist 319
|
||||
#define testlist 320
|
||||
#define testlist_safe 321
|
||||
#define dictmaker 322
|
||||
#define classdef 323
|
||||
#define arglist 324
|
||||
#define argument 325
|
||||
#define list_iter 326
|
||||
#define list_for 327
|
||||
#define list_if 328
|
||||
#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
|
||||
|
||||
def import_stmt(self, nodelist):
|
||||
# import_stmt: 'import' dotted_as_name (',' dotted_as_name)* |
|
||||
# from: 'from' dotted_name 'import'
|
||||
# ('*' | import_as_name (',' import_as_name)*)
|
||||
if nodelist[0][1] == 'from':
|
||||
names = []
|
||||
if nodelist[3][0] == token.NAME:
|
||||
for i in range(3, len(nodelist), 2):
|
||||
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]
|
||||
return n
|
||||
# import_stmt: import_name | import_from
|
||||
assert len(nodelist) == 1
|
||||
return self.com_node(nodelist[0])
|
||||
|
||||
if nodelist[1][0] == symbol.dotted_name:
|
||||
names = [(self.com_dotted_name(nodelist[1][1:]), None)]
|
||||
def import_name(self, nodelist):
|
||||
# import_name: 'import' dotted_as_names
|
||||
n = Import(self.com_dotted_as_names(nodelist[1]))
|
||||
n.lineno = nodelist[0][2]
|
||||
return n
|
||||
|
||||
def import_from(self, nodelist):
|
||||
# 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:
|
||||
names = []
|
||||
for i in range(1, len(nodelist), 2):
|
||||
names.append(self.com_dotted_as_name(nodelist[i]))
|
||||
n = Import(names)
|
||||
node = nodelist[3 + (nodelist[3][0] == token.LPAR)]
|
||||
n = From(fromname, self.com_import_as_names(node))
|
||||
n.lineno = nodelist[0][2]
|
||||
return n
|
||||
|
||||
|
@ -895,29 +895,41 @@ class Transformer:
|
|||
return name[:-1]
|
||||
|
||||
def com_dotted_as_name(self, node):
|
||||
dot = self.com_dotted_name(node[1])
|
||||
if len(node) <= 2:
|
||||
assert node[0] == symbol.dotted_as_name
|
||||
node = node[1:]
|
||||
dot = self.com_dotted_name(node[0][1:])
|
||||
if len(node) == 1:
|
||||
return dot, None
|
||||
if node[0] == symbol.dotted_name:
|
||||
pass
|
||||
else:
|
||||
assert node[2][1] == 'as'
|
||||
assert node[3][0] == token.NAME
|
||||
return dot, node[3][1]
|
||||
assert node[1][1] == 'as'
|
||||
assert node[2][0] == token.NAME
|
||||
return dot, node[2][1]
|
||||
|
||||
def com_dotted_as_names(self, node):
|
||||
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):
|
||||
if node[0] == token.STAR:
|
||||
return '*', None
|
||||
assert node[0] == symbol.import_as_name
|
||||
node = node[1:]
|
||||
assert node[0][0] == token.NAME
|
||||
if len(node) == 1:
|
||||
assert node[0][0] == token.NAME
|
||||
return node[0][1], None
|
||||
|
||||
assert node[1][1] == 'as', node
|
||||
assert node[2][0] == token.NAME
|
||||
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):
|
||||
bases = []
|
||||
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
|
||||
raise_stmt = 279
|
||||
import_stmt = 280
|
||||
import_as_name = 281
|
||||
dotted_as_name = 282
|
||||
dotted_name = 283
|
||||
global_stmt = 284
|
||||
exec_stmt = 285
|
||||
assert_stmt = 286
|
||||
compound_stmt = 287
|
||||
if_stmt = 288
|
||||
while_stmt = 289
|
||||
for_stmt = 290
|
||||
try_stmt = 291
|
||||
except_clause = 292
|
||||
suite = 293
|
||||
test = 294
|
||||
and_test = 295
|
||||
not_test = 296
|
||||
comparison = 297
|
||||
comp_op = 298
|
||||
expr = 299
|
||||
xor_expr = 300
|
||||
and_expr = 301
|
||||
shift_expr = 302
|
||||
arith_expr = 303
|
||||
term = 304
|
||||
factor = 305
|
||||
power = 306
|
||||
atom = 307
|
||||
listmaker = 308
|
||||
testlist_gexp = 309
|
||||
lambdef = 310
|
||||
trailer = 311
|
||||
subscriptlist = 312
|
||||
subscript = 313
|
||||
sliceop = 314
|
||||
exprlist = 315
|
||||
testlist = 316
|
||||
testlist_safe = 317
|
||||
dictmaker = 318
|
||||
classdef = 319
|
||||
arglist = 320
|
||||
argument = 321
|
||||
list_iter = 322
|
||||
list_for = 323
|
||||
list_if = 324
|
||||
gen_iter = 325
|
||||
gen_for = 326
|
||||
gen_if = 327
|
||||
testlist1 = 328
|
||||
encoding_decl = 329
|
||||
import_name = 281
|
||||
import_from = 282
|
||||
import_as_name = 283
|
||||
dotted_as_name = 284
|
||||
import_as_names = 285
|
||||
dotted_as_names = 286
|
||||
dotted_name = 287
|
||||
global_stmt = 288
|
||||
exec_stmt = 289
|
||||
assert_stmt = 290
|
||||
compound_stmt = 291
|
||||
if_stmt = 292
|
||||
while_stmt = 293
|
||||
for_stmt = 294
|
||||
try_stmt = 295
|
||||
except_clause = 296
|
||||
suite = 297
|
||||
test = 298
|
||||
and_test = 299
|
||||
not_test = 300
|
||||
comparison = 301
|
||||
comp_op = 302
|
||||
expr = 303
|
||||
xor_expr = 304
|
||||
and_expr = 305
|
||||
shift_expr = 306
|
||||
arith_expr = 307
|
||||
term = 308
|
||||
factor = 309
|
||||
power = 310
|
||||
atom = 311
|
||||
listmaker = 312
|
||||
testlist_gexp = 313
|
||||
lambdef = 314
|
||||
trailer = 315
|
||||
subscriptlist = 316
|
||||
subscript = 317
|
||||
sliceop = 318
|
||||
exprlist = 319
|
||||
testlist = 320
|
||||
testlist_safe = 321
|
||||
dictmaker = 322
|
||||
classdef = 323
|
||||
arglist = 324
|
||||
argument = 325
|
||||
list_iter = 326
|
||||
list_for = 327
|
||||
list_if = 328
|
||||
gen_iter = 329
|
||||
gen_for = 330
|
||||
gen_if = 331
|
||||
testlist1 = 332
|
||||
encoding_decl = 333
|
||||
#--end constants--
|
||||
|
||||
sym_name = {}
|
||||
|
|
|
@ -35,7 +35,8 @@ continue + try/finally ok
|
|||
testing continue and break in try/except in loop
|
||||
return_stmt
|
||||
raise_stmt
|
||||
import_stmt
|
||||
import_name
|
||||
import_from
|
||||
global_stmt
|
||||
exec_stmt
|
||||
assert_stmt
|
||||
|
|
|
@ -211,6 +211,47 @@ if 1:
|
|||
self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
|
||||
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():
|
||||
test_support.run_unittest(TestSpecifics)
|
||||
|
||||
|
|
|
@ -417,12 +417,16 @@ except RuntimeError: pass
|
|||
try: raise KeyboardInterrupt
|
||||
except KeyboardInterrupt: pass
|
||||
|
||||
print 'import_stmt' # 'import' NAME (',' NAME)* | 'from' NAME 'import' ('*' | NAME (',' NAME)*)
|
||||
print 'import_name' # 'import' dotted_as_names
|
||||
import 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 sys import *
|
||||
from sys import path, argv
|
||||
from sys import (path, argv)
|
||||
from sys import (path, argv,)
|
||||
|
||||
print 'global_stmt' # 'global' NAME (',' NAME)*
|
||||
def f():
|
||||
|
|
|
@ -130,12 +130,26 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
|
|||
def test_import_from_statement(self):
|
||||
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 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 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(
|
||||
"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):
|
||||
self.check_suite("import sys")
|
||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.4 alpha 3?
|
|||
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
|
||||
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
|
||||
|
@ -889,7 +892,7 @@ Library
|
|||
API matches math.log().
|
||||
|
||||
- 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.
|
||||
|
||||
|
|
|
@ -839,6 +839,7 @@ VALIDATER(expr_stmt); VALIDATER(power);
|
|||
VALIDATER(print_stmt); VALIDATER(del_stmt);
|
||||
VALIDATER(return_stmt); VALIDATER(list_iter);
|
||||
VALIDATER(raise_stmt); VALIDATER(import_stmt);
|
||||
VALIDATER(import_name); VALIDATER(import_from);
|
||||
VALIDATER(global_stmt); VALIDATER(list_if);
|
||||
VALIDATER(assert_stmt); VALIDATER(list_for);
|
||||
VALIDATER(exec_stmt); VALIDATER(compound_stmt);
|
||||
|
@ -1714,55 +1715,100 @@ validate_dotted_as_name(node *tree)
|
|||
}
|
||||
|
||||
|
||||
/* import_stmt:
|
||||
*
|
||||
* 'import' dotted_as_name (',' dotted_as_name)*
|
||||
* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
|
||||
/* dotted_as_name (',' dotted_as_name)* */
|
||||
static int
|
||||
validate_dotted_as_names(node *tree)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
int nch = NCH(tree);
|
||||
int res = (validate_ntype(tree, import_stmt)
|
||||
&& (nch >= 2) && is_even(nch)
|
||||
&& validate_ntype(CHILD(tree, 0), NAME));
|
||||
int res = validate_numnodes(tree, 1, "import_stmt");
|
||||
|
||||
if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
|
||||
int j;
|
||||
if (res) {
|
||||
int ntype = TYPE(CHILD(tree, 0));
|
||||
|
||||
res = validate_dotted_as_name(CHILD(tree, 1));
|
||||
for (j = 2; res && (j < nch); j += 2)
|
||||
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));
|
||||
}
|
||||
if (ntype == import_name || ntype == import_from)
|
||||
res = validate_node(CHILD(tree, 0));
|
||||
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)));
|
||||
res = 0;
|
||||
err_string("illegal import_stmt child type");
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (nch == 1) {
|
||||
res = 0;
|
||||
|
||||
PyErr_Format(parser_error,
|
||||
"Unrecognized child node of import_stmt: %d.",
|
||||
TYPE(CHILD(tree, 0)));
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
validate_global_stmt(node *tree)
|
||||
{
|
||||
|
@ -2823,6 +2869,12 @@ validate_node(node *tree)
|
|||
case import_stmt:
|
||||
res = validate_import_stmt(tree);
|
||||
break;
|
||||
case import_name:
|
||||
res = validate_import_name(tree);
|
||||
break;
|
||||
case import_from:
|
||||
res = validate_import_from(tree);
|
||||
break;
|
||||
case global_stmt:
|
||||
res = validate_global_stmt(tree);
|
||||
break;
|
||||
|
|
|
@ -3490,42 +3490,53 @@ com_from_import(struct compiling *c, node *n)
|
|||
static void
|
||||
com_import_stmt(struct compiling *c, node *n)
|
||||
{
|
||||
node *nn;
|
||||
int i;
|
||||
REQ(n, import_stmt);
|
||||
/* 'import' dotted_name (',' dotted_name)* |
|
||||
'from' dotted_name 'import' ('*' | NAME (',' NAME)*) */
|
||||
if (STR(CHILD(n, 0))[0] == 'f') {
|
||||
n = CHILD(n, 0);
|
||||
/* import_stmt: import_name | import_from */
|
||||
if (TYPE(n) == import_from) {
|
||||
/* 'from' dotted_name 'import' ('*' |
|
||||
'(' import_as_names ')' | import_as_names) */
|
||||
PyObject *tup;
|
||||
/* 'from' dotted_name 'import' ... */
|
||||
REQ(CHILD(n, 1), dotted_name);
|
||||
|
||||
if (TYPE(CHILD(n, 3)) == STAR) {
|
||||
nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
|
||||
if (TYPE(nn) == STAR)
|
||||
tup = Py_BuildValue("(s)", "*");
|
||||
} else {
|
||||
tup = PyTuple_New((NCH(n) - 2)/2);
|
||||
for (i = 3; i < NCH(n); i += 2) {
|
||||
PyTuple_SET_ITEM(tup, (i-3)/2,
|
||||
PyString_FromString(STR(
|
||||
CHILD(CHILD(n, i), 0))));
|
||||
else {
|
||||
if (TYPE(CHILD(nn, NCH(nn) - 1)) == COMMA &&
|
||||
TYPE(CHILD(n, 3)) != LPAR) {
|
||||
com_error(c, PyExc_SyntaxError,
|
||||
"trailing comma not allowed "
|
||||
"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));
|
||||
Py_DECREF(tup);
|
||||
com_push(c, 1);
|
||||
com_addopname(c, IMPORT_NAME, CHILD(n, 1));
|
||||
if (TYPE(CHILD(n, 3)) == STAR)
|
||||
if (TYPE(nn) == STAR)
|
||||
com_addbyte(c, IMPORT_STAR);
|
||||
else {
|
||||
for (i = 3; i < NCH(n); i += 2)
|
||||
com_from_import(c, CHILD(n, i));
|
||||
for (i = 0; i < NCH(nn); i += 2)
|
||||
com_from_import(c, CHILD(nn, i));
|
||||
com_addbyte(c, POP_TOP);
|
||||
}
|
||||
com_pop(c, 1);
|
||||
}
|
||||
else {
|
||||
/* 'import' ... */
|
||||
for (i = 1; i < NCH(n); i += 2) {
|
||||
node *subn = CHILD(n, i);
|
||||
/* 'import' dotted_as_names */
|
||||
nn = CHILD(n, 1);
|
||||
REQ(nn, dotted_as_names);
|
||||
for (i = 0; i < NCH(nn); i += 2) {
|
||||
node *subn = CHILD(nn, i);
|
||||
REQ(subn, dotted_as_name);
|
||||
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
|
||||
com_push(c, 1);
|
||||
|
@ -6291,14 +6302,15 @@ symtable_gen_iter(struct symtable *st, node *n)
|
|||
static void
|
||||
symtable_import(struct symtable *st, node *n)
|
||||
{
|
||||
node *nn;
|
||||
int i;
|
||||
/* import_stmt: 'import' dotted_as_name (',' dotted_as_name)*
|
||||
| 'from' dotted_name 'import'
|
||||
('*' | import_as_name (',' import_as_name)*)
|
||||
import_as_name: NAME [NAME NAME]
|
||||
*/
|
||||
if (STR(CHILD(n, 0))[0] == 'f') { /* from */
|
||||
/* import_stmt: import_name | import_from */
|
||||
n = CHILD(n, 0);
|
||||
if (TYPE(n) == import_from) {
|
||||
/* import_from: 'from' dotted_name 'import' ('*' |
|
||||
| '(' import_as_names ')' | import_as_names) */
|
||||
node *dotname = CHILD(n, 1);
|
||||
REQ(dotname, dotted_name);
|
||||
if (strcmp(STR(CHILD(dotname, 0)), "__future__") == 0) {
|
||||
/* check for bogus imports */
|
||||
if (n->n_lineno >= st->st_future->ff_last_lineno) {
|
||||
|
@ -6308,7 +6320,8 @@ symtable_import(struct symtable *st, node *n)
|
|||
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 (symtable_warn(st,
|
||||
"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_opt_lineno = n->n_lineno;
|
||||
} else {
|
||||
for (i = 3; i < NCH(n); i += 2) {
|
||||
node *c = CHILD(n, i);
|
||||
REQ(nn, import_as_names);
|
||||
for (i = 0; i < NCH(nn); i += 2) {
|
||||
node *c = CHILD(nn, i);
|
||||
if (NCH(c) > 1) /* import as */
|
||||
symtable_assign(st, CHILD(c, 2),
|
||||
DEF_IMPORT);
|
||||
|
@ -6328,9 +6342,11 @@ symtable_import(struct symtable *st, node *n)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < NCH(n); i += 2) {
|
||||
symtable_assign(st, CHILD(n, i), DEF_IMPORT);
|
||||
}
|
||||
/* 'import' dotted_as_names */
|
||||
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;
|
||||
char *feature;
|
||||
node *ch;
|
||||
node *ch, *nn;
|
||||
|
||||
REQ(n, import_stmt); /* must by from __future__ import ... */
|
||||
|
||||
for (i = 3; i < NCH(n); i += 2) {
|
||||
ch = CHILD(n, i);
|
||||
if (TYPE(ch) == STAR) {
|
||||
PyErr_SetString(PyExc_SyntaxError,
|
||||
FUTURE_IMPORT_STAR);
|
||||
PyErr_SyntaxLocation(filename, ch->n_lineno);
|
||||
return -1;
|
||||
}
|
||||
REQ(n, import_from);
|
||||
nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
|
||||
if (TYPE(nn) == STAR) {
|
||||
PyErr_SetString(PyExc_SyntaxError, FUTURE_IMPORT_STAR);
|
||||
PyErr_SyntaxLocation(filename, nn->n_lineno);
|
||||
return -1;
|
||||
}
|
||||
REQ(nn, import_as_names);
|
||||
for (i = 0; i < NCH(nn); i += 2) {
|
||||
ch = CHILD(nn, i);
|
||||
REQ(ch, import_as_name);
|
||||
feature = STR(CHILD(ch, 0));
|
||||
if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
|
||||
|
@ -188,7 +188,8 @@ future_parse(PyFutureFeatures *ff, node *n, const char *filename)
|
|||
case import_stmt: {
|
||||
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;
|
||||
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