Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dd36a62

Browse filesBrowse files
committed
Alternative approach
1 parent 97abdc7 commit dd36a62
Copy full SHA for dd36a62

File tree

Expand file treeCollapse file tree

3 files changed

+161
-71
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+161
-71
lines changed

‎Lib/annotationlib.py

Copy file name to clipboardExpand all lines: Lib/annotationlib.py
+90-57Lines changed: 90 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Format(enum.IntEnum):
3838
"__weakref__",
3939
"__arg__",
4040
"__globals__",
41+
"__extra_names__",
4142
"__code__",
4243
"__ast_node__",
4344
"__cell__",
@@ -82,6 +83,7 @@ def __init__(
8283
# is created through __class__ assignment on a _Stringifier object.
8384
self.__globals__ = None
8485
self.__cell__ = None
86+
self.__extra_names__ = None
8587
# These are initially None but serve as a cache and may be set to a non-None
8688
# value later.
8789
self.__code__ = None
@@ -151,6 +153,8 @@ def evaluate(self, *, globals=None, locals=None, type_params=None, owner=None):
151153
if not self.__forward_is_class__ or param_name not in globals:
152154
globals[param_name] = param
153155
locals.pop(param_name, None)
156+
if self.__extra_names__:
157+
locals = {**locals, **self.__extra_names__}
154158

155159
arg = self.__forward_arg__
156160
if arg.isidentifier() and not keyword.iskeyword(arg):
@@ -274,6 +278,7 @@ def __init__(
274278
cell=None,
275279
*,
276280
stringifier_dict,
281+
extra_names=None,
277282
):
278283
# Either an AST node or a simple str (for the common case where a ForwardRef
279284
# represent a single name).
@@ -285,49 +290,61 @@ def __init__(
285290
self.__code__ = None
286291
self.__ast_node__ = node
287292
self.__globals__ = globals
293+
self.__extra_names__ = extra_names
288294
self.__cell__ = cell
289295
self.__owner__ = owner
290296
self.__stringifier_dict__ = stringifier_dict
291297

292298
def __convert_to_ast(self, other):
293299
if isinstance(other, _Stringifier):
294300
if isinstance(other.__ast_node__, str):
295-
return ast.Name(id=other.__ast_node__)
296-
return other.__ast_node__
297-
elif isinstance(other, slice):
301+
return ast.Name(id=other.__ast_node__), other.__extra_names__
302+
return other.__ast_node__, other.__extra_names__
303+
elif other is None or type(other) in (str, int, float, bool, complex):
304+
return ast.Constant(value=other), None
305+
else:
306+
name = self.__stringifier_dict__.create_unique_name()
307+
return ast.Name(id=name), {name: other}
308+
309+
def __convert_to_ast_getitem(self, other):
310+
if isinstance(other, slice):
311+
extra_names = {}
312+
313+
def conv(obj):
314+
if obj is None:
315+
return None
316+
new_obj, new_extra_names = self.__convert_to_ast(obj)
317+
if new_extra_names is not None:
318+
extra_names.update(new_extra_names)
319+
return new_obj
320+
298321
return ast.Slice(
299-
lower=(
300-
self.__convert_to_ast(other.start)
301-
if other.start is not None
302-
else None
303-
),
304-
upper=(
305-
self.__convert_to_ast(other.stop)
306-
if other.stop is not None
307-
else None
308-
),
309-
step=(
310-
self.__convert_to_ast(other.step)
311-
if other.step is not None
312-
else None
313-
),
314-
)
322+
lower=conv(other.start),
323+
upper=conv(other.stop),
324+
step=conv(other.step),
325+
), extra_names
315326
else:
316-
return ast.Constant(value=other)
327+
return self.__convert_to_ast(other)
317328

318329
def __get_ast(self):
319330
node = self.__ast_node__
320331
if isinstance(node, str):
321332
return ast.Name(id=node)
322333
return node
323334

324-
def __make_new(self, node):
335+
def __make_new(self, node, extra_names=None):
336+
new_extra_names = {}
337+
if self.__extra_names__ is not None:
338+
new_extra_names.update(self.__extra_names__)
339+
if extra_names is not None:
340+
new_extra_names.update(extra_names)
325341
stringifier = _Stringifier(
326342
node,
327343
self.__globals__,
328344
self.__owner__,
329345
self.__forward_is_class__,
330346
stringifier_dict=self.__stringifier_dict__,
347+
extra_names=new_extra_names,
331348
)
332349
self.__stringifier_dict__.stringifiers.append(stringifier)
333350
return stringifier
@@ -343,27 +360,37 @@ def __getitem__(self, other):
343360
if self.__ast_node__ == "__classdict__":
344361
raise KeyError
345362
if isinstance(other, tuple):
346-
elts = [self.__convert_to_ast(elt) for elt in other]
363+
extra_names = {}
364+
elts = []
365+
for elt in other:
366+
new_elt, new_extra_names = self.__convert_to_ast_getitem(elt)
367+
if new_extra_names is not None:
368+
extra_names.update(new_extra_names)
369+
elts.append(new_elt)
347370
other = ast.Tuple(elts)
348371
else:
349-
other = self.__convert_to_ast(other)
372+
other, extra_names = self.__convert_to_ast_getitem(other)
350373
assert isinstance(other, ast.AST), repr(other)
351-
return self.__make_new(ast.Subscript(self.__get_ast(), other))
374+
return self.__make_new(ast.Subscript(self.__get_ast(), other), extra_names)
352375

353376
def __getattr__(self, attr):
354377
return self.__make_new(ast.Attribute(self.__get_ast(), attr))
355378

356379
def __call__(self, *args, **kwargs):
357-
return self.__make_new(
358-
ast.Call(
359-
self.__get_ast(),
360-
[self.__convert_to_ast(arg) for arg in args],
361-
[
362-
ast.keyword(key, self.__convert_to_ast(value))
363-
for key, value in kwargs.items()
364-
],
365-
)
366-
)
380+
extra_names = {}
381+
ast_args = []
382+
for arg in args:
383+
new_arg, new_extra_names = self.__convert_to_ast(arg)
384+
if new_extra_names is not None:
385+
extra_names.update(new_extra_names)
386+
ast_args.append(new_arg)
387+
ast_kwargs = []
388+
for key, value in kwargs.items():
389+
new_value, new_extra_names = self.__convert_to_ast(value)
390+
if new_extra_names is not None:
391+
extra_names.update(new_extra_names)
392+
ast_kwargs.append(ast.keyword(key, new_value))
393+
return self.__make_new(ast.Call(self.__get_ast(), ast_args, ast_kwargs), extra_names)
367394

368395
def __iter__(self):
369396
yield self.__make_new(ast.Starred(self.__get_ast()))
@@ -378,8 +405,9 @@ def __format__(self, format_spec):
378405

379406
def _make_binop(op: ast.AST):
380407
def binop(self, other):
408+
rhs, extra_names = self.__convert_to_ast(other)
381409
return self.__make_new(
382-
ast.BinOp(self.__get_ast(), op, self.__convert_to_ast(other))
410+
ast.BinOp(self.__get_ast(), op, rhs), extra_names
383411
)
384412

385413
return binop
@@ -392,25 +420,19 @@ def binop(self, other):
392420
__mod__ = _make_binop(ast.Mod())
393421
__lshift__ = _make_binop(ast.LShift())
394422
__rshift__ = _make_binop(ast.RShift())
423+
__or__ = _make_binop(ast.BitOr())
395424
__xor__ = _make_binop(ast.BitXor())
396425
__and__ = _make_binop(ast.BitAnd())
397426
__floordiv__ = _make_binop(ast.FloorDiv())
398427
__pow__ = _make_binop(ast.Pow())
399428

400-
def __or__(self, other):
401-
if self.__stringifier_dict__.create_unions:
402-
return types.UnionType[self, other]
403-
404-
return self.__make_new(
405-
ast.BinOp(self.__get_ast(), ast.BitOr(), self.__convert_to_ast(other))
406-
)
407-
408429
del _make_binop
409430

410431
def _make_rbinop(op: ast.AST):
411432
def rbinop(self, other):
433+
new_other, extra_names = self.__convert_to_ast(other)
412434
return self.__make_new(
413-
ast.BinOp(self.__convert_to_ast(other), op, self.__get_ast())
435+
ast.BinOp(new_other, op, self.__get_ast()), extra_names
414436
)
415437

416438
return rbinop
@@ -423,29 +445,24 @@ def rbinop(self, other):
423445
__rmod__ = _make_rbinop(ast.Mod())
424446
__rlshift__ = _make_rbinop(ast.LShift())
425447
__rrshift__ = _make_rbinop(ast.RShift())
448+
__ror__ = _make_rbinop(ast.BitOr())
426449
__rxor__ = _make_rbinop(ast.BitXor())
427450
__rand__ = _make_rbinop(ast.BitAnd())
428451
__rfloordiv__ = _make_rbinop(ast.FloorDiv())
429452
__rpow__ = _make_rbinop(ast.Pow())
430453

431-
def __ror__(self, other):
432-
if self.__stringifier_dict__.create_unions:
433-
return types.UnionType[other, self]
434-
435-
return self.__make_new(
436-
ast.BinOp(self.__convert_to_ast(other), ast.BitOr(), self.__get_ast())
437-
)
438-
439454
del _make_rbinop
440455

441456
def _make_compare(op):
442457
def compare(self, other):
458+
rhs, extra_names = self.__convert_to_ast(other)
443459
return self.__make_new(
444460
ast.Compare(
445461
left=self.__get_ast(),
446462
ops=[op],
447-
comparators=[self.__convert_to_ast(other)],
448-
)
463+
comparators=[rhs],
464+
),
465+
extra_names,
449466
)
450467

451468
return compare
@@ -479,8 +496,9 @@ def __init__(self, namespace, globals=None, owner=None, is_class=False, create_u
479496
self.globals = globals
480497
self.owner = owner
481498
self.is_class = is_class
482-
self.create_unions = create_unions
499+
self.create_unions = False
483500
self.stringifiers = []
501+
self.next_id = 1
484502

485503
def __missing__(self, key):
486504
fwdref = _Stringifier(
@@ -493,6 +511,11 @@ def __missing__(self, key):
493511
self.stringifiers.append(fwdref)
494512
return fwdref
495513

514+
def create_unique_name(self):
515+
name = f"__annotationlib_name_{self.next_id}__"
516+
self.next_id += 1
517+
return name
518+
496519

497520
def call_evaluate_function(evaluate, format, *, owner=None):
498521
"""Call an evaluate function. Evaluate functions are normally generated for
@@ -559,9 +582,9 @@ def call_annotate_function(annotate, format, *, owner=None, _is_evaluate=False):
559582
)
560583
annos = func(Format.VALUE_WITH_FAKE_GLOBALS)
561584
if _is_evaluate:
562-
return annos if isinstance(annos, str) else repr(annos)
585+
return _stringify_single(annos)
563586
return {
564-
key: val if isinstance(val, str) else repr(val)
587+
key: _stringify_single(val)
565588
for key, val in annos.items()
566589
}
567590
elif format == Format.FORWARDREF:
@@ -640,6 +663,16 @@ def call_annotate_function(annotate, format, *, owner=None, _is_evaluate=False):
640663
raise ValueError(f"Invalid format: {format!r}")
641664

642665

666+
def _stringify_single(anno):
667+
if anno is ...:
668+
return "..."
669+
# We have to handle str specially to support PEP 563 stringified annotations.
670+
elif isinstance(anno, str):
671+
return anno
672+
else:
673+
return repr(anno)
674+
675+
643676
def get_annotate_function(obj):
644677
"""Get the __annotate__ function for an object.
645678

‎Lib/ast.py

Copy file name to clipboardExpand all lines: Lib/ast.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ def iter_fields(node):
276276
Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
277277
that is present on *node*.
278278
"""
279+
print(node)
279280
for field in node._fields:
280281
try:
281282
yield field, getattr(node, field)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.