-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathastcompat.py
More file actions
69 lines (52 loc) · 2.63 KB
/
Copy pathastcompat.py
File metadata and controls
69 lines (52 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# -*- coding: utf-8 -*-
"""Conditionally import AST node types only supported by recent enough Python versions (3.7+)."""
__all__ = ["NamedExpr",
"Num", "Str", "Bytes", "NameConstant", "Ellipsis",
"Index", "ExtSlice",
"getconstant"]
import ast
from ..symbol import gensym
_NoSuchNodeType = gensym("_NoSuchNodeType")
# --------------------------------------------------------------------------------
# New AST node types
# Minimum language version supported by this module is Python 3.6.
# No new AST node types in Python 3.7.
try: # Python 3.8+
from ast import NamedExpr # a.k.a. walrus operator ":="
except ImportError: # pragma: no cover
NamedExpr = _NoSuchNodeType
# No new AST node types in Python 3.9.
# TODO: any new AST node types in Python 3.10? (release expected in October 2021)
# --------------------------------------------------------------------------------
# Deprecated AST node types
try: # Python 3.8+, https://docs.python.org/3/whatsnew/3.8.html#deprecated
from ast import Num, Str, Bytes, NameConstant, Ellipsis
except ImportError: # pragma: no cover
Num = Str = Bytes = NameConstant = Ellipsis = _NoSuchNodeType
try: # Python 3.9+, https://docs.python.org/3/whatsnew/3.9.html#deprecated
from ast import Index, ExtSlice
# We ignore the internal classes Suite, Param, AugLoad, AugStore,
# which were never used in Python 3.x.
except ImportError: # pragma: no cover
Index = ExtSlice = _NoSuchNodeType
# --------------------------------------------------------------------------------
# Compatibility functions
def getconstant(tree):
"""Given an AST node `tree` representing a constant, return the contained raw value.
This encapsulates the AST differences between Python 3.8+ and older versions.
There are no `setconstant` or `makeconstant` counterparts, because you can
just create an `ast.Constant` in Python 3.6 and later. The parser doesn't
emit them until Python 3.8, but Python 3.6+ compile `ast.Constant` just fine.
"""
if type(tree) is ast.Constant: # Python 3.8+
return tree.value
# up to Python 3.7
elif type(tree) is ast.NameConstant: # up to Python 3.7 # pragma: no cover
return tree.value
elif type(tree) is ast.Num: # pragma: no cover
return tree.n
elif type(tree) in (ast.Str, ast.Bytes): # pragma: no cover
return tree.s
elif type(tree) is ast.Ellipsis: # `ast.Ellipsis` is the AST node type, `builtins.Ellipsis` is `...`. # pragma: no cover
return ...
raise TypeError(f"Not an AST node representing a constant: {type(tree)} with value {repr(tree)}") # pragma: no cover