mirror of
https://github.com/python/cpython.git
synced 2025-08-27 12:16:04 +00:00
bpo-32892: Use ast.Constant instead of specific constant AST types. (GH-9445)
This commit is contained in:
parent
a94ee12c26
commit
3f22811fef
20 changed files with 337 additions and 678 deletions
73
Lib/ast.py
73
Lib/ast.py
|
@ -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(...),),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue