summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/compiler/transformer.py76
-rwxr-xr-xLib/symbol.py102
-rw-r--r--Lib/test/output/test_grammar3
-rw-r--r--Lib/test/test_compile.py41
-rw-r--r--Lib/test/test_grammar.py6
-rw-r--r--Lib/test/test_parser.py14
6 files changed, 159 insertions, 83 deletions
diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py
index cdeb5ffdc2..9fb18c28ae 100644
--- a/Lib/compiler/transformer.py
+++ b/Lib/compiler/transformer.py
@@ -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):
diff --git a/Lib/symbol.py b/Lib/symbol.py
index cb57208005..eaf5a2581d 100755
--- a/Lib/symbol.py
+++ b/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 = {}
diff --git a/Lib/test/output/test_grammar b/Lib/test/output/test_grammar
index 00fab49a6d..6174e7aca7 100644
--- a/Lib/test/output/test_grammar
+++ b/Lib/test/output/test_grammar
@@ -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
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index b1644cb35e..5011d03685 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -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)
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index e0d5b745d6..7f5d10d1e5 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -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():
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index 978ce5712c..0f8c1d0d0a 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -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")