mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +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} |   \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 @@ def raise_stmt(self, nodelist): | ||||||
|         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 = [] |  | ||||||
|             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 |  | ||||||
| 
 | 
 | ||||||
|         if nodelist[1][0] == symbol.dotted_name: |     def import_name(self, nodelist): | ||||||
|             names = [(self.com_dotted_name(nodelist[1][1:]), None)] |         # 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: |         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 @@ def com_dotted_name(self, node): | ||||||
|         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:] | ||||||
|  |         assert node[0][0] == token.NAME | ||||||
|         if len(node) == 1: |         if len(node) == 1: | ||||||
|             assert node[0][0] == token.NAME |  | ||||||
|             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 @@ | ||||||
| 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 @@ def test_none_assignment(self): | ||||||
|             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 @@ def g2(): return 1 | ||||||
| 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 @@ def test_function_defs(self): | ||||||
|     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
 |             res = 0; | ||||||
|              *      (',' import_as_name)+ |             err_string("illegal import_stmt child type"); | ||||||
|              */ |  | ||||||
|             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 |     else if (nch == 1) { | ||||||
|         res = 0; |         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); | ||||||
|  | @ -6327,10 +6341,12 @@ symtable_import(struct symtable *st, node *n) | ||||||
| 							DEF_IMPORT); | 							DEF_IMPORT); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} 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, | 		return -1; | ||||||
| 					FUTURE_IMPORT_STAR); | 	} | ||||||
| 			PyErr_SyntaxLocation(filename, ch->n_lineno); | 	REQ(nn, import_as_names); | ||||||
| 			return -1; | 	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Anthony Baxter
						Anthony Baxter