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
3f22811f
Commit
3f22811f
authored
Sep 27, 2018
by
Serhiy Storchaka
Committed by
GitHub
Sep 27, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-32892: Use ast.Constant instead of specific constant AST types. (GH-9445)
parent
a94ee12c
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
337 additions
and
678 deletions
+337
-678
Doc/library/ast.rst
Doc/library/ast.rst
+11
-4
Doc/whatsnew/3.8.rst
Doc/whatsnew/3.8.rst
+5
-0
Include/Python-ast.h
Include/Python-ast.h
+4
-32
Lib/ast.py
Lib/ast.py
+64
-9
Lib/inspect.py
Lib/inspect.py
+2
-8
Lib/test/test_ast.py
Lib/test/test_ast.py
+151
-53
Lib/test/test_fstring.py
Lib/test/test_fstring.py
+16
-8
Lib/test/test_future.py
Lib/test/test_future.py
+1
-1
Lib/test/test_pyclbr.py
Lib/test/test_pyclbr.py
+2
-1
Misc/NEWS.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst
...S.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst
+4
-0
Parser/Python.asdl
Parser/Python.asdl
+2
-10
Parser/asdl_c.py
Parser/asdl_c.py
+4
-35
Python/Python-ast.c
Python/Python-ast.c
+4
-308
Python/ast.c
Python/ast.c
+28
-54
Python/ast_opt.c
Python/ast_opt.c
+10
-51
Python/ast_unparse.c
Python/ast_unparse.c
+7
-17
Python/compile.c
Python/compile.c
+6
-58
Python/symtable.c
Python/symtable.c
+0
-5
Tools/clinic/clinic.py
Tools/clinic/clinic.py
+12
-5
Tools/parser/unparse.py
Tools/parser/unparse.py
+4
-19
No files found.
Doc/library/ast.rst
View file @
3f22811f
...
...
@@ -78,8 +78,8 @@ Node classes
node = ast.UnaryOp()
node.op = ast.USub()
node.operand = ast.
Num
()
node.operand.
n
= 5
node.operand = ast.
Constant
()
node.operand.
value
= 5
node.operand.lineno = 0
node.operand.col_offset = 0
node.lineno = 0
...
...
@@ -87,9 +87,16 @@ Node classes
or the more compact ::
node = ast.UnaryOp(ast.USub(), ast.
Num
(5, lineno=0, col_offset=0),
node = ast.UnaryOp(ast.USub(), ast.
Constant
(5, lineno=0, col_offset=0),
lineno=0, col_offset=0)
.. deprecated:: 3.8
Class :class:`ast.Constant` is now used for all constants. Old classes
:class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`,
:class:`ast.NameConstant` and :class:`ast.Ellipsis` are still available,
but they will be removed in future Python releases.
.. _abstract-grammar:
...
...
@@ -239,7 +246,7 @@ and classes for traversing abstract syntax trees:
def visit_Name(self, node):
return copy_location(Subscript(
value=Name(id='data', ctx=Load()),
slice=Index(value=
Str(s
=node.id)),
slice=Index(value=
Constant(value
=node.id)),
ctx=node.ctx
), node)
...
...
Doc/whatsnew/3.8.rst
View file @
3f22811f
...
...
@@ -262,6 +262,11 @@ Deprecated
(Contributed by Berker Peksag in :issue:`9372`.)
* :mod:`ast` classes ``Num``, ``Str``, ``Bytes``, ``NameConstant`` and
``Ellipsis`` are considered deprecated and will be removed in future Python
versions. :class:`~ast.Constant` should be used instead.
(Contributed by Serhiy Storchaka in :issue:`32892`.)
Removed
=======
...
...
Include/Python-ast.h
View file @
3f22811f
...
...
@@ -208,11 +208,10 @@ enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
IfExp_kind
=
5
,
Dict_kind
=
6
,
Set_kind
=
7
,
ListComp_kind
=
8
,
SetComp_kind
=
9
,
DictComp_kind
=
10
,
GeneratorExp_kind
=
11
,
Await_kind
=
12
,
Yield_kind
=
13
,
YieldFrom_kind
=
14
,
Compare_kind
=
15
,
Call_kind
=
16
,
Num_kind
=
17
,
Str_kind
=
18
,
FormattedValue_kind
=
19
,
JoinedStr_kind
=
20
,
Bytes_kind
=
21
,
NameConstant_kind
=
22
,
Ellipsis_kind
=
23
,
Constant_kind
=
24
,
Attribute_kind
=
25
,
Subscript_kind
=
26
,
Starred_kind
=
27
,
Name_kind
=
28
,
List_kind
=
29
,
Tuple_kind
=
30
};
Compare_kind
=
15
,
Call_kind
=
16
,
FormattedValue_kind
=
17
,
JoinedStr_kind
=
18
,
Constant_kind
=
19
,
Attribute_kind
=
20
,
Subscript_kind
=
21
,
Starred_kind
=
22
,
Name_kind
=
23
,
List_kind
=
24
,
Tuple_kind
=
25
};
struct
_expr
{
enum
_expr_kind
kind
;
union
{
...
...
@@ -297,14 +296,6 @@ struct _expr {
asdl_seq
*
keywords
;
}
Call
;
struct
{
object
n
;
}
Num
;
struct
{
string
s
;
}
Str
;
struct
{
expr_ty
value
;
int
conversion
;
...
...
@@ -315,14 +306,6 @@ struct _expr {
asdl_seq
*
values
;
}
JoinedStr
;
struct
{
bytes
s
;
}
Bytes
;
struct
{
singleton
value
;
}
NameConstant
;
struct
{
constant
value
;
}
Constant
;
...
...
@@ -566,23 +549,12 @@ expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators,
#define Call(a0, a1, a2, a3, a4, a5) _Py_Call(a0, a1, a2, a3, a4, a5)
expr_ty
_Py_Call
(
expr_ty
func
,
asdl_seq
*
args
,
asdl_seq
*
keywords
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3)
expr_ty
_Py_Num
(
object
n
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3)
expr_ty
_Py_Str
(
string
s
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define FormattedValue(a0, a1, a2, a3, a4, a5) _Py_FormattedValue(a0, a1, a2, a3, a4, a5)
expr_ty
_Py_FormattedValue
(
expr_ty
value
,
int
conversion
,
expr_ty
format_spec
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
#define JoinedStr(a0, a1, a2, a3) _Py_JoinedStr(a0, a1, a2, a3)
expr_ty
_Py_JoinedStr
(
asdl_seq
*
values
,
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 Constant(a0, a1, a2, a3) _Py_Constant(a0, a1, a2, a3)
expr_ty
_Py_Constant
(
constant
value
,
int
lineno
,
int
col_offset
,
PyArena
*
arena
);
...
...
Lib/ast.py
View file @
3f22811f
...
...
@@ -48,10 +48,8 @@ def literal_eval(node_or_string):
node_or_string
=
node_or_string
.
body
def
_convert_num
(
node
):
if
isinstance
(
node
,
Constant
):
if
isinstance
(
node
.
value
,
(
int
,
float
,
complex
)
):
if
type
(
node
.
value
)
in
(
int
,
float
,
complex
):
return
node
.
value
elif
isinstance
(
node
,
Num
):
return
node
.
n
raise
ValueError
(
'malformed node or string: '
+
repr
(
node
))
def
_convert_signed_num
(
node
):
if
isinstance
(
node
,
UnaryOp
)
and
isinstance
(
node
.
op
,
(
UAdd
,
USub
)):
...
...
@@ -64,10 +62,6 @@ def literal_eval(node_or_string):
def
_convert
(
node
):
if
isinstance
(
node
,
Constant
):
return
node
.
value
elif
isinstance
(
node
,
(
Str
,
Bytes
)):
return
node
.
s
elif
isinstance
(
node
,
Num
):
return
node
.
n
elif
isinstance
(
node
,
Tuple
):
return
tuple
(
map
(
_convert
,
node
.
elts
))
elif
isinstance
(
node
,
List
):
...
...
@@ -77,8 +71,6 @@ def literal_eval(node_or_string):
elif
isinstance
(
node
,
Dict
):
return
dict
(
zip
(
map
(
_convert
,
node
.
keys
),
map
(
_convert
,
node
.
values
)))
elif
isinstance
(
node
,
NameConstant
):
return
node
.
value
elif
isinstance
(
node
,
BinOp
)
and
isinstance
(
node
.
op
,
(
Add
,
Sub
)):
left
=
_convert_signed_num
(
node
.
left
)
right
=
_convert_num
(
node
.
right
)
...
...
@@ -329,3 +321,66 @@ class NodeTransformer(NodeVisitor):
else
:
setattr
(
node
,
field
,
new_node
)
return
node
# The following code is for backward compatibility.
# It will be removed in future.
def
_getter
(
self
):
return
self
.
value
def
_setter
(
self
,
value
):
self
.
value
=
value
Constant
.
n
=
property
(
_getter
,
_setter
)
Constant
.
s
=
property
(
_getter
,
_setter
)
class
_ABC
(
type
):
def
__instancecheck__
(
cls
,
inst
):
if
not
isinstance
(
inst
,
Constant
):
return
False
if
cls
in
_const_types
:
try
:
value
=
inst
.
value
except
AttributeError
:
return
False
else
:
return
type
(
value
)
in
_const_types
[
cls
]
return
type
.
__instancecheck__
(
cls
,
inst
)
def
_new
(
cls
,
*
args
,
**
kwargs
):
if
cls
in
_const_types
:
return
Constant
(
*
args
,
**
kwargs
)
return
Constant
.
__new__
(
cls
,
*
args
,
**
kwargs
)
class
Num
(
Constant
,
metaclass
=
_ABC
):
_fields
=
(
'n'
,)
__new__
=
_new
class
Str
(
Constant
,
metaclass
=
_ABC
):
_fields
=
(
's'
,)
__new__
=
_new
class
Bytes
(
Constant
,
metaclass
=
_ABC
):
_fields
=
(
's'
,)
__new__
=
_new
class
NameConstant
(
Constant
,
metaclass
=
_ABC
):
__new__
=
_new
class
Ellipsis
(
Constant
,
metaclass
=
_ABC
):
_fields
=
()
def
__new__
(
cls
,
*
args
,
**
kwargs
):
if
cls
is
Ellipsis
:
return
Constant
(...,
*
args
,
**
kwargs
)
return
Constant
.
__new__
(
cls
,
*
args
,
**
kwargs
)
_const_types
=
{
Num
:
(
int
,
float
,
complex
),
Str
:
(
str
,),
Bytes
:
(
bytes
,),
NameConstant
:
(
type
(
None
),
bool
),
Ellipsis
:
(
type
(...),),
}
Lib/inspect.py
View file @
3f22811f
...
...
@@ -2005,14 +2005,8 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
except
NameError
:
raise
RuntimeError
()
if
isinstance
(
value
,
str
):
return
ast
.
Str
(
value
)
if
isinstance
(
value
,
(
int
,
float
)):
return
ast
.
Num
(
value
)
if
isinstance
(
value
,
bytes
):
return
ast
.
Bytes
(
value
)
if
value
in
(
True
,
False
,
None
):
return
ast
.
NameConstant
(
value
)
if
isinstance
(
value
,
(
str
,
int
,
float
,
bytes
,
bool
,
type
(
None
))):
return
ast
.
Constant
(
value
)
raise
RuntimeError
()
class
RewriteSymbolics
(
ast
.
NodeTransformer
):
...
...
Lib/test/test_ast.py
View file @
3f22811f
This diff is collapsed.
Click to expand it.
Lib/test/test_fstring.py
View file @
3f22811f
...
...
@@ -116,9 +116,11 @@ f'eggs {a * x()} spam {b + y()}'"""
self
.
assertEqual
(
type
(
t
.
body
[
1
]),
ast
.
Expr
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
),
ast
.
JoinedStr
)
self
.
assertEqual
(
len
(
t
.
body
[
1
].
value
.
values
),
4
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
].
value
),
str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
1
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
].
value
),
str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
3
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
t
.
body
[
1
].
lineno
,
3
)
self
.
assertEqual
(
t
.
body
[
1
].
value
.
lineno
,
3
)
...
...
@@ -183,9 +185,11 @@ f'{a * f"-{x()}-"}'"""
self
.
assertEqual
(
binop
.
right
.
col_offset
,
7
)
# check the nested call location
self
.
assertEqual
(
len
(
binop
.
right
.
values
),
3
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
0
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
0
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
0
].
value
),
str
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
1
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
2
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
2
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
binop
.
right
.
values
[
2
].
value
),
str
)
self
.
assertEqual
(
binop
.
right
.
values
[
0
].
lineno
,
3
)
self
.
assertEqual
(
binop
.
right
.
values
[
1
].
lineno
,
3
)
self
.
assertEqual
(
binop
.
right
.
values
[
2
].
lineno
,
3
)
...
...
@@ -215,9 +219,11 @@ f'{a * x()} {a * x()} {a * x()}'
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
),
ast
.
JoinedStr
)
self
.
assertEqual
(
len
(
t
.
body
[
1
].
value
.
values
),
5
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
1
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
1
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
1
].
value
),
str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
3
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
3
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
3
].
value
),
str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
4
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
t
.
body
[
1
].
lineno
,
3
)
self
.
assertEqual
(
t
.
body
[
1
].
value
.
lineno
,
3
)
...
...
@@ -287,9 +293,11 @@ non-important content
self
.
assertEqual
(
type
(
t
.
body
[
1
]),
ast
.
Expr
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
),
ast
.
JoinedStr
)
self
.
assertEqual
(
len
(
t
.
body
[
1
].
value
.
values
),
3
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
0
].
value
),
str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
1
]),
ast
.
FormattedValue
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
]),
ast
.
Str
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
]),
ast
.
Constant
)
self
.
assertEqual
(
type
(
t
.
body
[
1
].
value
.
values
[
2
].
value
),
str
)
# NOTE: the following invalid behavior is described in bpo-16806.
# - line number should be the *first* line (3), not the *last* (8)
# - column offset should not be -1
...
...
Lib/test/test_future.py
View file @
3f22811f
...
...
@@ -230,7 +230,7 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq
(
"lukasz.langa.pl"
)
eq
(
"call.me(maybe)"
)
eq
(
"1 .real"
)
eq
(
"1.0
.real"
)
eq
(
"1.0.real"
)
eq
(
"....__class__"
)
eq
(
"list[str]"
)
eq
(
"dict[str, int]"
)
...
...
Lib/test/test_pyclbr.py
View file @
3f22811f
...
...
@@ -144,7 +144,8 @@ class PyclbrTest(TestCase):
def
test_easy
(
self
):
self
.
checkModule
(
'pyclbr'
)
self
.
checkModule
(
'ast'
)
# XXX: Metaclasses are not supported
# self.checkModule('ast')
self
.
checkModule
(
'doctest'
,
ignore
=
(
"TestResults"
,
"_SpoofOut"
,
"DocTestCase"
,
'_DocTestSuite'
))
self
.
checkModule
(
'difflib'
,
ignore
=
(
"Match"
,))
...
...
Misc/NEWS.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst
0 → 100644
View file @
3f22811f
The parser now represents all constants as :class:`ast.Constant` instead of
using specific constant AST types (``Num``, ``Str``, ``Bytes``,
``NameConstant`` and ``Ellipsis``). These classes are considered deprecated
and will be removed in future Python versions.
Parser/Python.asdl
View file @
3f22811f
-- ASDL's 7 builtin types are:
-- identifier, int, string, bytes, object, singleton, constant
--
-- singleton: None, True or False
-- constant can be None, whereas None means "no value" for object.
-- ASDL's 5 builtin types are:
-- identifier, int, string, object, constant
module Python
{
...
...
@@ -75,13 +72,8 @@ module Python
-- x < 4 < 3 and (x < 4) < 3
| Compare(expr left, cmpop* ops, expr* comparators)
| Call(expr func, expr* args, keyword* keywords)
| Num(object n) -- a number as a PyObject.
| Str(string s) -- need to specify raw, unicode, etc?
| FormattedValue(expr value, int? conversion, expr? format_spec)
| JoinedStr(expr* values)
| Bytes(bytes s)
| NameConstant(singleton value)
| Ellipsis
| Constant(constant value)
-- the following expression can appear in assignment context
...
...
Parser/asdl_c.py
View file @
3f22811f
...
...
@@ -855,17 +855,6 @@ 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)
...
...
@@ -883,13 +872,11 @@ static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena)
{
if (obj) {
if (PyArena_AddPyObject(arena, obj) < 0) {
*out = NULL;
return -1;
}
Py_INCREF(obj);
if (PyArena_AddPyObject(arena, obj) < 0) {
*out = NULL;
return -1;
}
Py_INCREF(obj);
*out = obj;
return 0;
}
...
...
@@ -903,24 +890,6 @@ static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena)
return obj2ast_object(obj, out, arena);
}
static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
{
if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
return 1;
}
return obj2ast_object(obj, out, arena);
}
static int obj2ast_bytes(PyObject* obj, PyObject** out, PyArena* arena)
{
if (!PyBytes_CheckExact(obj)) {
PyErr_SetString(PyExc_TypeError, "AST bytes must be of type bytes");
return 1;
}
return obj2ast_object(obj, out, arena);
}
static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
{
int i;
...
...
Python/Python-ast.c
View file @
3f22811f
This diff is collapsed.
Click to expand it.
Python/ast.c
View file @
3f22811f
...
...
@@ -295,23 +295,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
return
0
;
}
return
1
;
case
Num_kind
:
{
PyObject
*
n
=
exp
->
v
.
Num
.
n
;
if
(
!
PyLong_CheckExact
(
n
)
&&
!
PyFloat_CheckExact
(
n
)
&&
!
PyComplex_CheckExact
(
n
))
{
PyErr_SetString
(
PyExc_TypeError
,
"non-numeric type in Num"
);
return
0
;
}
return
1
;
}
case
Str_kind
:
{
PyObject
*
s
=
exp
->
v
.
Str
.
s
;
if
(
!
PyUnicode_CheckExact
(
s
))
{
PyErr_SetString
(
PyExc_TypeError
,
"non-string type in Str"
);
return
0
;
}
return
1
;
}
case
JoinedStr_kind
:
return
validate_exprs
(
exp
->
v
.
JoinedStr
.
values
,
Load
,
0
);
case
FormattedValue_kind
:
...
...
@@ -320,14 +303,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
if
(
exp
->
v
.
FormattedValue
.
format_spec
)
return
validate_expr
(
exp
->
v
.
FormattedValue
.
format_spec
,
Load
);
return
1
;
case
Bytes_kind
:
{
PyObject
*
b
=
exp
->
v
.
Bytes
.
s
;
if
(
!
PyBytes_CheckExact
(
b
))
{
PyErr_SetString
(
PyExc_TypeError
,
"non-bytes type in Bytes"
);
return
0
;
}
return
1
;
}
case
Attribute_kind
:
return
validate_expr
(
exp
->
v
.
Attribute
.
value
,
Load
);
case
Subscript_kind
:
...
...
@@ -339,10 +314,8 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
return
validate_exprs
(
exp
->
v
.
List
.
elts
,
ctx
,
0
);
case
Tuple_kind
:
return
validate_exprs
(
exp
->
v
.
Tuple
.
elts
,
ctx
,
0
);
/* Th
ese last cases do
n't have any checking. */
/* Th
is last case does
n't have any checking. */
case
Name_kind
:
case
NameConstant_kind
:
case
Ellipsis_kind
:
return
1
;
default:
PyErr_SetString
(
PyExc_SystemError
,
"unexpected expression"
);
...
...
@@ -1040,19 +1013,23 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
break
;
case
Dict_kind
:
case
Set_kind
:
case
Num_kind
:
case
Str_kind
:
case
Bytes_kind
:
case
JoinedStr_kind
:
case
FormattedValue_kind
:
expr_name
=
"literal"
;
break
;
case
NameConstant_kind
:
expr_name
=
"keyword"
;
break
;
case
Ellipsis_kind
:
expr_name
=
"Ellipsis"
;
case
Constant_kind
:
{
PyObject
*
value
=
e
->
v
.
Constant
.
value
;
if
(
value
==
Py_None
||
value
==
Py_False
||
value
==
Py_True
)
{
expr_name
=
"keyword"
;
}
else
if
(
value
==
Py_Ellipsis
)
{
expr_name
=
"Ellipsis"
;
}
else
{
expr_name
=
"literal"
;
}
break
;
}
case
Compare_kind
:
expr_name
=
"comparison"
;
break
;
...
...
@@ -2091,11 +2068,11 @@ ast_for_atom(struct compiling *c, const node *n)
size_t
len
=
strlen
(
s
);
if
(
len
>=
4
&&
len
<=
5
)
{
if
(
!
strcmp
(
s
,
"None"
))
return
Name
Constant
(
Py_None
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
Py_None
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
if
(
!
strcmp
(
s
,
"True"
))
return
Name
Constant
(
Py_True
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
Py_True
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
if
(
!
strcmp
(
s
,
"False"
))
return
Name
Constant
(
Py_False
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
Py_False
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
}
name
=
new_identifier
(
s
,
c
);
if
(
!
name
)
...
...
@@ -2144,10 +2121,10 @@ ast_for_atom(struct compiling *c, const node *n)
Py_DECREF
(
pynum
);
return
NULL
;
}
return
Num
(
pynum
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
pynum
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
}
case
ELLIPSIS
:
/* Ellipsis */
return
Ellipsis
(
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
Py_Ellipsis
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
case
LPAR
:
/* some parenthesized expressions */
ch
=
CHILD
(
n
,
1
);
...
...
@@ -4751,7 +4728,7 @@ typedef struct {
expr_ty's, and then after that start dynamically allocating,
doubling the number allocated each time. Note that the f-string
f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one
Str
for the literal 'a'. So you add expr_ty's about twice as
Constant
for the literal 'a'. So you add expr_ty's about twice as
fast as you add exressions in an f-string. */
Py_ssize_t
allocated
;
/* Number we've allocated. */
...
...
@@ -4903,7 +4880,7 @@ FstringParser_Dealloc(FstringParser *state)
ExprList_Dealloc
(
&
state
->
expr_list
);
}
/* Make a
Str
node, but decref the PyUnicode object being added. */
/* Make a
Constant
node, but decref the PyUnicode object being added. */
static
expr_ty
make_str_node_and_del
(
PyObject
**
str
,
struct
compiling
*
c
,
const
node
*
n
)
{
...
...
@@ -4914,7 +4891,7 @@ make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
Py_DECREF
(
s
);
return
NULL
;
}
return
Str
(
s
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
s
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
}
/* Add a non-f-string (that is, a regular literal string). str is
...
...
@@ -5002,11 +4979,11 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
break
;
/* We know we have an expression. Convert any existing string
to a
Str
node. */
to a
Constant
node. */
if
(
!
state
->
last_str
)
{
/* Do nothing. No previous literal. */
}
else
{
/* Convert the existing last_str literal to a
Str
node. */
/* Convert the existing last_str literal to a
Constant
node. */
expr_ty
str
=
make_str_node_and_del
(
&
state
->
last_str
,
c
,
n
);
if
(
!
str
||
ExprList_Append
(
&
state
->
expr_list
,
str
)
<
0
)
return
-
1
;
...
...
@@ -5033,7 +5010,7 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
}
/* Convert the partial state reflected in last_str and expr_list to an
expr_ty. The expr_ty can be a
Str
, or a JoinedStr. */
expr_ty. The expr_ty can be a
Constant
, or a JoinedStr. */
static
expr_ty
FstringParser_Finish
(
FstringParser
*
state
,
struct
compiling
*
c
,
const
node
*
n
)
...
...
@@ -5055,7 +5032,7 @@ FstringParser_Finish(FstringParser *state, struct compiling *c,
return
make_str_node_and_del
(
&
state
->
last_str
,
c
,
n
);
}
/* Create a
Str
node out of last_str, if needed. It will be the
/* Create a
Constant
node out of last_str, if needed. It will be the
last node in our expression list. */
if
(
state
->
last_str
)
{
expr_ty
str
=
make_str_node_and_del
(
&
state
->
last_str
,
c
,
n
);
...
...
@@ -5206,9 +5183,9 @@ parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
/* Accepts a STRING+ atom, and produces an expr_ty node. Run through
each STRING atom, and process it as needed. For bytes, just
concatenate them together, and the result will be a
Bytes
node. For
concatenate them together, and the result will be a
Constant
node. For
normal strings and f-strings, concatenate them together. The result
will be a
Str
node if there were no f-strings; a FormattedValue
will be a
Constant
node if there were no f-strings; a FormattedValue
node if there's just an f-string (with no leading or trailing
literals), or a JoinedStr node if there are multiple f-strings or
any literals involved. */
...
...
@@ -5279,7 +5256,7 @@ parsestrplus(struct compiling *c, const node *n)
/* Just return the bytes object and we're done. */
if
(
PyArena_AddPyObject
(
c
->
c_arena
,
bytes_str
)
<
0
)
goto
error
;
return
Bytes
(
bytes_str
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
return
Constant
(
bytes_str
,
LINENO
(
n
),
n
->
n_col_offset
,
c
->
c_arena
);
}
/* We're not a bytes string, bytes_str should never have been set. */
...
...
@@ -5304,9 +5281,6 @@ _PyAST_GetDocString(asdl_seq *body)
return
NULL
;
}
expr_ty
e
=
st
->
v
.
Expr
.
value
;
if
(
e
->
kind
==
Str_kind
)
{
return
e
->
v
.
Str
.
s
;
}
if
(
e
->
kind
==
Constant_kind
&&
PyUnicode_CheckExact
(
e
->
v
.
Constant
.
value
))
{
return
e
->
v
.
Constant
.
value
;
}
...
...
Python/ast_opt.c
View file @
3f22811f
...
...
@@ -5,47 +5,6 @@
#include "ast.h"
/* TODO: is_const and get_const_value are copied from Python/compile.c.
It should be deduped in the future. Maybe, we can include this file
from compile.c?
*/
static
int
is_const
(
expr_ty
e
)
{
switch
(
e
->
kind
)
{
case
Constant_kind
:
case
Num_kind
:
case
Str_kind
:
case
Bytes_kind
:
case
Ellipsis_kind
:
case
NameConstant_kind
:
return
1
;
default:
return
0
;
}
}
static
PyObject
*
get_const_value
(
expr_ty
e
)
{
switch
(
e
->
kind
)
{
case
Constant_kind
:
return
e
->
v
.
Constant
.
value
;
case
Num_kind
:
return
e
->
v
.
Num
.
n
;
case
Str_kind
:
return
e
->
v
.
Str
.
s
;
case
Bytes_kind
:
return
e
->
v
.
Bytes
.
s
;
case
Ellipsis_kind
:
return
Py_Ellipsis
;
case
NameConstant_kind
:
return
e
->
v
.
NameConstant
.
value
;
default:
Py_UNREACHABLE
();
}
}
static
int
make_const
(
expr_ty
node
,
PyObject
*
val
,
PyArena
*
arena
)
{
...
...
@@ -81,7 +40,7 @@ fold_unaryop(expr_ty node, PyArena *arena, int optimize)
{
expr_ty
arg
=
node
->
v
.
UnaryOp
.
operand
;
if
(
!
is_const
(
arg
)
)
{
if
(
arg
->
kind
!=
Constant_kind
)
{
/* Fold not into comparison */
if
(
node
->
v
.
UnaryOp
.
op
==
Not
&&
arg
->
kind
==
Compare_kind
&&
asdl_seq_LEN
(
arg
->
v
.
Compare
.
ops
)
==
1
)
{
...
...
@@ -123,7 +82,7 @@ fold_unaryop(expr_ty node, PyArena *arena, int optimize)
[
UAdd
]
=
PyNumber_Positive
,
[
USub
]
=
PyNumber_Negative
,
};
PyObject
*
newval
=
ops
[
node
->
v
.
UnaryOp
.
op
](
get_const_value
(
arg
)
);
PyObject
*
newval
=
ops
[
node
->
v
.
UnaryOp
.
op
](
arg
->
v
.
Constant
.
value
);
return
make_const
(
node
,
newval
,
arena
);
}
...
...
@@ -259,12 +218,12 @@ fold_binop(expr_ty node, PyArena *arena, int optimize)
expr_ty
lhs
,
rhs
;
lhs
=
node
->
v
.
BinOp
.
left
;
rhs
=
node
->
v
.
BinOp
.
right
;
if
(
!
is_const
(
lhs
)
||
!
is_const
(
rhs
)
)
{
if
(
lhs
->
kind
!=
Constant_kind
||
rhs
->
kind
!=
Constant_kind
)
{
return
1
;
}
PyObject
*
lv
=
get_const_value
(
lhs
)
;
PyObject
*
rv
=
get_const_value
(
rhs
)
;
PyObject
*
lv
=
lhs
->
v
.
Constant
.
value
;
PyObject
*
rv
=
rhs
->
v
.
Constant
.
value
;
PyObject
*
newval
;
switch
(
node
->
v
.
BinOp
.
op
)
{
...
...
@@ -316,7 +275,7 @@ make_const_tuple(asdl_seq *elts)
{
for
(
int
i
=
0
;
i
<
asdl_seq_LEN
(
elts
);
i
++
)
{
expr_ty
e
=
(
expr_ty
)
asdl_seq_GET
(
elts
,
i
);
if
(
!
is_const
(
e
)
)
{
if
(
e
->
kind
!=
Constant_kind
)
{
return
NULL
;
}
}
...
...
@@ -328,7 +287,7 @@ make_const_tuple(asdl_seq *elts)
for
(
int
i
=
0
;
i
<
asdl_seq_LEN
(
elts
);
i
++
)
{
expr_ty
e
=
(
expr_ty
)
asdl_seq_GET
(
elts
,
i
);
PyObject
*
v
=
get_const_value
(
e
)
;
PyObject
*
v
=
e
->
v
.
Constant
.
value
;
Py_INCREF
(
v
);
PyTuple_SET_ITEM
(
newval
,
i
,
v
);
}
...
...
@@ -357,16 +316,16 @@ fold_subscr(expr_ty node, PyArena *arena, int optimize)
arg
=
node
->
v
.
Subscript
.
value
;
slice
=
node
->
v
.
Subscript
.
slice
;
if
(
node
->
v
.
Subscript
.
ctx
!=
Load
||
!
is_const
(
arg
)
||
arg
->
kind
!=
Constant_kind
||
/* TODO: handle other types of slices */
slice
->
kind
!=
Index_kind
||
!
is_const
(
slice
->
v
.
Index
.
value
)
)
slice
->
v
.
Index
.
value
->
kind
!=
Constant_kind
)
{
return
1
;
}
idx
=
slice
->
v
.
Index
.
value
;
newval
=
PyObject_GetItem
(
get_const_value
(
arg
),
get_const_value
(
idx
)
);
newval
=
PyObject_GetItem
(
arg
->
v
.
Constant
.
value
,
idx
->
v
.
Constant
.
value
);
return
make_const
(
node
,
newval
,
arena
);
}
...
...
Python/ast_unparse.c
View file @
3f22811f
...
...
@@ -567,8 +567,6 @@ append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
switch
(
e
->
kind
)
{
case
Constant_kind
:
return
append_fstring_unicode
(
writer
,
e
->
v
.
Constant
.
value
);
case
Str_kind
:
return
append_fstring_unicode
(
writer
,
e
->
v
.
Str
.
s
);
case
JoinedStr_kind
:
return
append_joinedstr
(
writer
,
e
,
is_format_spec
);
case
FormattedValue_kind
:
...
...
@@ -690,13 +688,12 @@ static int
append_ast_attribute
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
const
char
*
period
;
APPEND_EXPR
(
e
->
v
.
Attribute
.
value
,
PR_ATOM
);
expr_ty
v
=
e
->
v
.
Attribute
.
value
;
APPEND_EXPR
(
v
,
PR_ATOM
);
/* Special case: integers require a space for attribute access to be
unambiguous. Floats and complex numbers don't but work with it, too. */
if
(
e
->
v
.
Attribute
.
value
->
kind
==
Num_kind
||
e
->
v
.
Attribute
.
value
->
kind
==
Constant_kind
)
{
unambiguous. */
if
(
v
->
kind
==
Constant_kind
&&
PyLong_CheckExact
(
v
->
v
.
Constant
.
value
))
{
period
=
" ."
;
}
else
{
...
...
@@ -841,21 +838,14 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
case
Call_kind
:
return
append_ast_call
(
writer
,
e
);
case
Constant_kind
:
if
(
e
->
v
.
Constant
.
value
==
Py_Ellipsis
)
{
APPEND_STR_FINISH
(
"..."
);
}
return
append_repr
(
writer
,
e
->
v
.
Constant
.
value
);
case
Num_kind
:
return
append_repr
(
writer
,
e
->
v
.
Num
.
n
);
case
Str_kind
:
return
append_repr
(
writer
,
e
->
v
.
Str
.
s
);
case
JoinedStr_kind
:
return
append_joinedstr
(
writer
,
e
,
false
);
case
FormattedValue_kind
:
return
append_formattedvalue
(
writer
,
e
,
false
);
case
Bytes_kind
:
return
append_repr
(
writer
,
e
->
v
.
Bytes
.
s
);
case
Ellipsis_kind
:
APPEND_STR_FINISH
(
"..."
);
case
NameConstant_kind
:
return
append_repr
(
writer
,
e
->
v
.
NameConstant
.
value
);
/* The following exprs can be assignment targets. */
case
Attribute_kind
:
return
append_ast_attribute
(
writer
,
e
);
...
...
Python/compile.c
View file @
3f22811f
...
...
@@ -1398,43 +1398,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
} \
}
static
int
is_const
(
expr_ty
e
)
{
switch
(
e
->
kind
)
{
case
Constant_kind
:
case
Num_kind
:
case
Str_kind
:
case
Bytes_kind
:
case
Ellipsis_kind
:
case
NameConstant_kind
:
return
1
;
default:
return
0
;
}
}
static
PyObject
*
get_const_value
(
expr_ty
e
)
{
switch
(
e
->
kind
)
{
case
Constant_kind
:
return
e
->
v
.
Constant
.
value
;
case
Num_kind
:
return
e
->
v
.
Num
.
n
;
case
Str_kind
:
return
e
->
v
.
Str
.
s
;
case
Bytes_kind
:
return
e
->
v
.
Bytes
.
s
;
case
Ellipsis_kind
:
return
Py_Ellipsis
;
case
NameConstant_kind
:
return
e
->
v
.
NameConstant
.
value
;
default:
Py_UNREACHABLE
();
}
}
/* Search if variable annotations are present statically in a block. */
static
int
...
...
@@ -2568,7 +2531,7 @@ static int
compiler_return
(
struct
compiler
*
c
,
stmt_ty
s
)
{
int
preserve_tos
=
((
s
->
v
.
Return
.
value
!=
NULL
)
&&
!
is_const
(
s
->
v
.
Return
.
value
));
(
s
->
v
.
Return
.
value
->
kind
!=
Constant_kind
));
if
(
c
->
u
->
u_ste
->
ste_type
!=
FunctionBlock
)
return
compiler_error
(
c
,
"'return' outside function"
);
if
(
s
->
v
.
Return
.
value
!=
NULL
&&
...
...
@@ -3054,7 +3017,7 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
return
1
;
}
if
(
is_const
(
value
)
)
{
if
(
value
->
kind
==
Constant_kind
)
{
/* ignore constant statement */
return
1
;
}
...
...
@@ -3502,7 +3465,7 @@ are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end)
Py_ssize_t
i
;
for
(
i
=
begin
;
i
<
end
;
i
++
)
{
expr_ty
key
=
(
expr_ty
)
asdl_seq_GET
(
seq
,
i
);
if
(
key
==
NULL
||
!
is_const
(
key
)
)
if
(
key
==
NULL
||
key
->
kind
!=
Constant_kind
)
return
0
;
}
return
1
;
...
...
@@ -3522,7 +3485,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
return
0
;
}
for
(
i
=
begin
;
i
<
end
;
i
++
)
{
key
=
get_const_value
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Dict
.
keys
,
i
))
;
key
=
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Dict
.
keys
,
i
))
->
v
.
Constant
.
value
;
Py_INCREF
(
key
);
PyTuple_SET_ITEM
(
keys
,
i
-
begin
,
key
);
}
...
...
@@ -4244,8 +4207,8 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
static
int
expr_constant
(
expr_ty
e
)
{
if
(
is_const
(
e
)
)
{
return
PyObject_IsTrue
(
get_const_value
(
e
)
);
if
(
e
->
kind
==
Constant_kind
)
{
return
PyObject_IsTrue
(
e
->
v
.
Constant
.
value
);
}
return
-
1
;
}
...
...
@@ -4505,25 +4468,10 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
case
Constant_kind
:
ADDOP_LOAD_CONST
(
c
,
e
->
v
.
Constant
.
value
);
break
;
case
Num_kind
:
ADDOP_LOAD_CONST
(
c
,
e
->
v
.
Num
.
n
);
break
;
case
Str_kind
:
ADDOP_LOAD_CONST
(
c
,
e
->
v
.
Str
.
s
);
break
;
case
JoinedStr_kind
:
return
compiler_joined_str
(
c
,
e
);
case
FormattedValue_kind
:
return
compiler_formatted_value
(
c
,
e
);
case
Bytes_kind
:
ADDOP_LOAD_CONST
(
c
,
e
->
v
.
Bytes
.
s
);
break
;
case
Ellipsis_kind
:
ADDOP_LOAD_CONST
(
c
,
Py_Ellipsis
);
break
;
case
NameConstant_kind
:
ADDOP_LOAD_CONST
(
c
,
e
->
v
.
NameConstant
.
value
);
break
;
/* The following exprs can be assignment targets. */
case
Attribute_kind
:
if
(
e
->
v
.
Attribute
.
ctx
!=
AugStore
)
...
...
Python/symtable.c
View file @
3f22811f
...
...
@@ -1461,11 +1461,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT_SEQ
(
st
,
expr
,
e
->
v
.
JoinedStr
.
values
);
break
;
case
Constant_kind
:
case
Num_kind
:
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/clinic/clinic.py
View file @
3f22811f
...
...
@@ -3840,9 +3840,6 @@ class DSLParser:
# "starred": "a = [1, 2, 3]; *a"
visit_Starred
=
bad_node
# allow ellipsis, for now
# visit_Ellipsis = bad_node
blacklist
=
DetectBadNodes
()
blacklist
.
visit
(
module
)
bad
=
blacklist
.
bad
...
...
@@ -3868,10 +3865,15 @@ class DSLParser:
py_default
=
'None'
c_default
=
"NULL"
elif
(
isinstance
(
expr
,
ast
.
BinOp
)
or
(
isinstance
(
expr
,
ast
.
UnaryOp
)
and
not
isinstance
(
expr
.
operand
,
ast
.
Num
))):
(
isinstance
(
expr
,
ast
.
UnaryOp
)
and
not
(
isinstance
(
expr
.
operand
,
ast
.
Num
)
or
(
hasattr
(
ast
,
'Constant'
)
and
isinstance
(
expr
.
operand
,
ast
.
Constant
)
and
type
(
expr
.
operand
.
value
)
in
(
int
,
float
,
complex
)))
)):
c_default
=
kwargs
.
get
(
"c_default"
)
if
not
(
isinstance
(
c_default
,
str
)
and
c_default
):
fail
(
"When you specify an expression ("
+
repr
(
default
)
+
") as your default value,
\
n
you MUST specify a valid c_default."
)
fail
(
"When you specify an expression ("
+
repr
(
default
)
+
") as your default value,
\
n
you MUST specify a valid c_default."
+
ast
.
dump
(
expr
)
)
py_default
=
default
value
=
unknown
elif
isinstance
(
expr
,
ast
.
Attribute
):
...
...
@@ -3946,6 +3948,11 @@ class DSLParser:
self
.
function
.
parameters
[
parameter_name
]
=
p
def
parse_converter
(
self
,
annotation
):
if
(
hasattr
(
ast
,
'Constant'
)
and
isinstance
(
annotation
,
ast
.
Constant
)
and
type
(
annotation
.
value
)
is
str
):
return
annotation
.
value
,
True
,
{}
if
isinstance
(
annotation
,
ast
.
Str
):
return
annotation
.
s
,
True
,
{}
...
...
Tools/parser/unparse.py
View file @
3f22811f
...
...
@@ -329,12 +329,6 @@ class Unparser:
self
.
leave
()
# expr
def
_Bytes
(
self
,
t
):
self
.
write
(
repr
(
t
.
s
))
def
_Str
(
self
,
tree
):
self
.
write
(
repr
(
tree
.
s
))
def
_JoinedStr
(
self
,
t
):
self
.
write
(
"f"
)
string
=
io
.
StringIO
()
...
...
@@ -352,10 +346,6 @@ class Unparser:
meth
=
getattr
(
self
,
"_fstring_"
+
type
(
value
).
__name__
)
meth
(
value
,
write
)
def
_fstring_Str
(
self
,
t
,
write
):
value
=
t
.
s
.
replace
(
"{"
,
"{{"
).
replace
(
"}"
,
"}}"
)
write
(
value
)
def
_fstring_Constant
(
self
,
t
,
write
):
assert
isinstance
(
t
.
value
,
str
)
value
=
t
.
value
.
replace
(
"{"
,
"{{"
).
replace
(
"}"
,
"}}"
)
...
...
@@ -384,6 +374,7 @@ class Unparser:
def
_write_constant
(
self
,
value
):
if
isinstance
(
value
,
(
float
,
complex
)):
# Substitute overflowing decimal literal for AST infinities.
self
.
write
(
repr
(
value
).
replace
(
"inf"
,
INFSTR
))
else
:
self
.
write
(
repr
(
value
))
...
...
@@ -398,16 +389,11 @@ class Unparser:
else
:
interleave
(
lambda
:
self
.
write
(
", "
),
self
.
_write_constant
,
value
)
self
.
write
(
")"
)
elif
value
is
...:
self
.
write
(
"..."
)
else
:
self
.
_write_constant
(
t
.
value
)
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
))
def
_List
(
self
,
t
):
self
.
write
(
"["
)
interleave
(
lambda
:
self
.
write
(
", "
),
self
.
dispatch
,
t
.
elts
)
...
...
@@ -539,8 +525,7 @@ class Unparser:
# Special case: 3.__abs__() is a syntax error, so if t.value
# is an integer literal then we need to either parenthesize
# it or add an extra space to get 3 .__abs__().
if
((
isinstance
(
t
.
value
,
ast
.
Num
)
and
isinstance
(
t
.
value
.
n
,
int
))
or
(
isinstance
(
t
.
value
,
ast
.
Constant
)
and
isinstance
(
t
.
value
.
value
,
int
))):
if
isinstance
(
t
.
value
,
ast
.
Constant
)
and
isinstance
(
t
.
value
.
value
,
int
):
self
.
write
(
" "
)
self
.
write
(
"."
)
self
.
write
(
t
.
attr
)
...
...
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