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
442f2099
Commit
442f2099
authored
Dec 06, 2012
by
Benjamin Peterson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
create NameConstant AST class for None, True, and False literals (closes #16619)
parent
4b237e3b
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
152 additions
and
72 deletions
+152
-72
Include/Python-ast.h
Include/Python-ast.h
+10
-2
Include/asdl.h
Include/asdl.h
+1
-0
Lib/ast.py
Lib/ast.py
+2
-4
Lib/test/test_ast.py
Lib/test/test_ast.py
+8
-5
Lib/test/test_syntax.py
Lib/test/test_syntax.py
+2
-2
Misc/NEWS
Misc/NEWS
+4
-0
Parser/Python.asdl
Parser/Python.asdl
+2
-2
Parser/asdl.py
Parser/asdl.py
+1
-1
Parser/asdl_c.py
Parser/asdl_c.py
+12
-0
Python/Python-ast.c
Python/Python-ast.c
+73
-0
Python/ast.c
Python/ast.c
+18
-4
Python/compile.c
Python/compile.c
+15
-6
Python/peephole.c
Python/peephole.c
+0
-46
Python/symtable.c
Python/symtable.c
+1
-0
Tools/parser/unparse.py
Tools/parser/unparse.py
+3
-0
No files found.
Include/Python-ast.h
View file @
442f2099
...
...
@@ -182,8 +182,9 @@ enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
SetComp_kind
=
9
,
DictComp_kind
=
10
,
GeneratorExp_kind
=
11
,
Yield_kind
=
12
,
YieldFrom_kind
=
13
,
Compare_kind
=
14
,
Call_kind
=
15
,
Num_kind
=
16
,
Str_kind
=
17
,
Bytes_kind
=
18
,
Ellipsis_kind
=
19
,
Attribute_kind
=
20
,
Subscript_kind
=
21
,
Starred_kind
=
22
,
Name_kind
=
23
,
List_kind
=
24
,
Tuple_kind
=
25
};
NameConstant_kind
=
19
,
Ellipsis_kind
=
20
,
Attribute_kind
=
21
,
Subscript_kind
=
22
,
Starred_kind
=
23
,
Name_kind
=
24
,
List_kind
=
25
,
Tuple_kind
=
26
};
struct
_expr
{
enum
_expr_kind
kind
;
union
{
...
...
@@ -278,6 +279,10 @@ struct _expr {
bytes
s
;
}
Bytes
;
struct
{
singleton
value
;
}
NameConstant
;
struct
{
expr_ty
value
;
identifier
attr
;
...
...
@@ -509,6 +514,9 @@ expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena);
expr_ty
_Py_Str
(
string
s
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define Bytes(a0, a1, a2, a3) _Py_Bytes(a0, a1, a2, a3)
expr_ty
_Py_Bytes
(
bytes
s
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define NameConstant(a0, a1, a2, a3) _Py_NameConstant(a0, a1, a2, a3)
expr_ty
_Py_NameConstant
(
singleton
value
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define Ellipsis(a0, a1, a2) _Py_Ellipsis(a0, a1, a2)
expr_ty
_Py_Ellipsis
(
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5)
...
...
Include/asdl.h
View file @
442f2099
...
...
@@ -5,6 +5,7 @@ typedef PyObject * identifier;
typedef
PyObject
*
string
;
typedef
PyObject
*
bytes
;
typedef
PyObject
*
object
;
typedef
PyObject
*
singleton
;
/* It would be nice if the code generated by asdl_c.py was completely
independent of Python, but it is a goal the requires too much work
...
...
Lib/ast.py
View file @
442f2099
...
...
@@ -42,7 +42,6 @@ def literal_eval(node_or_string):
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
sets, booleans, and None.
"""
_safe_names
=
{
'None'
:
None
,
'True'
:
True
,
'False'
:
False
}
if
isinstance
(
node_or_string
,
str
):
node_or_string
=
parse
(
node_or_string
,
mode
=
'eval'
)
if
isinstance
(
node_or_string
,
Expression
):
...
...
@@ -61,9 +60,8 @@ def literal_eval(node_or_string):
elif
isinstance
(
node
,
Dict
):
return
dict
((
_convert
(
k
),
_convert
(
v
))
for
k
,
v
in
zip
(
node
.
keys
,
node
.
values
))
elif
isinstance
(
node
,
Name
):
if
node
.
id
in
_safe_names
:
return
_safe_names
[
node
.
id
]
elif
isinstance
(
node
,
NameConstant
):
return
node
.
value
elif
isinstance
(
node
,
UnaryOp
)
and
\
isinstance
(
node
.
op
,
(
UAdd
,
USub
))
and
\
isinstance
(
node
.
operand
,
(
Num
,
UnaryOp
,
BinOp
)):
...
...
Lib/test/test_ast.py
View file @
442f2099
...
...
@@ -928,6 +928,9 @@ class ASTValidatorTests(unittest.TestCase):
def
test_tuple
(
self
):
self
.
_sequence
(
ast
.
Tuple
)
def
test_nameconstant
(
self
):
self
.
expr
(
ast
.
NameConstant
(
4
),
"singleton must be True, False, or None"
)
def
test_stdlib_validates
(
self
):
stdlib
=
os
.
path
.
dirname
(
ast
.
__file__
)
tests
=
[
fn
for
fn
in
os
.
listdir
(
stdlib
)
if
fn
.
endswith
(
".py"
)]
...
...
@@ -959,13 +962,13 @@ def main():
#### EVERYTHING BELOW IS GENERATED #####
exec_results
=
[
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'Name
'
,
(
1
,
0
),
'None'
,
(
'Load'
,)
))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'Name
Constant'
,
(
1
,
0
),
None
))]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[],
None
,
None
,
[],
[]),
[(
'Pass'
,
(
1
,
9
))],
[],
None
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'arg'
,
'a'
,
None
)],
None
,
None
,
[],
None
,
None
,
[],
[]),
[(
'Pass'
,
(
1
,
10
))],
[],
None
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'arg'
,
'a'
,
None
)],
None
,
None
,
[],
None
,
None
,
[(
'Num'
,
(
1
,
8
),
0
)],
[]),
[(
'Pass'
,
(
1
,
12
))],
[],
None
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
'args'
,
None
,
[],
None
,
None
,
[],
[]),
[(
'Pass'
,
(
1
,
14
))],
[],
None
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[],
'kwargs'
,
None
,
[],
[]),
[(
'Pass'
,
(
1
,
17
))],
[],
None
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'arg'
,
'a'
,
None
),
(
'arg'
,
'b'
,
None
),
(
'arg'
,
'c'
,
None
),
(
'arg'
,
'd'
,
None
),
(
'arg'
,
'e'
,
None
)],
'args'
,
None
,
[],
'kwargs'
,
None
,
[(
'Num'
,
(
1
,
11
),
1
),
(
'Name
'
,
(
1
,
16
),
'None'
,
(
'Load'
,)
),
(
'List'
,
(
1
,
24
),
[],
(
'Load'
,)),
(
'Dict'
,
(
1
,
30
),
[],
[])],
[]),
[(
'Pass'
,
(
1
,
52
))],
[],
None
)]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'arg'
,
'a'
,
None
),
(
'arg'
,
'b'
,
None
),
(
'arg'
,
'c'
,
None
),
(
'arg'
,
'd'
,
None
),
(
'arg'
,
'e'
,
None
)],
'args'
,
None
,
[],
'kwargs'
,
None
,
[(
'Num'
,
(
1
,
11
),
1
),
(
'Name
Constant'
,
(
1
,
16
),
None
),
(
'List'
,
(
1
,
24
),
[],
(
'Load'
,)),
(
'Dict'
,
(
1
,
30
),
[],
[])],
[]),
[(
'Pass'
,
(
1
,
52
))],
[],
None
)]),
(
'Module'
,
[(
'ClassDef'
,
(
1
,
0
),
'C'
,
[],
[],
None
,
None
,
[(
'Pass'
,
(
1
,
8
))],
[])]),
(
'Module'
,
[(
'ClassDef'
,
(
1
,
0
),
'C'
,
[(
'Name'
,
(
1
,
8
),
'object'
,
(
'Load'
,))],
[],
None
,
None
,
[(
'Pass'
,
(
1
,
17
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[],
None
,
None
,
[],
[]),
[(
'Return'
,
(
1
,
8
),
(
'Num'
,
(
1
,
15
),
1
))],
[],
None
)]),
...
...
@@ -1002,14 +1005,14 @@ single_results = [
(
'Interactive'
,
[(
'Expr'
,
(
1
,
0
),
(
'BinOp'
,
(
1
,
0
),
(
'Num'
,
(
1
,
0
),
1
),
(
'Add'
,),
(
'Num'
,
(
1
,
2
),
2
)))]),
]
eval_results
=
[
(
'Expression'
,
(
'Name
'
,
(
1
,
0
),
'None'
,
(
'Load'
,)
)),
(
'Expression'
,
(
'Name
Constant'
,
(
1
,
0
),
None
)),
(
'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
,
[],
None
,
None
,
[],
[]),
(
'Name
'
,
(
1
,
7
),
'None'
,
(
'Load'
,)
))),
(
'Expression'
,
(
'Lambda'
,
(
1
,
0
),
(
'arguments'
,
[],
None
,
None
,
[],
None
,
None
,
[],
[]),
(
'Name
Constant'
,
(
1
,
7
),
None
))),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[(
'Num'
,
(
1
,
2
),
1
)],
[(
'Num'
,
(
1
,
4
),
2
)])),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[],
[])),
(
'Expression'
,
(
'Set'
,
(
1
,
0
),
[(
'Name
'
,
(
1
,
1
),
'None'
,
(
'Load'
,)
)])),
(
'Expression'
,
(
'Set'
,
(
1
,
0
),
[(
'Name
Constant'
,
(
1
,
1
),
None
)])),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[(
'Num'
,
(
2
,
6
),
1
)],
[(
'Num'
,
(
4
,
10
),
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_syntax.py
View file @
442f2099
...
...
@@ -33,7 +33,7 @@ SyntaxError: invalid syntax
>>> None = 1
Traceback (most recent call last):
SyntaxError:
assignment
to keyword
SyntaxError:
can't assign
to keyword
It's a syntax error to assign to the empty tuple. Why isn't it an
error to assign to the empty list? It will always raise some error at
...
...
@@ -233,7 +233,7 @@ Traceback (most recent call last):
SyntaxError: can't assign to generator expression
>>> None += 1
Traceback (most recent call last):
SyntaxError:
assignment
to keyword
SyntaxError:
can't assign
to keyword
>>> f() += 1
Traceback (most recent call last):
SyntaxError: can't assign to function call
...
...
Misc/NEWS
View file @
442f2099
...
...
@@ -10,6 +10,10 @@ What's New in Python 3.4.0 Alpha 1?
Core and Builtins
-----------------
- Issue #16619: Create NameConstant AST class to represent None, True, and False
literals. As a result, these constants are never loaded at runtime from
builtins.
- Issue #16455: On FreeBSD and Solaris, if the locale is C, the
ASCII/surrogateescape codec is now used, instead of the locale encoding, to
decode the command line arguments. This change fixes inconsistencies with
...
...
Parser/Python.asdl
View file @
442f2099
-- ASDL's
five builtin types are identifier, int, string, bytes, object
-- ASDL's
six builtin types are identifier, int, string, bytes, object, singleton
module Python
{
...
...
@@ -69,8 +69,8 @@ module Python
| Num(object n) -- a number as a PyObject.
| Str(string s) -- need to specify raw, unicode, etc?
| Bytes(bytes s)
| NameConstant(singleton value)
| Ellipsis
-- other literals? bools?
-- the following expression can appear in assignment context
| Attribute(expr value, identifier attr, expr_context ctx)
...
...
Parser/asdl.py
View file @
442f2099
...
...
@@ -222,7 +222,7 @@ class ASDLParser(spark.GenericParser, object):
" field ::= Id ? "
return
Field
(
type
[
0
],
opt
=
True
)
builtin_types
=
(
"identifier"
,
"string"
,
"bytes"
,
"int"
,
"object"
)
builtin_types
=
(
"identifier"
,
"string"
,
"bytes"
,
"int"
,
"object"
,
"singleton"
)
# below is a collection of classes to capture the AST of an AST :-)
# not sure if any of the methods are useful yet, but I'm adding them
...
...
Parser/asdl_c.py
View file @
442f2099
...
...
@@ -820,6 +820,7 @@ static PyObject* ast2obj_object(void *o)
Py_INCREF((PyObject*)o);
return (PyObject*)o;
}
#define ast2obj_singleton ast2obj_object
#define ast2obj_identifier ast2obj_object
#define ast2obj_string ast2obj_object
#define ast2obj_bytes ast2obj_object
...
...
@@ -831,6 +832,17 @@ static PyObject* ast2obj_int(long b)
/* Conversion Python -> AST */
static int obj2ast_singleton(PyObject *obj, PyObject** out, PyArena* arena)
{
if (obj != Py_None && obj != Py_True && obj != Py_False) {
PyErr_SetString(PyExc_ValueError,
"AST singleton must be True, False, or None");
return 1;
}
*out = obj;
return 0;
}
static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
{
if (obj == Py_None)
...
...
Python/Python-ast.c
View file @
442f2099
...
...
@@ -271,6 +271,10 @@ static PyTypeObject *Bytes_type;
static
char
*
Bytes_fields
[]
=
{
"s"
,
};
static
PyTypeObject
*
NameConstant_type
;
static
char
*
NameConstant_fields
[]
=
{
"value"
,
};
static
PyTypeObject
*
Ellipsis_type
;
static
PyTypeObject
*
Attribute_type
;
_Py_IDENTIFIER
(
attr
);
...
...
@@ -673,6 +677,7 @@ static PyObject* ast2obj_object(void *o)
Py_INCREF
((
PyObject
*
)
o
);
return
(
PyObject
*
)
o
;
}
#define ast2obj_singleton ast2obj_object
#define ast2obj_identifier ast2obj_object
#define ast2obj_string ast2obj_object
#define ast2obj_bytes ast2obj_object
...
...
@@ -684,6 +689,17 @@ static PyObject* ast2obj_int(long b)
/* Conversion Python -> AST */
static
int
obj2ast_singleton
(
PyObject
*
obj
,
PyObject
**
out
,
PyArena
*
arena
)
{
if
(
obj
!=
Py_None
&&
obj
!=
Py_True
&&
obj
!=
Py_False
)
{
PyErr_SetString
(
PyExc_ValueError
,
"AST singleton must be True, False, or None"
);
return
1
;
}
*
out
=
obj
;
return
0
;
}
static
int
obj2ast_object
(
PyObject
*
obj
,
PyObject
**
out
,
PyArena
*
arena
)
{
if
(
obj
==
Py_None
)
...
...
@@ -860,6 +876,9 @@ static int init_types(void)
if
(
!
Str_type
)
return
0
;
Bytes_type
=
make_type
(
"Bytes"
,
expr_type
,
Bytes_fields
,
1
);
if
(
!
Bytes_type
)
return
0
;
NameConstant_type
=
make_type
(
"NameConstant"
,
expr_type
,
NameConstant_fields
,
1
);
if
(
!
NameConstant_type
)
return
0
;
Ellipsis_type
=
make_type
(
"Ellipsis"
,
expr_type
,
NULL
,
0
);
if
(
!
Ellipsis_type
)
return
0
;
Attribute_type
=
make_type
(
"Attribute"
,
expr_type
,
Attribute_fields
,
3
);
...
...
@@ -1920,6 +1939,25 @@ Bytes(bytes s, int lineno, int col_offset, PyArena *arena)
return
p
;
}
expr_ty
NameConstant
(
singleton
value
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
)
{
expr_ty
p
;
if
(
!
value
)
{
PyErr_SetString
(
PyExc_ValueError
,
"field value is required for NameConstant"
);
return
NULL
;
}
p
=
(
expr_ty
)
PyArena_Malloc
(
arena
,
sizeof
(
*
p
));
if
(
!
p
)
return
NULL
;
p
->
kind
=
NameConstant_kind
;
p
->
v
.
NameConstant
.
value
=
value
;
p
->
lineno
=
lineno
;
p
->
col_offset
=
col_offset
;
return
p
;
}
expr_ty
Ellipsis
(
int
lineno
,
int
col_offset
,
PyArena
*
arena
)
{
...
...
@@ -2028,6 +2066,7 @@ Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, PyArena
*
arena
)
{
expr_ty
p
;
assert
(
PyUnicode_CompareWithASCIIString
(
id
,
"True"
)
&&
PyUnicode_CompareWithASCIIString
(
id
,
"False"
)
&&
PyUnicode_CompareWithASCIIString
(
id
,
"None"
));
if
(
!
id
)
{
PyErr_SetString
(
PyExc_ValueError
,
"field id is required for Name"
);
...
...
@@ -2948,6 +2987,15 @@ ast2obj_expr(void* _o)
goto
failed
;
Py_DECREF
(
value
);
break
;
case
NameConstant_kind
:
result
=
PyType_GenericNew
(
NameConstant_type
,
NULL
,
NULL
);
if
(
!
result
)
goto
failed
;
value
=
ast2obj_singleton
(
o
->
v
.
NameConstant
.
value
);
if
(
!
value
)
goto
failed
;
if
(
_PyObject_SetAttrId
(
result
,
&
PyId_value
,
value
)
==
-
1
)
goto
failed
;
Py_DECREF
(
value
);
break
;
case
Ellipsis_kind
:
result
=
PyType_GenericNew
(
Ellipsis_type
,
NULL
,
NULL
);
if
(
!
result
)
goto
failed
;
...
...
@@ -5688,6 +5736,29 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
if
(
*
out
==
NULL
)
goto
failed
;
return
0
;
}
isinstance
=
PyObject_IsInstance
(
obj
,
(
PyObject
*
)
NameConstant_type
);
if
(
isinstance
==
-
1
)
{
return
1
;
}
if
(
isinstance
)
{
singleton
value
;
if
(
_PyObject_HasAttrId
(
obj
,
&
PyId_value
))
{
int
res
;
tmp
=
_PyObject_GetAttrId
(
obj
,
&
PyId_value
);
if
(
tmp
==
NULL
)
goto
failed
;
res
=
obj2ast_singleton
(
tmp
,
&
value
,
arena
);
if
(
res
!=
0
)
goto
failed
;
Py_XDECREF
(
tmp
);
tmp
=
NULL
;
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
"required field
\"
value
\"
missing from NameConstant"
);
return
1
;
}
*
out
=
NameConstant
(
value
,
lineno
,
col_offset
,
arena
);
if
(
*
out
==
NULL
)
goto
failed
;
return
0
;
}
isinstance
=
PyObject_IsInstance
(
obj
,
(
PyObject
*
)
Ellipsis_type
);
if
(
isinstance
==
-
1
)
{
return
1
;
...
...
@@ -7008,6 +7079,8 @@ PyInit__ast(void)
NULL
;
if
(
PyDict_SetItemString
(
d
,
"Bytes"
,
(
PyObject
*
)
Bytes_type
)
<
0
)
return
NULL
;
if
(
PyDict_SetItemString
(
d
,
"NameConstant"
,
(
PyObject
*
)
NameConstant_type
)
<
0
)
return
NULL
;
if
(
PyDict_SetItemString
(
d
,
"Ellipsis"
,
(
PyObject
*
)
Ellipsis_type
)
<
0
)
return
NULL
;
if
(
PyDict_SetItemString
(
d
,
"Attribute"
,
(
PyObject
*
)
Attribute_type
)
<
...
...
Python/ast.c
View file @
442f2099
...
...
@@ -282,6 +282,7 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
return
validate_exprs
(
exp
->
v
.
Tuple
.
elts
,
ctx
,
0
);
/* These last cases don't have any checking. */
case
Name_kind
:
case
NameConstant_kind
:
case
Ellipsis_kind
:
return
1
;
default:
...
...
@@ -903,7 +904,7 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
break
;
case
Name_kind
:
if
(
ctx
==
Store
)
{
if
(
forbidden_name
(
c
,
e
->
v
.
Name
.
id
,
n
,
1
))
if
(
forbidden_name
(
c
,
e
->
v
.
Name
.
id
,
n
,
0
))
return
0
;
/* forbidden_name() calls ast_error() */
}
e
->
v
.
Name
.
ctx
=
ctx
;
...
...
@@ -955,6 +956,9 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
case
Bytes_kind
:
expr_name
=
"literal"
;
break
;
case
NameConstant_kind
:
expr_name
=
"keyword"
;
break
;
case
Ellipsis_kind
:
expr_name
=
"Ellipsis"
;
break
;
...
...
@@ -1819,11 +1823,21 @@ ast_for_atom(struct compiling *c, const node *n)
switch
(
TYPE
(
ch
))
{
case
NAME
:
{
/* All names start in Load context, but may later be
changed. */
PyObject
*
name
=
NEW_IDENTIFIER
(
ch
);
PyObject
*
name
;
const
char
*
s
=
STR
(
ch
);
size_t
len
=
strlen
(
s
);
if
(
len
>=
4
&&
len
<=
5
)
{
if
(
!
strcmp
(
s
,
"None"
))
return
NameConstant
(
Py_None
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
if
(
!
strcmp
(
s
,
"True"
))
return
NameConstant
(
Py_True
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
if
(
!
strcmp
(
s
,
"False"
))
return
NameConstant
(
Py_False
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
}
name
=
new_identifier
(
s
,
c
);
if
(
!
name
)
return
NULL
;
/* All names start in Load context, but may later be changed. */
return
Name
(
name
,
Load
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
}
case
STRING
:
{
...
...
Python/compile.c
View file @
442f2099
...
...
@@ -3194,12 +3194,18 @@ expr_constant(struct compiler *c, expr_ty e)
case
Name_kind
:
/* optimize away names that can't be reassigned */
id
=
PyUnicode_AsUTF8
(
e
->
v
.
Name
.
id
);
if
(
strcmp
(
id
,
"True"
)
==
0
)
return
1
;
if
(
strcmp
(
id
,
"False"
)
==
0
)
return
0
;
if
(
strcmp
(
id
,
"None"
)
==
0
)
return
0
;
if
(
strcmp
(
id
,
"__debug__"
)
==
0
)
return
!
c
->
c_optimize
;
/* fall through */
if
(
id
&&
strcmp
(
id
,
"__debug__"
)
==
0
)
return
!
c
->
c_optimize
;
return
-
1
;
case
NameConstant_kind
:
{
PyObject
*
o
=
e
->
v
.
NameConstant
.
value
;
if
(
o
==
Py_None
)
return
0
;
else
if
(
o
==
Py_True
)
return
1
;
else
if
(
o
==
Py_False
)
return
0
;
}
default:
return
-
1
;
}
...
...
@@ -3375,6 +3381,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
case
Ellipsis_kind
:
ADDOP_O
(
c
,
LOAD_CONST
,
Py_Ellipsis
,
consts
);
break
;
case
NameConstant_kind
:
ADDOP_O
(
c
,
LOAD_CONST
,
e
->
v
.
NameConstant
.
value
,
consts
);
break
;
/* The following exprs can be assignment targets. */
case
Attribute_kind
:
if
(
e
->
v
.
Attribute
.
ctx
!=
AugStore
)
...
...
Python/peephole.c
View file @
442f2099
...
...
@@ -327,37 +327,6 @@ markblocks(unsigned char *code, Py_ssize_t len)
return
blocks
;
}
/* Helper to replace LOAD_NAME None/True/False with LOAD_CONST
Returns: 0 if no change, 1 if change, -1 if error */
static
int
load_global
(
unsigned
char
*
codestr
,
Py_ssize_t
i
,
char
*
name
,
PyObject
*
consts
)
{
Py_ssize_t
j
;
PyObject
*
obj
;
if
(
name
==
NULL
)
return
0
;
if
(
strcmp
(
name
,
"None"
)
==
0
)
obj
=
Py_None
;
else
if
(
strcmp
(
name
,
"True"
)
==
0
)
obj
=
Py_True
;
else
if
(
strcmp
(
name
,
"False"
)
==
0
)
obj
=
Py_False
;
else
return
0
;
for
(
j
=
0
;
j
<
PyList_GET_SIZE
(
consts
);
j
++
)
{
if
(
PyList_GET_ITEM
(
consts
,
j
)
==
obj
)
break
;
}
if
(
j
==
PyList_GET_SIZE
(
consts
))
{
if
(
PyList_Append
(
consts
,
obj
)
<
0
)
return
-
1
;
}
assert
(
PyList_GET_ITEM
(
consts
,
j
)
==
obj
);
codestr
[
i
]
=
LOAD_CONST
;
SETARG
(
codestr
,
i
,
j
);
return
1
;
}
/* Perform basic peephole optimizations to components of a code object.
The consts object should still be in list form to allow new constants
to be appended.
...
...
@@ -392,7 +361,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
Py_ssize_t
const_stack_size
=
0
;
int
in_consts
=
0
;
/* whether we are in a LOAD_CONST sequence */
unsigned
int
*
blocks
=
NULL
;
char
*
name
;
/* Bail out if an exception is set */
if
(
PyErr_Occurred
())
...
...
@@ -475,20 +443,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
codestr
[
i
+
3
]
=
NOP
;
break
;
/* Replace LOAD_GLOBAL/LOAD_NAME None/True/False
with LOAD_CONST None/True/False */
case
LOAD_NAME
:
case
LOAD_GLOBAL
:
j
=
GETARG
(
codestr
,
i
);
name
=
_PyUnicode_AsString
(
PyTuple_GET_ITEM
(
names
,
j
));
h
=
load_global
(
codestr
,
i
,
name
,
consts
);
if
(
h
<
0
)
goto
exitError
;
else
if
(
h
==
0
)
continue
;
CONST_STACK_PUSH_OP
(
i
);
break
;
/* Skip over LOAD_CONST trueconst
POP_JUMP_IF_FALSE xx. This improves
"while 1" performance. */
...
...
Python/symtable.c
View file @
442f2099
...
...
@@ -1437,6 +1437,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
case
Str_kind
:
case
Bytes_kind
:
case
Ellipsis_kind
:
case
NameConstant_kind
:
/* Nothing to do here. */
break
;
/* The following exprs can be assignment targets. */
...
...
Tools/parser/unparse.py
View file @
442f2099
...
...
@@ -307,6 +307,9 @@ class Unparser:
def
_Name
(
self
,
t
):
self
.
write
(
t
.
id
)
def
_NameConstant
(
self
,
t
):
self
.
write
(
repr
(
t
.
value
))
def
_Num
(
self
,
t
):
# Substitute overflowing decimal literal for AST infinities.
self
.
write
(
repr
(
t
.
n
).
replace
(
"inf"
,
INFSTR
))
...
...
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