Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c150536b
Commit
c150536b
authored
Dec 28, 2006
by
Neal Norwitz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PEP 3107 - Function Annotations thanks to Tony Lownds
parent
f6657e67
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
2704 additions
and
1746 deletions
+2704
-1746
Grammar/Grammar
Grammar/Grammar
+14
-7
Include/Python-ast.h
Include/Python-ast.h
+28
-4
Include/funcobject.h
Include/funcobject.h
+5
-0
Include/graminit.h
Include/graminit.h
+81
-76
Include/token.h
Include/token.h
+4
-3
Lib/compiler/ast.py
Lib/compiler/ast.py
+76
-12
Lib/compiler/pyassem.py
Lib/compiler/pyassem.py
+33
-11
Lib/compiler/pycodegen.py
Lib/compiler/pycodegen.py
+62
-15
Lib/compiler/symbols.py
Lib/compiler/symbols.py
+14
-7
Lib/compiler/transformer.py
Lib/compiler/transformer.py
+79
-39
Lib/symbol.py
Lib/symbol.py
+81
-76
Lib/test/output/test_tokenize
Lib/test/output/test_tokenize
+17
-1
Lib/test/test_ast.py
Lib/test/test_ast.py
+4
-4
Lib/test/test_compiler.py
Lib/test/test_compiler.py
+38
-3
Lib/test/test_grammar.py
Lib/test/test_grammar.py
+38
-10
Lib/test/test_tokenize.py
Lib/test/test_tokenize.py
+10
-0
Lib/test/tokenize_tests.txt
Lib/test/tokenize_tests.txt
+3
-0
Lib/token.py
Lib/token.py
+4
-3
Lib/tokenize.py
Lib/tokenize.py
+1
-1
Misc/NEWS
Misc/NEWS
+2
-0
Modules/parsermodule.c
Modules/parsermodule.c
+91
-44
Objects/funcobject.c
Objects/funcobject.c
+71
-0
Parser/Python.asdl
Parser/Python.asdl
+7
-3
Parser/tokenizer.c
Parser/tokenizer.c
+2
-0
Python/Python-ast.c
Python/Python-ast.c
+131
-8
Python/ast.c
Python/ast.c
+173
-130
Python/ceval.c
Python/ceval.c
+28
-0
Python/compile.c
Python/compile.c
+133
-8
Python/graminit.c
Python/graminit.c
+1410
-1257
Python/symtable.c
Python/symtable.c
+53
-20
Tools/compiler/ast.txt
Tools/compiler/ast.txt
+7
-3
Tools/compiler/astgen.py
Tools/compiler/astgen.py
+4
-1
No files found.
Grammar/Grammar
View file @
c150536b
...
...
@@ -21,13 +21,20 @@ eval_input: testlist NEWLINE* ENDMARKER
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
funcdef: [decorators] 'def' NAME parameters ':' suite
parameters: '(' [varargslist] ')'
varargslist: ((fpdef ['=' test] ',')*
('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME) |
fpdef ['=' test] (',' fpdef ['=' test])* [','])
fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')*
('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
| tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
tname: NAME [':' test]
tfpdef: tname | '(' tfplist ')'
tfplist: tfpdef (',' tfpdef)* [',']
varargslist: ((vfpdef ['=' test] ',')*
('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
| vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
vname: NAME
vfpdef: vname | '(' vfplist ')'
vfplist: vfpdef (',' vfpdef)* [',']
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
...
...
Include/Python-ast.h
View file @
c150536b
...
...
@@ -30,6 +30,8 @@ typedef struct _excepthandler *excepthandler_ty;
typedef
struct
_arguments
*
arguments_ty
;
typedef
struct
_arg
*
arg_ty
;
typedef
struct
_keyword
*
keyword_ty
;
typedef
struct
_alias
*
alias_ty
;
...
...
@@ -74,6 +76,7 @@ struct _stmt {
arguments_ty
args
;
asdl_seq
*
body
;
asdl_seq
*
decorators
;
expr_ty
returns
;
}
FunctionDef
;
struct
{
...
...
@@ -328,12 +331,30 @@ struct _excepthandler {
struct
_arguments
{
asdl_seq
*
args
;
identifier
vararg
;
expr_ty
varargannotation
;
asdl_seq
*
kwonlyargs
;
identifier
kwarg
;
expr_ty
kwargannotation
;
asdl_seq
*
defaults
;
asdl_seq
*
kw_defaults
;
};
enum
_arg_kind
{
SimpleArg_kind
=
1
,
NestedArgs_kind
=
2
};
struct
_arg
{
enum
_arg_kind
kind
;
union
{
struct
{
identifier
arg
;
expr_ty
annotation
;
}
SimpleArg
;
struct
{
asdl_seq
*
args
;
}
NestedArgs
;
}
v
;
};
struct
_keyword
{
identifier
arg
;
expr_ty
value
;
...
...
@@ -350,8 +371,8 @@ mod_ty Interactive(asdl_seq * body, PyArena *arena);
mod_ty
Expression
(
expr_ty
body
,
PyArena
*
arena
);
mod_ty
Suite
(
asdl_seq
*
body
,
PyArena
*
arena
);
stmt_ty
FunctionDef
(
identifier
name
,
arguments_ty
args
,
asdl_seq
*
body
,
asdl_seq
*
decorators
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
asdl_seq
*
decorators
,
expr_ty
returns
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
stmt_ty
ClassDef
(
identifier
name
,
asdl_seq
*
bases
,
asdl_seq
*
body
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
stmt_ty
Return
(
expr_ty
value
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
...
...
@@ -429,9 +450,12 @@ comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs,
PyArena
*
arena
);
excepthandler_ty
excepthandler
(
expr_ty
type
,
expr_ty
name
,
asdl_seq
*
body
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
arguments_ty
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
asdl_seq
*
kwonlyargs
,
identifier
kwarg
,
asdl_seq
*
defaults
,
arguments_ty
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
expr_ty
varargannotation
,
asdl_seq
*
kwonlyargs
,
identifier
kwarg
,
expr_ty
kwargannotation
,
asdl_seq
*
defaults
,
asdl_seq
*
kw_defaults
,
PyArena
*
arena
);
arg_ty
SimpleArg
(
identifier
arg
,
expr_ty
annotation
,
PyArena
*
arena
);
arg_ty
NestedArgs
(
asdl_seq
*
args
,
PyArena
*
arena
);
keyword_ty
keyword
(
identifier
arg
,
expr_ty
value
,
PyArena
*
arena
);
alias_ty
alias
(
identifier
name
,
identifier
asname
,
PyArena
*
arena
);
...
...
Include/funcobject.h
View file @
c150536b
...
...
@@ -30,6 +30,7 @@ typedef struct {
PyObject
*
func_dict
;
/* The __dict__ attribute, a dict or NULL */
PyObject
*
func_weakreflist
;
/* List of weak references */
PyObject
*
func_module
;
/* The __module__ attribute, can be anything */
PyObject
*
func_annotations
;
/* Annotations, a dict or NULL */
/* Invariant:
* func_closure contains the bindings for func_code->co_freevars, so
...
...
@@ -52,6 +53,8 @@ PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *);
PyAPI_FUNC
(
int
)
PyFunction_SetKwDefaults
(
PyObject
*
,
PyObject
*
);
PyAPI_FUNC
(
PyObject
*
)
PyFunction_GetClosure
(
PyObject
*
);
PyAPI_FUNC
(
int
)
PyFunction_SetClosure
(
PyObject
*
,
PyObject
*
);
PyAPI_FUNC
(
PyObject
*
)
PyFunction_GetAnnotations
(
PyObject
*
);
PyAPI_FUNC
(
int
)
PyFunction_SetAnnotations
(
PyObject
*
,
PyObject
*
);
/* Macros for direct access to these values. Type checks are *not*
done, so use with care. */
...
...
@@ -67,6 +70,8 @@ PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
(((PyFunctionObject *)func) -> func_kwdefaults)
#define PyFunction_GET_CLOSURE(func) \
(((PyFunctionObject *)func) -> func_closure)
#define PyFunction_GET_ANNOTATIONS(func) \
(((PyFunctionObject *)func) -> func_annotations)
/* The classmethod and staticmethod types lives here, too */
PyAPI_DATA
(
PyTypeObject
)
PyClassMethod_Type
;
...
...
Include/graminit.h
View file @
c150536b
...
...
@@ -5,79 +5,84 @@
#define decorators 260
#define funcdef 261
#define parameters 262
#define varargslist 263
#define fpdef 264
#define fplist 265
#define stmt 266
#define simple_stmt 267
#define small_stmt 268
#define expr_stmt 269
#define augassign 270
#define print_stmt 271
#define del_stmt 272
#define pass_stmt 273
#define flow_stmt 274
#define break_stmt 275
#define continue_stmt 276
#define return_stmt 277
#define yield_stmt 278
#define raise_stmt 279
#define import_stmt 280
#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 assert_stmt 289
#define compound_stmt 290
#define if_stmt 291
#define while_stmt 292
#define for_stmt 293
#define try_stmt 294
#define with_stmt 295
#define with_var 296
#define except_clause 297
#define suite 298
#define testlist_safe 299
#define old_test 300
#define old_lambdef 301
#define test 302
#define or_test 303
#define and_test 304
#define not_test 305
#define comparison 306
#define comp_op 307
#define expr 308
#define xor_expr 309
#define and_expr 310
#define shift_expr 311
#define arith_expr 312
#define term 313
#define factor 314
#define power 315
#define atom 316
#define listmaker 317
#define testlist_gexp 318
#define lambdef 319
#define trailer 320
#define subscriptlist 321
#define subscript 322
#define sliceop 323
#define exprlist 324
#define testlist 325
#define dictsetmaker 326
#define classdef 327
#define arglist 328
#define argument 329
#define list_iter 330
#define list_for 331
#define list_if 332
#define gen_iter 333
#define gen_for 334
#define gen_if 335
#define testlist1 336
#define encoding_decl 337
#define yield_expr 338
#define typedargslist 263
#define tname 264
#define tfpdef 265
#define tfplist 266
#define varargslist 267
#define vname 268
#define vfpdef 269
#define vfplist 270
#define stmt 271
#define simple_stmt 272
#define small_stmt 273
#define expr_stmt 274
#define augassign 275
#define print_stmt 276
#define del_stmt 277
#define pass_stmt 278
#define flow_stmt 279
#define break_stmt 280
#define continue_stmt 281
#define return_stmt 282
#define yield_stmt 283
#define raise_stmt 284
#define import_stmt 285
#define import_name 286
#define import_from 287
#define import_as_name 288
#define dotted_as_name 289
#define import_as_names 290
#define dotted_as_names 291
#define dotted_name 292
#define global_stmt 293
#define assert_stmt 294
#define compound_stmt 295
#define if_stmt 296
#define while_stmt 297
#define for_stmt 298
#define try_stmt 299
#define with_stmt 300
#define with_var 301
#define except_clause 302
#define suite 303
#define testlist_safe 304
#define old_test 305
#define old_lambdef 306
#define test 307
#define or_test 308
#define and_test 309
#define not_test 310
#define comparison 311
#define comp_op 312
#define expr 313
#define xor_expr 314
#define and_expr 315
#define shift_expr 316
#define arith_expr 317
#define term 318
#define factor 319
#define power 320
#define atom 321
#define listmaker 322
#define testlist_gexp 323
#define lambdef 324
#define trailer 325
#define subscriptlist 326
#define subscript 327
#define sliceop 328
#define exprlist 329
#define testlist 330
#define dictsetmaker 331
#define classdef 332
#define arglist 333
#define argument 334
#define list_iter 335
#define list_for 336
#define list_if 337
#define gen_iter 338
#define gen_for 339
#define gen_if 340
#define testlist1 341
#define encoding_decl 342
#define yield_expr 343
Include/token.h
View file @
c150536b
...
...
@@ -58,10 +58,11 @@ extern "C" {
#define DOUBLESLASH 48
#define DOUBLESLASHEQUAL 49
#define AT 50
#define RARROW 51
/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */
#define OP 5
1
#define ERRORTOKEN 5
2
#define N_TOKENS 5
3
#define OP 5
2
#define ERRORTOKEN 5
3
#define N_TOKENS 5
4
/* Special definitions for cooperation with parser */
...
...
Lib/compiler/ast.py
View file @
c150536b
...
...
@@ -33,7 +33,10 @@ class Node:
pass
# implemented by subclasses
class
EmptyNode
(
Node
):
pass
def
getChildNodes
(
self
):
return
()
def
getChildren
(
self
):
return
()
class
Expression
(
Node
):
# Expression is an artificial node class to support "eval"
...
...
@@ -487,12 +490,13 @@ class From(Node):
return
"From(%s, %s, %s)"
%
(
repr
(
self
.
modname
),
repr
(
self
.
names
),
repr
(
self
.
level
))
class
Function
(
Node
):
def
__init__
(
self
,
decorators
,
name
,
arg
names
,
defaults
,
kwonlyarg
s
,
flags
,
doc
,
code
,
lineno
=
None
):
def
__init__
(
self
,
decorators
,
name
,
arg
uments
,
defaults
,
kwonlyargs
,
return
s
,
flags
,
doc
,
code
,
lineno
=
None
):
self
.
decorators
=
decorators
self
.
name
=
name
self
.
arg
names
=
argname
s
self
.
arg
uments
=
argument
s
self
.
defaults
=
defaults
self
.
kwonlyargs
=
kwonlyargs
self
.
returns
=
returns
self
.
flags
=
flags
self
.
doc
=
doc
self
.
code
=
code
...
...
@@ -508,9 +512,10 @@ class Function(Node):
children
=
[]
children
.
append
(
self
.
decorators
)
children
.
append
(
self
.
name
)
children
.
append
(
self
.
argnames
)
children
.
extend
(
flatten
(
self
.
arguments
)
)
children
.
extend
(
flatten
(
self
.
defaults
))
children
.
append
(
self
.
kwonlyargs
)
children
.
extend
(
flatten
(
self
.
kwonlyargs
))
children
.
append
(
self
.
returns
)
children
.
append
(
self
.
flags
)
children
.
append
(
self
.
doc
)
children
.
append
(
self
.
code
)
...
...
@@ -520,18 +525,22 @@ class Function(Node):
nodelist
=
[]
if
self
.
decorators
is
not
None
:
nodelist
.
append
(
self
.
decorators
)
nodelist
.
extend
(
flatten_nodes
(
self
.
arguments
))
nodelist
.
extend
(
flatten_nodes
(
self
.
defaults
))
nodelist
.
extend
(
flatten_nodes
(
self
.
kwonlyargs
))
if
self
.
returns
is
not
None
:
nodelist
.
append
(
self
.
returns
)
nodelist
.
append
(
self
.
code
)
return
tuple
(
nodelist
)
def
__repr__
(
self
):
return
"Function(%s, %s, %s, %s, %s, %s, %s, %s
)"
%
(
repr
(
self
.
decorators
),
repr
(
self
.
name
),
repr
(
self
.
argnames
),
repr
(
self
.
defaults
),
repr
(
self
.
kwonlyarg
s
),
repr
(
self
.
flags
),
repr
(
self
.
doc
),
repr
(
self
.
code
))
return
"Function(%s, %s, %s, %s, %s, %s, %s, %s
, %s)"
%
(
repr
(
self
.
decorators
),
repr
(
self
.
name
),
repr
(
self
.
arguments
),
repr
(
self
.
defaults
),
repr
(
self
.
kwonlyargs
),
repr
(
self
.
return
s
),
repr
(
self
.
flags
),
repr
(
self
.
doc
),
repr
(
self
.
code
))
class
GenExpr
(
Node
):
def
__init__
(
self
,
code
,
lineno
=
None
):
self
.
code
=
code
self
.
lineno
=
lineno
self
.
arg
names
=
[
'.0'
]
self
.
arg
uments
=
[
SimpleArg
(
'.0'
,
None
)
]
self
.
varargs
=
self
.
kwargs
=
None
self
.
kwonlyargs
=
()
...
...
@@ -715,9 +724,24 @@ class Keyword(Node):
def
__repr__
(
self
):
return
"Keyword(%s, %s)"
%
(
repr
(
self
.
name
),
repr
(
self
.
expr
))
class
Kwarg
(
Node
):
def
__init__
(
self
,
arg
,
expr
,
lineno
=
None
):
self
.
arg
=
arg
self
.
expr
=
expr
self
.
lineno
=
lineno
def
getChildren
(
self
):
return
self
.
arg
,
self
.
expr
def
getChildNodes
(
self
):
return
self
.
arg
,
self
.
expr
def
__repr__
(
self
):
return
"Kwarg(%s, %s)"
%
(
repr
(
self
.
arg
),
repr
(
self
.
expr
))
class
Lambda
(
Node
):
def
__init__
(
self
,
arg
name
s
,
defaults
,
kwonlyargs
,
flags
,
code
,
lineno
=
None
):
self
.
arg
names
=
argname
s
def
__init__
(
self
,
arg
ument
s
,
defaults
,
kwonlyargs
,
flags
,
code
,
lineno
=
None
):
self
.
arg
uments
=
argument
s
self
.
defaults
=
defaults
self
.
kwonlyargs
=
kwonlyargs
self
.
flags
=
flags
...
...
@@ -728,25 +752,28 @@ class Lambda(Node):
self
.
varargs
=
1
if
flags
&
CO_VARKEYWORDS
:
self
.
kwargs
=
1
self
.
returns
=
None
def
getChildren
(
self
):
children
=
[]
children
.
append
(
self
.
argnames
)
children
.
extend
(
flatten
(
self
.
arguments
)
)
children
.
extend
(
flatten
(
self
.
defaults
))
children
.
append
(
self
.
kwonlyargs
)
children
.
extend
(
flatten
(
self
.
kwonlyargs
)
)
children
.
append
(
self
.
flags
)
children
.
append
(
self
.
code
)
return
tuple
(
children
)
def
getChildNodes
(
self
):
nodelist
=
[]
nodelist
.
extend
(
flatten_nodes
(
self
.
arguments
))
nodelist
.
extend
(
flatten_nodes
(
self
.
defaults
))
nodelist
.
extend
(
flatten_nodes
(
self
.
kwonlyargs
))
nodelist
.
append
(
self
.
code
)
return
tuple
(
nodelist
)
def
__repr__
(
self
):
return
"Lambda(%s, %s, %s, %s, %s)"
%
(
repr
(
self
.
arg
name
s
),
repr
(
self
.
defaults
),
repr
(
self
.
kwonlyargs
),
repr
(
self
.
flags
),
repr
(
self
.
code
))
return
"Lambda(%s, %s, %s, %s, %s)"
%
(
repr
(
self
.
arg
ument
s
),
repr
(
self
.
defaults
),
repr
(
self
.
kwonlyargs
),
repr
(
self
.
flags
),
repr
(
self
.
code
))
class
LeftShift
(
Node
):
def
__init__
(
self
,
(
left
,
right
),
lineno
=
None
):
...
...
@@ -897,6 +924,22 @@ class Name(Node):
def
__repr__
(
self
):
return
"Name(%s)"
%
(
repr
(
self
.
name
),)
class
NestedArgs
(
Node
):
def
__init__
(
self
,
args
,
lineno
=
None
):
self
.
args
=
args
self
.
lineno
=
lineno
def
getChildren
(
self
):
return
tuple
(
flatten
(
self
.
args
))
def
getChildNodes
(
self
):
nodelist
=
[]
nodelist
.
extend
(
flatten_nodes
(
self
.
args
))
return
tuple
(
nodelist
)
def
__repr__
(
self
):
return
"NestedArgs(%s)"
%
(
repr
(
self
.
args
),)
class
Not
(
Node
):
def
__init__
(
self
,
expr
,
lineno
=
None
):
self
.
expr
=
expr
...
...
@@ -1071,6 +1114,27 @@ class Set(Node):
def
__repr__
(
self
):
return
"Set(%s)"
%
(
repr
(
self
.
items
),)
class
SimpleArg
(
Node
):
def
__init__
(
self
,
name
,
annotation
,
lineno
=
None
):
self
.
name
=
name
self
.
annotation
=
annotation
self
.
lineno
=
lineno
def
getChildren
(
self
):
children
=
[]
children
.
append
(
self
.
name
)
children
.
append
(
self
.
annotation
)
return
tuple
(
children
)
def
getChildNodes
(
self
):
nodelist
=
[]
if
self
.
annotation
is
not
None
:
nodelist
.
append
(
self
.
annotation
)
return
tuple
(
nodelist
)
def
__repr__
(
self
):
return
"SimpleArg(%s, %s)"
%
(
repr
(
self
.
name
),
repr
(
self
.
annotation
))
class
Slice
(
Node
):
def
__init__
(
self
,
expr
,
flags
,
lower
,
upper
,
lineno
=
None
):
self
.
expr
=
expr
...
...
Lib/compiler/pyassem.py
View file @
c150536b
...
...
@@ -314,7 +314,7 @@ class PyFlowGraph(FlowGraph):
super_init
=
FlowGraph
.
__init__
def
__init__
(
self
,
name
,
filename
,
args
=
(),
kwonlyargs
=
{}
,
optimized
=
0
,
klass
=
None
):
args
=
(),
kwonlyargs
=
()
,
optimized
=
0
,
klass
=
None
):
self
.
super_init
()
self
.
name
=
name
self
.
filename
=
filename
...
...
@@ -338,24 +338,40 @@ class PyFlowGraph(FlowGraph):
# The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both
# kinds of variables.
self
.
closure
=
[]
self
.
varnames
=
list
(
args
)
or
[]
for
i
in
range
(
len
(
self
.
varnames
)):
# The varnames list needs to be computed after flags have been set
self
.
varnames
=
[]
self
.
stage
=
RAW
def
computeVarnames
(
self
):
# self.args is positional, vararg, kwarg, kwonly, unpacked. This
# order is due to the visit order in symbol module and could change.
# argcount is # len(self.args) - len(unpacked). We want
# self.varnames to be positional, kwonly, vararg, kwarg, unpacked
# and argcount to be len(positional).
# determine starting index of unpacked, kwonly, vararg
u
=
self
.
argcount
# starting index of unpacked
k
=
u
-
len
(
self
.
kwonlyargs
)
# starting index of kwonly
v
=
k
-
self
.
checkFlag
(
CO_VARARGS
)
-
self
.
checkFlag
(
CO_VARKEYWORDS
)
vars
=
list
(
self
.
args
)
self
.
varnames
=
vars
[:
v
]
+
vars
[
k
:
u
]
+
vars
[
v
:
k
]
+
vars
[
u
:]
self
.
argcount
=
v
# replace TupleArgs with calculated var name
for
i
in
range
(
self
.
argcount
):
var
=
self
.
varnames
[
i
]
if
isinstance
(
var
,
TupleArg
):
self
.
varnames
[
i
]
=
var
.
getName
()
self
.
stage
=
RAW
def
setDocstring
(
self
,
doc
):
self
.
docstring
=
doc
def
setFlag
(
self
,
flag
):
self
.
flags
=
self
.
flags
|
flag
if
flag
==
CO_VARARGS
:
self
.
argcount
=
self
.
argcount
-
1
def
checkFlag
(
self
,
flag
):
if
self
.
flags
&
flag
:
return
1
return
(
self
.
flags
&
flag
)
==
flag
def
setFreeVars
(
self
,
names
):
self
.
freevars
=
list
(
names
)
...
...
@@ -366,6 +382,7 @@ class PyFlowGraph(FlowGraph):
def
getCode
(
self
):
"""Get a Python code object"""
assert
self
.
stage
==
RAW
self
.
computeVarnames
()
self
.
computeStackDepth
()
self
.
flattenGraph
()
assert
self
.
stage
==
FLAT
...
...
@@ -575,6 +592,12 @@ class PyFlowGraph(FlowGraph):
lnotab
.
nextLine
(
oparg
)
continue
hi
,
lo
=
twobyte
(
oparg
)
extended
,
hi
=
twobyte
(
hi
)
if
extended
:
ehi
,
elo
=
twobyte
(
extended
)
lnotab
.
addCode
(
self
.
opnum
[
'EXTENDED_ARG'
],
elo
,
ehi
)
try
:
lnotab
.
addCode
(
self
.
opnum
[
opname
],
lo
,
hi
)
except
ValueError
:
...
...
@@ -595,8 +618,6 @@ class PyFlowGraph(FlowGraph):
else
:
nlocals
=
len
(
self
.
varnames
)
argcount
=
self
.
argcount
if
self
.
flags
&
CO_VARKEYWORDS
:
argcount
=
argcount
-
1
kwonlyargcount
=
len
(
self
.
kwonlyargs
)
return
new
.
code
(
argcount
,
kwonlyargcount
,
nlocals
,
self
.
stacksize
,
self
.
flags
,
...
...
@@ -809,7 +830,8 @@ class StackDepthTracker:
return
self
.
CALL_FUNCTION
(
argc
)
-
2
def
MAKE_FUNCTION
(
self
,
argc
):
hi
,
lo
=
divmod
(
argc
,
256
)
return
-
(
lo
+
hi
*
2
)
ehi
,
hi
=
divmod
(
hi
,
256
)
return
-
(
lo
+
hi
*
2
+
ehi
)
def
MAKE_CLOSURE
(
self
,
argc
):
# XXX need to account for free variables too!
return
-
argc
...
...
Lib/compiler/pycodegen.py
View file @
c150536b
...
...
@@ -378,18 +378,57 @@ class CodeGenerator:
walk
(
node
.
code
,
gen
)
gen
.
finish
()
self
.
set_lineno
(
node
)
num_kwargs
=
0
for
keyword
in
node
.
kwonlyargs
:
default
=
keyword
.
expr
if
isinstance
(
default
,
ast
.
EmptyNode
):
continue
self
.
emit
(
'LOAD_CONST'
,
keyword
.
name
)
self
.
emit
(
'LOAD_CONST'
,
keyword
.
arg
.
name
)
self
.
visit
(
default
)
num_kwargs
+=
1
for
default
in
node
.
defaults
:
self
.
visit
(
default
)
self
.
_makeClosure
(
gen
,
len
(
node
.
defaults
))
num_annotations
=
self
.
_visit_annotations
(
node
)
oparg
=
len
(
node
.
defaults
)
oparg
|=
num_kwargs
<<
8
oparg
|=
num_annotations
<<
16
self
.
_makeClosure
(
gen
,
oparg
)
for
i
in
range
(
ndecorators
):
self
.
emit
(
'CALL_FUNCTION'
,
1
)
def
_visit_annotations
(
self
,
node
):
# emit code, return num_annotations
annotations
=
[]
annotations
.
extend
(
self
.
_visit_argument_annotations
(
node
.
arguments
))
annotations
.
extend
(
self
.
_visit_kwarg_annotations
(
node
.
kwonlyargs
))
if
node
.
returns
:
self
.
visit
(
node
.
returns
)
annotations
.
append
(
'return'
)
if
not
annotations
:
return
0
self
.
emit
(
'LOAD_CONST'
,
tuple
(
annotations
))
return
len
(
annotations
)
+
1
def
_visit_argument_annotations
(
self
,
arguments
):
for
arg
in
arguments
:
if
isinstance
(
arg
,
ast
.
SimpleArg
):
if
arg
.
annotation
:
self
.
visit
(
arg
.
annotation
)
yield
arg
.
name
else
:
for
name
in
self
.
_visit_argument_annotations
(
arg
.
args
):
yield
name
def
_visit_kwarg_annotations
(
self
,
kwargs
):
for
kwarg
in
kwargs
:
arg
=
kwarg
.
arg
if
arg
.
annotation
:
self
.
visit
(
arg
.
annotation
)
yield
arg
.
name
def
visitClass
(
self
,
node
):
gen
=
self
.
ClassGen
(
node
,
self
.
scopes
,
self
.
get_module
())
...
...
@@ -1323,7 +1362,7 @@ class AbstractFunctionCode:
else
:
name
=
func
.
name
args
,
hasTupleArg
=
generateArgList
(
func
.
arg
name
s
)
args
,
hasTupleArg
=
generateArgList
(
func
.
arg
ument
s
)
kwonlyargs
=
generateKwonlyArgList
(
func
.
kwonlyargs
)
self
.
graph
=
pyassem
.
PyFlowGraph
(
name
,
func
.
filename
,
args
,
kwonlyargs
=
kwonlyargs
,
...
...
@@ -1334,7 +1373,7 @@ class AbstractFunctionCode:
if
not
isLambda
and
func
.
doc
:
self
.
setDocstring
(
func
.
doc
)
lnf
=
walk
(
func
.
code
,
self
.
NameFinder
(
args
),
verbose
=
0
)
lnf
=
walk
(
func
.
code
,
self
.
NameFinder
(
args
+
kwonlyargs
),
verbose
=
0
)
self
.
locals
.
push
(
lnf
.
getLocals
())
if
func
.
varargs
:
self
.
graph
.
setFlag
(
CO_VARARGS
)
...
...
@@ -1342,7 +1381,7 @@ class AbstractFunctionCode:
self
.
graph
.
setFlag
(
CO_VARKEYWORDS
)
self
.
set_lineno
(
func
)
if
hasTupleArg
:
self
.
generateArgUnpack
(
func
.
arg
name
s
)
self
.
generateArgUnpack
(
func
.
arg
ument
s
)
def
get_module
(
self
):
return
self
.
module
...
...
@@ -1356,9 +1395,9 @@ class AbstractFunctionCode:
def
generateArgUnpack
(
self
,
args
):
for
i
in
range
(
len
(
args
)):
arg
=
args
[
i
]
if
isinstance
(
arg
,
tuple
):
if
isinstance
(
arg
,
ast
.
NestedArgs
):
self
.
emit
(
'LOAD_FAST'
,
'.%d'
%
(
i
*
2
))
self
.
unpackSequence
(
arg
)
self
.
unpackSequence
(
tuple
(
_nested_names
(
arg
))
)
def
unpackSequence
(
self
,
tup
):
if
VERSION
>
1
:
...
...
@@ -1452,21 +1491,29 @@ def generateArgList(arglist):
count
=
0
for
i
in
range
(
len
(
arglist
)):
elt
=
arglist
[
i
]
if
isinstance
(
elt
,
str
):
args
.
append
(
elt
)
elif
isinstance
(
elt
,
tuple
):
args
.
append
(
TupleArg
(
i
*
2
,
elt
))
extra
.
extend
(
misc
.
flatten
(
elt
))
if
isinstance
(
elt
,
ast
.
SimpleArg
):
args
.
append
(
elt
.
name
)
elif
isinstance
(
elt
,
ast
.
NestedArgs
):
t
=
tuple
(
_nested_names
(
elt
))
args
.
append
(
TupleArg
(
i
*
2
,
t
))
extra
.
extend
(
misc
.
flatten
(
t
))
count
=
count
+
1
else
:
raise
ValueError
,
"unexpect argument type:"
,
elt
return
args
+
extra
,
count
def
_nested_names
(
elt
):
for
arg
in
elt
.
args
:
if
isinstance
(
arg
,
ast
.
SimpleArg
):
yield
arg
.
name
elif
isinstance
(
arg
,
ast
.
NestedArgs
):
yield
tuple
(
_nested_names
(
arg
))
def
generateKwonlyArgList
(
keywordOnlyArgs
):
kwonlyargs
=
{}
kwonlyargs
=
[]
for
elt
in
keywordOnlyArgs
:
assert
isinstance
(
elt
,
ast
.
K
eyword
)
kwonlyargs
[
elt
.
name
]
=
elt
.
expr
assert
isinstance
(
elt
,
ast
.
K
warg
)
kwonlyargs
.
append
(
elt
.
arg
.
name
)
return
kwonlyargs
def
findOp
(
node
):
...
...
Lib/compiler/symbols.py
View file @
c150536b
...
...
@@ -233,7 +233,12 @@ class SymbolVisitor:
if
parent
.
nested
or
isinstance
(
parent
,
FunctionScope
):
scope
.
nested
=
1
self
.
scopes
[
node
]
=
scope
self
.
_do_args
(
scope
,
node
.
argnames
)
args
=
node
.
arguments
for
kwonly
in
node
.
kwonlyargs
:
args
.
append
(
kwonly
.
arg
)
self
.
_do_arguments
(
scope
,
args
)
self
.
visit
(
node
.
code
,
scope
)
self
.
handle_free_vars
(
scope
,
parent
)
...
...
@@ -275,16 +280,18 @@ class SymbolVisitor:
if
parent
.
nested
or
isinstance
(
parent
,
FunctionScope
):
scope
.
nested
=
1
self
.
scopes
[
node
]
=
scope
self
.
_do_arg
s
(
scope
,
node
.
argname
s
)
self
.
_do_arg
uments
(
scope
,
node
.
argument
s
)
self
.
visit
(
node
.
code
,
scope
)
self
.
handle_free_vars
(
scope
,
parent
)
def
_do_args
(
self
,
scope
,
args
):
for
name
in
args
:
if
type
(
name
)
==
types
.
TupleType
:
self
.
_do_args
(
scope
,
name
)
def
_do_arguments
(
self
,
scope
,
arguments
):
for
node
in
arguments
:
if
isinstance
(
node
,
ast
.
SimpleArg
):
scope
.
add_param
(
node
.
name
)
if
node
.
annotation
:
self
.
visit
(
node
.
annotation
,
scope
)
else
:
s
cope
.
add_param
(
name
)
s
elf
.
_do_arguments
(
scope
,
node
.
args
)
def
handle_free_vars
(
self
,
scope
,
parent
):
parent
.
add_child
(
scope
)
...
...
Lib/compiler/transformer.py
View file @
c150536b
...
...
@@ -234,25 +234,24 @@ class Transformer:
return
Decorators
(
items
)
def
funcdef
(
self
,
nodelist
):
# -6 -5 -4 -3 -2 -1
# funcdef: [decorators] 'def' NAME parameters ':' suite
# parameters: '(' [varargslist] ')'
if
len
(
nodelist
)
==
6
:
assert
nodelist
[
0
][
0
]
==
symbol
.
decorators
# 0 1 2 4 -1
# funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
# parameters: '(' [typedargslist] ')'
if
nodelist
[
0
][
0
]
==
symbol
.
decorators
:
decorators
=
self
.
decorators
(
nodelist
[
0
][
1
:])
nodelist
=
nodelist
[
1
:]
else
:
assert
len
(
nodelist
)
==
5
decorators
=
None
assert
len
(
nodelist
)
in
(
5
,
7
)
lineno
=
nodelist
[
-
4
][
2
]
name
=
nodelist
[
-
4
][
1
]
args
=
nodelist
[
-
3
][
2
]
lineno
=
nodelist
[
0
][
2
]
name
=
nodelist
[
1
][
1
]
args
=
nodelist
[
2
][
2
]
if
args
[
0
]
==
symbol
.
varargslist
:
names
,
defaults
,
kwonlyargs
,
flags
=
self
.
com_arglist
(
args
[
1
:])
if
args
[
0
]
==
symbol
.
varargslist
or
args
[
0
]
==
symbol
.
typedargslist
:
arguments
,
defaults
,
kwonly
,
flags
=
self
.
com_arglist
(
args
[
1
:])
else
:
names
=
defaults
=
kwonlyargs
=
()
arguments
=
defaults
=
kwonly
=
()
flags
=
0
doc
=
self
.
get_docstring
(
nodelist
[
-
1
])
...
...
@@ -263,22 +262,28 @@ class Transformer:
assert
isinstance
(
code
,
Stmt
)
assert
isinstance
(
code
.
nodes
[
0
],
Discard
)
del
code
.
nodes
[
0
]
return
Function
(
decorators
,
name
,
names
,
defaults
,
kwonlyargs
,
flags
,
doc
,
code
,
lineno
=
lineno
)
if
len
(
nodelist
)
==
7
:
returns
=
self
.
com_node
(
nodelist
[
4
])
else
:
returns
=
None
return
Function
(
decorators
,
name
,
arguments
,
defaults
,
kwonly
,
returns
,
flags
,
doc
,
code
,
lineno
=
lineno
)
def
lambdef
(
self
,
nodelist
):
# lambdef: 'lambda' [varargslist] ':' test
if
nodelist
[
2
][
0
]
==
symbol
.
varargslist
:
name
s
,
defaults
,
kwonlyargs
,
flags
=
\
argument
s
,
defaults
,
kwonlyargs
,
flags
=
\
self
.
com_arglist
(
nodelist
[
2
][
1
:])
else
:
name
s
=
defaults
=
kwonlyargs
=
()
argument
s
=
defaults
=
kwonlyargs
=
()
flags
=
0
# code for lambda
code
=
self
.
com_node
(
nodelist
[
-
1
])
return
Lambda
(
name
s
,
defaults
,
kwonlyargs
,
return
Lambda
(
argument
s
,
defaults
,
kwonlyargs
,
flags
,
code
,
lineno
=
nodelist
[
1
][
2
])
old_lambdef
=
lambdef
...
...
@@ -324,10 +329,25 @@ class Transformer:
def
varargslist
(
self
,
nodelist
):
raise
WalkerError
def
fpdef
(
self
,
nodelist
):
def
v
fpdef
(
self
,
nodelist
):
raise
WalkerError
def
fplist
(
self
,
nodelist
):
def
vfplist
(
self
,
nodelist
):
raise
WalkerError
def
vname
(
self
,
nodelist
):
raise
WalkerError
def
typedargslist
(
self
,
nodelist
):
raise
WalkerError
def
tfpdef
(
self
,
nodelist
):
raise
WalkerError
def
tfplist
(
self
,
nodelist
):
raise
WalkerError
def
tname
(
self
,
nodelist
):
raise
WalkerError
def
dotted_name
(
self
,
nodelist
):
...
...
@@ -786,9 +806,10 @@ class Transformer:
return
Discard
(
Const
(
None
))
def
keywordonlyargs
(
self
,
nodelist
):
# (','
NAME
['=' test])*
# (','
tname
['=' test])*
# ^^^
# ------+
# tname and vname are handled.
kwonlyargs
=
[]
i
=
0
while
i
<
len
(
nodelist
):
...
...
@@ -802,10 +823,25 @@ class Transformer:
i
+=
2
if
node
[
0
]
==
token
.
DOUBLESTAR
:
return
kwonlyargs
,
i
elif
node
[
0
]
==
token
.
NAME
:
kwonlyargs
.
append
(
Keyword
(
node
[
1
],
default
,
lineno
=
node
[
2
]))
elif
node
[
0
]
in
(
symbol
.
vname
,
symbol
.
tname
):
lineno
=
extractLineNo
(
node
)
kwarg
=
Kwarg
(
self
.
_simplearg
(
node
),
default
,
lineno
=
lineno
)
kwonlyargs
.
append
(
kwarg
)
i
+=
2
return
kwonlyargs
,
i
def
_simplearg
(
self
,
node
):
# tname: NAME [':' test]
# vname: NAME
assert
node
[
0
]
==
symbol
.
vname
or
node
[
0
]
==
symbol
.
tname
name
=
node
[
1
][
1
]
lineno
=
node
[
1
][
2
]
assert
isinstance
(
name
,
str
)
if
len
(
node
)
>
2
:
annotation
=
self
.
com_node
(
node
[
3
])
else
:
annotation
=
None
return
SimpleArg
(
name
,
annotation
,
lineno
)
def
com_arglist
(
self
,
nodelist
):
# varargslist:
...
...
@@ -814,7 +850,7 @@ class Transformer:
# | fpdef ['=' test] (',' fpdef ['=' test])* [',']
# fpdef: NAME | '(' fplist ')'
# fplist: fpdef (',' fpdef)* [',']
name
s
=
[]
argument
s
=
[]
kwonlyargs
=
[]
defaults
=
[]
flags
=
0
...
...
@@ -825,14 +861,15 @@ class Transformer:
if
node
[
0
]
==
token
.
STAR
or
node
[
0
]
==
token
.
DOUBLESTAR
:
if
node
[
0
]
==
token
.
STAR
:
node
=
nodelist
[
i
+
1
]
if
node
[
0
]
==
token
.
NAME
:
# vararg
names
.
append
(
node
[
1
]
)
if
node
[
0
]
in
(
symbol
.
tname
,
symbol
.
vname
)
:
# vararg
arguments
.
append
(
self
.
_simplearg
(
node
)
)
flags
=
flags
|
CO_VARARGS
i
=
i
+
3
else
:
# no vararg
assert
node
[
0
]
==
token
.
COMMA
i
+=
2
if
i
<
len
(
nodelist
)
and
nodelist
[
i
][
0
]
==
token
.
NAME
:
if
i
<
len
(
nodelist
)
and
\
nodelist
[
i
][
0
]
in
(
symbol
.
tname
,
symbol
.
vname
):
kwonlyargs
,
skip
=
self
.
keywordonlyargs
(
nodelist
[
i
:])
i
+=
skip
...
...
@@ -843,13 +880,13 @@ class Transformer:
node
=
nodelist
[
i
+
1
]
else
:
raise
ValueError
,
"unexpected token: %s"
%
t
names
.
append
(
node
[
1
]
)
arguments
.
append
(
self
.
_simplearg
(
node
)
)
flags
=
flags
|
CO_VARKEYWORDS
break
#
fpdef: NAME | '('
fplist ')'
names
.
append
(
self
.
com_
fpdef
(
node
))
#
tfpdef: tname | '(' t
fplist ')'
arguments
.
append
(
self
.
com_t
fpdef
(
node
))
i
=
i
+
1
if
i
<
len
(
nodelist
)
and
nodelist
[
i
][
0
]
==
token
.
EQUAL
:
...
...
@@ -863,21 +900,24 @@ class Transformer:
# skip the comma
i
=
i
+
1
return
name
s
,
defaults
,
kwonlyargs
,
flags
return
argument
s
,
defaults
,
kwonlyargs
,
flags
def
com_fpdef
(
self
,
node
):
# fpdef: NAME | '(' fplist ')'
def
com_tfpdef
(
self
,
node
):
# tfpdef: tname | '(' tfplist ')'
# def f((x)): -- x is not nested
while
node
[
1
][
0
]
==
token
.
LPAR
and
len
(
node
[
2
])
==
2
:
node
=
node
[
2
][
1
]
if
node
[
1
][
0
]
==
token
.
LPAR
:
return
self
.
com_fplist
(
node
[
2
]
)
return
node
[
1
][
1
]
return
NestedArgs
(
self
.
com_tfplist
(
node
[
2
])
)
return
self
.
_simplearg
(
node
[
1
])
def
com_fplist
(
self
,
node
):
#
fplist: fpdef (','
fpdef)* [',']
def
com_
t
fplist
(
self
,
node
):
#
tfplist: tfpdef (',' t
fpdef)* [',']
if
len
(
node
)
==
2
:
return
self
.
com_
fpdef
(
node
[
1
])
return
self
.
com_
tfpdef
(
node
[
1
]),
list
=
[]
for
i
in
range
(
1
,
len
(
node
),
2
):
list
.
append
(
self
.
com_fpdef
(
node
[
i
]))
list
.
append
(
self
.
com_
t
fpdef
(
node
[
i
]))
return
tuple
(
list
)
def
com_dotted_name
(
self
,
node
):
...
...
Lib/symbol.py
View file @
c150536b
...
...
@@ -17,82 +17,87 @@ decorator = 259
decorators
=
260
funcdef
=
261
parameters
=
262
varargslist
=
263
fpdef
=
264
fplist
=
265
stmt
=
266
simple_stmt
=
267
small_stmt
=
268
expr_stmt
=
269
augassign
=
270
print_stmt
=
271
del_stmt
=
272
pass_stmt
=
273
flow_stmt
=
274
break_stmt
=
275
continue_stmt
=
276
return_stmt
=
277
yield_stmt
=
278
raise_stmt
=
279
import_stmt
=
280
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
assert_stmt
=
289
compound_stmt
=
290
if_stmt
=
291
while_stmt
=
292
for_stmt
=
293
try_stmt
=
294
with_stmt
=
295
with_var
=
296
except_clause
=
297
suite
=
298
testlist_safe
=
299
old_test
=
300
old_lambdef
=
301
test
=
302
or_test
=
303
and_test
=
304
not_test
=
305
comparison
=
306
comp_op
=
307
expr
=
308
xor_expr
=
309
and_expr
=
310
shift_expr
=
311
arith_expr
=
312
term
=
313
factor
=
314
power
=
315
atom
=
316
listmaker
=
317
testlist_gexp
=
318
lambdef
=
319
trailer
=
320
subscriptlist
=
321
subscript
=
322
sliceop
=
323
exprlist
=
324
testlist
=
325
dictsetmaker
=
326
classdef
=
327
arglist
=
328
argument
=
329
list_iter
=
330
list_for
=
331
list_if
=
332
gen_iter
=
333
gen_for
=
334
gen_if
=
335
testlist1
=
336
encoding_decl
=
337
yield_expr
=
338
typedargslist
=
263
tname
=
264
tfpdef
=
265
tfplist
=
266
varargslist
=
267
vname
=
268
vfpdef
=
269
vfplist
=
270
stmt
=
271
simple_stmt
=
272
small_stmt
=
273
expr_stmt
=
274
augassign
=
275
print_stmt
=
276
del_stmt
=
277
pass_stmt
=
278
flow_stmt
=
279
break_stmt
=
280
continue_stmt
=
281
return_stmt
=
282
yield_stmt
=
283
raise_stmt
=
284
import_stmt
=
285
import_name
=
286
import_from
=
287
import_as_name
=
288
dotted_as_name
=
289
import_as_names
=
290
dotted_as_names
=
291
dotted_name
=
292
global_stmt
=
293
assert_stmt
=
294
compound_stmt
=
295
if_stmt
=
296
while_stmt
=
297
for_stmt
=
298
try_stmt
=
299
with_stmt
=
300
with_var
=
301
except_clause
=
302
suite
=
303
testlist_safe
=
304
old_test
=
305
old_lambdef
=
306
test
=
307
or_test
=
308
and_test
=
309
not_test
=
310
comparison
=
311
comp_op
=
312
expr
=
313
xor_expr
=
314
and_expr
=
315
shift_expr
=
316
arith_expr
=
317
term
=
318
factor
=
319
power
=
320
atom
=
321
listmaker
=
322
testlist_gexp
=
323
lambdef
=
324
trailer
=
325
subscriptlist
=
326
subscript
=
327
sliceop
=
328
exprlist
=
329
testlist
=
330
dictsetmaker
=
331
classdef
=
332
arglist
=
333
argument
=
334
list_iter
=
335
list_for
=
336
list_if
=
337
gen_iter
=
338
gen_for
=
339
gen_if
=
340
testlist1
=
341
encoding_decl
=
342
yield_expr
=
343
#--end constants--
sym_name
=
{}
...
...
Lib/test/output/test_tokenize
View file @
c150536b
...
...
@@ -682,4 +682,20 @@ test_tokenize
177,11-177,15: NAME 'pass'
177,15-177,16: NEWLINE '\n'
178,0-178,1: NL '\n'
179,0-179,0: ENDMARKER ''
179,0-179,1: OP '@'
179,1-179,13: NAME 'staticmethod'
179,13-179,14: NEWLINE '\n'
180,0-180,3: NAME 'def'
180,4-180,7: NAME 'foo'
180,7-180,8: OP '('
180,8-180,9: NAME 'x'
180,9-180,10: OP ':'
180,10-180,11: NUMBER '1'
180,11-180,12: OP ')'
180,12-180,14: OP '->'
180,14-180,15: NUMBER '1'
180,15-180,16: OP ':'
180,17-180,21: NAME 'pass'
180,21-180,22: NEWLINE '\n'
181,0-181,1: NL '\n'
182,0-182,0: ENDMARKER ''
Lib/test/test_ast.py
View file @
c150536b
...
...
@@ -151,9 +151,9 @@ def run_tests():
#### EVERYTHING BELOW IS GENERATED #####
exec_results
=
[
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
[],
None
,
[],
[]),
[(
'Pass'
,
(
1
,
9
))],
[]
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[],
None
,
None
,
[],
[]),
[(
'Pass'
,
(
1
,
9
))],
[],
None
)]),
(
'Module'
,
[(
'ClassDef'
,
(
1
,
0
),
'C'
,
[],
[(
'Pass'
,
(
1
,
8
))])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
[],
None
,
[],
[]),
[(
'Return'
,
(
1
,
8
),
(
'Num'
,
(
1
,
15
),
1
))],
[]
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[],
None
,
None
,
[],
[]),
[(
'Return'
,
(
1
,
8
),
(
'Num'
,
(
1
,
15
),
1
))],
[],
None
)]),
(
'Module'
,
[(
'Delete'
,
(
1
,
0
),
[(
'Name'
,
(
1
,
4
),
'v'
,
(
'Del'
,))])]),
(
'Module'
,
[(
'Assign'
,
(
1
,
0
),
[(
'Name'
,
(
1
,
0
),
'v'
,
(
'Store'
,))],
(
'Num'
,
(
1
,
4
),
1
))]),
(
'Module'
,
[(
'AugAssign'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'v'
,
(
'Store'
,)),
(
'Add'
,),
(
'Num'
,
(
1
,
5
),
1
))]),
...
...
@@ -180,13 +180,13 @@ eval_results = [
(
'Expression'
,
(
'BoolOp'
,
(
1
,
0
),
(
'And'
,),
[(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
6
),
'b'
,
(
'Load'
,))])),
(
'Expression'
,
(
'BinOp'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
(
'Add'
,),
(
'Name'
,
(
1
,
4
),
'b'
,
(
'Load'
,)))),
(
'Expression'
,
(
'UnaryOp'
,
(
1
,
0
),
(
'Not'
,),
(
'Name'
,
(
1
,
4
),
'v'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Lambda'
,
(
1
,
0
),
(
'arguments'
,
[],
None
,
[]
,
None
,
[],
[]),
(
'Name'
,
(
1
,
7
),
'None'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Lambda'
,
(
1
,
0
),
(
'arguments'
,
[],
None
,
None
,
[],
None
,
None
,
[],
[]),
(
'Name'
,
(
1
,
7
),
'None'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[(
'Num'
,
(
1
,
2
),
1
)],
[(
'Num'
,
(
1
,
4
),
2
)])),
(
'Expression'
,
(
'ListComp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'a'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Name'
,
(
1
,
7
),
'b'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
12
),
'c'
,
(
'Load'
,)),
[(
'Name'
,
(
1
,
17
),
'd'
,
(
'Load'
,))])])),
(
'Expression'
,
(
'GeneratorExp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'a'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Name'
,
(
1
,
7
),
'b'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
12
),
'c'
,
(
'Load'
,)),
[(
'Name'
,
(
1
,
17
),
'd'
,
(
'Load'
,))])])),
(
'Expression'
,
(
'Compare'
,
(
1
,
0
),
(
'Num'
,
(
1
,
0
),
1
),
[(
'Lt'
,),
(
'Lt'
,)],
[(
'Num'
,
(
1
,
4
),
2
),
(
'Num'
,
(
1
,
8
),
3
)])),
(
'Expression'
,
(
'Call'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'f'
,
(
'Load'
,)),
[(
'Num'
,
(
1
,
2
),
1
),
(
'Num'
,
(
1
,
4
),
2
)],
[(
'keyword'
,
'c'
,
(
'Num'
,
(
1
,
8
),
3
))],
(
'Name'
,
(
1
,
11
),
'd'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
15
),
'e'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Num'
,
(
1
,
0
),
10
L
)),
(
'Expression'
,
(
'Num'
,
(
1
,
0
),
10
)),
(
'Expression'
,
(
'Str'
,
(
1
,
0
),
'string'
)),
(
'Expression'
,
(
'Attribute'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
'b'
,
(
'Load'
,))),
(
'Expression'
,
(
'Subscript'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
(
'Slice'
,
(
'Name'
,
(
1
,
2
),
'b'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
4
),
'c'
,
(
'Load'
,)),
None
),
(
'Load'
,))),
...
...
Lib/test/test_compiler.py
View file @
c150536b
...
...
@@ -115,6 +115,24 @@ class CompilerTest(unittest.TestCase):
dct
=
{}
exec
(
c
,
dct
)
self
.
assertEquals
(
dct
.
get
(
'result'
),
3
)
c
=
compiler
.
compile
(
'def g(a):
\
n
'
' def f(): return a + 2
\
n
'
' return f()
\
n
'
'result = g(1)'
,
'<string>'
,
'exec'
)
dct
=
{}
exec
(
c
,
dct
)
self
.
assertEquals
(
dct
.
get
(
'result'
),
3
)
c
=
compiler
.
compile
(
'def g((a, b)):
\
n
'
' def f(): return a + b
\
n
'
' return f()
\
n
'
'result = g((1, 2))'
,
'<string>'
,
'exec'
)
dct
=
{}
exec
(
c
,
dct
)
self
.
assertEquals
(
dct
.
get
(
'result'
),
3
)
def
testGenExp
(
self
):
c
=
compiler
.
compile
(
'list((i,j) for i in range(3) if i < 3'
...
...
@@ -123,6 +141,22 @@ class CompilerTest(unittest.TestCase):
'eval'
)
self
.
assertEquals
(
eval
(
c
),
[(
0
,
3
),
(
1
,
3
),
(
2
,
3
)])
def
testFuncAnnotations
(
self
):
testdata
=
[
(
'def f(a: 1): pass'
,
{
'a'
:
1
}),
(
'''def f(a, (b:1, c:2, d), e:3=4, f=5,
*g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass
'''
,
{
'b'
:
1
,
'c'
:
2
,
'e'
:
3
,
'g'
:
6
,
'h'
:
7
,
'j'
:
9
,
'k'
:
11
,
'return'
:
12
}),
]
for
sourcecode
,
expected
in
testdata
:
# avoid IndentationError: unexpected indent from trailing lines
sourcecode
=
sourcecode
.
rstrip
()
+
'
\
n
'
c
=
compiler
.
compile
(
sourcecode
,
'<string>'
,
'exec'
)
dct
=
{}
exec
(
c
,
dct
)
self
.
assertEquals
(
dct
[
'f'
].
func_annotations
,
expected
)
NOLINENO
=
(
compiler
.
ast
.
Module
,
compiler
.
ast
.
Stmt
,
compiler
.
ast
.
Discard
)
...
...
@@ -167,10 +201,11 @@ from math import *
###############################################################################
def
test_main
():
def
test_main
(
all
=
False
):
global
TEST_ALL
TEST_ALL
=
test
.
test_support
.
is_resource_enabled
(
"compiler"
)
TEST_ALL
=
all
or
test
.
test_support
.
is_resource_enabled
(
"compiler"
)
test
.
test_support
.
run_unittest
(
CompilerTest
)
if
__name__
==
"__main__"
:
test_main
()
import
sys
test_main
(
'all'
in
sys
.
argv
)
Lib/test/test_grammar.py
View file @
c150536b
...
...
@@ -138,16 +138,22 @@ class GrammarTests(unittest.TestCase):
x
=
eval
(
'1, 0 or 1'
)
def
testFuncdef
(
self
):
### 'def' NAME parameters ':' suite
### parameters: '(' [varargslist] ')'
### varargslist: (fpdef ['=' test] ',')*
### ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
### | ('**'|'*' '*') NAME)
### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
### fpdef: NAME | '(' fplist ')'
### fplist: fpdef (',' fpdef)* [',']
### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
### argument: [test '='] test # Really [keyword '='] test
### [decorators] 'def' NAME parameters ['->' test] ':' suite
### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
### decorators: decorator+
### parameters: '(' [typedargslist] ')'
### typedargslist: ((tfpdef ['=' test] ',')*
### ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
### | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
### tname: NAME [':' test]
### tfpdef: tname | '(' tfplist ')'
### tfplist: tfpdef (',' tfpdef)* [',']
### varargslist: ((vfpdef ['=' test] ',')*
### ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
### | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
### vname: NAME
### vfpdef: vname | '(' vfplist ')'
### vfplist: vfpdef (',' vfpdef)* [',']
def
f1
():
pass
f1
()
f1
(
*
())
...
...
@@ -294,6 +300,28 @@ class GrammarTests(unittest.TestCase):
pos2key2dict
(
1
,
2
,
k2
=
100
,
tokwarg1
=
100
,
tokwarg2
=
200
)
pos2key2dict
(
1
,
2
,
tokwarg1
=
100
,
tokwarg2
=
200
,
k2
=
100
)
# argument annotation tests
def
f
(
x
)
->
list
:
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'return'
:
list
})
def
f
(
x
:
int
):
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'x'
:
int
})
def
f
(
*
x
:
str
):
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'x'
:
str
})
def
f
(
**
x
:
float
):
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'x'
:
float
})
def
f
(
x
,
y
:
1
+
2
):
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'y'
:
3
})
def
f
(
a
,
(
b
:
1
,
c
:
2
,
d
)):
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'b'
:
1
,
'c'
:
2
})
def
f
(
a
,
(
b
:
1
,
c
:
2
,
d
),
e
:
3
=
4
,
f
=
5
,
*
g
:
6
):
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'b'
:
1
,
'c'
:
2
,
'e'
:
3
,
'g'
:
6
})
def
f
(
a
,
(
b
:
1
,
c
:
2
,
d
),
e
:
3
=
4
,
f
=
5
,
*
g
:
6
,
h
:
7
,
i
=
8
,
j
:
9
=
10
,
**
k
:
11
)
->
12
:
pass
self
.
assertEquals
(
f
.
func_annotations
,
{
'b'
:
1
,
'c'
:
2
,
'e'
:
3
,
'g'
:
6
,
'h'
:
7
,
'j'
:
9
,
'k'
:
11
,
'return'
:
12
})
def
testLambdef
(
self
):
### lambdef: 'lambda' [varargslist] ':' test
l1
=
lambda
:
0
...
...
Lib/test/test_tokenize.py
View file @
c150536b
...
...
@@ -219,5 +219,15 @@ def foo():
if
verbose
:
print
'finished'
def
test_rarrow
():
"""
This function exists solely to test the tokenization of the RARROW
operator.
>>> tokenize(iter(['->']).next) #doctest: +NORMALIZE_WHITESPACE
1,0-1,2:
\
t
OP
\
t
'->'
2,0-2,0:
\
t
ENDMARKER
\
t
''
"""
if
__name__
==
"__main__"
:
test_main
()
Lib/test/tokenize_tests.txt
View file @
c150536b
...
...
@@ -176,3 +176,6 @@ x = sys.modules['time'].time()
@staticmethod
def foo(): pass
@staticmethod
def foo(x:1)->1: pass
Lib/token.py
View file @
c150536b
...
...
@@ -60,9 +60,10 @@ DOUBLESTAREQUAL = 47
DOUBLESLASH
=
48
DOUBLESLASHEQUAL
=
49
AT
=
50
OP
=
51
ERRORTOKEN
=
52
N_TOKENS
=
53
RARROW
=
51
OP
=
52
ERRORTOKEN
=
53
N_TOKENS
=
54
NT_OFFSET
=
256
#--end constants--
...
...
Lib/tokenize.py
View file @
c150536b
...
...
@@ -78,7 +78,7 @@ String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
# longest operators first (e.g., if = came before ==, == would get
# recognized as two instances of =).
Operator
=
group
(
r"\
*
\*=?"
,
r">>=?"
,
r"<<=?"
,
r"!="
,
r"//=?"
,
r"//=?"
,
r"->"
,
r"[+\
-*/%&|^=<>]=?
",
r"
~
")
...
...
Misc/NEWS
View file @
c150536b
...
...
@@ -36,6 +36,8 @@ TO DO
Core and Builtins
-----------------
- Added function annotations per PEP 3107.
- Moved intern() to sys.intern().
- exec is now a function.
...
...
Modules/parsermodule.c
View file @
c150536b
...
...
@@ -854,7 +854,7 @@ VALIDATER(node); VALIDATER(small_stmt);
VALIDATER
(
class
);
VALIDATER
(
node
);
VALIDATER
(
parameters
);
VALIDATER
(
suite
);
VALIDATER
(
testlist
);
VALIDATER
(
varargslist
);
VALIDATER
(
fpdef
);
VALIDATER
(
fplist
);
VALIDATER
(
vfpdef
);
VALIDATER
(
v
fplist
);
VALIDATER
(
stmt
);
VALIDATER
(
simple_stmt
);
VALIDATER
(
expr_stmt
);
VALIDATER
(
power
);
VALIDATER
(
print_stmt
);
VALIDATER
(
del_stmt
);
...
...
@@ -863,7 +863,7 @@ 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
(
compound_stmt
);
VALIDATER
(
compound_stmt
);
VALIDATER
(
vname
);
VALIDATER
(
while
);
VALIDATER
(
for
);
VALIDATER
(
try
);
VALIDATER
(
except_clause
);
VALIDATER
(
test
);
VALIDATER
(
and_test
);
...
...
@@ -1120,7 +1120,32 @@ validate_testlist_safe(node *tree)
}
/* '*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME
/* validate either vname or tname.
* vname: NAME
* tname: NAME [':' test]
*/
static
int
validate_vname
(
node
*
tree
)
{
int
nch
=
NCH
(
tree
);
if
(
TYPE
(
tree
)
==
vname
)
{
return
nch
==
1
&&
validate_name
(
CHILD
(
tree
,
0
),
NULL
);
}
else
if
(
TYPE
(
tree
)
==
tname
)
{
if
(
nch
==
1
)
{
return
validate_name
(
CHILD
(
tree
,
0
),
NULL
);
}
else
if
(
nch
==
3
)
{
return
validate_name
(
CHILD
(
tree
,
0
),
NULL
)
&&
validate_colon
(
CHILD
(
tree
,
1
))
&&
validate_test
(
CHILD
(
tree
,
2
));
}
}
return
0
;
}
/* '*' vname (',' vname ['=' test])* [',' '**' vname] | '**' vname
* ..or tname in place of vname. vname: NAME; tname: NAME [':' test]
*/
static
int
validate_varargslist_trailer
(
node
*
tree
,
int
start
)
...
...
@@ -1136,26 +1161,27 @@ validate_varargslist_trailer(node *tree, int start)
sym
=
TYPE
(
CHILD
(
tree
,
start
));
if
(
sym
==
STAR
)
{
/*
* '*'
[NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME
* '*'
vname (',' vname ['=' test])* [',' '**' vname] | '**' vname
*/
if
(
nch
-
start
==
2
)
res
=
validate_
name
(
CHILD
(
tree
,
start
+
1
),
NULL
);
res
=
validate_
vname
(
CHILD
(
tree
,
start
+
1
)
);
else
if
(
nch
-
start
==
5
&&
TYPE
(
CHILD
(
tree
,
start
+
2
))
==
COMMA
)
res
=
(
validate_
name
(
CHILD
(
tree
,
start
+
1
),
NULL
)
res
=
(
validate_
vname
(
CHILD
(
tree
,
start
+
1
)
)
&&
validate_comma
(
CHILD
(
tree
,
start
+
2
))
&&
validate_doublestar
(
CHILD
(
tree
,
start
+
3
))
&&
validate_
name
(
CHILD
(
tree
,
start
+
4
),
NULL
));
&&
validate_
vname
(
CHILD
(
tree
,
start
+
4
)
));
else
{
/* skip over
[NAME] (',' NAME
['=' test])* */
/* skip over
vname (',' vname
['=' test])* */
i
=
start
+
1
;
if
(
TYPE
(
CHILD
(
tree
,
i
))
==
NAME
)
{
/* skip over [NAME] */
if
(
TYPE
(
CHILD
(
tree
,
i
))
==
vname
||
TYPE
(
CHILD
(
tree
,
i
))
==
tname
)
{
/* skip over vname or tname */
i
+=
1
;
}
while
(
res
&&
i
+
1
<
nch
)
{
/* validate (','
NAME
['=' test])* */
while
(
res
&&
i
+
1
<
nch
)
{
/* validate (','
vname
['=' test])* */
res
=
validate_comma
(
CHILD
(
tree
,
i
));
if
(
TYPE
(
CHILD
(
tree
,
i
+
1
))
==
DOUBLESTAR
)
break
;
res
=
res
&&
validate_
name
(
CHILD
(
tree
,
i
+
1
),
NULL
);
res
=
res
&&
validate_
vname
(
CHILD
(
tree
,
i
+
1
)
);
if
(
res
&&
i
+
2
<
nch
&&
TYPE
(
CHILD
(
tree
,
i
+
2
))
==
EQUAL
)
{
res
=
res
&&
(
i
+
3
<
nch
)
&&
validate_test
(
CHILD
(
tree
,
i
+
3
));
...
...
@@ -1165,9 +1191,9 @@ validate_varargslist_trailer(node *tree, int start)
i
+=
2
;
}
}
/* [',' '**'
NAME
] */
/* [',' '**'
vname
] */
if
(
res
&&
i
+
1
<
nch
&&
TYPE
(
CHILD
(
tree
,
i
+
1
))
==
DOUBLESTAR
)
{
res
=
validate_
name
(
CHILD
(
tree
,
i
+
2
),
NULL
);
res
=
validate_
vname
(
CHILD
(
tree
,
i
+
2
)
);
}
}
}
...
...
@@ -1176,7 +1202,7 @@ validate_varargslist_trailer(node *tree, int start)
* '**' NAME
*/
if
(
nch
-
start
==
2
)
res
=
validate_
name
(
CHILD
(
tree
,
start
+
1
),
NULL
);
res
=
validate_
vname
(
CHILD
(
tree
,
start
+
1
)
);
}
if
(
!
res
)
err_string
(
"illegal variable argument trailer for varargslist"
);
...
...
@@ -1184,21 +1210,34 @@ validate_varargslist_trailer(node *tree, int start)
}
/*
validate_varargslist()
/* validate_varargslist()
*
* varargslist:
* (fpdef ['=' test] ',')*
* ('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME)
* | fpdef ['=' test] (',' fpdef ['=' test])* [',']
* Validate typedargslist or varargslist.
*
* typedargslist: ((tfpdef ['=' test] ',')*
* ('*' [tname] (',' tname ['=' test])* [',' '**' tname] |
* '**' tname)
* | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
* tname: NAME [':' test]
* tfpdef: tname | '(' tfplist ')'
* tfplist: tfpdef (',' tfpdef)* [',']
* varargslist: ((vfpdef ['=' test] ',')*
* ('*' [vname] (',' vname ['=' test])* [',' '**' vname] |
* '**' vname)
* | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
* vname: NAME
* vfpdef: vname | '(' vfplist ')'
* vfplist: vfpdef (',' vfpdef)* [',']
*
*/
static
int
validate_varargslist
(
node
*
tree
)
{
int
nch
=
NCH
(
tree
);
int
res
=
validate_ntype
(
tree
,
varargslist
)
&&
(
nch
!=
0
);
int
res
=
(
TYPE
(
tree
)
==
varargslist
||
TYPE
(
tree
)
==
typedargslist
)
&&
(
nch
!=
0
);
int
sym
;
if
(
!
res
)
return
0
;
if
(
nch
<
1
)
{
...
...
@@ -1211,19 +1250,19 @@ validate_varargslist(node *tree)
* '*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME
*/
res
=
validate_varargslist_trailer
(
tree
,
0
);
else
if
(
sym
==
fpdef
)
{
else
if
(
sym
==
vfpdef
||
sym
==
t
fpdef
)
{
int
i
=
0
;
sym
=
TYPE
(
CHILD
(
tree
,
nch
-
1
));
if
(
sym
==
NAME
)
{
if
(
sym
==
vname
||
sym
==
tname
)
{
/*
* (fpdef ['=' test] ',')+
* ('*'
NAME [',' '**' NAME
]
* | '**'
NAME
)
* (
v
fpdef ['=' test] ',')+
* ('*'
vname [',' '**' vname
]
* | '**'
vname
)
*/
/* skip over (fpdef ['=' test] ',')+ */
/* skip over (
v
fpdef ['=' test] ',')+ */
while
(
res
&&
(
i
+
2
<=
nch
))
{
res
=
validate_fpdef
(
CHILD
(
tree
,
i
));
res
=
validate_
v
fpdef
(
CHILD
(
tree
,
i
));
++
i
;
if
(
res
&&
TYPE
(
CHILD
(
tree
,
i
))
==
EQUAL
&&
(
i
+
2
<=
nch
))
{
res
=
(
validate_equal
(
CHILD
(
tree
,
i
))
...
...
@@ -1248,7 +1287,7 @@ validate_varargslist(node *tree)
}
else
{
/*
*
fpdef ['=' test] (','
fpdef ['=' test])* [',']
*
vfpdef ['=' test] (',' v
fpdef ['=' test])* [',']
*/
/* strip trailing comma node */
if
(
sym
==
COMMA
)
{
...
...
@@ -1258,9 +1297,9 @@ validate_varargslist(node *tree)
--
nch
;
}
/*
*
fpdef ['=' test] (','
fpdef ['=' test])*
*
vfpdef ['=' test] (',' v
fpdef ['=' test])*
*/
res
=
validate_fpdef
(
CHILD
(
tree
,
0
));
res
=
validate_
v
fpdef
(
CHILD
(
tree
,
0
));
++
i
;
if
(
res
&&
(
i
+
2
<=
nch
)
&&
TYPE
(
CHILD
(
tree
,
i
))
==
EQUAL
)
{
res
=
(
validate_equal
(
CHILD
(
tree
,
i
))
...
...
@@ -1268,12 +1307,12 @@ validate_varargslist(node *tree)
i
+=
2
;
}
/*
* ... (',' fpdef ['=' test])*
* ... (','
v
fpdef ['=' test])*
* i ---^^^
*/
while
(
res
&&
(
nch
-
i
)
>=
2
)
{
res
=
(
validate_comma
(
CHILD
(
tree
,
i
))
&&
validate_fpdef
(
CHILD
(
tree
,
i
+
1
)));
&&
validate_
v
fpdef
(
CHILD
(
tree
,
i
+
1
)));
i
+=
2
;
if
(
res
&&
(
nch
-
i
)
>=
2
&&
TYPE
(
CHILD
(
tree
,
i
))
==
EQUAL
)
{
res
=
(
validate_equal
(
CHILD
(
tree
,
i
))
...
...
@@ -1405,24 +1444,32 @@ validate_gen_if(node *tree)
return
res
;
}
/* validate_fpdef()
/* validate_vfpdef()
*
* Validate vfpdef or tfpdef.
*
* vname: NAME
* vfpdef: vname | '(' vfplist ')'
* vfplist: vfpdef (',' vfpdef)* [',']
*
* tname: NAME [':' test]
* tfpdef: tname | '(' tfplist ')'
* tfplist: tfpdef (',' tfpdef)* [',']
*
* fpdef:
* NAME
* | '(' fplist ')'
*/
static
int
validate_fpdef
(
node
*
tree
)
validate_
v
fpdef
(
node
*
tree
)
{
int
nch
=
NCH
(
tree
);
int
res
=
validate_ntype
(
tree
,
fpdef
);
int
typ
=
TYPE
(
tree
);
int
res
=
typ
==
vfpdef
||
typ
==
tfpdef
;
if
(
res
)
{
if
(
nch
==
1
)
res
=
validate_
ntype
(
CHILD
(
tree
,
0
),
NAME
);
res
=
validate_
vname
(
CHILD
(
tree
,
0
)
);
else
if
(
nch
==
3
)
res
=
(
validate_lparen
(
CHILD
(
tree
,
0
))
&&
validate_fplist
(
CHILD
(
tree
,
1
))
&&
validate_
v
fplist
(
CHILD
(
tree
,
1
))
&&
validate_rparen
(
CHILD
(
tree
,
2
)));
else
res
=
validate_numnodes
(
tree
,
1
,
"fpdef"
);
...
...
@@ -1432,10 +1479,10 @@ validate_fpdef(node *tree)
static
int
validate_fplist
(
node
*
tree
)
validate_
v
fplist
(
node
*
tree
)
{
return
(
validate_repeating_list
(
tree
,
fplist
,
validate_
fpdef
,
"
fplist"
));
return
(
validate_repeating_list
(
tree
,
v
fplist
,
validate_
vfpdef
,
"v
fplist"
));
}
...
...
Objects/funcobject.c
View file @
c150536b
...
...
@@ -38,6 +38,7 @@ PyFunction_New(PyObject *code, PyObject *globals)
op
->
func_doc
=
doc
;
op
->
func_dict
=
NULL
;
op
->
func_module
=
NULL
;
op
->
func_annotations
=
NULL
;
/* __module__: If module name is in globals, use it.
Otherwise, use None.
...
...
@@ -187,6 +188,38 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
return
0
;
}
PyObject
*
PyFunction_GetAnnotations
(
PyObject
*
op
)
{
if
(
!
PyFunction_Check
(
op
))
{
PyErr_BadInternalCall
();
return
NULL
;
}
return
((
PyFunctionObject
*
)
op
)
->
func_annotations
;
}
int
PyFunction_SetAnnotations
(
PyObject
*
op
,
PyObject
*
annotations
)
{
if
(
!
PyFunction_Check
(
op
))
{
PyErr_BadInternalCall
();
return
-
1
;
}
if
(
annotations
==
Py_None
)
annotations
=
NULL
;
else
if
(
annotations
&&
PyDict_Check
(
annotations
))
{
Py_INCREF
(
annotations
);
}
else
{
PyErr_SetString
(
PyExc_SystemError
,
"non-dict annotations"
);
return
-
1
;
}
Py_XDECREF
(((
PyFunctionObject
*
)
op
)
->
func_annotations
);
((
PyFunctionObject
*
)
op
)
->
func_annotations
=
annotations
;
return
0
;
}
/* Methods */
#define OFF(x) offsetof(PyFunctionObject, x)
...
...
@@ -395,12 +428,48 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value)
return
0
;
}
static
PyObject
*
func_get_annotations
(
PyFunctionObject
*
op
)
{
if
(
op
->
func_annotations
==
NULL
)
{
op
->
func_annotations
=
PyDict_New
();
if
(
op
->
func_annotations
==
NULL
)
return
NULL
;
}
Py_INCREF
(
op
->
func_annotations
);
return
op
->
func_annotations
;
}
static
int
func_set_annotations
(
PyFunctionObject
*
op
,
PyObject
*
value
)
{
PyObject
*
tmp
;
if
(
value
==
Py_None
)
value
=
NULL
;
/* Legal to del f.func_annotations.
* Can only set func_annotations to NULL (through C api)
* or a dict. */
if
(
value
!=
NULL
&&
!
PyDict_Check
(
value
))
{
PyErr_SetString
(
PyExc_TypeError
,
"func_annotations must be set to a dict object"
);
return
-
1
;
}
tmp
=
op
->
func_annotations
;
Py_XINCREF
(
value
);
op
->
func_annotations
=
value
;
Py_XDECREF
(
tmp
);
return
0
;
}
static
PyGetSetDef
func_getsetlist
[]
=
{
{
"func_code"
,
(
getter
)
func_get_code
,
(
setter
)
func_set_code
},
{
"func_defaults"
,
(
getter
)
func_get_defaults
,
(
setter
)
func_set_defaults
},
{
"func_kwdefaults"
,
(
getter
)
func_get_kwdefaults
,
(
setter
)
func_set_kwdefaults
},
{
"func_annotations"
,
(
getter
)
func_get_annotations
,
(
setter
)
func_set_annotations
},
{
"func_dict"
,
(
getter
)
func_get_dict
,
(
setter
)
func_set_dict
},
{
"__dict__"
,
(
getter
)
func_get_dict
,
(
setter
)
func_set_dict
},
{
"func_name"
,
(
getter
)
func_get_name
,
(
setter
)
func_set_name
},
...
...
@@ -524,6 +593,7 @@ func_dealloc(PyFunctionObject *op)
Py_XDECREF
(
op
->
func_doc
);
Py_XDECREF
(
op
->
func_dict
);
Py_XDECREF
(
op
->
func_closure
);
Py_XDECREF
(
op
->
func_annotations
);
PyObject_GC_Del
(
op
);
}
...
...
@@ -546,6 +616,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
Py_VISIT
(
f
->
func_name
);
Py_VISIT
(
f
->
func_dict
);
Py_VISIT
(
f
->
func_closure
);
Py_VISIT
(
f
->
func_annotations
);
return
0
;
}
...
...
Parser/Python.asdl
View file @
c150536b
...
...
@@ -10,7 +10,7 @@ module Python version "$Revision$"
| Suite(stmt* body)
stmt = FunctionDef(identifier name, arguments args,
stmt* body, expr* decorators)
stmt* body, expr* decorators
, expr? returns
)
| ClassDef(identifier name, expr* bases, stmt* body)
| Return(expr? value)
...
...
@@ -100,8 +100,12 @@ module Python version "$Revision$"
excepthandler = (expr? type, expr? name, stmt* body, int lineno,
int col_offset)
arguments = (expr* args, identifier? vararg, expr* kwonlyargs,
identifier? kwarg, expr* defaults, expr* kw_defaults)
arguments = (arg* args, identifier? vararg, expr? varargannotation,
arg* kwonlyargs, identifier? kwarg,
expr? kwargannotation, expr* defaults,
expr* kw_defaults)
arg = SimpleArg(identifier arg, expr? annotation)
| NestedArgs(arg* args)
-- keyword arguments supplied to call
keyword = (identifier arg, expr value)
...
...
Parser/tokenizer.c
View file @
c150536b
...
...
@@ -92,6 +92,7 @@ char *_PyParser_TokenNames[] = {
"DOUBLESLASH"
,
"DOUBLESLASHEQUAL"
,
"AT"
,
"RARROW"
,
/* This table must match the #defines in token.h! */
"OP"
,
"<ERRORTOKEN>"
,
...
...
@@ -998,6 +999,7 @@ PyToken_TwoChars(int c1, int c2)
case
'-'
:
switch
(
c2
)
{
case
'='
:
return
MINEQUAL
;
case
'>'
:
return
RARROW
;
}
break
;
case
'*'
:
...
...
Python/Python-ast.c
View file @
c150536b
...
...
@@ -34,6 +34,7 @@ static char *FunctionDef_fields[]={
"args"
,
"body"
,
"decorators"
,
"returns"
,
};
static
PyTypeObject
*
ClassDef_type
;
static
char
*
ClassDef_fields
[]
=
{
...
...
@@ -333,11 +334,24 @@ static PyObject* ast2obj_arguments(void*);
static
char
*
arguments_fields
[]
=
{
"args"
,
"vararg"
,
"varargannotation"
,
"kwonlyargs"
,
"kwarg"
,
"kwargannotation"
,
"defaults"
,
"kw_defaults"
,
};
static
PyTypeObject
*
arg_type
;
static
PyObject
*
ast2obj_arg
(
void
*
);
static
PyTypeObject
*
SimpleArg_type
;
static
char
*
SimpleArg_fields
[]
=
{
"arg"
,
"annotation"
,
};
static
PyTypeObject
*
NestedArgs_type
;
static
char
*
NestedArgs_fields
[]
=
{
"args"
,
};
static
PyTypeObject
*
keyword_type
;
static
PyObject
*
ast2obj_keyword
(
void
*
);
static
char
*
keyword_fields
[]
=
{
...
...
@@ -454,7 +468,7 @@ static int init_types(void)
if
(
!
stmt_type
)
return
0
;
if
(
!
add_attributes
(
stmt_type
,
stmt_attributes
,
2
))
return
0
;
FunctionDef_type
=
make_type
(
"FunctionDef"
,
stmt_type
,
FunctionDef_fields
,
4
);
FunctionDef_fields
,
5
);
if
(
!
FunctionDef_type
)
return
0
;
ClassDef_type
=
make_type
(
"ClassDef"
,
stmt_type
,
ClassDef_fields
,
3
);
if
(
!
ClassDef_type
)
return
0
;
...
...
@@ -710,8 +724,16 @@ static int init_types(void)
excepthandler_type
=
make_type
(
"excepthandler"
,
AST_type
,
excepthandler_fields
,
5
);
if
(
!
excepthandler_type
)
return
0
;
arguments_type
=
make_type
(
"arguments"
,
AST_type
,
arguments_fields
,
6
);
arguments_type
=
make_type
(
"arguments"
,
AST_type
,
arguments_fields
,
8
);
if
(
!
arguments_type
)
return
0
;
arg_type
=
make_type
(
"arg"
,
AST_type
,
NULL
,
0
);
if
(
!
arg_type
)
return
0
;
if
(
!
add_attributes
(
arg_type
,
NULL
,
0
))
return
0
;
SimpleArg_type
=
make_type
(
"SimpleArg"
,
arg_type
,
SimpleArg_fields
,
2
);
if
(
!
SimpleArg_type
)
return
0
;
NestedArgs_type
=
make_type
(
"NestedArgs"
,
arg_type
,
NestedArgs_fields
,
1
);
if
(
!
NestedArgs_type
)
return
0
;
keyword_type
=
make_type
(
"keyword"
,
AST_type
,
keyword_fields
,
2
);
if
(
!
keyword_type
)
return
0
;
alias_type
=
make_type
(
"alias"
,
AST_type
,
alias_fields
,
2
);
...
...
@@ -783,7 +805,8 @@ Suite(asdl_seq * body, PyArena *arena)
stmt_ty
FunctionDef
(
identifier
name
,
arguments_ty
args
,
asdl_seq
*
body
,
asdl_seq
*
decorators
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
)
decorators
,
expr_ty
returns
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
)
{
stmt_ty
p
;
if
(
!
name
)
{
...
...
@@ -806,6 +829,7 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
p
->
v
.
FunctionDef
.
args
=
args
;
p
->
v
.
FunctionDef
.
body
=
body
;
p
->
v
.
FunctionDef
.
decorators
=
decorators
;
p
->
v
.
FunctionDef
.
returns
=
returns
;
p
->
lineno
=
lineno
;
p
->
col_offset
=
col_offset
;
return
p
;
...
...
@@ -1830,8 +1854,9 @@ excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int lineno, int
}
arguments_ty
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
asdl_seq
*
kwonlyargs
,
identifier
kwarg
,
asdl_seq
*
defaults
,
asdl_seq
*
kw_defaults
,
PyArena
*
arena
)
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
expr_ty
varargannotation
,
asdl_seq
*
kwonlyargs
,
identifier
kwarg
,
expr_ty
kwargannotation
,
asdl_seq
*
defaults
,
asdl_seq
*
kw_defaults
,
PyArena
*
arena
)
{
arguments_ty
p
;
p
=
(
arguments_ty
)
PyArena_Malloc
(
arena
,
sizeof
(
*
p
));
...
...
@@ -1841,13 +1866,49 @@ arguments(asdl_seq * args, identifier vararg, asdl_seq * kwonlyargs, identifier
}
p
->
args
=
args
;
p
->
vararg
=
vararg
;
p
->
varargannotation
=
varargannotation
;
p
->
kwonlyargs
=
kwonlyargs
;
p
->
kwarg
=
kwarg
;
p
->
kwargannotation
=
kwargannotation
;
p
->
defaults
=
defaults
;
p
->
kw_defaults
=
kw_defaults
;
return
p
;
}
arg_ty
SimpleArg
(
identifier
arg
,
expr_ty
annotation
,
PyArena
*
arena
)
{
arg_ty
p
;
if
(
!
arg
)
{
PyErr_SetString
(
PyExc_ValueError
,
"field arg is required for SimpleArg"
);
return
NULL
;
}
p
=
(
arg_ty
)
PyArena_Malloc
(
arena
,
sizeof
(
*
p
));
if
(
!
p
)
{
PyErr_NoMemory
();
return
NULL
;
}
p
->
kind
=
SimpleArg_kind
;
p
->
v
.
SimpleArg
.
arg
=
arg
;
p
->
v
.
SimpleArg
.
annotation
=
annotation
;
return
p
;
}
arg_ty
NestedArgs
(
asdl_seq
*
args
,
PyArena
*
arena
)
{
arg_ty
p
;
p
=
(
arg_ty
)
PyArena_Malloc
(
arena
,
sizeof
(
*
p
));
if
(
!
p
)
{
PyErr_NoMemory
();
return
NULL
;
}
p
->
kind
=
NestedArgs_kind
;
p
->
v
.
NestedArgs
.
args
=
args
;
return
p
;
}
keyword_ty
keyword
(
identifier
arg
,
expr_ty
value
,
PyArena
*
arena
)
{
...
...
@@ -1981,6 +2042,11 @@ ast2obj_stmt(void* _o)
if
(
PyObject_SetAttrString
(
result
,
"decorators"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_expr
(
o
->
v
.
FunctionDef
.
returns
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"returns"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
break
;
case
ClassDef_kind
:
result
=
PyType_GenericNew
(
ClassDef_type
,
NULL
,
NULL
);
...
...
@@ -2901,7 +2967,7 @@ ast2obj_arguments(void* _o)
result
=
PyType_GenericNew
(
arguments_type
,
NULL
,
NULL
);
if
(
!
result
)
return
NULL
;
value
=
ast2obj_list
(
o
->
args
,
ast2obj_
expr
);
value
=
ast2obj_list
(
o
->
args
,
ast2obj_
arg
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"args"
,
value
)
==
-
1
)
goto
failed
;
...
...
@@ -2911,7 +2977,12 @@ ast2obj_arguments(void* _o)
if
(
PyObject_SetAttrString
(
result
,
"vararg"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_list
(
o
->
kwonlyargs
,
ast2obj_expr
);
value
=
ast2obj_expr
(
o
->
varargannotation
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"varargannotation"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_list
(
o
->
kwonlyargs
,
ast2obj_arg
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"kwonlyargs"
,
value
)
==
-
1
)
goto
failed
;
...
...
@@ -2921,6 +2992,11 @@ ast2obj_arguments(void* _o)
if
(
PyObject_SetAttrString
(
result
,
"kwarg"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_expr
(
o
->
kwargannotation
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"kwargannotation"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_list
(
o
->
defaults
,
ast2obj_expr
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"defaults"
,
value
)
==
-
1
)
...
...
@@ -2938,6 +3014,48 @@ failed:
return
NULL
;
}
PyObject
*
ast2obj_arg
(
void
*
_o
)
{
arg_ty
o
=
(
arg_ty
)
_o
;
PyObject
*
result
=
NULL
,
*
value
=
NULL
;
if
(
!
o
)
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
switch
(
o
->
kind
)
{
case
SimpleArg_kind
:
result
=
PyType_GenericNew
(
SimpleArg_type
,
NULL
,
NULL
);
if
(
!
result
)
goto
failed
;
value
=
ast2obj_identifier
(
o
->
v
.
SimpleArg
.
arg
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"arg"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_expr
(
o
->
v
.
SimpleArg
.
annotation
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"annotation"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
break
;
case
NestedArgs_kind
:
result
=
PyType_GenericNew
(
NestedArgs_type
,
NULL
,
NULL
);
if
(
!
result
)
goto
failed
;
value
=
ast2obj_list
(
o
->
v
.
NestedArgs
.
args
,
ast2obj_arg
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"args"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
break
;
}
return
result
;
failed:
Py_XDECREF
(
value
);
Py_XDECREF
(
result
);
return
NULL
;
}
PyObject
*
ast2obj_keyword
(
void
*
_o
)
{
...
...
@@ -3008,7 +3126,7 @@ init_ast(void)
if
(
PyDict_SetItemString
(
d
,
"AST"
,
(
PyObject
*
)
AST_type
)
<
0
)
return
;
if
(
PyModule_AddIntConstant
(
m
,
"PyCF_ONLY_AST"
,
PyCF_ONLY_AST
)
<
0
)
return
;
if
(
PyModule_AddStringConstant
(
m
,
"__version__"
,
"5
1773
"
)
<
0
)
if
(
PyModule_AddStringConstant
(
m
,
"__version__"
,
"5
2491
"
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"mod"
,
(
PyObject
*
)
mod_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"Module"
,
(
PyObject
*
)
Module_type
)
<
0
)
...
...
@@ -3146,6 +3264,11 @@ init_ast(void)
(
PyObject
*
)
excepthandler_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"arguments"
,
(
PyObject
*
)
arguments_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"arg"
,
(
PyObject
*
)
arg_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"SimpleArg"
,
(
PyObject
*
)
SimpleArg_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"NestedArgs"
,
(
PyObject
*
)
NestedArgs_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"keyword"
,
(
PyObject
*
)
keyword_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"alias"
,
(
PyObject
*
)
alias_type
)
<
0
)
return
;
...
...
Python/ast.c
View file @
c150536b
This diff is collapsed.
Click to expand it.
Python/ceval.c
View file @
c150536b
...
...
@@ -2293,10 +2293,37 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
{
int
posdefaults
=
oparg
&
0xff
;
int
kwdefaults
=
(
oparg
>>
8
)
&
0xff
;
int
num_annotations
=
(
oparg
>>
16
)
&
0x7fff
;
v
=
POP
();
/* code object */
x
=
PyFunction_New
(
v
,
f
->
f_globals
);
Py_DECREF
(
v
);
if
(
x
!=
NULL
&&
num_annotations
>
0
)
{
Py_ssize_t
name_ix
;
u
=
POP
();
/* names of args with annotations */
v
=
PyDict_New
();
if
(
v
==
NULL
)
{
Py_DECREF
(
x
);
x
=
NULL
;
break
;
}
name_ix
=
PyTuple_Size
(
u
);
assert
(
num_annotations
==
name_ix
+
1
);
while
(
name_ix
>
0
)
{
--
name_ix
;
t
=
PyTuple_GET_ITEM
(
u
,
name_ix
);
w
=
POP
();
/* XXX(nnorwitz): check for errors */
PyDict_SetItem
(
v
,
t
,
w
);
Py_DECREF
(
w
);
}
err
=
PyFunction_SetAnnotations
(
x
,
v
);
Py_DECREF
(
v
);
Py_DECREF
(
u
);
}
/* XXX Maybe this should be a separate opcode? */
if
(
x
!=
NULL
&&
posdefaults
>
0
)
{
v
=
PyTuple_New
(
posdefaults
);
...
...
@@ -2322,6 +2349,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
while
(
--
kwdefaults
>=
0
)
{
w
=
POP
();
/* default value */
u
=
POP
();
/* kw only arg name */
/* XXX(nnorwitz): check for errors */
PyDict_SetItem
(
v
,
u
,
w
);
}
err
=
PyFunction_SetKwDefaults
(
x
,
v
);
...
...
Python/compile.c
View file @
c150536b
...
...
@@ -832,7 +832,7 @@ opcode_stack_effect(int opcode, int oparg)
case
RAISE_VARARGS
:
return
-
oparg
;
#define NARGS(o) (((o) % 256) + 2*((
o) /
256))
#define NARGS(o) (((o) % 256) + 2*((
(o) / 256) %
256))
case
CALL_FUNCTION
:
return
-
NARGS
(
oparg
);
case
CALL_FUNCTION_VAR
:
...
...
@@ -841,7 +841,7 @@ opcode_stack_effect(int opcode, int oparg)
case
CALL_FUNCTION_VAR_KW
:
return
-
NARGS
(
oparg
)
-
2
;
case
MAKE_FUNCTION
:
return
-
NARGS
(
oparg
);
return
-
NARGS
(
oparg
)
-
((
oparg
>>
16
)
&
0xffff
)
;
#undef NARGS
case
BUILD_SLICE
:
if
(
oparg
==
3
)
...
...
@@ -1266,15 +1266,38 @@ compiler_decorators(struct compiler *c, asdl_seq* decos)
return
1
;
}
static
int
compiler_unpack_nested
(
struct
compiler
*
c
,
asdl_seq
*
args
)
{
int
i
,
len
;
len
=
asdl_seq_LEN
(
args
);
ADDOP_I
(
c
,
UNPACK_SEQUENCE
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
arg_ty
elt
=
(
arg_ty
)
asdl_seq_GET
(
args
,
i
);
switch
(
elt
->
kind
)
{
case
SimpleArg_kind
:
if
(
!
compiler_nameop
(
c
,
elt
->
v
.
SimpleArg
.
arg
,
Store
))
return
0
;
break
;
case
NestedArgs_kind
:
if
(
!
compiler_unpack_nested
(
c
,
elt
->
v
.
NestedArgs
.
args
))
return
0
;
break
;
default:
return
0
;
}
}
return
1
;
}
static
int
compiler_arguments
(
struct
compiler
*
c
,
arguments_ty
args
)
{
int
i
;
int
n
=
asdl_seq_LEN
(
args
->
args
);
/* Correctly handle nested argument lists */
for
(
i
=
0
;
i
<
n
;
i
++
)
{
expr_ty
arg
=
(
expr
_ty
)
asdl_seq_GET
(
args
->
args
,
i
);
if
(
arg
->
kind
==
Tuple
_kind
)
{
arg_ty
arg
=
(
arg
_ty
)
asdl_seq_GET
(
args
->
args
,
i
);
if
(
arg
->
kind
==
NestedArgs
_kind
)
{
PyObject
*
id
=
PyString_FromFormat
(
".%d"
,
i
);
if
(
id
==
NULL
)
{
return
0
;
...
...
@@ -1284,7 +1307,8 @@ compiler_arguments(struct compiler *c, arguments_ty args)
return
0
;
}
Py_DECREF
(
id
);
VISIT
(
c
,
expr
,
arg
);
if
(
!
compiler_unpack_nested
(
c
,
arg
->
v
.
NestedArgs
.
args
))
return
0
;
}
}
return
1
;
...
...
@@ -1296,10 +1320,10 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
{
int
i
,
default_count
=
0
;
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
kwonlyargs
);
i
++
)
{
expr
_ty
arg
=
asdl_seq_GET
(
kwonlyargs
,
i
);
arg
_ty
arg
=
asdl_seq_GET
(
kwonlyargs
,
i
);
expr_ty
default_
=
asdl_seq_GET
(
kw_defaults
,
i
);
if
(
default_
)
{
ADDOP_O
(
c
,
LOAD_CONST
,
arg
->
v
.
Name
.
id
,
consts
);
ADDOP_O
(
c
,
LOAD_CONST
,
arg
->
v
.
SimpleArg
.
arg
,
consts
);
if
(
!
compiler_visit_expr
(
c
,
default_
))
{
return
-
1
;
}
...
...
@@ -1309,15 +1333,113 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
return
default_count
;
}
static
int
compiler_visit_argannotation
(
struct
compiler
*
c
,
identifier
id
,
expr_ty
annotation
,
PyObject
*
names
)
{
if
(
annotation
)
{
VISIT
(
c
,
expr
,
annotation
);
if
(
PyList_Append
(
names
,
id
))
return
-
1
;
}
return
0
;
}
static
int
compiler_visit_argannotations
(
struct
compiler
*
c
,
asdl_seq
*
args
,
PyObject
*
names
)
{
int
i
,
error
;
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
args
);
i
++
)
{
arg_ty
arg
=
(
arg_ty
)
asdl_seq_GET
(
args
,
i
);
if
(
arg
->
kind
==
NestedArgs_kind
)
error
=
compiler_visit_argannotations
(
c
,
arg
->
v
.
NestedArgs
.
args
,
names
);
else
error
=
compiler_visit_argannotation
(
c
,
arg
->
v
.
SimpleArg
.
arg
,
arg
->
v
.
SimpleArg
.
annotation
,
names
);
if
(
error
)
return
error
;
}
return
0
;
}
static
int
compiler_visit_annotations
(
struct
compiler
*
c
,
arguments_ty
args
,
expr_ty
returns
)
{
/* push arg annotations and a list of the argument names. return the #
of items pushed. this is out-of-order wrt the source code. */
static
identifier
return_str
;
PyObject
*
names
;
int
len
;
names
=
PyList_New
(
0
);
if
(
!
names
)
return
-
1
;
if
(
compiler_visit_argannotations
(
c
,
args
->
args
,
names
))
goto
error
;
if
(
args
->
varargannotation
&&
compiler_visit_argannotation
(
c
,
args
->
vararg
,
args
->
varargannotation
,
names
))
goto
error
;
if
(
compiler_visit_argannotations
(
c
,
args
->
kwonlyargs
,
names
))
goto
error
;
if
(
args
->
kwargannotation
&&
compiler_visit_argannotation
(
c
,
args
->
kwarg
,
args
->
kwargannotation
,
names
))
goto
error
;
if
(
!
return_str
)
{
return_str
=
PyString_InternFromString
(
"return"
);
if
(
!
return_str
)
goto
error
;
}
if
(
compiler_visit_argannotation
(
c
,
return_str
,
returns
,
names
))
{
goto
error
;
}
len
=
PyList_GET_SIZE
(
names
);
if
(
len
)
{
/* convert names to a tuple and place on stack */
PyObject
*
elt
;
int
i
;
PyObject
*
s
=
PyTuple_New
(
len
);
if
(
!
s
)
goto
error
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
elt
=
PyList_GET_ITEM
(
names
,
i
);
Py_INCREF
(
elt
);
PyTuple_SET_ITEM
(
s
,
i
,
elt
);
}
ADDOP_O
(
c
,
LOAD_CONST
,
s
,
consts
);
Py_DECREF
(
s
);
len
++
;
/* include the just-pushed tuple */
}
Py_DECREF
(
names
);
return
len
;
error:
Py_DECREF
(
names
);
return
-
1
;
}
static
int
compiler_function
(
struct
compiler
*
c
,
stmt_ty
s
)
{
PyCodeObject
*
co
;
PyObject
*
first_const
=
Py_None
;
arguments_ty
args
=
s
->
v
.
FunctionDef
.
args
;
expr_ty
returns
=
s
->
v
.
FunctionDef
.
returns
;
asdl_seq
*
decos
=
s
->
v
.
FunctionDef
.
decorators
;
stmt_ty
st
;
int
i
,
n
,
docstring
,
kw_default_count
=
0
,
arglength
;
int
num_annotations
;
assert
(
s
->
kind
==
FunctionDef_kind
);
...
...
@@ -1332,6 +1454,7 @@ compiler_function(struct compiler *c, stmt_ty s)
}
if
(
args
->
defaults
)
VISIT_SEQ
(
c
,
expr
,
args
->
defaults
);
num_annotations
=
compiler_visit_annotations
(
c
,
args
,
returns
);
if
(
!
compiler_enter_scope
(
c
,
s
->
v
.
FunctionDef
.
name
,
(
void
*
)
s
,
s
->
lineno
))
...
...
@@ -1364,9 +1487,11 @@ compiler_function(struct compiler *c, stmt_ty s)
arglength
=
asdl_seq_LEN
(
args
->
defaults
);
arglength
|=
kw_default_count
<<
8
;
arglength
|=
num_annotations
<<
16
;
compiler_make_closure
(
c
,
co
,
arglength
);
Py_DECREF
(
co
);
/* decorators */
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
decos
);
i
++
)
{
ADDOP_I
(
c
,
CALL_FUNCTION
,
1
);
}
...
...
Python/graminit.c
View file @
c150536b
This diff is collapsed.
Click to expand it.
Python/symtable.c
View file @
c150536b
...
...
@@ -172,9 +172,12 @@ static int symtable_visit_alias(struct symtable *st, alias_ty);
static
int
symtable_visit_comprehension
(
struct
symtable
*
st
,
comprehension_ty
);
static
int
symtable_visit_keyword
(
struct
symtable
*
st
,
keyword_ty
);
static
int
symtable_visit_slice
(
struct
symtable
*
st
,
slice_ty
);
static
int
symtable_visit_params
(
struct
symtable
*
st
,
asdl_seq
*
args
,
int
top
);
static
int
symtable_visit_params_nested
(
struct
symtable
*
st
,
asdl_seq
*
args
);
static
int
symtable_visit_params
(
struct
symtable
*
st
,
asdl_seq
*
args
,
int
top
,
int
annotations
);
static
int
symtable_visit_params_nested
(
struct
symtable
*
st
,
asdl_seq
*
args
,
int
annotations
);
static
int
symtable_implicit_arg
(
struct
symtable
*
st
,
int
pos
);
static
int
symtable_visit_annotations
(
struct
symtable
*
st
,
stmt_ty
s
);
static
identifier
top
=
NULL
,
lambda
=
NULL
,
genexpr
=
NULL
;
...
...
@@ -935,6 +938,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if
(
s
->
v
.
FunctionDef
.
args
->
kw_defaults
)
VISIT_KWONLYDEFAULTS
(
st
,
s
->
v
.
FunctionDef
.
args
->
kw_defaults
);
if
(
!
symtable_visit_annotations
(
st
,
s
))
return
0
;
if
(
s
->
v
.
FunctionDef
.
decorators
)
VISIT_SEQ
(
st
,
expr
,
s
->
v
.
FunctionDef
.
decorators
);
if
(
!
symtable_enter_block
(
st
,
s
->
v
.
FunctionDef
.
name
,
...
...
@@ -1219,22 +1224,29 @@ symtable_implicit_arg(struct symtable *st, int pos)
}
static
int
symtable_visit_params
(
struct
symtable
*
st
,
asdl_seq
*
args
,
int
toplevel
)
symtable_visit_params
(
struct
symtable
*
st
,
asdl_seq
*
args
,
int
toplevel
,
int
annotations
)
{
int
i
;
if
(
!
args
)
return
-
1
;
/* go through all the toplevel arguments first */
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
args
);
i
++
)
{
expr_ty
arg
=
(
expr_ty
)
asdl_seq_GET
(
args
,
i
);
if
(
arg
->
kind
==
Name_kind
)
{
assert
(
arg
->
v
.
Name
.
ctx
==
Param
||
(
arg
->
v
.
Name
.
ctx
==
Store
&&
!
toplevel
));
if
(
!
symtable_add_def
(
st
,
arg
->
v
.
Name
.
id
,
DEF_PARAM
))
return
0
;
arg_ty
arg
=
(
arg_ty
)
asdl_seq_GET
(
args
,
i
);
if
(
arg
->
kind
==
SimpleArg_kind
)
{
if
(
!
annotations
)
{
if
(
!
symtable_add_def
(
st
,
arg
->
v
.
SimpleArg
.
arg
,
DEF_PARAM
))
return
0
;
}
else
if
(
arg
->
v
.
SimpleArg
.
annotation
)
VISIT
(
st
,
expr
,
arg
->
v
.
SimpleArg
.
annotation
);
}
else
if
(
arg
->
kind
==
Tuple_kind
)
{
assert
(
arg
->
v
.
Tuple
.
ctx
==
Store
);
if
(
toplevel
)
{
else
if
(
arg
->
kind
==
NestedArgs_kind
)
{
if
(
toplevel
&&
!
annotations
)
{
if
(
!
symtable_implicit_arg
(
st
,
i
))
return
0
;
}
...
...
@@ -1249,7 +1261,7 @@ symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel)
}
if
(
!
toplevel
)
{
if
(
!
symtable_visit_params_nested
(
st
,
args
))
if
(
!
symtable_visit_params_nested
(
st
,
args
,
annotations
))
return
0
;
}
...
...
@@ -1257,16 +1269,37 @@ symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel)
}
static
int
symtable_visit_params_nested
(
struct
symtable
*
st
,
asdl_seq
*
args
)
symtable_visit_params_nested
(
struct
symtable
*
st
,
asdl_seq
*
args
,
int
annotations
)
{
int
i
;
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
args
);
i
++
)
{
expr_ty
arg
=
(
expr_ty
)
asdl_seq_GET
(
args
,
i
);
if
(
arg
->
kind
==
Tuple_kind
&&
!
symtable_visit_params
(
st
,
arg
->
v
.
Tuple
.
elts
,
0
))
arg_ty
arg
=
(
arg_ty
)
asdl_seq_GET
(
args
,
i
);
if
(
arg
->
kind
==
NestedArgs_kind
&&
!
symtable_visit_params
(
st
,
arg
->
v
.
NestedArgs
.
args
,
0
,
annotations
))
return
0
;
}
return
1
;
}
static
int
symtable_visit_annotations
(
struct
symtable
*
st
,
stmt_ty
s
)
{
arguments_ty
a
=
s
->
v
.
FunctionDef
.
args
;
if
(
a
->
args
&&
!
symtable_visit_params
(
st
,
a
->
args
,
1
,
1
))
return
0
;
if
(
a
->
varargannotation
)
VISIT
(
st
,
expr
,
a
->
varargannotation
);
if
(
a
->
kwargannotation
)
VISIT
(
st
,
expr
,
a
->
kwargannotation
);
if
(
a
->
kwonlyargs
&&
!
symtable_visit_params
(
st
,
a
->
kwonlyargs
,
1
,
1
))
return
0
;
if
(
s
->
v
.
FunctionDef
.
returns
)
VISIT
(
st
,
expr
,
s
->
v
.
FunctionDef
.
returns
);
return
1
;
}
...
...
@@ -1276,9 +1309,9 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
/* skip default arguments inside function block
XXX should ast be different?
*/
if
(
a
->
args
&&
!
symtable_visit_params
(
st
,
a
->
args
,
1
))
if
(
a
->
args
&&
!
symtable_visit_params
(
st
,
a
->
args
,
1
,
0
))
return
0
;
if
(
a
->
kwonlyargs
&&
!
symtable_visit_params
(
st
,
a
->
kwonlyargs
,
1
))
if
(
a
->
kwonlyargs
&&
!
symtable_visit_params
(
st
,
a
->
kwonlyargs
,
1
,
0
))
return
0
;
if
(
a
->
vararg
)
{
if
(
!
symtable_add_def
(
st
,
a
->
vararg
,
DEF_PARAM
))
...
...
@@ -1290,7 +1323,7 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
return
0
;
st
->
st_cur
->
ste_varkeywords
=
1
;
}
if
(
a
->
args
&&
!
symtable_visit_params_nested
(
st
,
a
->
args
))
if
(
a
->
args
&&
!
symtable_visit_params_nested
(
st
,
a
->
args
,
0
))
return
0
;
return
1
;
}
...
...
Tools/compiler/ast.txt
View file @
c150536b
...
...
@@ -12,8 +12,11 @@
Module: doc*, node
Stmt: nodes!
Decorators: nodes!
Function: decorators&, name*, argnames*, defaults!, kwonlyargs*, flags*, doc*, code
Lambda: argnames*, defaults!, kwonlyargs*, flags*, code
Function: decorators&, name*, arguments!, defaults!, kwonlyargs!, returns&, flags*, doc*, code
Lambda: arguments!, defaults!, kwonlyargs!, flags*, code
SimpleArg: name*, annotation&
NestedArgs: args!
Kwarg: arg, expr
Class: name*, bases!, doc*, code
Pass:
Break:
...
...
@@ -93,9 +96,10 @@ init(Lambda):
self.varargs = 1
if flags & CO_VARKEYWORDS:
self.kwargs = 1
self.returns = None
init(GenExpr):
self.arg
names = ['.0'
]
self.arg
uments = [SimpleArg('.0', None)
]
self.varargs = self.kwargs = None
self.kwonlyargs = ()
...
...
Tools/compiler/astgen.py
View file @
c150536b
...
...
@@ -266,7 +266,10 @@ class Node:
pass
# implemented by subclasses
class
EmptyNode
(
Node
):
pass
def
getChildNodes
(
self
):
return
()
def
getChildren
(
self
):
return
()
class
Expression
(
Node
):
# Expression is an artificial node class to support "eval"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment