8186
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
1
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
2
|
ast_unparse |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
3
|
~~~~~~~~~~~ |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
4
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
5
|
This module is a backport of the unparse function of the Python 3.9 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
6
|
ast module. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
7
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
8
|
Original ast module code is |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
9
|
:copyright: Copyright 2008 by Armin Ronacher. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
10
|
:license: Python License. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
11
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
12
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
13
|
import ast |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
14
|
import sys |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
15
|
from enum import IntEnum, auto |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
16
|
from contextlib import contextmanager, nullcontext |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
17
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
18
|
# Large float and imaginary literals get turned into infinities in the AST. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
19
|
# We unparse those infinities to INFSTR. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
20
|
_INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
21
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
22
|
class _Precedence(IntEnum): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
23
|
"""Precedence table that originated from python grammar.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
24
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
25
|
TUPLE = auto() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
26
|
YIELD = auto() # 'yield', 'yield from' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
27
|
TEST = auto() # 'if'-'else', 'lambda' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
28
|
OR = auto() # 'or' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
29
|
AND = auto() # 'and' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
30
|
NOT = auto() # 'not' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
31
|
CMP = auto() # '<', '>', '==', '>=', '<=', '!=', |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
32
|
# 'in', 'not in', 'is', 'is not' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
33
|
EXPR = auto() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
34
|
BOR = EXPR # '|' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
35
|
BXOR = auto() # '^' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
36
|
BAND = auto() # '&' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
37
|
SHIFT = auto() # '<<', '>>' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
38
|
ARITH = auto() # '+', '-' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
39
|
TERM = auto() # '*', '@', '/', '%', '//' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
40
|
FACTOR = auto() # unary '+', '-', '~' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
41
|
POWER = auto() # '**' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
42
|
AWAIT = auto() # 'await' |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
43
|
ATOM = auto() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
44
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
45
|
def next(self): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
46
|
try: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
47
|
return self.__class__(self + 1) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
48
|
except ValueError: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
49
|
return self |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
50
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
51
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
52
|
_SINGLE_QUOTES = ("'", '"') |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
53
|
_MULTI_QUOTES = ('"""', "'''") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
54
|
_ALL_QUOTES = (*_SINGLE_QUOTES, *_MULTI_QUOTES) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
55
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
56
|
class _Unparser(ast.NodeVisitor): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
57
|
"""Methods in this class recursively traverse an AST and |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
58
|
output source code for the abstract syntax; original formatting |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
59
|
is disregarded.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
60
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
61
|
def __init__(self, *, _avoid_backslashes=False): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
62
|
self._source = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
63
|
self._buffer = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
64
|
self._precedences = {} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
65
|
self._type_ignores = {} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
66
|
self._indent = 0 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
67
|
self._avoid_backslashes = _avoid_backslashes |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
68
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
69
|
def interleave(self, inter, f, seq): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
70
|
"""Call f on each item in seq, calling inter() in between.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
71
|
seq = iter(seq) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
72
|
try: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
73
|
f(next(seq)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
74
|
except StopIteration: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
75
|
pass |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
76
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
77
|
for x in seq: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
78
|
inter() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
79
|
f(x) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
80
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
81
|
def items_view(self, traverser, items): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
82
|
"""Traverse and separate the given *items* with a comma and append it to |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
83
|
the buffer. If *items* is a single item sequence, a trailing comma |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
84
|
will be added.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
85
|
if len(items) == 1: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
86
|
traverser(items[0]) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
87
|
self.write(",") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
88
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
89
|
self.interleave(lambda: self.write(", "), traverser, items) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
90
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
91
|
def maybe_newline(self): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
92
|
"""Adds a newline if it isn't the start of generated source""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
93
|
if self._source: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
94
|
self.write("\n") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
95
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
96
|
def fill(self, text=""): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
97
|
"""Indent a piece of text and append it, according to the current |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
98
|
indentation level""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
99
|
self.maybe_newline() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
100
|
self.write(" " * self._indent + text) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
101
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
102
|
def write(self, text): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
103
|
"""Append a piece of text""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
104
|
self._source.append(text) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
105
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
106
|
def buffer_writer(self, text): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
107
|
self._buffer.append(text) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
108
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
109
|
@property |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
110
|
def buffer(self): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
111
|
value = "".join(self._buffer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
112
|
self._buffer.clear() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
113
|
return value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
114
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
115
|
@contextmanager |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
116
|
def block(self, *, extra = None): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
117
|
"""A context manager for preparing the source for blocks. It adds |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
118
|
the character':', increases the indentation on enter and decreases |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
119
|
the indentation on exit. If *extra* is given, it will be directly |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
120
|
appended after the colon character. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
121
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
122
|
self.write(":") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
123
|
if extra: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
124
|
self.write(extra) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
125
|
self._indent += 1 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
126
|
yield |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
127
|
self._indent -= 1 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
128
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
129
|
@contextmanager |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
130
|
def delimit(self, start, end): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
131
|
"""A context manager for preparing the source for expressions. It adds |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
132
|
*start* to the buffer and enters, after exit it adds *end*.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
133
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
134
|
self.write(start) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
135
|
yield |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
136
|
self.write(end) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
137
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
138
|
def delimit_if(self, start, end, condition): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
139
|
if condition: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
140
|
return self.delimit(start, end) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
141
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
142
|
return nullcontext() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
143
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
144
|
def require_parens(self, precedence, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
145
|
"""Shortcut to adding precedence related parens""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
146
|
return self.delimit_if("(", ")", self.get_precedence(node) > precedence) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
147
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
148
|
def get_precedence(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
149
|
return self._precedences.get(node, _Precedence.TEST) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
150
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
151
|
def set_precedence(self, precedence, *nodes): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
152
|
for node in nodes: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
153
|
self._precedences[node] = precedence |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
154
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
155
|
def get_raw_docstring(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
156
|
"""If a docstring node is found in the body of the *node* parameter, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
157
|
return that docstring node, None otherwise. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
158
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
159
|
Logic mirrored from ``_PyAST_GetDocString``.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
160
|
if not isinstance( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
161
|
node, (ast.AsyncFunctionDef, ast.FunctionDef, ast.ClassDef, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
162
|
ast.Module) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
163
|
) or len(node.body) < 1: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
164
|
return None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
165
|
node = node.body[0] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
166
|
if not isinstance(node, ast.Expr): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
167
|
return None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
168
|
node = node.value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
169
|
if isinstance(node, ast.Constant) and isinstance(node.value, str): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
170
|
return node |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
171
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
172
|
def get_type_comment(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
173
|
comment = self._type_ignores.get(node.lineno) or node.type_comment |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
174
|
if comment is not None: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
175
|
return f" # type: {comment}" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
176
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
177
|
def traverse(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
178
|
if isinstance(node, list): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
179
|
for item in node: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
180
|
self.traverse(item) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
181
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
182
|
super().visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
183
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
184
|
def visit(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
185
|
"""Outputs a source code string that, if converted back to an ast |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
186
|
(using ast.parse) will generate an AST equivalent to *node*""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
187
|
self._source = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
188
|
self.traverse(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
189
|
return "".join(self._source) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
190
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
191
|
def _write_docstring_and_traverse_body(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
192
|
if (docstring := self.get_raw_docstring(node)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
193
|
self._write_docstring(docstring) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
194
|
self.traverse(node.body[1:]) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
195
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
196
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
197
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
198
|
def visit_Module(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
199
|
self._type_ignores = { |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
200
|
ignore.lineno: f"ignore{ignore.tag}" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
201
|
for ignore in node.type_ignores |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
202
|
} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
203
|
self._write_docstring_and_traverse_body(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
204
|
self._type_ignores.clear() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
205
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
206
|
def visit_FunctionType(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
207
|
with self.delimit("(", ")"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
208
|
self.interleave( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
209
|
lambda: self.write(", "), self.traverse, node.argtypes |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
210
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
211
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
212
|
self.write(" -> ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
213
|
self.traverse(node.returns) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
214
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
215
|
def visit_Expr(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
216
|
self.fill() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
217
|
self.set_precedence(_Precedence.YIELD, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
218
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
219
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
220
|
def visit_NamedExpr(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
221
|
with self.require_parens(_Precedence.TUPLE, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
222
|
self.set_precedence(_Precedence.ATOM, node.target, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
223
|
self.traverse(node.target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
224
|
self.write(" := ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
225
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
226
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
227
|
def visit_Import(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
228
|
self.fill("import ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
229
|
self.interleave(lambda: self.write(", "), self.traverse, node.names) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
230
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
231
|
def visit_ImportFrom(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
232
|
self.fill("from ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
233
|
self.write("." * node.level) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
234
|
if node.module: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
235
|
self.write(node.module) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
236
|
self.write(" import ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
237
|
self.interleave(lambda: self.write(", "), self.traverse, node.names) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
238
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
239
|
def visit_Assign(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
240
|
self.fill() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
241
|
for target in node.targets: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
242
|
self.traverse(target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
243
|
self.write(" = ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
244
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
245
|
if type_comment := self.get_type_comment(node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
246
|
self.write(type_comment) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
247
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
248
|
def visit_AugAssign(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
249
|
self.fill() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
250
|
self.traverse(node.target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
251
|
self.write(" " + self.binop[node.op.__class__.__name__] + "= ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
252
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
253
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
254
|
def visit_AnnAssign(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
255
|
self.fill() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
256
|
with self.delimit_if("(", ")", not node.simple and isinstance(node.target, ast.Name)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
257
|
self.traverse(node.target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
258
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
259
|
self.traverse(node.annotation) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
260
|
if node.value: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
261
|
self.write(" = ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
262
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
263
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
264
|
def visit_Return(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
265
|
self.fill("return") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
266
|
if node.value: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
267
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
268
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
269
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
270
|
def visit_Pass(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
271
|
self.fill("pass") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
272
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
273
|
def visit_Break(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
274
|
self.fill("break") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
275
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
276
|
def visit_Continue(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
277
|
self.fill("continue") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
278
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
279
|
def visit_Delete(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
280
|
self.fill("del ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
281
|
self.interleave(lambda: self.write(", "), self.traverse, node.targets) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
282
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
283
|
def visit_Assert(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
284
|
self.fill("assert ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
285
|
self.traverse(node.test) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
286
|
if node.msg: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
287
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
288
|
self.traverse(node.msg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
289
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
290
|
def visit_Global(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
291
|
self.fill("global ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
292
|
self.interleave(lambda: self.write(", "), self.write, node.names) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
293
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
294
|
def visit_Nonlocal(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
295
|
self.fill("nonlocal ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
296
|
self.interleave(lambda: self.write(", "), self.write, node.names) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
297
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
298
|
def visit_Await(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
299
|
with self.require_parens(_Precedence.AWAIT, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
300
|
self.write("await") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
301
|
if node.value: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
302
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
303
|
self.set_precedence(_Precedence.ATOM, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
304
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
305
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
306
|
def visit_Yield(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
307
|
with self.require_parens(_Precedence.YIELD, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
308
|
self.write("yield") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
309
|
if node.value: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
310
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
311
|
self.set_precedence(_Precedence.ATOM, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
312
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
313
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
314
|
def visit_YieldFrom(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
315
|
with self.require_parens(_Precedence.YIELD, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
316
|
self.write("yield from ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
317
|
if not node.value: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
318
|
raise ValueError("Node can't be used without a value attribute.") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
319
|
self.set_precedence(_Precedence.ATOM, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
320
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
321
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
322
|
def visit_Raise(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
323
|
self.fill("raise") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
324
|
if not node.exc: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
325
|
if node.cause: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
326
|
raise ValueError("Node can't use cause without an exception.") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
327
|
return |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
328
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
329
|
self.traverse(node.exc) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
330
|
if node.cause: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
331
|
self.write(" from ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
332
|
self.traverse(node.cause) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
333
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
334
|
def visit_Try(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
335
|
self.fill("try") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
336
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
337
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
338
|
for ex in node.handlers: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
339
|
self.traverse(ex) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
340
|
if node.orelse: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
341
|
self.fill("else") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
342
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
343
|
self.traverse(node.orelse) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
344
|
if node.finalbody: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
345
|
self.fill("finally") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
346
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
347
|
self.traverse(node.finalbody) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
348
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
349
|
def visit_ExceptHandler(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
350
|
self.fill("except") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
351
|
if node.type: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
352
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
353
|
self.traverse(node.type) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
354
|
if node.name: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
355
|
self.write(" as ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
356
|
self.write(node.name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
357
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
358
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
359
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
360
|
def visit_ClassDef(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
361
|
self.maybe_newline() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
362
|
for deco in node.decorator_list: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
363
|
self.fill("@") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
364
|
self.traverse(deco) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
365
|
self.fill("class " + node.name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
366
|
with self.delimit_if("(", ")", condition = node.bases or node.keywords): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
367
|
comma = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
368
|
for e in node.bases: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
369
|
if comma: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
370
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
371
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
372
|
comma = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
373
|
self.traverse(e) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
374
|
for e in node.keywords: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
375
|
if comma: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
376
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
377
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
378
|
comma = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
379
|
self.traverse(e) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
380
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
381
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
382
|
self._write_docstring_and_traverse_body(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
383
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
384
|
def visit_FunctionDef(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
385
|
self._function_helper(node, "def") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
386
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
387
|
def visit_AsyncFunctionDef(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
388
|
self._function_helper(node, "async def") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
389
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
390
|
def _function_helper(self, node, fill_suffix): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
391
|
self.maybe_newline() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
392
|
for deco in node.decorator_list: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
393
|
self.fill("@") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
394
|
self.traverse(deco) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
395
|
def_str = fill_suffix + " " + node.name |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
396
|
self.fill(def_str) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
397
|
with self.delimit("(", ")"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
398
|
self.traverse(node.args) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
399
|
if node.returns: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
400
|
self.write(" -> ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
401
|
self.traverse(node.returns) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
402
|
with self.block(extra=self.get_type_comment(node)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
403
|
self._write_docstring_and_traverse_body(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
404
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
405
|
def visit_For(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
406
|
self._for_helper("for ", node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
407
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
408
|
def visit_AsyncFor(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
409
|
self._for_helper("async for ", node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
410
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
411
|
def _for_helper(self, fill, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
412
|
self.fill(fill) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
413
|
self.traverse(node.target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
414
|
self.write(" in ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
415
|
self.traverse(node.iter) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
416
|
with self.block(extra=self.get_type_comment(node)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
417
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
418
|
if node.orelse: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
419
|
self.fill("else") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
420
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
421
|
self.traverse(node.orelse) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
422
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
423
|
def visit_If(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
424
|
self.fill("if ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
425
|
self.traverse(node.test) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
426
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
427
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
428
|
# collapse nested ifs into equivalent elifs. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
429
|
while node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], ast.If): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
430
|
node = node.orelse[0] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
431
|
self.fill("elif ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
432
|
self.traverse(node.test) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
433
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
434
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
435
|
# final else |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
436
|
if node.orelse: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
437
|
self.fill("else") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
438
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
439
|
self.traverse(node.orelse) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
440
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
441
|
def visit_While(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
442
|
self.fill("while ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
443
|
self.traverse(node.test) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
444
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
445
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
446
|
if node.orelse: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
447
|
self.fill("else") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
448
|
with self.block(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
449
|
self.traverse(node.orelse) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
450
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
451
|
def visit_With(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
452
|
self.fill("with ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
453
|
self.interleave(lambda: self.write(", "), self.traverse, node.items) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
454
|
with self.block(extra=self.get_type_comment(node)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
455
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
456
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
457
|
def visit_AsyncWith(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
458
|
self.fill("async with ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
459
|
self.interleave(lambda: self.write(", "), self.traverse, node.items) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
460
|
with self.block(extra=self.get_type_comment(node)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
461
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
462
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
463
|
def _str_literal_helper( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
464
|
self, string, *, quote_types=_ALL_QUOTES, escape_special_whitespace=False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
465
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
466
|
"""Helper for writing string literals, minimizing escapes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
467
|
Returns the tuple (string literal to write, possible quote types). |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
468
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
469
|
def escape_char(c): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
470
|
# \n and \t are non-printable, but we only escape them if |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
471
|
# escape_special_whitespace is True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
472
|
if not escape_special_whitespace and c in "\n\t": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
473
|
return c |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
474
|
# Always escape backslashes and other non-printable characters |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
475
|
if c == "\\" or not c.isprintable(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
476
|
return c.encode("unicode_escape").decode("ascii") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
477
|
return c |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
478
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
479
|
escaped_string = "".join(map(escape_char, string)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
480
|
possible_quotes = quote_types |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
481
|
if "\n" in escaped_string: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
482
|
possible_quotes = [q for q in possible_quotes if q in _MULTI_QUOTES] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
483
|
possible_quotes = [q for q in possible_quotes if q not in escaped_string] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
484
|
if not possible_quotes: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
485
|
# If there aren't any possible_quotes, fallback to using repr |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
486
|
# on the original string. Try to use a quote from quote_types, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
487
|
# e.g., so that we use triple quotes for docstrings. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
488
|
string = repr(string) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
489
|
quote = next((q for q in quote_types if string[0] in q), string[0]) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
490
|
return string[1:-1], [quote] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
491
|
if escaped_string: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
492
|
# Sort so that we prefer '''"''' over """\"""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
493
|
possible_quotes.sort(key=lambda q: q[0] == escaped_string[-1]) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
494
|
# If we're using triple quotes and we'd need to escape a final |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
495
|
# quote, escape it |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
496
|
if possible_quotes[0][0] == escaped_string[-1]: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
497
|
assert len(possible_quotes[0]) == 3 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
498
|
escaped_string = escaped_string[:-1] + "\\" + escaped_string[-1] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
499
|
return escaped_string, possible_quotes |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
500
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
501
|
def _write_str_avoiding_backslashes(self, string, *, quote_types=_ALL_QUOTES): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
502
|
"""Write string literal value with a best effort attempt to avoid backslashes.""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
503
|
string, quote_types = self._str_literal_helper(string, quote_types=quote_types) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
504
|
quote_type = quote_types[0] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
505
|
self.write(f"{quote_type}{string}{quote_type}") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
506
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
507
|
def visit_JoinedStr(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
508
|
self.write("f") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
509
|
if self._avoid_backslashes: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
510
|
self._fstring_JoinedStr(node, self.buffer_writer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
511
|
self._write_str_avoiding_backslashes(self.buffer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
512
|
return |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
513
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
514
|
# If we don't need to avoid backslashes globally (i.e., we only need |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
515
|
# to avoid them inside FormattedValues), it's cosmetically preferred |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
516
|
# to use escaped whitespace. That is, it's preferred to use backslashes |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
517
|
# for cases like: f"{x}\n". To accomplish this, we keep track of what |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
518
|
# in our buffer corresponds to FormattedValues and what corresponds to |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
519
|
# Constant parts of the f-string, and allow escapes accordingly. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
520
|
buffer = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
521
|
for value in node.values: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
522
|
meth = getattr(self, "_fstring_" + type(value).__name__) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
523
|
meth(value, self.buffer_writer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
524
|
buffer.append((self.buffer, isinstance(value, ast.Constant))) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
525
|
new_buffer = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
526
|
quote_types = _ALL_QUOTES |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
527
|
for value, is_constant in buffer: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
528
|
# Repeatedly narrow down the list of possible quote_types |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
529
|
value, quote_types = self._str_literal_helper( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
530
|
value, quote_types=quote_types, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
531
|
escape_special_whitespace=is_constant |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
532
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
533
|
new_buffer.append(value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
534
|
value = "".join(new_buffer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
535
|
quote_type = quote_types[0] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
536
|
self.write(f"{quote_type}{value}{quote_type}") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
537
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
538
|
def visit_FormattedValue(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
539
|
self.write("f") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
540
|
self._fstring_FormattedValue(node, self.buffer_writer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
541
|
self._write_str_avoiding_backslashes(self.buffer) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
542
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
543
|
def _fstring_JoinedStr(self, node, write): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
544
|
for value in node.values: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
545
|
meth = getattr(self, "_fstring_" + type(value).__name__) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
546
|
meth(value, write) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
547
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
548
|
def _fstring_Constant(self, node, write): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
549
|
if not isinstance(node.value, str): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
550
|
raise ValueError("Constants inside JoinedStr should be a string.") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
551
|
value = node.value.replace("{", "{{").replace("}", "}}") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
552
|
write(value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
553
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
554
|
def _fstring_FormattedValue(self, node, write): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
555
|
write("{") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
556
|
unparser = type(self)(_avoid_backslashes=True) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
557
|
unparser.set_precedence(_Precedence.TEST.next(), node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
558
|
expr = unparser.visit(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
559
|
if expr.startswith("{"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
560
|
write(" ") # Separate pair of opening brackets as "{ {" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
561
|
if "\\" in expr: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
562
|
raise ValueError("Unable to avoid backslash in f-string expression part") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
563
|
write(expr) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
564
|
if node.conversion != -1: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
565
|
conversion = chr(node.conversion) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
566
|
if conversion not in "sra": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
567
|
raise ValueError("Unknown f-string conversion.") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
568
|
write(f"!{conversion}") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
569
|
if node.format_spec: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
570
|
write(":") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
571
|
meth = getattr(self, "_fstring_" + type(node.format_spec).__name__) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
572
|
meth(node.format_spec, write) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
573
|
write("}") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
574
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
575
|
def visit_Name(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
576
|
self.write(node.id) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
577
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
578
|
def _write_docstring(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
579
|
self.fill() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
580
|
if node.kind == "u": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
581
|
self.write("u") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
582
|
self._write_str_avoiding_backslashes(node.value, quote_types=_MULTI_QUOTES) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
583
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
584
|
def _write_constant(self, value): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
585
|
if isinstance(value, (float, complex)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
586
|
# Substitute overflowing decimal literal for AST infinities, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
587
|
# and inf - inf for NaNs. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
588
|
self.write( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
589
|
repr(value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
590
|
.replace("inf", _INFSTR) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
591
|
.replace("nan", f"({_INFSTR}-{_INFSTR})") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
592
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
593
|
elif self._avoid_backslashes and isinstance(value, str): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
594
|
self._write_str_avoiding_backslashes(value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
595
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
596
|
self.write(repr(value)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
597
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
598
|
def visit_Constant(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
599
|
value = node.value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
600
|
if isinstance(value, tuple): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
601
|
with self.delimit("(", ")"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
602
|
self.items_view(self._write_constant, value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
603
|
elif value is ...: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
604
|
self.write("...") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
605
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
606
|
if node.kind == "u": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
607
|
self.write("u") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
608
|
self._write_constant(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
609
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
610
|
def visit_List(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
611
|
with self.delimit("[", "]"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
612
|
self.interleave(lambda: self.write(", "), self.traverse, node.elts) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
613
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
614
|
def visit_ListComp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
615
|
with self.delimit("[", "]"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
616
|
self.traverse(node.elt) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
617
|
for gen in node.generators: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
618
|
self.traverse(gen) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
619
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
620
|
def visit_GeneratorExp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
621
|
with self.delimit("(", ")"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
622
|
self.traverse(node.elt) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
623
|
for gen in node.generators: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
624
|
self.traverse(gen) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
625
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
626
|
def visit_SetComp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
627
|
with self.delimit("{", "}"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
628
|
self.traverse(node.elt) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
629
|
for gen in node.generators: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
630
|
self.traverse(gen) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
631
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
632
|
def visit_DictComp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
633
|
with self.delimit("{", "}"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
634
|
self.traverse(node.key) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
635
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
636
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
637
|
for gen in node.generators: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
638
|
self.traverse(gen) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
639
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
640
|
def visit_comprehension(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
641
|
if node.is_async: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
642
|
self.write(" async for ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
643
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
644
|
self.write(" for ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
645
|
self.set_precedence(_Precedence.TUPLE, node.target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
646
|
self.traverse(node.target) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
647
|
self.write(" in ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
648
|
self.set_precedence(_Precedence.TEST.next(), node.iter, *node.ifs) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
649
|
self.traverse(node.iter) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
650
|
for if_clause in node.ifs: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
651
|
self.write(" if ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
652
|
self.traverse(if_clause) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
653
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
654
|
def visit_IfExp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
655
|
with self.require_parens(_Precedence.TEST, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
656
|
self.set_precedence(_Precedence.TEST.next(), node.body, node.test) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
657
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
658
|
self.write(" if ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
659
|
self.traverse(node.test) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
660
|
self.write(" else ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
661
|
self.set_precedence(_Precedence.TEST, node.orelse) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
662
|
self.traverse(node.orelse) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
663
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
664
|
def visit_Set(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
665
|
if node.elts: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
666
|
with self.delimit("{", "}"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
667
|
self.interleave(lambda: self.write(", "), self.traverse, node.elts) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
668
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
669
|
# `{}` would be interpreted as a dictionary literal, and |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
670
|
# `set` might be shadowed. Thus: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
671
|
self.write('{*()}') |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
672
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
673
|
def visit_Dict(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
674
|
def write_key_value_pair(k, v): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
675
|
self.traverse(k) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
676
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
677
|
self.traverse(v) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
678
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
679
|
def write_item(item): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
680
|
k, v = item |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
681
|
if k is None: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
682
|
# for dictionary unpacking operator in dicts {**{'y': 2}} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
683
|
# see PEP 448 for details |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
684
|
self.write("**") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
685
|
self.set_precedence(_Precedence.EXPR, v) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
686
|
self.traverse(v) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
687
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
688
|
write_key_value_pair(k, v) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
689
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
690
|
with self.delimit("{", "}"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
691
|
self.interleave( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
692
|
lambda: self.write(", "), write_item, zip(node.keys, node.values) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
693
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
694
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
695
|
def visit_Tuple(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
696
|
with self.delimit("(", ")"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
697
|
self.items_view(self.traverse, node.elts) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
698
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
699
|
unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
700
|
unop_precedence = { |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
701
|
"not": _Precedence.NOT, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
702
|
"~": _Precedence.FACTOR, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
703
|
"+": _Precedence.FACTOR, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
704
|
"-": _Precedence.FACTOR, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
705
|
} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
706
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
707
|
def visit_UnaryOp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
708
|
operator = self.unop[node.op.__class__.__name__] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
709
|
operator_precedence = self.unop_precedence[operator] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
710
|
with self.require_parens(operator_precedence, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
711
|
self.write(operator) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
712
|
# factor prefixes (+, -, ~) shouldn't be seperated |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
713
|
# from the value they belong, (e.g: +1 instead of + 1) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
714
|
if operator_precedence is not _Precedence.FACTOR: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
715
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
716
|
self.set_precedence(operator_precedence, node.operand) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
717
|
self.traverse(node.operand) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
718
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
719
|
binop = { |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
720
|
"Add": "+", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
721
|
"Sub": "-", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
722
|
"Mult": "*", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
723
|
"MatMult": "@", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
724
|
"Div": "/", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
725
|
"Mod": "%", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
726
|
"LShift": "<<", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
727
|
"RShift": ">>", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
728
|
"BitOr": "|", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
729
|
"BitXor": "^", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
730
|
"BitAnd": "&", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
731
|
"FloorDiv": "//", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
732
|
"Pow": "**", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
733
|
} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
734
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
735
|
binop_precedence = { |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
736
|
"+": _Precedence.ARITH, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
737
|
"-": _Precedence.ARITH, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
738
|
"*": _Precedence.TERM, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
739
|
"@": _Precedence.TERM, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
740
|
"/": _Precedence.TERM, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
741
|
"%": _Precedence.TERM, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
742
|
"<<": _Precedence.SHIFT, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
743
|
">>": _Precedence.SHIFT, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
744
|
"|": _Precedence.BOR, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
745
|
"^": _Precedence.BXOR, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
746
|
"&": _Precedence.BAND, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
747
|
"//": _Precedence.TERM, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
748
|
"**": _Precedence.POWER, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
749
|
} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
750
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
751
|
binop_rassoc = frozenset(("**",)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
752
|
def visit_BinOp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
753
|
operator = self.binop[node.op.__class__.__name__] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
754
|
operator_precedence = self.binop_precedence[operator] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
755
|
with self.require_parens(operator_precedence, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
756
|
if operator in self.binop_rassoc: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
757
|
left_precedence = operator_precedence.next() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
758
|
right_precedence = operator_precedence |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
759
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
760
|
left_precedence = operator_precedence |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
761
|
right_precedence = operator_precedence.next() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
762
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
763
|
self.set_precedence(left_precedence, node.left) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
764
|
self.traverse(node.left) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
765
|
self.write(f" {operator} ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
766
|
self.set_precedence(right_precedence, node.right) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
767
|
self.traverse(node.right) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
768
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
769
|
cmpops = { |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
770
|
"Eq": "==", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
771
|
"NotEq": "!=", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
772
|
"Lt": "<", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
773
|
"LtE": "<=", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
774
|
"Gt": ">", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
775
|
"GtE": ">=", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
776
|
"Is": "is", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
777
|
"IsNot": "is not", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
778
|
"In": "in", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
779
|
"NotIn": "not in", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
780
|
} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
781
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
782
|
def visit_Compare(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
783
|
with self.require_parens(_Precedence.CMP, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
784
|
self.set_precedence(_Precedence.CMP.next(), node.left, *node.comparators) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
785
|
self.traverse(node.left) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
786
|
for o, e in zip(node.ops, node.comparators): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
787
|
self.write(" " + self.cmpops[o.__class__.__name__] + " ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
788
|
self.traverse(e) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
789
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
790
|
boolops = {"And": "and", "Or": "or"} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
791
|
boolop_precedence = {"and": _Precedence.AND, "or": _Precedence.OR} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
792
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
793
|
def visit_BoolOp(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
794
|
operator = self.boolops[node.op.__class__.__name__] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
795
|
operator_precedence = self.boolop_precedence[operator] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
796
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
797
|
def increasing_level_traverse(node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
798
|
nonlocal operator_precedence |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
799
|
operator_precedence = operator_precedence.next() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
800
|
self.set_precedence(operator_precedence, node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
801
|
self.traverse(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
802
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
803
|
with self.require_parens(operator_precedence, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
804
|
s = f" {operator} " |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
805
|
self.interleave(lambda: self.write(s), increasing_level_traverse, node.values) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
806
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
807
|
def visit_Attribute(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
808
|
self.set_precedence(_Precedence.ATOM, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
809
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
810
|
# Special case: 3.__abs__() is a syntax error, so if node.value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
811
|
# is an integer literal then we need to either parenthesize |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
812
|
# it or add an extra space to get 3 .__abs__(). |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
813
|
if isinstance(node.value, ast.Constant) and isinstance(node.value.value, int): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
814
|
self.write(" ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
815
|
self.write(".") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
816
|
self.write(node.attr) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
817
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
818
|
def visit_Call(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
819
|
self.set_precedence(_Precedence.ATOM, node.func) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
820
|
self.traverse(node.func) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
821
|
with self.delimit("(", ")"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
822
|
comma = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
823
|
for e in node.args: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
824
|
if comma: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
825
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
826
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
827
|
comma = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
828
|
self.traverse(e) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
829
|
for e in node.keywords: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
830
|
if comma: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
831
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
832
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
833
|
comma = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
834
|
self.traverse(e) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
835
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
836
|
def visit_Subscript(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
837
|
def is_simple_tuple(slice_value): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
838
|
# when unparsing a non-empty tuple, the parantheses can be safely |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
839
|
# omitted if there aren't any elements that explicitly requires |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
840
|
# parantheses (such as starred expressions). |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
841
|
return ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
842
|
isinstance(slice_value, ast.Tuple) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
843
|
and slice_value.elts |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
844
|
and not any(isinstance(elt, ast.Starred) for elt in slice_value.elts) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
845
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
846
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
847
|
self.set_precedence(_Precedence.ATOM, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
848
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
849
|
with self.delimit("[", "]"): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
850
|
if is_simple_tuple(node.slice): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
851
|
self.items_view(self.traverse, node.slice.elts) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
852
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
853
|
self.traverse(node.slice) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
854
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
855
|
def visit_Starred(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
856
|
self.write("*") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
857
|
self.set_precedence(_Precedence.EXPR, node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
858
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
859
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
860
|
def visit_Ellipsis(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
861
|
self.write("...") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
862
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
863
|
def visit_Slice(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
864
|
if node.lower: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
865
|
self.traverse(node.lower) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
866
|
self.write(":") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
867
|
if node.upper: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
868
|
self.traverse(node.upper) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
869
|
if node.step: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
870
|
self.write(":") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
871
|
self.traverse(node.step) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
872
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
873
|
def visit_arg(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
874
|
self.write(node.arg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
875
|
if node.annotation: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
876
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
877
|
self.traverse(node.annotation) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
878
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
879
|
def visit_arguments(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
880
|
first = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
881
|
# normal arguments |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
882
|
all_args = node.posonlyargs + node.args |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
883
|
defaults = [None] * (len(all_args) - len(node.defaults)) + node.defaults |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
884
|
for index, elements in enumerate(zip(all_args, defaults), 1): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
885
|
a, d = elements |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
886
|
if first: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
887
|
first = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
888
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
889
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
890
|
self.traverse(a) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
891
|
if d: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
892
|
self.write("=") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
893
|
self.traverse(d) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
894
|
if index == len(node.posonlyargs): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
895
|
self.write(", /") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
896
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
897
|
# varargs, or bare '*' if no varargs but keyword-only arguments present |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
898
|
if node.vararg or node.kwonlyargs: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
899
|
if first: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
900
|
first = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
901
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
902
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
903
|
self.write("*") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
904
|
if node.vararg: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
905
|
self.write(node.vararg.arg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
906
|
if node.vararg.annotation: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
907
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
908
|
self.traverse(node.vararg.annotation) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
909
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
910
|
# keyword-only arguments |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
911
|
if node.kwonlyargs: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
912
|
for a, d in zip(node.kwonlyargs, node.kw_defaults): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
913
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
914
|
self.traverse(a) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
915
|
if d: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
916
|
self.write("=") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
917
|
self.traverse(d) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
918
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
919
|
# kwargs |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
920
|
if node.kwarg: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
921
|
if first: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
922
|
first = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
923
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
924
|
self.write(", ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
925
|
self.write("**" + node.kwarg.arg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
926
|
if node.kwarg.annotation: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
927
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
928
|
self.traverse(node.kwarg.annotation) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
929
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
930
|
def visit_keyword(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
931
|
if node.arg is None: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
932
|
self.write("**") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
933
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
934
|
self.write(node.arg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
935
|
self.write("=") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
936
|
self.traverse(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
937
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
938
|
def visit_Lambda(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
939
|
with self.require_parens(_Precedence.TEST, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
940
|
self.write("lambda ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
941
|
self.traverse(node.args) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
942
|
self.write(": ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
943
|
self.set_precedence(_Precedence.TEST, node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
944
|
self.traverse(node.body) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
945
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
946
|
def visit_alias(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
947
|
self.write(node.name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
948
|
if node.asname: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
949
|
self.write(" as " + node.asname) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
950
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
951
|
def visit_withitem(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
952
|
self.traverse(node.context_expr) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
953
|
if node.optional_vars: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
954
|
self.write(" as ") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
955
|
self.traverse(node.optional_vars) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
956
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
957
|
def unparse(ast_obj): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
958
|
unparser = _Unparser() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
959
|
return unparser.visit(ast_obj) |