Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-119180: annotationlib: Fix __all__, other minor fixes #122365

Merged
merged 3 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions Lib/annotationlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
import sys
import types

__all__ = ["Format", "ForwardRef", "call_annotate_function", "get_annotations"]
__all__ = [
"Format",
"ForwardRef",
"call_annotate_function",
"call_evaluate_function",
"get_annotate_function",
Comment on lines +13 to +14
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two were missing. The rest of the changes in this file are just formatting.

"get_annotations",
]


class Format(enum.IntEnum):
Expand Down Expand Up @@ -421,8 +428,7 @@ def call_evaluate_function(evaluate, format, *, owner=None):
return call_annotate_function(evaluate, format, owner=owner, _is_evaluate=True)


def call_annotate_function(annotate, format, *, owner=None,
_is_evaluate=False):
def call_annotate_function(annotate, format, *, owner=None, _is_evaluate=False):
"""Call an __annotate__ function. __annotate__ functions are normally
generated by the compiler to defer the evaluation of annotations. They
can be called with any of the format arguments in the Format enum, but
Expand Down Expand Up @@ -468,8 +474,13 @@ def call_annotate_function(annotate, format, *, owner=None,
closure = tuple(new_closure)
else:
closure = None
func = types.FunctionType(annotate.__code__, globals, closure=closure,
argdefs=annotate.__defaults__, kwdefaults=annotate.__kwdefaults__)
func = types.FunctionType(
annotate.__code__,
globals,
closure=closure,
argdefs=annotate.__defaults__,
kwdefaults=annotate.__kwdefaults__,
)
annos = func(Format.VALUE)
if _is_evaluate:
return annos if isinstance(annos, str) else repr(annos)
Expand Down Expand Up @@ -523,8 +534,13 @@ def call_annotate_function(annotate, format, *, owner=None,
closure = tuple(new_closure)
else:
closure = None
func = types.FunctionType(annotate.__code__, globals, closure=closure,
argdefs=annotate.__defaults__, kwdefaults=annotate.__kwdefaults__)
func = types.FunctionType(
annotate.__code__,
globals,
closure=closure,
argdefs=annotate.__defaults__,
kwdefaults=annotate.__kwdefaults__,
)
result = func(Format.VALUE)
for obj in globals.stringifiers:
obj.__class__ = ForwardRef
Expand Down
4 changes: 1 addition & 3 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
stack(), trace() - get info about frames on the stack or in a traceback

signature() - get a Signature object for the callable

get_annotations() - safely compute an object's annotations
"""

# This module is in the public domain. No warranties.
Expand Down Expand Up @@ -142,7 +140,7 @@


import abc
from annotationlib import get_annotations
from annotationlib import get_annotations # re-exported
import ast
import dis
import collections.abc
Expand Down
67 changes: 44 additions & 23 deletions Lib/test/test_annotationlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from annotationlib import Format, get_annotations, get_annotate_function
from typing import Unpack

from test import support
from test.test_inspect import inspect_stock_annotations
from test.test_inspect import inspect_stringized_annotations
from test.test_inspect import inspect_stringized_annotations_2
Expand Down Expand Up @@ -287,7 +288,9 @@ class C1(metaclass=NoDict):
)
self.assertEqual(annotationlib.get_annotations(NoDict), {"b": str})
self.assertEqual(
annotationlib.get_annotations(NoDict, format=annotationlib.Format.FORWARDREF),
annotationlib.get_annotations(
NoDict, format=annotationlib.Format.FORWARDREF
),
{"b": str},
)
self.assertEqual(
Expand Down Expand Up @@ -675,12 +678,13 @@ def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self):
)
self.assertEqual(B_annotations, {"x": int, "y": str, "z": bytes})

def test_pep695_generic_class_with_future_annotations_name_clash_with_global_vars(self):
def test_pep695_generic_class_with_future_annotations_name_clash_with_global_vars(
self,
):
ann_module695 = inspect_stringized_annotations_pep695
C_annotations = annotationlib.get_annotations(ann_module695.C, eval_str=True)
self.assertEqual(
set(C_annotations.values()),
set(ann_module695.C.__type_params__)
set(C_annotations.values()), set(ann_module695.C.__type_params__)
)

def test_pep_695_generic_function_with_future_annotations(self):
Expand All @@ -697,17 +701,19 @@ def test_pep_695_generic_function_with_future_annotations(self):
self.assertIs(generic_func_annotations["z"].__origin__, func_t_params[2])
self.assertIs(generic_func_annotations["zz"].__origin__, func_t_params[2])

def test_pep_695_generic_function_with_future_annotations_name_clash_with_global_vars(self):
def test_pep_695_generic_function_with_future_annotations_name_clash_with_global_vars(
self,
):
self.assertEqual(
set(
annotationlib.get_annotations(
inspect_stringized_annotations_pep695.generic_function_2,
eval_str=True
eval_str=True,
).values()
),
set(
inspect_stringized_annotations_pep695.generic_function_2.__type_params__
)
),
)

def test_pep_695_generic_method_with_future_annotations(self):
Expand All @@ -721,23 +727,27 @@ def test_pep_695_generic_method_with_future_annotations(self):
}
self.assertEqual(
generic_method_annotations,
{"x": params["Foo"], "y": params["Bar"], "return": None}
{"x": params["Foo"], "y": params["Bar"], "return": None},
)

def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_vars(self):
def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_vars(
self,
):
self.assertEqual(
set(
annotationlib.get_annotations(
inspect_stringized_annotations_pep695.D.generic_method_2,
eval_str=True
eval_str=True,
).values()
),
set(
inspect_stringized_annotations_pep695.D.generic_method_2.__type_params__
)
),
)

def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_and_local_vars(self):
def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_and_local_vars(
self,
):
self.assertEqual(
annotationlib.get_annotations(
inspect_stringized_annotations_pep695.E, eval_str=True
Expand All @@ -749,20 +759,20 @@ def test_pep_695_generics_with_future_annotations_nested_in_function(self):
results = inspect_stringized_annotations_pep695.nested()

self.assertEqual(
set(results.F_annotations.values()),
set(results.F.__type_params__)
set(results.F_annotations.values()), set(results.F.__type_params__)
)
self.assertEqual(
set(results.F_meth_annotations.values()),
set(results.F.generic_method.__type_params__)
set(results.F.generic_method.__type_params__),
)
self.assertNotEqual(
set(results.F_meth_annotations.values()),
set(results.F.__type_params__)
set(results.F_meth_annotations.values()), set(results.F.__type_params__)
)
self.assertEqual(
set(results.F_meth_annotations.values()).intersection(results.F.__type_params__),
set()
set(results.F_meth_annotations.values()).intersection(
results.F.__type_params__
),
set(),
)

self.assertEqual(results.G_annotations, {"x": str})
Expand All @@ -783,7 +793,9 @@ def evaluate(format, exc=NotImplementedError):
with self.assertRaises(NameError):
annotationlib.call_evaluate_function(evaluate, annotationlib.Format.VALUE)
self.assertEqual(
annotationlib.call_evaluate_function(evaluate, annotationlib.Format.FORWARDREF),
annotationlib.call_evaluate_function(
evaluate, annotationlib.Format.FORWARDREF
),
annotationlib.ForwardRef("undefined"),
)
self.assertEqual(
Expand Down Expand Up @@ -813,12 +825,14 @@ class Y(metaclass=Meta):
self.assertEqual(get_annotate_function(Y)(Format.VALUE), {"b": float})

def test_unannotated_meta(self):
class Meta(type): pass
class Meta(type):
pass

class X(metaclass=Meta):
a: str

class Y(X): pass
class Y(X):
pass

self.assertEqual(get_annotations(Meta), {})
self.assertIs(get_annotate_function(Meta), None)
Expand Down Expand Up @@ -867,6 +881,13 @@ class D(metaclass=Meta):
self.assertEqual(get_annotations(c), c.expected_annotations)
annotate_func = get_annotate_function(c)
if c.expected_annotations:
self.assertEqual(annotate_func(Format.VALUE), c.expected_annotations)
self.assertEqual(
annotate_func(Format.VALUE), c.expected_annotations
)
else:
self.assertIs(annotate_func, None)


class TestAnnotationLib(unittest.TestCase):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only non-formatting change in this file.

def test__all__(self):
support.check__all__(self, annotationlib)
Loading