mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	SF patch #1007189, multi-line imports, for instance:
"from blah import (foo, bar baz, bongo)"
This commit is contained in:
		
							parent
							
								
									876032e570
								
							
						
					
					
						commit
						1a4ddaecc7
					
				
					 14 changed files with 1394 additions and 1181 deletions
				
			
		|  | @ -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 @@ def raise_stmt(self, nodelist): | |||
|         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) | ||||
|         # import_stmt: import_name | import_from | ||||
|         assert len(nodelist) == 1 | ||||
|         return self.com_node(nodelist[0]) | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
|         if nodelist[1][0] == symbol.dotted_name: | ||||
|             names = [(self.com_dotted_name(nodelist[1][1:]), None)] | ||||
|     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 @@ def com_dotted_name(self, node): | |||
|         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:] | ||||
|         if len(node) == 1: | ||||
|         assert node[0][0] == token.NAME | ||||
|         if len(node) == 1: | ||||
|             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 @@ | |||
| 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 @@ def test_none_assignment(self): | |||
|             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 @@ def g2(): return 1 | |||
| 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 @@ def test_function_defs(self): | |||
|     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))); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|             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); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 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); | ||||
| 	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Anthony Baxter
						Anthony Baxter