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
4f72a786
Commit
4f72a786
authored
Oct 27, 2006
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Jiwon Seo's PEP 3102 implementation.
See SF#1549670. The compiler package has not yet been updated.
parent
fc2a0a8e
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
739 additions
and
227 deletions
+739
-227
Grammar/Grammar
Grammar/Grammar
+1
-1
Include/Python-ast.h
Include/Python-ast.h
+5
-2
Include/code.h
Include/code.h
+4
-2
Include/eval.h
Include/eval.h
+1
-1
Include/funcobject.h
Include/funcobject.h
+5
-0
Lib/compiler/ast.py
Lib/compiler/ast.py
+9
-4
Lib/compiler/pyassem.py
Lib/compiler/pyassem.py
+8
-3
Lib/compiler/pycodegen.py
Lib/compiler/pycodegen.py
+15
-0
Lib/compiler/transformer.py
Lib/compiler/transformer.py
+50
-11
Lib/test/output/test_extcall
Lib/test/output/test_extcall
+38
-38
Lib/test/test_ast.py
Lib/test/test_ast.py
+3
-3
Lib/test/test_code.py
Lib/test/test_code.py
+24
-2
Lib/test/test_compiler.py
Lib/test/test_compiler.py
+45
-30
Lib/test/test_frozen.py
Lib/test/test_frozen.py
+7
-0
Lib/test/test_grammar.py
Lib/test/test_grammar.py
+15
-1
Lib/test/test_new.py
Lib/test/test_new.py
+13
-6
Modules/_ctypes/callbacks.c
Modules/_ctypes/callbacks.c
+1
-0
Modules/parsermodule.c
Modules/parsermodule.c
+33
-9
Modules/pyexpat.c
Modules/pyexpat.c
+1
-0
Objects/codeobject.c
Objects/codeobject.c
+20
-5
Objects/funcobject.c
Objects/funcobject.c
+73
-0
Parser/Python.asdl
Parser/Python.asdl
+2
-2
Python/Python-ast.c
Python/Python-ast.c
+18
-4
Python/ast.c
Python/ast.c
+178
-63
Python/ceval.c
Python/ceval.c
+64
-14
Python/compile.c
Python/compile.c
+49
-6
Python/graminit.c
Python/graminit.c
+29
-16
Python/import.c
Python/import.c
+2
-1
Python/marshal.c
Python/marshal.c
+5
-1
Python/symtable.c
Python/symtable.c
+18
-0
Tools/compiler/ast.txt
Tools/compiler/ast.txt
+3
-2
No files found.
Grammar/Grammar
View file @
4f72a786
...
...
@@ -24,7 +24,7 @@ decorators: decorator+
funcdef: [decorators] 'def' NAME parameters ':' suite
parameters: '(' [varargslist] ')'
varargslist: ((fpdef ['=' test] ',')*
('*'
NAME
[',' '**' NAME] | '**' NAME) |
('*'
[NAME] (',' NAME ['=' test])*
[',' '**' NAME] | '**' NAME) |
fpdef ['=' test] (',' fpdef ['=' test])* [','])
fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']
...
...
Include/Python-ast.h
View file @
4f72a786
...
...
@@ -328,8 +328,10 @@ struct _excepthandler {
struct
_arguments
{
asdl_seq
*
args
;
identifier
vararg
;
asdl_seq
*
kwonlyargs
;
identifier
kwarg
;
asdl_seq
*
defaults
;
asdl_seq
*
kw_defaults
;
};
struct
_keyword
{
...
...
@@ -427,8 +429,9 @@ 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
,
identifier
kwarg
,
asdl_seq
*
defaults
,
PyArena
*
arena
);
arguments_ty
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
asdl_seq
*
kwonlyargs
,
identifier
kwarg
,
asdl_seq
*
defaults
,
asdl_seq
*
kw_defaults
,
PyArena
*
arena
);
keyword_ty
keyword
(
identifier
arg
,
expr_ty
value
,
PyArena
*
arena
);
alias_ty
alias
(
identifier
name
,
identifier
asname
,
PyArena
*
arena
);
...
...
Include/code.h
View file @
4f72a786
...
...
@@ -10,6 +10,7 @@ extern "C" {
typedef
struct
{
PyObject_HEAD
int
co_argcount
;
/* #arguments, except *args */
int
co_kwonlyargcount
;
/* #keyword only arguments */
int
co_nlocals
;
/* #local variables */
int
co_stacksize
;
/* #entries needed for evaluation stack */
int
co_flags
;
/* CO_..., see below */
...
...
@@ -63,8 +64,9 @@ PyAPI_DATA(PyTypeObject) PyCode_Type;
/* Public interface */
PyAPI_FUNC
(
PyCodeObject
*
)
PyCode_New
(
int
,
int
,
int
,
int
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
int
,
PyObject
*
);
int
,
int
,
int
,
int
,
int
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyObject
*
,
int
,
PyObject
*
);
/* same as struct above */
PyAPI_FUNC
(
int
)
PyCode_Addr2Line
(
PyCodeObject
*
,
int
);
...
...
Include/eval.h
View file @
4f72a786
...
...
@@ -15,7 +15,7 @@ PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co,
PyObject
**
args
,
int
argc
,
PyObject
**
kwds
,
int
kwdc
,
PyObject
**
defs
,
int
defc
,
PyObject
*
closure
);
PyObject
*
kwdefs
,
PyObject
*
closure
);
PyAPI_FUNC
(
PyObject
*
)
_PyEval_CallTracing
(
PyObject
*
func
,
PyObject
*
args
);
...
...
Include/funcobject.h
View file @
4f72a786
...
...
@@ -23,6 +23,7 @@ typedef struct {
PyObject
*
func_code
;
/* A code object */
PyObject
*
func_globals
;
/* A dictionary (other mappings won't do) */
PyObject
*
func_defaults
;
/* NULL or a tuple */
PyObject
*
func_kwdefaults
;
/* NULL or a dict */
PyObject
*
func_closure
;
/* NULL or a tuple of cell objects */
PyObject
*
func_doc
;
/* The __doc__ attribute, can be anything */
PyObject
*
func_name
;
/* The __name__ attribute, a string object */
...
...
@@ -47,6 +48,8 @@ PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *);
PyAPI_FUNC
(
PyObject
*
)
PyFunction_GetModule
(
PyObject
*
);
PyAPI_FUNC
(
PyObject
*
)
PyFunction_GetDefaults
(
PyObject
*
);
PyAPI_FUNC
(
int
)
PyFunction_SetDefaults
(
PyObject
*
,
PyObject
*
);
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
*
);
...
...
@@ -60,6 +63,8 @@ PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
(((PyFunctionObject *)func) -> func_module)
#define PyFunction_GET_DEFAULTS(func) \
(((PyFunctionObject *)func) -> func_defaults)
#define PyFunction_GET_KW_DEFAULTS(func) \
(((PyFunctionObject *)func) -> func_kwdefaults)
#define PyFunction_GET_CLOSURE(func) \
(((PyFunctionObject *)func) -> func_closure)
...
...
Lib/compiler/ast.py
View file @
4f72a786
...
...
@@ -487,11 +487,12 @@ 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
,
argnames
,
defaults
,
flags
,
doc
,
code
,
lineno
=
None
):
def
__init__
(
self
,
decorators
,
name
,
argnames
,
defaults
,
kwonlyargs
,
flags
,
doc
,
code
,
lineno
=
None
):
self
.
decorators
=
decorators
self
.
name
=
name
self
.
argnames
=
argnames
self
.
defaults
=
defaults
self
.
kwonlyargs
=
kwonlyargs
self
.
flags
=
flags
self
.
doc
=
doc
self
.
code
=
code
...
...
@@ -509,6 +510,7 @@ class Function(Node):
children
.
append
(
self
.
name
)
children
.
append
(
self
.
argnames
)
children
.
extend
(
flatten
(
self
.
defaults
))
children
.
append
(
self
.
kwonlyargs
)
children
.
append
(
self
.
flags
)
children
.
append
(
self
.
doc
)
children
.
append
(
self
.
code
)
...
...
@@ -523,7 +525,7 @@ class Function(Node):
return
tuple
(
nodelist
)
def
__repr__
(
self
):
return
"Function(%s, %s, %s, %s, %s, %s, %s
)"
%
(
repr
(
self
.
decorators
),
repr
(
self
.
name
),
repr
(
self
.
argnames
),
repr
(
self
.
default
s
),
repr
(
self
.
flags
),
repr
(
self
.
doc
),
repr
(
self
.
code
))
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
))
class
GenExpr
(
Node
):
def
__init__
(
self
,
code
,
lineno
=
None
):
...
...
@@ -531,6 +533,7 @@ class GenExpr(Node):
self
.
lineno
=
lineno
self
.
argnames
=
[
'.0'
]
self
.
varargs
=
self
.
kwargs
=
None
self
.
kwonlyargs
=
()
def
getChildren
(
self
):
...
...
@@ -713,9 +716,10 @@ class Keyword(Node):
return
"Keyword(%s, %s)"
%
(
repr
(
self
.
name
),
repr
(
self
.
expr
))
class
Lambda
(
Node
):
def
__init__
(
self
,
argnames
,
defaults
,
flags
,
code
,
lineno
=
None
):
def
__init__
(
self
,
argnames
,
defaults
,
kwonlyargs
,
flags
,
code
,
lineno
=
None
):
self
.
argnames
=
argnames
self
.
defaults
=
defaults
self
.
kwonlyargs
=
kwonlyargs
self
.
flags
=
flags
self
.
code
=
code
self
.
lineno
=
lineno
...
...
@@ -730,6 +734,7 @@ class Lambda(Node):
children
=
[]
children
.
append
(
self
.
argnames
)
children
.
extend
(
flatten
(
self
.
defaults
))
children
.
append
(
self
.
kwonlyargs
)
children
.
append
(
self
.
flags
)
children
.
append
(
self
.
code
)
return
tuple
(
children
)
...
...
@@ -741,7 +746,7 @@ class Lambda(Node):
return
tuple
(
nodelist
)
def
__repr__
(
self
):
return
"Lambda(%s, %s, %s, %s
)"
%
(
repr
(
self
.
argnames
),
repr
(
self
.
default
s
),
repr
(
self
.
flags
),
repr
(
self
.
code
))
return
"Lambda(%s, %s, %s, %s
, %s)"
%
(
repr
(
self
.
argnames
),
repr
(
self
.
defaults
),
repr
(
self
.
kwonlyarg
s
),
repr
(
self
.
flags
),
repr
(
self
.
code
))
class
LeftShift
(
Node
):
def
__init__
(
self
,
(
left
,
right
),
lineno
=
None
):
...
...
Lib/compiler/pyassem.py
View file @
4f72a786
...
...
@@ -313,13 +313,15 @@ DONE = "DONE"
class
PyFlowGraph
(
FlowGraph
):
super_init
=
FlowGraph
.
__init__
def
__init__
(
self
,
name
,
filename
,
args
=
(),
optimized
=
0
,
klass
=
None
):
def
__init__
(
self
,
name
,
filename
,
args
=
(),
kwonlyargs
=
{},
optimized
=
0
,
klass
=
None
):
self
.
super_init
()
self
.
name
=
name
self
.
filename
=
filename
self
.
docstring
=
None
self
.
args
=
args
# XXX
self
.
argcount
=
getArgCount
(
args
)
self
.
kwonlyargs
=
kwonlyargs
self
.
klass
=
klass
if
optimized
:
self
.
flags
=
CO_OPTIMIZED
|
CO_NEWLOCALS
...
...
@@ -595,7 +597,9 @@ class PyFlowGraph(FlowGraph):
argcount
=
self
.
argcount
if
self
.
flags
&
CO_VARKEYWORDS
:
argcount
=
argcount
-
1
return
new
.
code
(
argcount
,
nlocals
,
self
.
stacksize
,
self
.
flags
,
kwonlyargcount
=
len
(
self
.
kwonlyargs
)
return
new
.
code
(
argcount
,
kwonlyargcount
,
nlocals
,
self
.
stacksize
,
self
.
flags
,
self
.
lnotab
.
getCode
(),
self
.
getConsts
(),
tuple
(
self
.
names
),
tuple
(
self
.
varnames
),
self
.
filename
,
self
.
name
,
self
.
lnotab
.
firstline
,
...
...
@@ -804,7 +808,8 @@ class StackDepthTracker:
def
CALL_FUNCTION_VAR_KW
(
self
,
argc
):
return
self
.
CALL_FUNCTION
(
argc
)
-
2
def
MAKE_FUNCTION
(
self
,
argc
):
return
-
argc
hi
,
lo
=
divmod
(
argc
,
256
)
return
-
(
lo
+
hi
*
2
)
def
MAKE_CLOSURE
(
self
,
argc
):
# XXX need to account for free variables too!
return
-
argc
...
...
Lib/compiler/pycodegen.py
View file @
4f72a786
...
...
@@ -378,6 +378,12 @@ class CodeGenerator:
walk
(
node
.
code
,
gen
)
gen
.
finish
()
self
.
set_lineno
(
node
)
for
keyword
in
node
.
kwonlyargs
:
default
=
keyword
.
expr
if
isinstance
(
default
,
ast
.
EmptyNode
):
continue
self
.
emit
(
'LOAD_CONST'
,
keyword
.
name
)
self
.
visit
(
default
)
for
default
in
node
.
defaults
:
self
.
visit
(
default
)
self
.
_makeClosure
(
gen
,
len
(
node
.
defaults
))
...
...
@@ -1320,7 +1326,9 @@ class AbstractFunctionCode:
name
=
func
.
name
args
,
hasTupleArg
=
generateArgList
(
func
.
argnames
)
kwonlyargs
=
generateKwonlyArgList
(
func
.
kwonlyargs
)
self
.
graph
=
pyassem
.
PyFlowGraph
(
name
,
func
.
filename
,
args
,
kwonlyargs
=
kwonlyargs
,
optimized
=
1
)
self
.
isLambda
=
isLambda
self
.
super_init
()
...
...
@@ -1456,6 +1464,13 @@ def generateArgList(arglist):
raise
ValueError
,
"unexpect argument type:"
,
elt
return
args
+
extra
,
count
def
generateKwonlyArgList
(
keywordOnlyArgs
):
kwonlyargs
=
{}
for
elt
in
keywordOnlyArgs
:
assert
isinstance
(
elt
,
ast
.
Keyword
)
kwonlyargs
[
elt
.
name
]
=
elt
.
expr
return
kwonlyargs
def
findOp
(
node
):
"""Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
v
=
OpFinder
()
...
...
Lib/compiler/transformer.py
View file @
4f72a786
...
...
@@ -250,9 +250,9 @@ class Transformer:
args
=
nodelist
[
-
3
][
2
]
if
args
[
0
]
==
symbol
.
varargslist
:
names
,
defaults
,
flags
=
self
.
com_arglist
(
args
[
1
:])
names
,
defaults
,
kwonlyargs
,
flags
=
self
.
com_arglist
(
args
[
1
:])
else
:
names
=
defaults
=
()
names
=
defaults
=
kwonlyargs
=
()
flags
=
0
doc
=
self
.
get_docstring
(
nodelist
[
-
1
])
...
...
@@ -263,21 +263,23 @@ class Transformer:
assert
isinstance
(
code
,
Stmt
)
assert
isinstance
(
code
.
nodes
[
0
],
Discard
)
del
code
.
nodes
[
0
]
return
Function
(
decorators
,
name
,
names
,
defaults
,
flags
,
doc
,
code
,
lineno
=
lineno
)
return
Function
(
decorators
,
name
,
names
,
defaults
,
kwonlyargs
,
flags
,
doc
,
code
,
lineno
=
lineno
)
def
lambdef
(
self
,
nodelist
):
# lambdef: 'lambda' [varargslist] ':' test
if
nodelist
[
2
][
0
]
==
symbol
.
varargslist
:
names
,
defaults
,
flags
=
self
.
com_arglist
(
nodelist
[
2
][
1
:])
names
,
defaults
,
kwonlyargs
,
flags
=
\
self
.
com_arglist
(
nodelist
[
2
][
1
:])
else
:
names
=
defaults
=
()
names
=
defaults
=
kwonlyargs
=
()
flags
=
0
# code for lambda
code
=
self
.
com_node
(
nodelist
[
-
1
])
return
Lambda
(
names
,
defaults
,
flags
,
code
,
lineno
=
nodelist
[
1
][
2
])
return
Lambda
(
names
,
defaults
,
kwonlyargs
,
flags
,
code
,
lineno
=
nodelist
[
1
][
2
])
old_lambdef
=
lambdef
def
classdef
(
self
,
nodelist
):
...
...
@@ -783,13 +785,37 @@ class Transformer:
# ('const', xxxx)) Nodes)
return
Discard
(
Const
(
None
))
def
keywordonlyargs
(
self
,
nodelist
):
# (',' NAME ['=' test])*
# ^^^
# ------+
kwonlyargs
=
[]
i
=
0
while
i
<
len
(
nodelist
):
default
=
EmptyNode
()
node
=
nodelist
[
i
]
#assert node[0] == token.COMMA
#node = nodelist[i+1]
if
i
+
1
<
len
(
nodelist
)
and
nodelist
[
i
+
1
][
0
]
==
token
.
EQUAL
:
assert
i
+
2
<
len
(
nodelist
)
default
=
self
.
com_node
(
nodelist
[
i
+
2
])
i
+=
2
if
node
[
0
]
==
token
.
DOUBLESTAR
:
return
kwonlyargs
,
i
elif
node
[
0
]
==
token
.
NAME
:
kwonlyargs
.
append
(
Keyword
(
node
[
1
],
default
,
lineno
=
node
[
2
]))
i
+=
2
return
kwonlyargs
,
i
def
com_arglist
(
self
,
nodelist
):
# varargslist:
# (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME)
# | fpdef ['=' test] (',' fpdef ['=' test])* [',']
# (fpdef ['=' test] ',')*
# ('*' [NAME] (',' NAME '=' test)* [',' '**' NAME] | '**' NAME)
# | fpdef ['=' test] (',' fpdef ['=' test])* [',']
# fpdef: NAME | '(' fplist ')'
# fplist: fpdef (',' fpdef)* [',']
names
=
[]
kwonlyargs
=
[]
defaults
=
[]
flags
=
0
...
...
@@ -799,10 +825,22 @@ 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
:
if
node
[
0
]
==
token
.
NAME
:
# vararg
names
.
append
(
node
[
1
])
flags
=
flags
|
CO_VARARGS
i
=
i
+
3
else
:
# no vararg
assert
node
[
0
]
==
token
.
COMMA
i
+=
1
#elif node[0] == token.COMMA:
# i += 1
# kwonlyargs, skip = self.keywordonlyargs(nodelist[i:])
# i += skip
if
nodelist
[
i
][
0
]
==
token
.
NAME
:
kwonlyargs
,
skip
=
self
.
keywordonlyargs
(
nodelist
[
i
:])
i
+=
skip
print
"kwonlyargs:"
,
kwonlyargs
if
i
<
len
(
nodelist
):
# should be DOUBLESTAR
...
...
@@ -831,7 +869,8 @@ class Transformer:
# skip the comma
i
=
i
+
1
return
names
,
defaults
,
flags
print
"names:"
,
names
,
"defaults:"
,
defaults
,
"kwonlyargs:"
,
kwonlyargs
,
"flags:"
,
flags
return
names
,
defaults
,
kwonlyargs
,
flags
def
com_fpdef
(
self
,
node
):
# fpdef: NAME | '(' fplist ')'
...
...
Lib/test/output/test_extcall
View file @
4f72a786
...
...
@@ -9,9 +9,9 @@ test_extcall
(1, 2, 3) {'a': 4, 'b': 5}
(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
TypeError: g() takes at least 1 argument (0 given)
TypeError: g() takes at least 1 argument (0 given)
TypeError: g() takes at least 1 argument (0 given)
TypeError: g() takes at least 1
positional
argument (0 given)
TypeError: g() takes at least 1
positional
argument (0 given)
TypeError: g() takes at least 1
positional
argument (0 given)
1 () {}
1 (2,) {}
1 (2, 3) {}
...
...
@@ -35,24 +35,24 @@ dir() got multiple values for keyword argument 'b'
3 512 True
3
3
za () {} -> za() takes exactly 1 argument (0 given)
za () {} -> za() takes exactly 1
positional
argument (0 given)
za () {'a': 'aa'} -> ok za aa B D E V a
za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd'
za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd'
za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got an unexpected keyword argument 'b'
za (1, 2) {} -> za() takes exactly 1 argument (2 given)
za (1, 2) {'a': 'aa'} -> za() takes exactly 1 non-keyword argument (2 given)
za (1, 2) {'d': 'dd'} -> za() takes exactly 1 non-keyword argument (2 given)
za (1, 2) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword argument (2 given)
za (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword argument (2 given)
za (1, 2, 3, 4, 5) {} -> za() takes exactly 1 argument (5 given)
za (1, 2, 3, 4, 5) {'a': 'aa'} -> za() takes exactly 1 non-keyword argument (5 given)
za (1, 2, 3, 4, 5) {'d': 'dd'} -> za() takes exactly 1 non-keyword argument (5 given)
za (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword argument (5 given)
za (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword argument (5 given)
zade () {} -> zade() takes at least 1 argument (0 given)
za (1, 2) {} -> za() takes exactly 1
positional
argument (2 given)
za (1, 2) {'a': 'aa'} -> za() takes exactly 1 non-keyword
positional
argument (2 given)
za (1, 2) {'d': 'dd'} -> za() takes exactly 1 non-keyword
positional
argument (2 given)
za (1, 2) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword
positional
argument (2 given)
za (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword
positional
argument (2 given)
za (1, 2, 3, 4, 5) {} -> za() takes exactly 1
positional
argument (5 given)
za (1, 2, 3, 4, 5) {'a': 'aa'} -> za() takes exactly 1 non-keyword
positional
argument (5 given)
za (1, 2, 3, 4, 5) {'d': 'dd'} -> za() takes exactly 1 non-keyword
positional
argument (5 given)
za (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword
positional
argument (5 given)
za (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword
positional
argument (5 given)
zade () {} -> zade() takes at least 1
positional
argument (0 given)
zade () {'a': 'aa'} -> ok zade aa B d e V a
zade () {'d': 'dd'} -> zade() takes at least 1 non-keyword argument (0 given)
zade () {'d': 'dd'} -> zade() takes at least 1 non-keyword
positional
argument (0 given)
zade () {'a': 'aa', 'd': 'dd'} -> ok zade aa B dd e V d
zade () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got an unexpected keyword argument 'b'
zade (1, 2) {} -> ok zade 1 B 2 e V e
...
...
@@ -60,30 +60,30 @@ zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a'
zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd'
zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a'
zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a'
zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 arguments (5 given)
zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() takes at most 3 non-keyword arguments (5 given)
zade (1, 2, 3, 4, 5) {'d': 'dd'} -> zade() takes at most 3 non-keyword arguments (5 given)
zade (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zade() takes at most 3 non-keyword arguments (5 given)
zade (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() takes at most 3 non-keyword arguments (5 given)
zabk () {} -> zabk() takes exactly 2 arguments (0 given)
zabk () {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (1 given)
zabk () {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (0 given)
zabk () {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (1 given)
zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3
positional
arguments (5 given)
zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() takes at most 3 non-keyword
positional
arguments (5 given)
zade (1, 2, 3, 4, 5) {'d': 'dd'} -> zade() takes at most 3 non-keyword
positional
arguments (5 given)
zade (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zade() takes at most 3 non-keyword
positional
arguments (5 given)
zade (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() takes at most 3 non-keyword
positional
arguments (5 given)
zabk () {} -> zabk() takes exactly 2
positional
arguments (0 given)
zabk () {'a': 'aa'} -> zabk() takes exactly 2 non-keyword
positional
arguments (1 given)
zabk () {'d': 'dd'} -> zabk() takes exactly 2 non-keyword
positional
arguments (0 given)
zabk () {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword
positional
arguments (1 given)
zabk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabk aa bb D E V {'d': 'dd', 'e': 'ee'}
zabk (1, 2) {} -> ok zabk 1 2 D E V {}
zabk (1, 2) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a'
zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'}
zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a'
zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a'
zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 arguments (5 given)
zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
zabk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
zabk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
zabk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() takes exactly 2 non-keyword arguments (5 given)
zabdv () {} -> zabdv() takes at least 2 arguments (0 given)
zabdv () {'a': 'aa'} -> zabdv() takes at least 2 non-keyword arguments (1 given)
zabdv () {'d': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (0 given)
zabdv () {'a': 'aa', 'd': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (1 given)
zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2
positional
arguments (5 given)
zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() takes exactly 2 non-keyword
positional
arguments (5 given)
zabk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabk() takes exactly 2 non-keyword
positional
arguments (5 given)
zabk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword
positional
arguments (5 given)
zabk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() takes exactly 2 non-keyword
positional
arguments (5 given)
zabdv () {} -> zabdv() takes at least 2
positional
arguments (0 given)
zabdv () {'a': 'aa'} -> zabdv() takes at least 2 non-keyword
positional
arguments (1 given)
zabdv () {'d': 'dd'} -> zabdv() takes at least 2 non-keyword
positional
arguments (0 given)
zabdv () {'a': 'aa', 'd': 'dd'} -> zabdv() takes at least 2 non-keyword
positional
arguments (1 given)
zabdv () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got an unexpected keyword argument 'e'
zabdv (1, 2) {} -> ok zabdv 1 2 d E () e
zabdv (1, 2) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a'
...
...
@@ -95,10 +95,10 @@ zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword arg
zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd'
zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a'
zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a'
zabdevk () {} -> zabdevk() takes at least 2 arguments (0 given)
zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword arguments (1 given)
zabdevk () {'d': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (0 given)
zabdevk () {'a': 'aa', 'd': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (1 given)
zabdevk () {} -> zabdevk() takes at least 2
positional
arguments (0 given)
zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword
positional
arguments (1 given)
zabdevk () {'d': 'dd'} -> zabdevk() takes at least 2 non-keyword
positional
arguments (0 given)
zabdevk () {'a': 'aa', 'd': 'dd'} -> zabdevk() takes at least 2 non-keyword
positional
arguments (1 given)
zabdevk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabdevk aa bb dd ee () {}
zabdevk (1, 2) {} -> ok zabdevk 1 2 d e () {}
zabdevk (1, 2) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a'
...
...
Lib/test/test_ast.py
View file @
4f72a786
...
...
@@ -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
,
[]
,
[]),
[(
'Pass'
,
(
1
,
9
))],
[])]),
(
'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
,
[]
,
[]),
[(
'Return'
,
(
1
,
8
),
(
'Num'
,
(
1
,
15
),
1
))],
[])]),
(
'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,7 +180,7 @@ 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
,
[]
,
[]),
(
'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'
,))])])),
...
...
Lib/test/test_code.py
View file @
4f72a786
...
...
@@ -9,6 +9,7 @@
>>> dump(f.func_code)
name: f
argcount: 1
kwonlyargcount: 0
names: ()
varnames: ('x', 'g')
cellvars: ('x',)
...
...
@@ -20,6 +21,7 @@ consts: ('None', '<code object g>')
>>> dump(f(4).func_code)
name: g
argcount: 1
kwonlyargcount: 0
names: ()
varnames: ('y',)
cellvars: ()
...
...
@@ -34,9 +36,11 @@ consts: ('None',)
... c = a * b
... return c
...
>>> dump(h.func_code)
name: h
argcount: 2
kwonlyargcount: 0
names: ()
varnames: ('x', 'y', 'a', 'b', 'c')
cellvars: ()
...
...
@@ -53,6 +57,7 @@ consts: ('None',)
>>> dump(attrs.func_code)
name: attrs
argcount: 1
kwonlyargcount: 0
names: ('attr1', 'attr2', 'attr3')
varnames: ('obj',)
cellvars: ()
...
...
@@ -70,6 +75,7 @@ consts: ('None',)
>>> dump(optimize_away.func_code)
name: optimize_away
argcount: 0
kwonlyargcount: 0
names: ()
varnames: ()
cellvars: ()
...
...
@@ -78,6 +84,22 @@ nlocals: 0
flags: 67
consts: ("'doc string'", 'None')
>>> def keywordonly_args(a,b,*,k1):
... return a,b,k1
...
>>> dump(keywordonly_args.func_code)
name: keywordonly_args
argcount: 2
kwonlyargcount: 1
names: ()
varnames: ('a', 'b', 'k1')
cellvars: ()
freevars: ()
nlocals: 3
flags: 67
consts: ('None',)
"""
def
consts
(
t
):
...
...
@@ -91,8 +113,8 @@ def consts(t):
def
dump
(
co
):
"""Print out a text representation of a code object."""
for
attr
in
[
"name"
,
"argcount"
,
"
names"
,
"varnames"
,
"cellvar
s"
,
"freevars"
,
"nlocals"
,
"flags"
]:
for
attr
in
[
"name"
,
"argcount"
,
"
kwonlyargcount"
,
"names"
,
"varname
s"
,
"
cellvars"
,
"
freevars"
,
"nlocals"
,
"flags"
]:
print
"%s: %s"
%
(
attr
,
getattr
(
co
,
"co_"
+
attr
))
print
"consts:"
,
tuple
(
consts
(
co
.
co_consts
))
...
...
Lib/test/test_compiler.py
View file @
4f72a786
...
...
@@ -19,36 +19,51 @@ class CompilerTest(unittest.TestCase):
libdir
=
os
.
path
.
dirname
(
unittest
.
__file__
)
testdir
=
os
.
path
.
dirname
(
test
.
test_support
.
__file__
)
for
dir
in
[
libdir
,
testdir
]:
for
basename
in
os
.
listdir
(
dir
):
# Print still working message since this test can be really slow
if
next_time
<=
time
.
time
():
next_time
=
time
.
time
()
+
_PRINT_WORKING_MSG_INTERVAL
print
>>
sys
.
__stdout__
,
\
' testCompileLibrary still working, be patient...'
sys
.
__stdout__
.
flush
()
if
not
basename
.
endswith
(
".py"
):
continue
if
not
TEST_ALL
and
random
()
<
0.98
:
continue
path
=
os
.
path
.
join
(
dir
,
basename
)
if
test
.
test_support
.
verbose
:
print
"compiling"
,
path
f
=
open
(
path
,
"U"
)
buf
=
f
.
read
()
f
.
close
()
if
"badsyntax"
in
basename
or
"bad_coding"
in
basename
:
self
.
assertRaises
(
SyntaxError
,
compiler
.
compile
,
buf
,
basename
,
"exec"
)
else
:
try
:
compiler
.
compile
(
buf
,
basename
,
"exec"
)
except
Exception
,
e
:
args
=
list
(
e
.
args
)
args
[
0
]
+=
"[in file %s]"
%
basename
e
.
args
=
tuple
(
args
)
raise
## for dir in [libdir, testdir]:
## for basename in os.listdir(dir):
## # Print still working message since this test can be really slow
## if next_time <= time.time():
## next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
## print >>sys.__stdout__, \
## ' testCompileLibrary still working, be patient...'
## sys.__stdout__.flush()
##
## if not basename.endswith(".py"):
## continue
## if not TEST_ALL and random() < 0.98:
## continue
## path = os.path.join(dir, basename)
## if test.test_support.verbose:
## print "compiling", path
## f = open(path, "U")
## buf = f.read()
## f.close()
## if "badsyntax" in basename or "bad_coding" in basename:
## self.assertRaises(SyntaxError, compiler.compile,
## buf, basename, "exec")
## else:
## try:
## compiler.compile(buf, basename, "exec")
## except Exception, e:
## args = list(e.args)
## args[0] += "[in file %s]" % basename
## e.args = tuple(args)
## raise
path
=
"/home/jiwon/p3yk/Lib/test/test_keywordonlyarg.py"
if
test
.
test_support
.
verbose
:
print
"compiling"
,
path
f
=
open
(
path
,
"U"
)
buf
=
f
.
read
()
f
.
close
()
#try:
compiler
.
compile
(
buf
,
"test_keywordonlyarg.py"
,
"exec"
)
#except Exception, e:
# args = list(e.args)
# args[0] += "[in file %s]" % path
# e.args = tuple(args)
# raise
def
testNewClassSyntax
(
self
):
compiler
.
compile
(
"class foo():pass
\
n
\
n
"
,
"<string>"
,
"exec"
)
...
...
Lib/test/test_frozen.py
View file @
4f72a786
# Test the frozen module defined in frozen.c.
# Currently test_frozen fails:
# Implementing pep3102(keyword only argument) needs changes in
# code object, which needs modification to marshal.
# However, to regenerate hard-coded marshal data in frozen.c,
# we need to run Tools/freeze/freeze.py, which currently doesn't work
# because Lib/modulefinder.py cannot handle relative module import
# This test will keep failing until Lib/modulefinder.py is fixed
from
test.test_support
import
TestFailed
import
sys
,
os
...
...
Lib/test/test_grammar.py
View file @
4f72a786
...
...
@@ -148,7 +148,8 @@ x = eval('1, 0 or 1')
print
'funcdef'
### 'def' NAME parameters ':' suite
### parameters: '(' [varargslist] ')'
### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
### varargslist: (fpdef ['=' test] ',')*
### ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
### | ('**'|'*' '*') NAME)
### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
### fpdef: NAME | '(' fplist ')'
...
...
@@ -265,6 +266,16 @@ def d31v((x)): pass
d31v
(
1
)
def
d32v
((
x
,)):
pass
d32v
((
1
,))
#keyword only argument tests
def
pos0key1
(
*
,
key
):
return
key
pos0key1
(
key
=
100
)
def
pos2key2
(
p1
,
p2
,
*
,
k1
,
k2
=
100
):
return
p1
,
p2
,
k1
,
k2
pos2key2
(
1
,
2
,
k1
=
100
)
pos2key2
(
1
,
2
,
k1
=
100
,
k2
=
200
)
pos2key2
(
1
,
2
,
k2
=
100
,
k1
=
200
)
def
pos2key2dict
(
p1
,
p2
,
*
,
k1
=
100
,
k2
,
**
kwarg
):
return
p1
,
p2
,
k1
,
k2
,
kwarg
pos2key2dict
(
1
,
2
,
k2
=
100
,
tokwarg1
=
100
,
tokwarg2
=
200
)
pos2key2dict
(
1
,
2
,
tokwarg1
=
100
,
tokwarg2
=
200
,
k2
=
100
)
### lambdef: 'lambda' [varargslist] ':' test
print
'lambdef'
...
...
@@ -279,6 +290,9 @@ l5 = lambda x, y, z=2: x + y + z
verify
(
l5
(
1
,
2
)
==
5
)
verify
(
l5
(
1
,
2
,
3
)
==
6
)
check_syntax
(
"lambda x: x = 2"
)
l6
=
lambda
x
,
y
,
*
,
k
=
20
:
x
+
y
+
k
verify
(
l6
(
1
,
2
)
==
1
+
2
+
20
)
verify
(
l6
(
1
,
2
,
k
=
10
)
==
1
+
2
+
10
)
### stmt: simple_stmt | compound_stmt
# Tested below
...
...
Lib/test/test_new.py
View file @
4f72a786
...
...
@@ -103,6 +103,7 @@ if hasattr(new, 'code'):
c
=
f
.
func_code
argcount
=
c
.
co_argcount
kwonlyargcount
=
c
.
co_kwonlyargcount
nlocals
=
c
.
co_nlocals
stacksize
=
c
.
co_stacksize
flags
=
c
.
co_flags
...
...
@@ -117,17 +118,20 @@ if hasattr(new, 'code'):
freevars
=
c
.
co_freevars
cellvars
=
c
.
co_cellvars
d
=
new
.
code
(
argcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
d
=
new
.
code
(
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
constants
,
names
,
varnames
,
filename
,
name
,
firstlineno
,
lnotab
,
freevars
,
cellvars
)
# test backwards-compatibility version with no freevars or cellvars
d
=
new
.
code
(
argcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
d
=
new
.
code
(
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
constants
,
names
,
varnames
,
filename
,
name
,
firstlineno
,
lnotab
)
try
:
# this used to trigger a SystemError
d
=
new
.
code
(
-
argcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
d
=
new
.
code
(
-
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
constants
,
names
,
varnames
,
filename
,
name
,
firstlineno
,
lnotab
)
except
ValueError
:
...
...
@@ -136,7 +140,8 @@ if hasattr(new, 'code'):
raise
TestFailed
,
"negative co_argcount didn't trigger an exception"
try
:
# this used to trigger a SystemError
d
=
new
.
code
(
argcount
,
-
nlocals
,
stacksize
,
flags
,
codestring
,
d
=
new
.
code
(
argcount
,
kwonlyargcount
,
-
nlocals
,
stacksize
,
flags
,
codestring
,
constants
,
names
,
varnames
,
filename
,
name
,
firstlineno
,
lnotab
)
except
ValueError
:
...
...
@@ -145,7 +150,8 @@ if hasattr(new, 'code'):
raise
TestFailed
,
"negative co_nlocals didn't trigger an exception"
try
:
# this used to trigger a Py_FatalError!
d
=
new
.
code
(
argcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
d
=
new
.
code
(
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
constants
,
(
5
,),
varnames
,
filename
,
name
,
firstlineno
,
lnotab
)
except
TypeError
:
...
...
@@ -156,7 +162,8 @@ if hasattr(new, 'code'):
# new.code used to be a way to mutate a tuple...
class
S
(
str
):
pass
t
=
(
S
(
"ab"
),)
d
=
new
.
code
(
argcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
d
=
new
.
code
(
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
codestring
,
constants
,
t
,
varnames
,
filename
,
name
,
firstlineno
,
lnotab
)
verify
(
type
(
t
[
0
])
is
S
,
"eek, tuple changed under us!"
)
...
...
Modules/_ctypes/callbacks.c
View file @
4f72a786
...
...
@@ -51,6 +51,7 @@ void _AddTraceback(char *funcname, char *filename, int lineno)
if
(
!
empty_string
)
goto
bad
;
py_code
=
PyCode_New
(
0
,
/*int argcount,*/
0
,
/*int kwonlyargcount,*/
0
,
/*int nlocals,*/
0
,
/*int stacksize,*/
0
,
/*int flags,*/
...
...
Modules/parsermodule.c
View file @
4f72a786
...
...
@@ -1105,13 +1105,13 @@ validate_testlist_safe(node *tree)
}
/* '*'
NAME
[',' '**' NAME] | '**' NAME
/* '*'
[NAME] (',' NAME ['=' test])*
[',' '**' NAME] | '**' NAME
*/
static
int
validate_varargslist_trailer
(
node
*
tree
,
int
start
)
{
int
nch
=
NCH
(
tree
);
int
res
=
0
;
int
res
=
0
,
i
;
int
sym
;
if
(
nch
<=
start
)
{
...
...
@@ -1121,15 +1121,40 @@ validate_varargslist_trailer(node *tree, int start)
sym
=
TYPE
(
CHILD
(
tree
,
start
));
if
(
sym
==
STAR
)
{
/*
*
('*' NAME [',' '**' NAME]
*
'*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME
*/
if
(
nch
-
start
==
2
)
res
=
validate_name
(
CHILD
(
tree
,
start
+
1
),
NULL
);
else
if
(
nch
-
start
==
5
)
else
if
(
nch
-
start
==
5
&&
TYPE
(
CHILD
(
tree
,
start
+
2
))
==
COMMA
)
res
=
(
validate_name
(
CHILD
(
tree
,
start
+
1
),
NULL
)
&&
validate_comma
(
CHILD
(
tree
,
start
+
2
))
&&
validate_doublestar
(
CHILD
(
tree
,
start
+
3
))
&&
validate_name
(
CHILD
(
tree
,
start
+
4
),
NULL
));
else
{
/* skip over [NAME] (',' NAME ['=' test])* */
i
=
start
+
1
;
if
(
TYPE
(
CHILD
(
tree
,
i
))
==
NAME
)
{
/* skip over [NAME] */
i
+=
1
;
}
while
(
res
&&
i
+
1
<
nch
)
{
/* validate (',' NAME ['=' test])* */
res
=
validate_comma
(
CHILD
(
tree
,
i
));
if
(
TYPE
(
CHILD
(
tree
,
i
+
1
))
==
DOUBLESTAR
)
break
;
res
=
res
&&
validate_name
(
CHILD
(
tree
,
i
+
1
),
NULL
);
if
(
res
&&
i
+
2
<
nch
&&
TYPE
(
CHILD
(
tree
,
i
+
2
))
==
EQUAL
)
{
res
=
res
&&
(
i
+
3
<
nch
)
&&
validate_test
(
CHILD
(
tree
,
i
+
3
));
i
+=
4
;
}
else
{
i
+=
2
;
}
}
/* [',' '**' NAME] */
if
(
res
&&
i
+
1
<
nch
&&
TYPE
(
CHILD
(
tree
,
i
+
1
))
==
DOUBLESTAR
)
{
res
=
validate_name
(
CHILD
(
tree
,
i
+
2
),
NULL
);
}
}
}
else
if
(
sym
==
DOUBLESTAR
)
{
/*
...
...
@@ -1148,9 +1173,8 @@ validate_varargslist_trailer(node *tree, int start)
*
* varargslist:
* (fpdef ['=' test] ',')*
* ('*' NAME [',' '**' NAME]
* | '**' NAME)
* | fpdef ['=' test] (',' fpdef ['=' test])* [',']
* ('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME)
* | fpdef ['=' test] (',' fpdef ['=' test])* [',']
*
*/
static
int
...
...
@@ -1169,7 +1193,7 @@ validate_varargslist(node *tree)
sym
=
TYPE
(
CHILD
(
tree
,
0
));
if
(
sym
==
STAR
||
sym
==
DOUBLESTAR
)
/* whole thing matches:
*
'*' NAME
[',' '**' NAME] | '**' NAME
*
'*' [NAME] (',' NAME ['=' test])*
[',' '**' NAME] | '**' NAME
*/
res
=
validate_varargslist_trailer
(
tree
,
0
);
else
if
(
sym
==
fpdef
)
{
...
...
@@ -1201,7 +1225,7 @@ validate_varargslist(node *tree)
break
;
}
}
/* ..
. '*' NAME [',' '**' NAME] | '**' NAME
/* ..
('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME)
* i --^^^
*/
if
(
res
)
...
...
Modules/pyexpat.c
View file @
4f72a786
...
...
@@ -279,6 +279,7 @@ getcode(enum HandlerTypes slot, char* func_name, int lineno)
filename
=
PyString_FromString
(
__FILE__
);
handler_info
[
slot
].
tb_code
=
PyCode_New
(
0
,
/* argcount */
0
,
/* kwonlyargcount */
0
,
/* nlocals */
0
,
/* stacksize */
0
,
/* flags */
...
...
Objects/codeobject.c
View file @
4f72a786
...
...
@@ -41,7 +41,8 @@ intern_strings(PyObject *tuple)
PyCodeObject
*
PyCode_New
(
int
argcount
,
int
nlocals
,
int
stacksize
,
int
flags
,
PyCode_New
(
int
argcount
,
int
kwonlyargcount
,
int
nlocals
,
int
stacksize
,
int
flags
,
PyObject
*
code
,
PyObject
*
consts
,
PyObject
*
names
,
PyObject
*
varnames
,
PyObject
*
freevars
,
PyObject
*
cellvars
,
PyObject
*
filename
,
PyObject
*
name
,
int
firstlineno
,
...
...
@@ -80,6 +81,7 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags,
co
=
PyObject_NEW
(
PyCodeObject
,
&
PyCode_Type
);
if
(
co
!=
NULL
)
{
co
->
co_argcount
=
argcount
;
co
->
co_kwonlyargcount
=
kwonlyargcount
;
co
->
co_nlocals
=
nlocals
;
co
->
co_stacksize
=
stacksize
;
co
->
co_flags
=
flags
;
...
...
@@ -112,6 +114,7 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags,
static
PyMemberDef
code_memberlist
[]
=
{
{
"co_argcount"
,
T_INT
,
OFF
(
co_argcount
),
READONLY
},
{
"co_kwonlyargcount"
,
T_INT
,
OFF
(
co_kwonlyargcount
),
READONLY
},
{
"co_nlocals"
,
T_INT
,
OFF
(
co_nlocals
),
READONLY
},
{
"co_stacksize"
,
T_INT
,
OFF
(
co_stacksize
),
READONLY
},
{
"co_flags"
,
T_INT
,
OFF
(
co_flags
),
READONLY
},
...
...
@@ -182,6 +185,7 @@ static PyObject *
code_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
argcount
;
int
kwonlyargcount
;
int
nlocals
;
int
stacksize
;
int
flags
;
...
...
@@ -197,8 +201,9 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
int
firstlineno
;
PyObject
*
lnotab
;
if
(
!
PyArg_ParseTuple
(
args
,
"iiiiSO!O!O!SSiS|O!O!:code"
,
&
argcount
,
&
nlocals
,
&
stacksize
,
&
flags
,
if
(
!
PyArg_ParseTuple
(
args
,
"iiiiiSO!O!O!SSiS|O!O!:code"
,
&
argcount
,
&
kwonlyargcount
,
&
nlocals
,
&
stacksize
,
&
flags
,
&
code
,
&
PyTuple_Type
,
&
consts
,
&
PyTuple_Type
,
&
names
,
...
...
@@ -216,6 +221,12 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
goto
cleanup
;
}
if
(
kwonlyargcount
<
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"code: kwonlyargcount must not be negative"
);
goto
cleanup
;
}
if
(
nlocals
<
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
...
...
@@ -242,7 +253,8 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if
(
ourcellvars
==
NULL
)
goto
cleanup
;
co
=
(
PyObject
*
)
PyCode_New
(
argcount
,
nlocals
,
stacksize
,
flags
,
co
=
(
PyObject
*
)
PyCode_New
(
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
code
,
consts
,
ournames
,
ourvarnames
,
ourfreevars
,
ourcellvars
,
filename
,
name
,
firstlineno
,
lnotab
);
...
...
@@ -312,6 +324,8 @@ code_richcompare(PyObject *self, PyObject *other, int op)
if
(
eq
<=
0
)
goto
unequal
;
eq
=
co
->
co_argcount
==
cp
->
co_argcount
;
if
(
!
eq
)
goto
unequal
;
eq
=
co
->
co_kwonlyargcount
==
cp
->
co_kwonlyargcount
;
if
(
!
eq
)
goto
unequal
;
eq
=
co
->
co_nlocals
==
cp
->
co_nlocals
;
if
(
!
eq
)
goto
unequal
;
eq
=
co
->
co_flags
==
cp
->
co_flags
;
...
...
@@ -369,7 +383,8 @@ code_hash(PyCodeObject *co)
h6
=
PyObject_Hash
(
co
->
co_cellvars
);
if
(
h6
==
-
1
)
return
-
1
;
h
=
h0
^
h1
^
h2
^
h3
^
h4
^
h5
^
h6
^
co
->
co_argcount
^
co
->
co_nlocals
^
co
->
co_flags
;
co
->
co_argcount
^
co
->
co_kwonlyargcount
^
co
->
co_nlocals
^
co
->
co_flags
;
if
(
h
==
-
1
)
h
=
-
2
;
return
h
;
}
...
...
Objects/funcobject.c
View file @
4f72a786
...
...
@@ -24,6 +24,7 @@ PyFunction_New(PyObject *code, PyObject *globals)
op
->
func_name
=
((
PyCodeObject
*
)
code
)
->
co_name
;
Py_INCREF
(
op
->
func_name
);
op
->
func_defaults
=
NULL
;
/* No default arguments */
op
->
func_kwdefaults
=
NULL
;
/* No keyword only defaults */
op
->
func_closure
=
NULL
;
consts
=
((
PyCodeObject
*
)
code
)
->
co_consts
;
if
(
PyTuple_Size
(
consts
)
>=
1
)
{
...
...
@@ -121,6 +122,38 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
return
0
;
}
PyObject
*
PyFunction_GetKwDefaults
(
PyObject
*
op
)
{
if
(
!
PyFunction_Check
(
op
))
{
PyErr_BadInternalCall
();
return
NULL
;
}
return
((
PyFunctionObject
*
)
op
)
->
func_kwdefaults
;
}
int
PyFunction_SetKwDefaults
(
PyObject
*
op
,
PyObject
*
defaults
)
{
if
(
!
PyFunction_Check
(
op
))
{
PyErr_BadInternalCall
();
return
-
1
;
}
if
(
defaults
==
Py_None
)
defaults
=
NULL
;
else
if
(
defaults
&&
PyDict_Check
(
defaults
))
{
Py_INCREF
(
defaults
);
}
else
{
PyErr_SetString
(
PyExc_SystemError
,
"non-dict keyword only default args"
);
return
-
1
;
}
Py_XDECREF
(((
PyFunctionObject
*
)
op
)
->
func_kwdefaults
);
((
PyFunctionObject
*
)
op
)
->
func_kwdefaults
=
defaults
;
return
0
;
}
PyObject
*
PyFunction_GetClosure
(
PyObject
*
op
)
{
...
...
@@ -325,10 +358,49 @@ func_set_defaults(PyFunctionObject *op, PyObject *value)
return
0
;
}
static
PyObject
*
func_get_kwdefaults
(
PyFunctionObject
*
op
)
{
if
(
restricted
())
return
NULL
;
if
(
op
->
func_kwdefaults
==
NULL
)
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
Py_INCREF
(
op
->
func_kwdefaults
);
return
op
->
func_kwdefaults
;
}
static
int
func_set_kwdefaults
(
PyFunctionObject
*
op
,
PyObject
*
value
)
{
PyObject
*
tmp
;
if
(
restricted
())
return
-
1
;
if
(
value
==
Py_None
)
value
=
NULL
;
/* Legal to del f.func_defaults.
* Can only set func_kwdefaults to NULL or a dict. */
if
(
value
!=
NULL
&&
!
PyDict_Check
(
value
))
{
PyErr_SetString
(
PyExc_TypeError
,
"func_kwdefaults must be set to a dict object"
);
return
-
1
;
}
tmp
=
op
->
func_kwdefaults
;
Py_XINCREF
(
value
);
op
->
func_kwdefaults
=
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_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
},
...
...
@@ -519,6 +591,7 @@ function_call(PyObject *func, PyObject *arg, PyObject *kw)
PyFunction_GET_GLOBALS
(
func
),
(
PyObject
*
)
NULL
,
&
PyTuple_GET_ITEM
(
arg
,
0
),
PyTuple_Size
(
arg
),
k
,
nk
,
d
,
nd
,
PyFunction_GET_KW_DEFAULTS
(
func
),
PyFunction_GET_CLOSURE
(
func
));
if
(
k
!=
NULL
)
...
...
Parser/Python.asdl
View file @
4f72a786
...
...
@@ -100,8 +100,8 @@ module Python version "$Revision$"
excepthandler = (expr? type, expr? name, stmt* body, int lineno,
int col_offset)
arguments = (expr* args, identifier? vararg,
identifier? kwarg, expr*
defaults)
arguments = (expr* args, identifier? vararg,
expr* kwonlyargs,
identifier? kwarg, expr* defaults, expr* kw_
defaults)
-- keyword arguments supplied to call
keyword = (identifier arg, expr value)
...
...
Python/Python-ast.c
View file @
4f72a786
...
...
@@ -333,8 +333,10 @@ static PyObject* ast2obj_arguments(void*);
static
char
*
arguments_fields
[]
=
{
"args"
,
"vararg"
,
"kwonlyargs"
,
"kwarg"
,
"defaults"
,
"kw_defaults"
,
};
static
PyTypeObject
*
keyword_type
;
static
PyObject
*
ast2obj_keyword
(
void
*
);
...
...
@@ -708,7 +710,7 @@ 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
,
4
);
arguments_type
=
make_type
(
"arguments"
,
AST_type
,
arguments_fields
,
6
);
if
(
!
arguments_type
)
return
0
;
keyword_type
=
make_type
(
"keyword"
,
AST_type
,
keyword_fields
,
2
);
if
(
!
keyword_type
)
return
0
;
...
...
@@ -1828,8 +1830,8 @@ excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int lineno, int
}
arguments_ty
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
identifier
kwarg
,
asdl_seq
*
defaults
,
PyArena
*
arena
)
arguments
(
asdl_seq
*
args
,
identifier
vararg
,
asdl_seq
*
kwonlyargs
,
identifier
kwarg
,
asdl_seq
*
defaults
,
asdl_seq
*
kw_
defaults
,
PyArena
*
arena
)
{
arguments_ty
p
;
p
=
(
arguments_ty
)
PyArena_Malloc
(
arena
,
sizeof
(
*
p
));
...
...
@@ -1839,8 +1841,10 @@ arguments(asdl_seq * args, identifier vararg, identifier kwarg, asdl_seq *
}
p
->
args
=
args
;
p
->
vararg
=
vararg
;
p
->
kwonlyargs
=
kwonlyargs
;
p
->
kwarg
=
kwarg
;
p
->
defaults
=
defaults
;
p
->
kw_defaults
=
kw_defaults
;
return
p
;
}
...
...
@@ -2907,6 +2911,11 @@ ast2obj_arguments(void* _o)
if
(
PyObject_SetAttrString
(
result
,
"vararg"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_list
(
o
->
kwonlyargs
,
ast2obj_expr
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"kwonlyargs"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_identifier
(
o
->
kwarg
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"kwarg"
,
value
)
==
-
1
)
...
...
@@ -2917,6 +2926,11 @@ ast2obj_arguments(void* _o)
if
(
PyObject_SetAttrString
(
result
,
"defaults"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
value
=
ast2obj_list
(
o
->
kw_defaults
,
ast2obj_expr
);
if
(
!
value
)
goto
failed
;
if
(
PyObject_SetAttrString
(
result
,
"kw_defaults"
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
return
result
;
failed:
Py_XDECREF
(
value
);
...
...
@@ -2994,7 +3008,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__"
,
"51
631
"
)
<
0
)
if
(
PyModule_AddStringConstant
(
m
,
"__version__"
,
"51
773
"
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"mod"
,
(
PyObject
*
)
mod_type
)
<
0
)
return
;
if
(
PyDict_SetItemString
(
d
,
"Module"
,
(
PyObject
*
)
Module_type
)
<
0
)
...
...
Python/ast.c
View file @
4f72a786
...
...
@@ -591,6 +591,63 @@ compiler_complex_args(struct compiling *c, const node *n)
return
result
;
}
/* returns -1 if failed to handle keyword only arguments
returns new position to keep processing if successful
(',' NAME ['=' test])*
^^^
start pointing here
*/
static
int
handle_keywordonly_args
(
struct
compiling
*
c
,
const
node
*
n
,
int
start
,
asdl_seq
*
kwonlyargs
,
asdl_seq
*
kwdefaults
)
{
node
*
ch
;
expr_ty
name
;
int
i
=
start
;
int
j
=
0
;
/* index for kwdefaults and kwonlyargs */
assert
(
kwonlyargs
!=
NULL
);
assert
(
kwdefaults
!=
NULL
);
while
(
i
<
NCH
(
n
))
{
ch
=
CHILD
(
n
,
i
);
switch
(
TYPE
(
ch
))
{
case
NAME
:
if
(
i
+
1
<
NCH
(
n
)
&&
TYPE
(
CHILD
(
n
,
i
+
1
))
==
EQUAL
)
{
expr_ty
expression
=
ast_for_expr
(
c
,
CHILD
(
n
,
i
+
2
));
if
(
!
expression
)
{
ast_error
(
ch
,
"assignment to None"
);
goto
error
;
}
asdl_seq_SET
(
kwdefaults
,
j
,
expression
);
i
+=
2
;
/* '=' and test */
}
else
{
/* setting NULL if no default value exists */
asdl_seq_SET
(
kwdefaults
,
j
,
NULL
);
}
if
(
!
strcmp
(
STR
(
ch
),
"None"
))
{
ast_error
(
ch
,
"assignment to None"
);
goto
error
;
}
name
=
Name
(
NEW_IDENTIFIER
(
ch
),
Param
,
LINENO
(
ch
),
ch
->
n_col_offset
,
c
->
c_arena
);
if
(
!
name
)
{
ast_error
(
ch
,
"expecting name"
);
goto
error
;
}
asdl_seq_SET
(
kwonlyargs
,
j
++
,
name
);
i
+=
2
;
/* the name and the comma */
break
;
case
DOUBLESTAR
:
return
i
;
default:
ast_error
(
ch
,
"unexpected node"
);
goto
error
;
}
}
return
i
;
error:
return
-
1
;
}
/* Create AST for argument list. */
...
...
@@ -598,35 +655,71 @@ static arguments_ty
ast_for_arguments
(
struct
compiling
*
c
,
const
node
*
n
)
{
/* parameters: '(' [varargslist] ')'
varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME]
| '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
varargslist: (fpdef ['=' test] ',')*
('*' [NAME] (',' fpdef ['=' test])* [',' '**' NAME] | '**' NAME)
| fpdef ['=' test] (',' fpdef ['=' test])* [',']
*/
int
i
,
j
,
k
,
n_args
=
0
,
n_defaults
=
0
,
found_default
=
0
;
asdl_seq
*
args
,
*
defaults
;
int
i
,
j
,
k
,
nposargs
=
0
,
nkwonlyargs
=
0
;
int
nposdefaults
=
0
,
found_default
=
0
;
asdl_seq
*
posargs
,
*
posdefaults
,
*
kwonlyargs
,
*
kwdefaults
;
identifier
vararg
=
NULL
,
kwarg
=
NULL
;
node
*
ch
;
if
(
TYPE
(
n
)
==
parameters
)
{
if
(
NCH
(
n
)
==
2
)
/* () as argument list */
return
arguments
(
NULL
,
NULL
,
NULL
,
NULL
,
c
->
c_arena
);
n
=
CHILD
(
n
,
1
);
if
(
NCH
(
n
)
==
2
)
/* () as argument list */
return
arguments
(
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
c
->
c_arena
);
n
=
CHILD
(
n
,
1
);
}
REQ
(
n
,
varargslist
);
/* first count the number of
norm
al args & defaults */
/* first count the number of
position
al args & defaults */
for
(
i
=
0
;
i
<
NCH
(
n
);
i
++
)
{
ch
=
CHILD
(
n
,
i
);
if
(
TYPE
(
ch
)
==
fpdef
)
n_args
++
;
if
(
TYPE
(
ch
)
==
EQUAL
)
n_defaults
++
;
}
args
=
(
n_args
?
asdl_seq_new
(
n_args
,
c
->
c_arena
)
:
NULL
);
if
(
!
args
&&
n_args
)
return
NULL
;
/* Don't need to goto error; no objects allocated */
defaults
=
(
n_defaults
?
asdl_seq_new
(
n_defaults
,
c
->
c_arena
)
:
NULL
);
if
(
!
defaults
&&
n_defaults
)
return
NULL
;
/* Don't need to goto error; no objects allocated */
ch
=
CHILD
(
n
,
i
);
if
(
TYPE
(
ch
)
==
STAR
)
{
if
(
TYPE
(
CHILD
(
n
,
i
+
1
))
==
NAME
)
{
/* skip NAME of vararg */
/* so that following can count only keyword only args */
i
+=
2
;
}
else
{
i
++
;
}
break
;
}
if
(
TYPE
(
ch
)
==
fpdef
)
nposargs
++
;
if
(
TYPE
(
ch
)
==
EQUAL
)
nposdefaults
++
;
}
/* count the number of keyword only args &
defaults for keyword only args */
for
(
;
i
<
NCH
(
n
);
++
i
)
{
ch
=
CHILD
(
n
,
i
);
if
(
TYPE
(
ch
)
==
DOUBLESTAR
)
break
;
if
(
TYPE
(
ch
)
==
NAME
)
nkwonlyargs
++
;
}
posargs
=
(
nposargs
?
asdl_seq_new
(
nposargs
,
c
->
c_arena
)
:
NULL
);
if
(
!
posargs
&&
nposargs
)
return
NULL
;
/* Don't need to goto error; no objects allocated */
kwonlyargs
=
(
nkwonlyargs
?
asdl_seq_new
(
nkwonlyargs
,
c
->
c_arena
)
:
NULL
);
if
(
!
kwonlyargs
&&
nkwonlyargs
)
return
NULL
;
/* Don't need to goto error; no objects allocated */
posdefaults
=
(
nposdefaults
?
asdl_seq_new
(
nposdefaults
,
c
->
c_arena
)
:
NULL
);
if
(
!
posdefaults
&&
nposdefaults
)
return
NULL
;
/* Don't need to goto error; no objects allocated */
/* The length of kwonlyargs and kwdefaults are same
since we set NULL as default for keyword only argument w/o default
- we have sequence data structure, but no dictionary */
kwdefaults
=
(
nkwonlyargs
?
asdl_seq_new
(
nkwonlyargs
,
c
->
c_arena
)
:
NULL
);
if
(
!
kwdefaults
&&
nkwonlyargs
)
return
NULL
;
/* Don't need to goto error; no objects allocated */
if
(
nposargs
+
nkwonlyargs
>
255
)
{
ast_error
(
n
,
"more than 255 arguments"
);
return
NULL
;
}
/* fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']
...
...
@@ -635,8 +728,8 @@ ast_for_arguments(struct compiling *c, const node *n)
j
=
0
;
/* index for defaults */
k
=
0
;
/* index for args */
while
(
i
<
NCH
(
n
))
{
ch
=
CHILD
(
n
,
i
);
switch
(
TYPE
(
ch
))
{
ch
=
CHILD
(
n
,
i
);
switch
(
TYPE
(
ch
))
{
case
fpdef
:
/* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is
anything other than EQUAL or a comma? */
...
...
@@ -644,57 +737,80 @@ ast_for_arguments(struct compiling *c, const node *n)
if
(
i
+
1
<
NCH
(
n
)
&&
TYPE
(
CHILD
(
n
,
i
+
1
))
==
EQUAL
)
{
expr_ty
expression
=
ast_for_expr
(
c
,
CHILD
(
n
,
i
+
2
));
if
(
!
expression
)
goto
error
;
assert
(
defaults
!=
NULL
);
asdl_seq_SET
(
defaults
,
j
++
,
expression
);
goto
error
;
assert
(
posdefaults
!=
NULL
);
asdl_seq_SET
(
posdefaults
,
j
++
,
expression
);
i
+=
2
;
found_default
=
1
;
found_default
=
1
;
}
else
if
(
found_default
)
{
ast_error
(
n
,
"non-default argument follows default argument"
);
goto
error
;
}
else
if
(
found_default
)
{
ast_error
(
n
,
"non-default argument follows default argument"
);
goto
error
;
}
if
(
NCH
(
ch
)
==
3
)
{
ch
=
CHILD
(
ch
,
1
);
/* def foo((x)): is not complex, special case. */
if
(
NCH
(
ch
)
!=
1
)
{
/* We have complex arguments, setup for unpacking. */
asdl_seq_SET
(
args
,
k
++
,
compiler_complex_args
(
c
,
ch
));
}
else
{
/* def foo((x)): setup for checking NAME below. */
ch
=
CHILD
(
ch
,
0
);
}
ch
=
CHILD
(
ch
,
1
);
/* def foo((x)): is not complex, special case. */
if
(
NCH
(
ch
)
!=
1
)
{
/* We have complex arguments, setup for unpacking. */
asdl_seq_SET
(
posargs
,
k
++
,
compiler_complex_args
(
c
,
ch
));
}
else
{
/* def foo((x)): setup for checking NAME below. */
ch
=
CHILD
(
ch
,
0
);
}
}
if
(
TYPE
(
CHILD
(
ch
,
0
))
==
NAME
)
{
expr_ty
name
;
if
(
!
strcmp
(
STR
(
CHILD
(
ch
,
0
)),
"None"
))
{
ast_error
(
CHILD
(
ch
,
0
),
"assignment to None"
);
goto
error
;
}
expr_ty
name
;
if
(
!
strcmp
(
STR
(
CHILD
(
ch
,
0
)),
"None"
))
{
ast_error
(
CHILD
(
ch
,
0
),
"assignment to None"
);
goto
error
;
}
name
=
Name
(
NEW_IDENTIFIER
(
CHILD
(
ch
,
0
)),
Param
,
LINENO
(
ch
),
ch
->
n_col_offset
,
c
->
c_arena
);
if
(
!
name
)
goto
error
;
asdl_seq_SET
(
args
,
k
++
,
name
);
}
asdl_seq_SET
(
pos
args
,
k
++
,
name
);
}
i
+=
2
;
/* the name and the comma */
break
;
case
STAR
:
if
(
!
strcmp
(
STR
(
CHILD
(
n
,
i
+
1
)),
"None"
))
{
ast_error
(
CHILD
(
n
,
i
+
1
),
"assignment to None"
);
goto
error
;
}
vararg
=
NEW_IDENTIFIER
(
CHILD
(
n
,
i
+
1
));
i
+=
3
;
if
(
i
+
1
>=
NCH
(
n
))
{
ast_error
(
CHILD
(
n
,
i
),
"no name for vararg"
);
goto
error
;
}
if
(
!
strcmp
(
STR
(
CHILD
(
n
,
i
+
1
)),
"None"
))
{
ast_error
(
CHILD
(
n
,
i
+
1
),
"assignment to None"
);
goto
error
;
}
if
(
TYPE
(
CHILD
(
n
,
i
+
1
))
==
COMMA
)
{
int
res
=
0
;
i
+=
2
;
/* now follows keyword only arguments */
res
=
handle_keywordonly_args
(
c
,
n
,
i
,
kwonlyargs
,
kwdefaults
);
if
(
res
==
-
1
)
goto
error
;
i
=
res
;
/* res has new position to process */
}
else
{
vararg
=
NEW_IDENTIFIER
(
CHILD
(
n
,
i
+
1
));
i
+=
3
;
if
(
i
<
NCH
(
n
)
&&
TYPE
(
CHILD
(
n
,
i
))
==
NAME
)
{
int
res
=
0
;
res
=
handle_keywordonly_args
(
c
,
n
,
i
,
kwonlyargs
,
kwdefaults
);
if
(
res
==
-
1
)
goto
error
;
i
=
res
;
/* res has new position to process */
}
}
break
;
case
DOUBLESTAR
:
if
(
!
strcmp
(
STR
(
CHILD
(
n
,
i
+
1
)),
"None"
))
{
ast_error
(
CHILD
(
n
,
i
+
1
),
"assignment to None"
);
goto
error
;
}
if
(
!
strcmp
(
STR
(
CHILD
(
n
,
i
+
1
)),
"None"
))
{
ast_error
(
CHILD
(
n
,
i
+
1
),
"assignment to None"
);
goto
error
;
}
kwarg
=
NEW_IDENTIFIER
(
CHILD
(
n
,
i
+
1
));
i
+=
3
;
break
;
...
...
@@ -703,11 +819,10 @@ ast_for_arguments(struct compiling *c, const node *n)
"unexpected node in varargslist: %d @ %d"
,
TYPE
(
ch
),
i
);
goto
error
;
}
}
}
return
arguments
(
args
,
vararg
,
kwarg
,
defaults
,
c
->
c_arena
);
return
arguments
(
posargs
,
vararg
,
kwonlyargs
,
kwarg
,
posdefaults
,
kwdefaults
,
c
->
c_arena
);
error:
Py_XDECREF
(
vararg
);
Py_XDECREF
(
kwarg
);
...
...
@@ -851,7 +966,7 @@ ast_for_lambdef(struct compiling *c, const node *n)
expr_ty
expression
;
if
(
NCH
(
n
)
==
3
)
{
args
=
arguments
(
NULL
,
NULL
,
NULL
,
NULL
,
c
->
c_arena
);
args
=
arguments
(
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
c
->
c_arena
);
if
(
!
args
)
return
NULL
;
expression
=
ast_for_expr
(
c
,
CHILD
(
n
,
2
));
...
...
Python/ceval.c
View file @
4f72a786
...
...
@@ -494,7 +494,7 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
(
PyObject
**
)
NULL
,
0
,
(
PyObject
**
)
NULL
,
0
,
(
PyObject
**
)
NULL
,
0
,
NULL
);
NULL
,
NULL
);
}
...
...
@@ -2290,26 +2290,46 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}
case
MAKE_FUNCTION
:
{
int
posdefaults
=
oparg
&
0xff
;
int
kwdefaults
=
(
oparg
>>
8
)
&
0xff
;
v
=
POP
();
/* code object */
x
=
PyFunction_New
(
v
,
f
->
f_globals
);
Py_DECREF
(
v
);
/* XXX Maybe this should be a separate opcode? */
if
(
x
!=
NULL
&&
oparg
>
0
)
{
v
=
PyTuple_New
(
oparg
);
if
(
x
!=
NULL
&&
posdefaults
>
0
)
{
v
=
PyTuple_New
(
posdefaults
);
if
(
v
==
NULL
)
{
Py_DECREF
(
x
);
x
=
NULL
;
break
;
}
while
(
--
oparg
>=
0
)
{
while
(
--
posdefaults
>=
0
)
{
w
=
POP
();
PyTuple_SET_ITEM
(
v
,
oparg
,
w
);
PyTuple_SET_ITEM
(
v
,
posdefaults
,
w
);
}
err
=
PyFunction_SetDefaults
(
x
,
v
);
Py_DECREF
(
v
);
}
if
(
x
!=
NULL
&&
kwdefaults
>
0
)
{
v
=
PyDict_New
();
if
(
v
==
NULL
)
{
Py_DECREF
(
x
);
x
=
NULL
;
break
;
}
while
(
--
kwdefaults
>=
0
)
{
w
=
POP
();
/* default value */
u
=
POP
();
/* kw only arg name */
PyDict_SetItem
(
v
,
u
,
w
);
}
err
=
PyFunction_SetKwDefaults
(
x
,
v
);
Py_DECREF
(
v
);
}
PUSH
(
x
);
break
;
}
case
MAKE_CLOSURE
:
{
...
...
@@ -2577,7 +2597,7 @@ fast_yield:
PyObject
*
PyEval_EvalCodeEx
(
PyCodeObject
*
co
,
PyObject
*
globals
,
PyObject
*
locals
,
PyObject
**
args
,
int
argcount
,
PyObject
**
kws
,
int
kwcount
,
PyObject
**
defs
,
int
defcount
,
PyObject
*
closure
)
PyObject
**
defs
,
int
defcount
,
PyObject
*
kwdefs
,
PyObject
*
closure
)
{
register
PyFrameObject
*
f
;
register
PyObject
*
retval
=
NULL
;
...
...
@@ -2601,6 +2621,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
freevars
=
f
->
f_localsplus
+
co
->
co_nlocals
;
if
(
co
->
co_argcount
>
0
||
co
->
co_kwonlyargcount
>
0
||
co
->
co_flags
&
(
CO_VARARGS
|
CO_VARKEYWORDS
))
{
int
i
;
int
n
=
argcount
;
...
...
@@ -2609,7 +2630,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
kwdict
=
PyDict_New
();
if
(
kwdict
==
NULL
)
goto
fail
;
i
=
co
->
co_argcount
;
i
=
co
->
co_argcount
+
co
->
co_kwonlyargcount
;
if
(
co
->
co_flags
&
CO_VARARGS
)
i
++
;
SETLOCAL
(
i
,
kwdict
);
...
...
@@ -2618,7 +2639,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
if
(
!
(
co
->
co_flags
&
CO_VARARGS
))
{
PyErr_Format
(
PyExc_TypeError
,
"%.200s() takes %s %d "
"%sargument%s (%d given)"
,
"%s
positional
argument%s (%d given)"
,
PyString_AsString
(
co
->
co_name
),
defcount
?
"at most"
:
"exactly"
,
co
->
co_argcount
,
...
...
@@ -2638,7 +2659,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
u
=
PyTuple_New
(
argcount
-
n
);
if
(
u
==
NULL
)
goto
fail
;
SETLOCAL
(
co
->
co_argcount
,
u
);
SETLOCAL
(
co
->
co_argcount
+
co
->
co_kwonlyargcount
,
u
);
for
(
i
=
n
;
i
<
argcount
;
i
++
)
{
x
=
args
[
i
];
Py_INCREF
(
x
);
...
...
@@ -2656,7 +2677,9 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
goto
fail
;
}
/* XXX slow -- speed up using dictionary? */
for
(
j
=
0
;
j
<
co
->
co_argcount
;
j
++
)
{
for
(
j
=
0
;
j
<
co
->
co_argcount
+
co
->
co_kwonlyargcount
;
j
++
)
{
PyObject
*
nm
=
PyTuple_GET_ITEM
(
co
->
co_varnames
,
j
);
int
cmp
=
PyObject_RichCompareBool
(
...
...
@@ -2669,7 +2692,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
/* Check errors from Compare */
if
(
PyErr_Occurred
())
goto
fail
;
if
(
j
>=
co
->
co_argcount
)
{
if
(
j
>=
co
->
co_argcount
+
co
->
co_kwonlyargcount
)
{
if
(
kwdict
==
NULL
)
{
PyErr_Format
(
PyExc_TypeError
,
"%.200s() got an unexpected "
...
...
@@ -2694,13 +2717,38 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
SETLOCAL
(
j
,
value
);
}
}
if
(
co
->
co_kwonlyargcount
>
0
)
{
for
(
i
=
co
->
co_argcount
;
i
<
co
->
co_argcount
+
co
->
co_kwonlyargcount
;
i
++
)
{
if
(
GETLOCAL
(
i
)
!=
NULL
)
continue
;
PyObject
*
name
=
PyTuple_GET_ITEM
(
co
->
co_varnames
,
i
);
PyObject
*
def
=
NULL
;
if
(
kwdefs
!=
NULL
)
def
=
PyDict_GetItem
(
kwdefs
,
name
);
if
(
def
!=
NULL
)
{
Py_INCREF
(
def
);
SETLOCAL
(
i
,
def
);
continue
;
}
PyErr_Format
(
PyExc_TypeError
,
"%.200s() needs "
"keyword only argument %s"
,
PyString_AsString
(
co
->
co_name
),
PyString_AsString
(
name
));
goto
fail
;
}
}
if
(
argcount
<
co
->
co_argcount
)
{
int
m
=
co
->
co_argcount
-
defcount
;
for
(
i
=
argcount
;
i
<
m
;
i
++
)
{
if
(
GETLOCAL
(
i
)
==
NULL
)
{
PyErr_Format
(
PyExc_TypeError
,
"%.200s() takes %s %d "
"%sargument%s (%d given)"
,
"%spositional argument%s "
"(%d given)"
,
PyString_AsString
(
co
->
co_name
),
((
co
->
co_flags
&
CO_VARARGS
)
||
defcount
)
?
"at least"
...
...
@@ -3565,12 +3613,14 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
PyCodeObject
*
co
=
(
PyCodeObject
*
)
PyFunction_GET_CODE
(
func
);
PyObject
*
globals
=
PyFunction_GET_GLOBALS
(
func
);
PyObject
*
argdefs
=
PyFunction_GET_DEFAULTS
(
func
);
PyObject
*
kwdefs
=
PyFunction_GET_KW_DEFAULTS
(
func
);
PyObject
**
d
=
NULL
;
int
nd
=
0
;
PCALL
(
PCALL_FUNCTION
);
PCALL
(
PCALL_FAST_FUNCTION
);
if
(
argdefs
==
NULL
&&
co
->
co_argcount
==
n
&&
nk
==
0
&&
if
(
argdefs
==
NULL
&&
co
->
co_argcount
==
n
&&
co
->
co_kwonlyargcount
==
0
&&
nk
==
0
&&
co
->
co_flags
==
(
CO_OPTIMIZED
|
CO_NEWLOCALS
|
CO_NOFREE
))
{
PyFrameObject
*
f
;
PyObject
*
retval
=
NULL
;
...
...
@@ -3608,7 +3658,7 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
}
return
PyEval_EvalCodeEx
(
co
,
globals
,
(
PyObject
*
)
NULL
,
(
*
pp_stack
)
-
n
,
na
,
(
*
pp_stack
)
-
2
*
nk
,
nk
,
d
,
nd
,
(
*
pp_stack
)
-
2
*
nk
,
nk
,
d
,
nd
,
kwdefs
,
PyFunction_GET_CLOSURE
(
func
));
}
...
...
Python/compile.c
View file @
4f72a786
...
...
@@ -115,6 +115,7 @@ struct compiler_unit {
PyObject
*
u_private
;
/* for private name mangling */
int
u_argcount
;
/* number of arguments for block */
int
u_kwonlyargcount
;
/* number of keyword only arguments for block */
/* Pointer to the most recently allocated block. By following b_list
members, you can reach all early allocated blocks. */
basicblock
*
u_blocks
;
...
...
@@ -494,6 +495,7 @@ compiler_enter_scope(struct compiler *c, identifier name, void *key,
}
memset
(
u
,
0
,
sizeof
(
struct
compiler_unit
));
u
->
u_argcount
=
0
;
u
->
u_kwonlyargcount
=
0
;
u
->
u_ste
=
PySymtable_Lookup
(
c
->
c_st
,
key
);
if
(
!
u
->
u_ste
)
{
compiler_unit_free
(
u
);
...
...
@@ -896,9 +898,9 @@ opcode_stack_effect(int opcode, int oparg)
return
-
NARGS
(
oparg
)
-
1
;
case
CALL_FUNCTION_VAR_KW
:
return
-
NARGS
(
oparg
)
-
2
;
#undef NARGS
case
MAKE_FUNCTION
:
return
-
oparg
;
return
-
NARGS
(
oparg
);
#undef NARGS
case
BUILD_SLICE
:
if
(
oparg
==
3
)
return
-
2
;
...
...
@@ -1346,6 +1348,25 @@ compiler_arguments(struct compiler *c, arguments_ty args)
return
1
;
}
static
int
compiler_visit_kwonlydefaults
(
struct
compiler
*
c
,
asdl_seq
*
kwonlyargs
,
asdl_seq
*
kw_defaults
)
{
int
i
,
default_count
=
0
;
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
kwonlyargs
);
i
++
)
{
expr_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
);
if
(
!
compiler_visit_expr
(
c
,
default_
))
{
return
-
1
;
}
default_count
++
;
}
}
return
default_count
;
}
static
int
compiler_function
(
struct
compiler
*
c
,
stmt_ty
s
)
{
...
...
@@ -1354,14 +1375,22 @@ compiler_function(struct compiler *c, stmt_ty s)
arguments_ty
args
=
s
->
v
.
FunctionDef
.
args
;
asdl_seq
*
decos
=
s
->
v
.
FunctionDef
.
decorators
;
stmt_ty
st
;
int
i
,
n
,
docstring
;
int
i
,
n
,
docstring
,
kw_default_count
=
0
,
arglength
;
assert
(
s
->
kind
==
FunctionDef_kind
);
if
(
!
compiler_decorators
(
c
,
decos
))
return
0
;
if
(
args
->
kwonlyargs
)
{
int
res
=
compiler_visit_kwonlydefaults
(
c
,
args
->
kwonlyargs
,
args
->
kw_defaults
);
if
(
res
<
0
)
return
0
;
kw_default_count
=
res
;
}
if
(
args
->
defaults
)
VISIT_SEQ
(
c
,
expr
,
args
->
defaults
);
if
(
!
compiler_enter_scope
(
c
,
s
->
v
.
FunctionDef
.
name
,
(
void
*
)
s
,
s
->
lineno
))
return
0
;
...
...
@@ -1379,6 +1408,7 @@ compiler_function(struct compiler *c, stmt_ty s)
compiler_arguments
(
c
,
args
);
c
->
u
->
u_argcount
=
asdl_seq_LEN
(
args
->
args
);
c
->
u
->
u_kwonlyargcount
=
asdl_seq_LEN
(
args
->
kwonlyargs
);
n
=
asdl_seq_LEN
(
s
->
v
.
FunctionDef
.
body
);
/* if there was a docstring, we need to skip the first statement */
for
(
i
=
docstring
;
i
<
n
;
i
++
)
{
...
...
@@ -1390,7 +1420,9 @@ compiler_function(struct compiler *c, stmt_ty s)
if
(
co
==
NULL
)
return
0
;
compiler_make_closure
(
c
,
co
,
asdl_seq_LEN
(
args
->
defaults
));
arglength
=
asdl_seq_LEN
(
args
->
defaults
);
arglength
|=
kw_default_count
<<
8
;
compiler_make_closure
(
c
,
co
,
arglength
);
Py_DECREF
(
co
);
for
(
i
=
0
;
i
<
asdl_seq_LEN
(
decos
);
i
++
)
{
...
...
@@ -1485,6 +1517,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
{
PyCodeObject
*
co
;
static
identifier
name
;
int
kw_default_count
=
0
,
arglength
;
arguments_ty
args
=
e
->
v
.
Lambda
.
args
;
assert
(
e
->
kind
==
Lambda_kind
);
...
...
@@ -1494,6 +1527,12 @@ compiler_lambda(struct compiler *c, expr_ty e)
return
0
;
}
if
(
args
->
kwonlyargs
)
{
int
res
=
compiler_visit_kwonlydefaults
(
c
,
args
->
kwonlyargs
,
args
->
kw_defaults
);
if
(
res
<
0
)
return
0
;
kw_default_count
=
res
;
}
if
(
args
->
defaults
)
VISIT_SEQ
(
c
,
expr
,
args
->
defaults
);
if
(
!
compiler_enter_scope
(
c
,
name
,
(
void
*
)
e
,
e
->
lineno
))
...
...
@@ -1503,6 +1542,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
compiler_arguments
(
c
,
args
);
c
->
u
->
u_argcount
=
asdl_seq_LEN
(
args
->
args
);
c
->
u
->
u_kwonlyargcount
=
asdl_seq_LEN
(
args
->
kwonlyargs
);
VISIT_IN_SCOPE
(
c
,
expr
,
e
->
v
.
Lambda
.
body
);
ADDOP_IN_SCOPE
(
c
,
RETURN_VALUE
);
co
=
assemble
(
c
,
1
);
...
...
@@ -1510,7 +1550,9 @@ compiler_lambda(struct compiler *c, expr_ty e)
if
(
co
==
NULL
)
return
0
;
compiler_make_closure
(
c
,
co
,
asdl_seq_LEN
(
args
->
defaults
));
arglength
=
asdl_seq_LEN
(
args
->
defaults
);
arglength
|=
kw_default_count
<<
8
;
compiler_make_closure
(
c
,
co
,
arglength
);
Py_DECREF
(
co
);
return
1
;
...
...
@@ -3791,7 +3833,8 @@ makecode(struct compiler *c, struct assembler *a)
Py_DECREF
(
consts
);
consts
=
tmp
;
co
=
PyCode_New
(
c
->
u
->
u_argcount
,
nlocals
,
stackdepth
(
c
),
flags
,
co
=
PyCode_New
(
c
->
u
->
u_argcount
,
c
->
u
->
u_kwonlyargcount
,
nlocals
,
stackdepth
(
c
),
flags
,
bytecode
,
consts
,
names
,
varnames
,
freevars
,
cellvars
,
filename
,
c
->
u
->
u_name
,
...
...
Python/graminit.c
View file @
4f72a786
...
...
@@ -146,14 +146,16 @@ static arc arcs_7_1[3] = {
{
27
,
5
},
{
0
,
1
},
};
static
arc
arcs_7_2
[
1
]
=
{
static
arc
arcs_7_2
[
3
]
=
{
{
19
,
6
},
{
27
,
7
},
{
0
,
2
},
};
static
arc
arcs_7_3
[
1
]
=
{
{
19
,
7
},
{
19
,
8
},
};
static
arc
arcs_7_4
[
1
]
=
{
{
26
,
8
},
{
26
,
9
},
};
static
arc
arcs_7_5
[
4
]
=
{
{
24
,
1
},
...
...
@@ -162,30 +164,41 @@ static arc arcs_7_5[4] = {
{
0
,
5
},
};
static
arc
arcs_7_6
[
2
]
=
{
{
27
,
9
},
{
27
,
7
},
{
0
,
6
},
};
static
arc
arcs_7_7
[
1
]
=
{
{
0
,
7
},
static
arc
arcs_7_7
[
2
]
=
{
{
19
,
10
},
{
29
,
3
},
};
static
arc
arcs_7_8
[
2
]
=
{
{
27
,
5
},
static
arc
arcs_7_8
[
1
]
=
{
{
0
,
8
},
};
static
arc
arcs_7_9
[
1
]
=
{
{
29
,
3
},
static
arc
arcs_7_9
[
2
]
=
{
{
27
,
5
},
{
0
,
9
},
};
static
arc
arcs_7_10
[
3
]
=
{
{
27
,
7
},
{
25
,
11
},
{
0
,
10
},
};
static
arc
arcs_7_11
[
1
]
=
{
{
26
,
6
},
};
static
state
states_7
[
1
0
]
=
{
static
state
states_7
[
1
2
]
=
{
{
3
,
arcs_7_0
},
{
3
,
arcs_7_1
},
{
1
,
arcs_7_2
},
{
3
,
arcs_7_2
},
{
1
,
arcs_7_3
},
{
1
,
arcs_7_4
},
{
4
,
arcs_7_5
},
{
2
,
arcs_7_6
},
{
1
,
arcs_7_7
},
{
2
,
arcs_7_8
},
{
1
,
arcs_7_9
},
{
2
,
arcs_7_7
},
{
1
,
arcs_7_8
},
{
2
,
arcs_7_9
},
{
3
,
arcs_7_10
},
{
1
,
arcs_7_11
},
};
static
arc
arcs_8_0
[
2
]
=
{
{
19
,
1
},
...
...
@@ -1766,7 +1779,7 @@ static dfa dfas[83] = {
"
\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
"
},
{
262
,
"parameters"
,
0
,
4
,
states_6
,
"
\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
"
},
{
263
,
"varargslist"
,
0
,
1
0
,
states_7
,
{
263
,
"varargslist"
,
0
,
1
2
,
states_7
,
"
\000\040\010\060\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
"
},
{
264
,
"fpdef"
,
0
,
4
,
states_8
,
"
\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
"
},
...
...
Python/import.c
View file @
4f72a786
...
...
@@ -67,9 +67,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
Python 3000: 3000
3010 (removed UNARY_CONVERT)
3020 (added BUILD_SET)
3030 (added keyword-only parameters)
.
*/
#define MAGIC (30
2
0 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define MAGIC (30
3
0 | ((long)'\r'<<16) | ((long)'\n'<<24))
/* Magic word as global; note that _PyImport_Init() can change the
value of this global to accommodate for alterations of how the
...
...
Python/marshal.c
View file @
4f72a786
...
...
@@ -349,6 +349,7 @@ w_object(PyObject *v, WFILE *p)
PyCodeObject
*
co
=
(
PyCodeObject
*
)
v
;
w_byte
(
TYPE_CODE
,
p
);
w_long
(
co
->
co_argcount
,
p
);
w_long
(
co
->
co_kwonlyargcount
,
p
);
w_long
(
co
->
co_nlocals
,
p
);
w_long
(
co
->
co_stacksize
,
p
);
w_long
(
co
->
co_flags
,
p
);
...
...
@@ -815,6 +816,7 @@ r_object(RFILE *p)
}
else
{
int
argcount
;
int
kwonlyargcount
;
int
nlocals
;
int
stacksize
;
int
flags
;
...
...
@@ -832,6 +834,7 @@ r_object(RFILE *p)
v
=
NULL
;
argcount
=
r_long
(
p
);
kwonlyargcount
=
r_long
(
p
);
nlocals
=
r_long
(
p
);
stacksize
=
r_long
(
p
);
flags
=
r_long
(
p
);
...
...
@@ -865,7 +868,8 @@ r_object(RFILE *p)
goto
code_error
;
v
=
(
PyObject
*
)
PyCode_New
(
argcount
,
nlocals
,
stacksize
,
flags
,
argcount
,
kwonlyargcount
,
nlocals
,
stacksize
,
flags
,
code
,
consts
,
names
,
varnames
,
freevars
,
cellvars
,
filename
,
name
,
firstlineno
,
lnotab
);
...
...
Python/symtable.c
View file @
4f72a786
...
...
@@ -893,6 +893,17 @@ error:
} \
}
#define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS) { \
int i = 0; \
asdl_seq *seq = (KW_DEFAULTS);
/* avoid variable capture */
\
for (i = 0; i < asdl_seq_LEN(seq); i++) { \
expr_ty elt = (expr_ty)asdl_seq_GET(seq, i); \
if (!elt) continue;
/* can be NULL */
\
if (!symtable_visit_expr((ST), elt)) \
return 0; \
} \
}
static
int
symtable_new_tmpname
(
struct
symtable
*
st
)
{
...
...
@@ -910,6 +921,8 @@ symtable_new_tmpname(struct symtable *st)
return
1
;
}
static
int
symtable_visit_stmt
(
struct
symtable
*
st
,
stmt_ty
s
)
{
...
...
@@ -919,6 +932,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
return
0
;
if
(
s
->
v
.
FunctionDef
.
args
->
defaults
)
VISIT_SEQ
(
st
,
expr
,
s
->
v
.
FunctionDef
.
args
->
defaults
);
if
(
s
->
v
.
FunctionDef
.
args
->
kw_defaults
)
VISIT_KWONLYDEFAULTS
(
st
,
s
->
v
.
FunctionDef
.
args
->
kw_defaults
);
if
(
s
->
v
.
FunctionDef
.
decorators
)
VISIT_SEQ
(
st
,
expr
,
s
->
v
.
FunctionDef
.
decorators
);
if
(
!
symtable_enter_block
(
st
,
s
->
v
.
FunctionDef
.
name
,
...
...
@@ -1262,6 +1278,8 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
*/
if
(
a
->
args
&&
!
symtable_visit_params
(
st
,
a
->
args
,
1
))
return
0
;
if
(
a
->
kwonlyargs
&&
!
symtable_visit_params
(
st
,
a
->
kwonlyargs
,
1
))
return
0
;
if
(
a
->
vararg
)
{
if
(
!
symtable_add_def
(
st
,
a
->
vararg
,
DEF_PARAM
))
return
0
;
...
...
Tools/compiler/ast.txt
View file @
4f72a786
...
...
@@ -12,8 +12,8 @@
Module: doc*, node
Stmt: nodes!
Decorators: nodes!
Function: decorators&, name*, argnames*, defaults!, flags*, doc*, code
Lambda: argnames*, defaults!, flags*, code
Function: decorators&, name*, argnames*, defaults!,
kwonlyargs*,
flags*, doc*, code
Lambda: argnames*, defaults!,
kwonlyargs*,
flags*, code
Class: name*, bases!, doc*, code
Pass:
Break:
...
...
@@ -97,6 +97,7 @@ init(Lambda):
init(GenExpr):
self.argnames = ['.0']
self.varargs = self.kwargs = None
self.kwonlyargs = ()
init(GenExprFor):
self.is_outmost = False
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