summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJelle Zijlstra <jelle.zijlstra@gmail.com>2025-04-28 15:38:11 (GMT)
committerGitHub <noreply@github.com>2025-04-28 15:38:11 (GMT)
commit7f16f1bc114ea42ceb51ccb5008b74571a875f6b (patch)
tree65dee6fe866152bfb65f1b99d92fe852099df1e9
parent4cec0b510bfb779bc683825aa03961642b1e1549 (diff)
downloadcpython-7f16f1bc114ea42ceb51ccb5008b74571a875f6b.zip
cpython-7f16f1bc114ea42ceb51ccb5008b74571a875f6b.tar.gz
cpython-7f16f1bc114ea42ceb51ccb5008b74571a875f6b.tar.bz2
typing, annotationlib: clean tests (#133087)
- Add @cpython_only decorator to lazy import tests - Rename reference to SOURCE format - Always two newlines between test case classes - Merge two classes of ForwardRef tests - Use get_annotations instead of annotationlib.get_annotations - Format test_annotationlib with Black (not expecting that we'll keep this up but it's close to Black-formatted right now)
-rw-r--r--Lib/test/test_annotationlib.py602
-rw-r--r--Lib/test/test_typing.py80
2 files changed, 327 insertions, 355 deletions
diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py
index 0890be5..be55f04 100644
--- a/Lib/test/test_annotationlib.py
+++ b/Lib/test/test_annotationlib.py
@@ -16,12 +16,7 @@ from annotationlib import (
annotations_to_string,
type_repr,
)
-from typing import (
- Unpack,
- get_type_hints,
- List,
- Union,
-)
+from typing import Unpack, get_type_hints, List, Union
from test import support
from test.support import import_helper
@@ -64,9 +59,9 @@ class TestForwardRefFormat(unittest.TestCase):
def inner(arg: x):
pass
- anno = annotationlib.get_annotations(inner, format=Format.FORWARDREF)
+ anno = get_annotations(inner, format=Format.FORWARDREF)
fwdref = anno["arg"]
- self.assertIsInstance(fwdref, annotationlib.ForwardRef)
+ self.assertIsInstance(fwdref, ForwardRef)
self.assertEqual(fwdref.__forward_arg__, "x")
with self.assertRaises(NameError):
fwdref.evaluate()
@@ -74,17 +69,17 @@ class TestForwardRefFormat(unittest.TestCase):
x = 1
self.assertEqual(fwdref.evaluate(), x)
- anno = annotationlib.get_annotations(inner, format=Format.FORWARDREF)
+ anno = get_annotations(inner, format=Format.FORWARDREF)
self.assertEqual(anno["arg"], x)
def test_function(self):
def f(x: int, y: doesntexist):
pass
- anno = annotationlib.get_annotations(f, format=Format.FORWARDREF)
+ anno = get_annotations(f, format=Format.FORWARDREF)
self.assertIs(anno["x"], int)
fwdref = anno["y"]
- self.assertIsInstance(fwdref, annotationlib.ForwardRef)
+ self.assertIsInstance(fwdref, ForwardRef)
self.assertEqual(fwdref.__forward_arg__, "doesntexist")
with self.assertRaises(NameError):
fwdref.evaluate()
@@ -101,7 +96,7 @@ class TestForwardRefFormat(unittest.TestCase):
):
pass
- anno = annotationlib.get_annotations(f, format=Format.FORWARDREF)
+ anno = get_annotations(f, format=Format.FORWARDREF)
x_anno = anno["x"]
self.assertIsInstance(x_anno, ForwardRef)
self.assertEqual(x_anno, support.EqualToForwardRef("some.module", owner=f))
@@ -127,14 +122,14 @@ class TestForwardRefFormat(unittest.TestCase):
self.assertEqual(gamma_anno, support.EqualToForwardRef("some < obj", owner=f))
-class TestSourceFormat(unittest.TestCase):
+class TestStringFormat(unittest.TestCase):
def test_closure(self):
x = 0
def inner(arg: x):
pass
- anno = annotationlib.get_annotations(inner, format=Format.STRING)
+ anno = get_annotations(inner, format=Format.STRING)
self.assertEqual(anno, {"arg": "x"})
def test_closure_undefined(self):
@@ -144,14 +139,14 @@ class TestSourceFormat(unittest.TestCase):
def inner(arg: x):
pass
- anno = annotationlib.get_annotations(inner, format=Format.STRING)
+ anno = get_annotations(inner, format=Format.STRING)
self.assertEqual(anno, {"arg": "x"})
def test_function(self):
def f(x: int, y: doesntexist):
pass
- anno = annotationlib.get_annotations(f, format=Format.STRING)
+ anno = get_annotations(f, format=Format.STRING)
self.assertEqual(anno, {"x": "int", "y": "doesntexist"})
def test_expressions(self):
@@ -185,7 +180,7 @@ class TestSourceFormat(unittest.TestCase):
):
pass
- anno = annotationlib.get_annotations(f, format=Format.STRING)
+ anno = get_annotations(f, format=Format.STRING)
self.assertEqual(
anno,
{
@@ -236,7 +231,7 @@ class TestSourceFormat(unittest.TestCase):
):
pass
- anno = annotationlib.get_annotations(f, format=Format.STRING)
+ anno = get_annotations(f, format=Format.STRING)
self.assertEqual(
anno,
{
@@ -270,7 +265,7 @@ class TestSourceFormat(unittest.TestCase):
):
pass
- anno = annotationlib.get_annotations(f, format=Format.STRING)
+ anno = get_annotations(f, format=Format.STRING)
self.assertEqual(
anno,
{
@@ -293,125 +288,19 @@ class TestSourceFormat(unittest.TestCase):
pass
with self.assertRaisesRegex(TypeError, format_msg):
- annotationlib.get_annotations(f, format=Format.STRING)
+ get_annotations(f, format=Format.STRING)
def f(fstring_format: f"{a:02d}"):
pass
with self.assertRaisesRegex(TypeError, format_msg):
- annotationlib.get_annotations(f, format=Format.STRING)
-
-
-class TestForwardRefClass(unittest.TestCase):
- def test_special_attrs(self):
- # Forward refs provide a different introspection API. __name__ and
- # __qualname__ make little sense for forward refs as they can store
- # complex typing expressions.
- fr = annotationlib.ForwardRef("set[Any]")
- self.assertFalse(hasattr(fr, "__name__"))
- self.assertFalse(hasattr(fr, "__qualname__"))
- self.assertEqual(fr.__module__, "annotationlib")
- # Forward refs are currently unpicklable once they contain a code object.
- fr.__forward_code__ # fill the cache
- for proto in range(pickle.HIGHEST_PROTOCOL + 1):
- with self.assertRaises(TypeError):
- pickle.dumps(fr, proto)
-
- def test_evaluate_with_type_params(self):
- class Gen[T]:
- alias = int
-
- with self.assertRaises(NameError):
- ForwardRef("T").evaluate()
- with self.assertRaises(NameError):
- ForwardRef("T").evaluate(type_params=())
- with self.assertRaises(NameError):
- ForwardRef("T").evaluate(owner=int)
-
- (T,) = Gen.__type_params__
- self.assertIs(ForwardRef("T").evaluate(type_params=Gen.__type_params__), T)
- self.assertIs(ForwardRef("T").evaluate(owner=Gen), T)
-
- with self.assertRaises(NameError):
- ForwardRef("alias").evaluate(type_params=Gen.__type_params__)
- self.assertIs(ForwardRef("alias").evaluate(owner=Gen), int)
- # If you pass custom locals, we don't look at the owner's locals
- with self.assertRaises(NameError):
- ForwardRef("alias").evaluate(owner=Gen, locals={})
- # But if the name exists in the locals, it works
- self.assertIs(
- ForwardRef("alias").evaluate(owner=Gen, locals={"alias": str}), str
- )
-
- def test_fwdref_with_module(self):
- self.assertIs(ForwardRef("Format", module="annotationlib").evaluate(), Format)
- self.assertIs(
- ForwardRef("Counter", module="collections").evaluate(), collections.Counter
- )
- self.assertEqual(
- ForwardRef("Counter[int]", module="collections").evaluate(),
- collections.Counter[int],
- )
-
- with self.assertRaises(NameError):
- # If globals are passed explicitly, we don't look at the module dict
- ForwardRef("Format", module="annotationlib").evaluate(globals={})
-
- def test_fwdref_to_builtin(self):
- self.assertIs(ForwardRef("int").evaluate(), int)
- self.assertIs(ForwardRef("int", module="collections").evaluate(), int)
- self.assertIs(ForwardRef("int", owner=str).evaluate(), int)
-
- # builtins are still searched with explicit globals
- self.assertIs(ForwardRef("int").evaluate(globals={}), int)
-
- # explicit values in globals have precedence
- obj = object()
- self.assertIs(ForwardRef("int").evaluate(globals={"int": obj}), obj)
-
- def test_fwdref_value_is_not_cached(self):
- fr = ForwardRef("hello")
- with self.assertRaises(NameError):
- fr.evaluate()
- self.assertIs(fr.evaluate(globals={"hello": str}), str)
- with self.assertRaises(NameError):
- fr.evaluate()
-
- def test_fwdref_with_owner(self):
- self.assertEqual(
- ForwardRef("Counter[int]", owner=collections).evaluate(),
- collections.Counter[int],
- )
-
- def test_name_lookup_without_eval(self):
- # test the codepath where we look up simple names directly in the
- # namespaces without going through eval()
- self.assertIs(ForwardRef("int").evaluate(), int)
- self.assertIs(ForwardRef("int").evaluate(locals={"int": str}), str)
- self.assertIs(
- ForwardRef("int").evaluate(locals={"int": float}, globals={"int": str}),
- float,
- )
- self.assertIs(ForwardRef("int").evaluate(globals={"int": str}), str)
- with support.swap_attr(builtins, "int", dict):
- self.assertIs(ForwardRef("int").evaluate(), dict)
-
- with self.assertRaises(NameError):
- ForwardRef("doesntexist").evaluate()
-
- def test_fwdref_invalid_syntax(self):
- fr = ForwardRef("if")
- with self.assertRaises(SyntaxError):
- fr.evaluate()
- fr = ForwardRef("1+")
- with self.assertRaises(SyntaxError):
- fr.evaluate()
+ get_annotations(f, format=Format.STRING)
class TestGetAnnotations(unittest.TestCase):
def test_builtin_type(self):
- self.assertEqual(annotationlib.get_annotations(int), {})
- self.assertEqual(annotationlib.get_annotations(object), {})
+ self.assertEqual(get_annotations(int), {})
+ self.assertEqual(get_annotations(object), {})
def test_custom_metaclass(self):
class Meta(type):
@@ -420,7 +309,7 @@ class TestGetAnnotations(unittest.TestCase):
class C(metaclass=Meta):
x: int
- self.assertEqual(annotationlib.get_annotations(C), {"x": int})
+ self.assertEqual(get_annotations(C), {"x": int})
def test_missing_dunder_dict(self):
class NoDict(type):
@@ -433,22 +322,22 @@ class TestGetAnnotations(unittest.TestCase):
class C1(metaclass=NoDict):
a: int
- self.assertEqual(annotationlib.get_annotations(C1), {"a": int})
+ self.assertEqual(get_annotations(C1), {"a": int})
self.assertEqual(
- annotationlib.get_annotations(C1, format=Format.FORWARDREF),
+ get_annotations(C1, format=Format.FORWARDREF),
{"a": int},
)
self.assertEqual(
- annotationlib.get_annotations(C1, format=Format.STRING),
+ get_annotations(C1, format=Format.STRING),
{"a": "int"},
)
- self.assertEqual(annotationlib.get_annotations(NoDict), {"b": str})
+ self.assertEqual(get_annotations(NoDict), {"b": str})
self.assertEqual(
- annotationlib.get_annotations(NoDict, format=Format.FORWARDREF),
+ get_annotations(NoDict, format=Format.FORWARDREF),
{"b": str},
)
self.assertEqual(
- annotationlib.get_annotations(NoDict, format=Format.STRING),
+ get_annotations(NoDict, format=Format.STRING),
{"b": "str"},
)
@@ -460,53 +349,53 @@ class TestGetAnnotations(unittest.TestCase):
pass
self.assertEqual(
- annotationlib.get_annotations(f1, format=Format.VALUE),
+ get_annotations(f1, format=Format.VALUE),
{"a": int},
)
- self.assertEqual(annotationlib.get_annotations(f1, format=1), {"a": int})
+ self.assertEqual(get_annotations(f1, format=1), {"a": int})
fwd = support.EqualToForwardRef("undefined", owner=f2)
self.assertEqual(
- annotationlib.get_annotations(f2, format=Format.FORWARDREF),
+ get_annotations(f2, format=Format.FORWARDREF),
{"a": fwd},
)
- self.assertEqual(annotationlib.get_annotations(f2, format=3), {"a": fwd})
+ self.assertEqual(get_annotations(f2, format=3), {"a": fwd})
self.assertEqual(
- annotationlib.get_annotations(f1, format=Format.STRING),
+ get_annotations(f1, format=Format.STRING),
{"a": "int"},
)
- self.assertEqual(annotationlib.get_annotations(f1, format=4), {"a": "int"})
+ self.assertEqual(get_annotations(f1, format=4), {"a": "int"})
with self.assertRaises(ValueError):
- annotationlib.get_annotations(f1, format=42)
+ get_annotations(f1, format=42)
with self.assertRaisesRegex(
ValueError,
r"The VALUE_WITH_FAKE_GLOBALS format is for internal use only",
):
- annotationlib.get_annotations(f1, format=Format.VALUE_WITH_FAKE_GLOBALS)
+ get_annotations(f1, format=Format.VALUE_WITH_FAKE_GLOBALS)
with self.assertRaisesRegex(
ValueError,
r"The VALUE_WITH_FAKE_GLOBALS format is for internal use only",
):
- annotationlib.get_annotations(f1, format=2)
+ get_annotations(f1, format=2)
def test_custom_object_with_annotations(self):
class C:
def __init__(self):
self.__annotations__ = {"x": int, "y": str}
- self.assertEqual(annotationlib.get_annotations(C()), {"x": int, "y": str})
+ self.assertEqual(get_annotations(C()), {"x": int, "y": str})
def test_custom_format_eval_str(self):
def foo():
pass
with self.assertRaises(ValueError):
- annotationlib.get_annotations(foo, format=Format.FORWARDREF, eval_str=True)
- annotationlib.get_annotations(foo, format=Format.STRING, eval_str=True)
+ get_annotations(foo, format=Format.FORWARDREF, eval_str=True)
+ get_annotations(foo, format=Format.STRING, eval_str=True)
def test_stock_annotations(self):
def foo(a: int, b: str):
@@ -515,11 +404,11 @@ class TestGetAnnotations(unittest.TestCase):
for format in (Format.VALUE, Format.FORWARDREF):
with self.subTest(format=format):
self.assertEqual(
- annotationlib.get_annotations(foo, format=format),
+ get_annotations(foo, format=format),
{"a": int, "b": str},
)
self.assertEqual(
- annotationlib.get_annotations(foo, format=Format.STRING),
+ get_annotations(foo, format=Format.STRING),
{"a": "int", "b": "str"},
)
@@ -529,16 +418,16 @@ class TestGetAnnotations(unittest.TestCase):
continue
with self.subTest(format=format):
self.assertEqual(
- annotationlib.get_annotations(foo, format=format),
+ get_annotations(foo, format=format),
{"a": "foo", "b": "str"},
)
self.assertEqual(
- annotationlib.get_annotations(foo, eval_str=True, locals=locals()),
+ get_annotations(foo, eval_str=True, locals=locals()),
{"a": foo, "b": str},
)
self.assertEqual(
- annotationlib.get_annotations(foo, eval_str=True, globals=locals()),
+ get_annotations(foo, eval_str=True, globals=locals()),
{"a": foo, "b": str},
)
@@ -554,33 +443,29 @@ class TestGetAnnotations(unittest.TestCase):
{"format": Format.FORWARDREF, "eval_str": False},
]:
with self.subTest(**kwargs):
+ self.assertEqual(get_annotations(isa, **kwargs), {"a": int, "b": str})
self.assertEqual(
- annotationlib.get_annotations(isa, **kwargs), {"a": int, "b": str}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.MyClass, **kwargs),
+ get_annotations(isa.MyClass, **kwargs),
{"a": int, "b": str},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function, **kwargs),
+ get_annotations(isa.function, **kwargs),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function2, **kwargs),
+ get_annotations(isa.function2, **kwargs),
{"a": int, "b": "str", "c": isa.MyClass, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function3, **kwargs),
+ get_annotations(isa.function3, **kwargs),
{"a": "int", "b": "str", "c": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(annotationlib, **kwargs), {}
+ get_annotations(annotationlib, **kwargs), {}
) # annotations module has no annotations
+ self.assertEqual(get_annotations(isa.UnannotatedClass, **kwargs), {})
self.assertEqual(
- annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.unannotated_function, **kwargs),
+ get_annotations(isa.unannotated_function, **kwargs),
{},
)
@@ -589,68 +474,60 @@ class TestGetAnnotations(unittest.TestCase):
{"format": Format.VALUE, "eval_str": True},
]:
with self.subTest(**kwargs):
+ self.assertEqual(get_annotations(isa, **kwargs), {"a": int, "b": str})
self.assertEqual(
- annotationlib.get_annotations(isa, **kwargs), {"a": int, "b": str}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.MyClass, **kwargs),
+ get_annotations(isa.MyClass, **kwargs),
{"a": int, "b": str},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function, **kwargs),
+ get_annotations(isa.function, **kwargs),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function2, **kwargs),
+ get_annotations(isa.function2, **kwargs),
{"a": int, "b": str, "c": isa.MyClass, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function3, **kwargs),
+ get_annotations(isa.function3, **kwargs),
{"a": int, "b": str, "c": isa.MyClass},
)
+ self.assertEqual(get_annotations(annotationlib, **kwargs), {})
+ self.assertEqual(get_annotations(isa.UnannotatedClass, **kwargs), {})
self.assertEqual(
- annotationlib.get_annotations(annotationlib, **kwargs), {}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.unannotated_function, **kwargs),
+ get_annotations(isa.unannotated_function, **kwargs),
{},
)
self.assertEqual(
- annotationlib.get_annotations(isa, format=Format.STRING),
+ get_annotations(isa, format=Format.STRING),
{"a": "int", "b": "str"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.MyClass, format=Format.STRING),
+ get_annotations(isa.MyClass, format=Format.STRING),
{"a": "int", "b": "str"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function, format=Format.STRING),
+ get_annotations(isa.function, format=Format.STRING),
{"a": "int", "b": "str", "return": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function2, format=Format.STRING),
+ get_annotations(isa.function2, format=Format.STRING),
{"a": "int", "b": "str", "c": "MyClass", "return": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function3, format=Format.STRING),
+ get_annotations(isa.function3, format=Format.STRING),
{"a": "int", "b": "str", "c": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(annotationlib, format=Format.STRING),
+ get_annotations(annotationlib, format=Format.STRING),
{},
)
self.assertEqual(
- annotationlib.get_annotations(isa.UnannotatedClass, format=Format.STRING),
+ get_annotations(isa.UnannotatedClass, format=Format.STRING),
{},
)
self.assertEqual(
- annotationlib.get_annotations(
- isa.unannotated_function, format=Format.STRING
- ),
+ get_annotations(isa.unannotated_function, format=Format.STRING),
{},
)
@@ -661,23 +538,23 @@ class TestGetAnnotations(unittest.TestCase):
self.assertEqual(wrapped(1, "x"), isa.MyClass(3, "xxx"))
self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
self.assertEqual(
- annotationlib.get_annotations(wrapped),
+ get_annotations(wrapped),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(wrapped, format=Format.FORWARDREF),
+ get_annotations(wrapped, format=Format.FORWARDREF),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(wrapped, format=Format.STRING),
+ get_annotations(wrapped, format=Format.STRING),
{"a": "int", "b": "str", "return": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(wrapped, eval_str=True),
+ get_annotations(wrapped, eval_str=True),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(wrapped, eval_str=False),
+ get_annotations(wrapped, eval_str=False),
{"a": int, "b": str, "return": isa.MyClass},
)
@@ -695,30 +572,28 @@ class TestGetAnnotations(unittest.TestCase):
]:
with self.subTest(**kwargs):
self.assertEqual(
- annotationlib.get_annotations(isa, **kwargs),
+ get_annotations(isa, **kwargs),
{"a": "int", "b": "str"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.MyClass, **kwargs),
+ get_annotations(isa.MyClass, **kwargs),
{"a": "int", "b": "str"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function, **kwargs),
+ get_annotations(isa.function, **kwargs),
{"a": "int", "b": "str", "return": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function2, **kwargs),
+ get_annotations(isa.function2, **kwargs),
{"a": "int", "b": "'str'", "c": "MyClass", "return": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function3, **kwargs),
+ get_annotations(isa.function3, **kwargs),
{"a": "'int'", "b": "'str'", "c": "'MyClass'"},
)
+ self.assertEqual(get_annotations(isa.UnannotatedClass, **kwargs), {})
self.assertEqual(
- annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.unannotated_function, **kwargs),
+ get_annotations(isa.unannotated_function, **kwargs),
{},
)
@@ -727,38 +602,34 @@ class TestGetAnnotations(unittest.TestCase):
{"format": Format.VALUE, "eval_str": True},
]:
with self.subTest(**kwargs):
+ self.assertEqual(get_annotations(isa, **kwargs), {"a": int, "b": str})
self.assertEqual(
- annotationlib.get_annotations(isa, **kwargs), {"a": int, "b": str}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.MyClass, **kwargs),
+ get_annotations(isa.MyClass, **kwargs),
{"a": int, "b": str},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function, **kwargs),
+ get_annotations(isa.function, **kwargs),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function2, **kwargs),
+ get_annotations(isa.function2, **kwargs),
{"a": int, "b": "str", "c": isa.MyClass, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(isa.function3, **kwargs),
+ get_annotations(isa.function3, **kwargs),
{"a": "int", "b": "str", "c": "MyClass"},
)
+ self.assertEqual(get_annotations(isa.UnannotatedClass, **kwargs), {})
self.assertEqual(
- annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
- )
- self.assertEqual(
- annotationlib.get_annotations(isa.unannotated_function, **kwargs),
+ get_annotations(isa.unannotated_function, **kwargs),
{},
)
def test_stringized_annotations_in_empty_module(self):
isa2 = inspect_stringized_annotations_2
- self.assertEqual(annotationlib.get_annotations(isa2), {})
- self.assertEqual(annotationlib.get_annotations(isa2, eval_str=True), {})
- self.assertEqual(annotationlib.get_annotations(isa2, eval_str=False), {})
+ self.assertEqual(get_annotations(isa2), {})
+ self.assertEqual(get_annotations(isa2, eval_str=True), {})
+ self.assertEqual(get_annotations(isa2, eval_str=False), {})
def test_stringized_annotations_on_wrapper(self):
isa = inspect_stringized_annotations
@@ -766,15 +637,15 @@ class TestGetAnnotations(unittest.TestCase):
self.assertEqual(wrapped(1, "x"), isa.MyClass(3, "xxx"))
self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
self.assertEqual(
- annotationlib.get_annotations(wrapped),
+ get_annotations(wrapped),
{"a": "int", "b": "str", "return": "MyClass"},
)
self.assertEqual(
- annotationlib.get_annotations(wrapped, eval_str=True),
+ get_annotations(wrapped, eval_str=True),
{"a": int, "b": str, "return": isa.MyClass},
)
self.assertEqual(
- annotationlib.get_annotations(wrapped, eval_str=False),
+ get_annotations(wrapped, eval_str=False),
{"a": "int", "b": "str", "return": "MyClass"},
)
@@ -782,13 +653,11 @@ class TestGetAnnotations(unittest.TestCase):
isa = inspect_stringized_annotations
# test that local namespace lookups work
self.assertEqual(
- annotationlib.get_annotations(isa.MyClassWithLocalAnnotations),
+ get_annotations(isa.MyClassWithLocalAnnotations),
{"x": "mytype"},
)
self.assertEqual(
- annotationlib.get_annotations(
- isa.MyClassWithLocalAnnotations, eval_str=True
- ),
+ get_annotations(isa.MyClassWithLocalAnnotations, eval_str=True),
{"x": int},
)
@@ -796,23 +665,23 @@ class TestGetAnnotations(unittest.TestCase):
def f(x: int):
pass
- self.assertEqual(annotationlib.get_annotations(f), {"x": int})
+ self.assertEqual(get_annotations(f), {"x": int})
self.assertEqual(
- annotationlib.get_annotations(f, format=Format.FORWARDREF),
+ get_annotations(f, format=Format.FORWARDREF),
{"x": int},
)
f.__annotations__["x"] = str
# The modification is reflected in VALUE (the default)
- self.assertEqual(annotationlib.get_annotations(f), {"x": str})
+ self.assertEqual(get_annotations(f), {"x": str})
# ... and also in FORWARDREF, which tries __annotations__ if available
self.assertEqual(
- annotationlib.get_annotations(f, format=Format.FORWARDREF),
+ get_annotations(f, format=Format.FORWARDREF),
{"x": str},
)
# ... but not in STRING which always uses __annotate__
self.assertEqual(
- annotationlib.get_annotations(f, format=Format.STRING),
+ get_annotations(f, format=Format.STRING),
{"x": "int"},
)
@@ -832,7 +701,7 @@ class TestGetAnnotations(unittest.TestCase):
ValueError, r".*__annotations__ is neither a dict nor None"
),
):
- annotationlib.get_annotations(wa, format=format)
+ get_annotations(wa, format=format)
def test_annotations_on_custom_object(self):
class HasAnnotations:
@@ -841,16 +710,10 @@ class TestGetAnnotations(unittest.TestCase):
return {"x": int}
ha = HasAnnotations()
- self.assertEqual(
- annotationlib.get_annotations(ha, format=Format.VALUE), {"x": int}
- )
- self.assertEqual(
- annotationlib.get_annotations(ha, format=Format.FORWARDREF), {"x": int}
- )
+ self.assertEqual(get_annotations(ha, format=Format.VALUE), {"x": int})
+ self.assertEqual(get_annotations(ha, format=Format.FORWARDREF), {"x": int})
- self.assertEqual(
- annotationlib.get_annotations(ha, format=Format.STRING), {"x": "int"}
- )
+ self.assertEqual(get_annotations(ha, format=Format.STRING), {"x": "int"})
def test_raising_annotations_on_custom_object(self):
class HasRaisingAnnotations:
@@ -861,15 +724,13 @@ class TestGetAnnotations(unittest.TestCase):
hra = HasRaisingAnnotations()
with self.assertRaises(NameError):
- annotationlib.get_annotations(hra, format=Format.VALUE)
+ get_annotations(hra, format=Format.VALUE)
with self.assertRaises(NameError):
- annotationlib.get_annotations(hra, format=Format.FORWARDREF)
+ get_annotations(hra, format=Format.FORWARDREF)
undefined = float
- self.assertEqual(
- annotationlib.get_annotations(hra, format=Format.VALUE), {"x": float}
- )
+ self.assertEqual(get_annotations(hra, format=Format.VALUE), {"x": float})
def test_forwardref_prefers_annotations(self):
class HasBoth:
@@ -882,15 +743,9 @@ class TestGetAnnotations(unittest.TestCase):
return lambda format: {"x": str}
hb = HasBoth()
- self.assertEqual(
- annotationlib.get_annotations(hb, format=Format.VALUE), {"x": int}
- )
- self.assertEqual(
- annotationlib.get_annotations(hb, format=Format.FORWARDREF), {"x": int}
- )
- self.assertEqual(
- annotationlib.get_annotations(hb, format=Format.STRING), {"x": str}
- )
+ self.assertEqual(get_annotations(hb, format=Format.VALUE), {"x": int})
+ self.assertEqual(get_annotations(hb, format=Format.FORWARDREF), {"x": int})
+ self.assertEqual(get_annotations(hb, format=Format.STRING), {"x": str})
def test_only_annotate(self):
def f(x: int):
@@ -902,14 +757,10 @@ class TestGetAnnotations(unittest.TestCase):
return f.__annotate__
oa = OnlyAnnotate()
+ self.assertEqual(get_annotations(oa, format=Format.VALUE), {"x": int})
+ self.assertEqual(get_annotations(oa, format=Format.FORWARDREF), {"x": int})
self.assertEqual(
- annotationlib.get_annotations(oa, format=Format.VALUE), {"x": int}
- )
- self.assertEqual(
- annotationlib.get_annotations(oa, format=Format.FORWARDREF), {"x": int}
- )
- self.assertEqual(
- annotationlib.get_annotations(oa, format=Format.STRING),
+ get_annotations(oa, format=Format.STRING),
{"x": "int"},
)
@@ -927,25 +778,23 @@ class TestGetAnnotations(unittest.TestCase):
for obj in (None, 1, object(), CustomClass()):
with self.subTest(format=format, obj=obj):
with self.assertRaises(TypeError):
- annotationlib.get_annotations(obj, format=format)
+ get_annotations(obj, format=format)
# Callables and types with no annotations return an empty dict
for obj in (int, len, MyCallable()):
with self.subTest(format=format, obj=obj):
- self.assertEqual(
- annotationlib.get_annotations(obj, format=format), {}
- )
+ self.assertEqual(get_annotations(obj, format=format), {})
def test_pep695_generic_class_with_future_annotations(self):
ann_module695 = inspect_stringized_annotations_pep695
- A_annotations = annotationlib.get_annotations(ann_module695.A, eval_str=True)
+ A_annotations = get_annotations(ann_module695.A, eval_str=True)
A_type_params = ann_module695.A.__type_params__
self.assertIs(A_annotations["x"], A_type_params[0])
self.assertEqual(A_annotations["y"].__args__[0], Unpack[A_type_params[1]])
self.assertIs(A_annotations["z"].__args__[0], A_type_params[2])
def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self):
- B_annotations = annotationlib.get_annotations(
+ B_annotations = get_annotations(
inspect_stringized_annotations_pep695.B, eval_str=True
)
self.assertEqual(B_annotations, {"x": int, "y": str, "z": bytes})
@@ -954,14 +803,14 @@ class TestGetAnnotations(unittest.TestCase):
self,
):
ann_module695 = inspect_stringized_annotations_pep695
- C_annotations = annotationlib.get_annotations(ann_module695.C, eval_str=True)
+ C_annotations = get_annotations(ann_module695.C, eval_str=True)
self.assertEqual(
set(C_annotations.values()), set(ann_module695.C.__type_params__)
)
def test_pep_695_generic_function_with_future_annotations(self):
ann_module695 = inspect_stringized_annotations_pep695
- generic_func_annotations = annotationlib.get_annotations(
+ generic_func_annotations = get_annotations(
ann_module695.generic_function, eval_str=True
)
func_t_params = ann_module695.generic_function.__type_params__
@@ -978,7 +827,7 @@ class TestGetAnnotations(unittest.TestCase):
):
self.assertEqual(
set(
- annotationlib.get_annotations(
+ get_annotations(
inspect_stringized_annotations_pep695.generic_function_2,
eval_str=True,
).values()
@@ -990,7 +839,7 @@ class TestGetAnnotations(unittest.TestCase):
def test_pep_695_generic_method_with_future_annotations(self):
ann_module695 = inspect_stringized_annotations_pep695
- generic_method_annotations = annotationlib.get_annotations(
+ generic_method_annotations = get_annotations(
ann_module695.D.generic_method, eval_str=True
)
params = {
@@ -1007,7 +856,7 @@ class TestGetAnnotations(unittest.TestCase):
):
self.assertEqual(
set(
- annotationlib.get_annotations(
+ get_annotations(
inspect_stringized_annotations_pep695.D.generic_method_2,
eval_str=True,
).values()
@@ -1021,9 +870,7 @@ class TestGetAnnotations(unittest.TestCase):
self,
):
self.assertEqual(
- annotationlib.get_annotations(
- inspect_stringized_annotations_pep695.E, eval_str=True
- ),
+ get_annotations(inspect_stringized_annotations_pep695.E, eval_str=True),
{"x": str},
)
@@ -1179,7 +1026,7 @@ class TestGetAnnotateFunction(unittest.TestCase):
self.assertEqual(get_annotate_function(C)(Format.VALUE), {"a": int})
-class TestToSource(unittest.TestCase):
+class TestTypeRepr(unittest.TestCase):
def test_type_repr(self):
class Nested:
pass
@@ -1190,9 +1037,11 @@ class TestToSource(unittest.TestCase):
self.assertEqual(type_repr(int), "int")
self.assertEqual(type_repr(MyClass), f"{__name__}.MyClass")
self.assertEqual(
- type_repr(Nested), f"{__name__}.TestToSource.test_type_repr.<locals>.Nested")
+ type_repr(Nested), f"{__name__}.TestTypeRepr.test_type_repr.<locals>.Nested"
+ )
self.assertEqual(
- type_repr(nested), f"{__name__}.TestToSource.test_type_repr.<locals>.nested")
+ type_repr(nested), f"{__name__}.TestTypeRepr.test_type_repr.<locals>.nested"
+ )
self.assertEqual(type_repr(len), "len")
self.assertEqual(type_repr(type_repr), "annotationlib.type_repr")
self.assertEqual(type_repr(times_three), f"{__name__}.times_three")
@@ -1203,6 +1052,8 @@ class TestToSource(unittest.TestCase):
self.assertEqual(type_repr(Format.VALUE), repr(Format.VALUE))
self.assertEqual(type_repr(MyClass()), "my repr")
+
+class TestAnnotationsToString(unittest.TestCase):
def test_annotations_to_string(self):
self.assertEqual(annotations_to_string({}), {})
self.assertEqual(annotations_to_string({"x": int}), {"x": "int"})
@@ -1216,14 +1067,14 @@ class A:
pass
-class ForwardRefTests(unittest.TestCase):
+class TestForwardRefClass(unittest.TestCase):
def test_forwardref_instance_type_error(self):
- fr = ForwardRef('int')
+ fr = ForwardRef("int")
with self.assertRaises(TypeError):
isinstance(42, fr)
def test_forwardref_subclass_type_error(self):
- fr = ForwardRef('int')
+ fr = ForwardRef("int")
with self.assertRaises(TypeError):
issubclass(int, fr)
@@ -1232,26 +1083,27 @@ class ForwardRefTests(unittest.TestCase):
ForwardRef(1) # only `str` type is allowed
def test_forward_equality(self):
- fr = ForwardRef('int')
- self.assertEqual(fr, ForwardRef('int'))
- self.assertNotEqual(List['int'], List[int])
- self.assertNotEqual(fr, ForwardRef('int', module=__name__))
- frm = ForwardRef('int', module=__name__)
- self.assertEqual(frm, ForwardRef('int', module=__name__))
- self.assertNotEqual(frm, ForwardRef('int', module='__other_name__'))
+ fr = ForwardRef("int")
+ self.assertEqual(fr, ForwardRef("int"))
+ self.assertNotEqual(List["int"], List[int])
+ self.assertNotEqual(fr, ForwardRef("int", module=__name__))
+ frm = ForwardRef("int", module=__name__)
+ self.assertEqual(frm, ForwardRef("int", module=__name__))
+ self.assertNotEqual(frm, ForwardRef("int", module="__other_name__"))
def test_forward_equality_get_type_hints(self):
- c1 = ForwardRef('C')
- c1_gth = ForwardRef('C')
- c2 = ForwardRef('C')
- c2_gth = ForwardRef('C')
+ c1 = ForwardRef("C")
+ c1_gth = ForwardRef("C")
+ c2 = ForwardRef("C")
+ c2_gth = ForwardRef("C")
class C:
pass
+
def foo(a: c1_gth, b: c2_gth):
pass
- self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': C, 'b': C})
+ self.assertEqual(get_type_hints(foo, globals(), locals()), {"a": C, "b": C})
self.assertEqual(c1, c2)
self.assertEqual(c1, c1_gth)
self.assertEqual(c1_gth, c2_gth)
@@ -1262,40 +1114,44 @@ class ForwardRefTests(unittest.TestCase):
self.assertEqual(Union[c1, c1_gth, int], Union[c1, int])
def test_forward_equality_hash(self):
- c1 = ForwardRef('int')
- c1_gth = ForwardRef('int')
- c2 = ForwardRef('int')
- c2_gth = ForwardRef('int')
+ c1 = ForwardRef("int")
+ c1_gth = ForwardRef("int")
+ c2 = ForwardRef("int")
+ c2_gth = ForwardRef("int")
def foo(a: c1_gth, b: c2_gth):
pass
+
get_type_hints(foo, globals(), locals())
self.assertEqual(hash(c1), hash(c2))
self.assertEqual(hash(c1_gth), hash(c2_gth))
self.assertEqual(hash(c1), hash(c1_gth))
- c3 = ForwardRef('int', module=__name__)
- c4 = ForwardRef('int', module='__other_name__')
+ c3 = ForwardRef("int", module=__name__)
+ c4 = ForwardRef("int", module="__other_name__")
self.assertNotEqual(hash(c3), hash(c1))
self.assertNotEqual(hash(c3), hash(c1_gth))
self.assertNotEqual(hash(c3), hash(c4))
- self.assertEqual(hash(c3), hash(ForwardRef('int', module=__name__)))
+ self.assertEqual(hash(c3), hash(ForwardRef("int", module=__name__)))
def test_forward_equality_namespace(self):
def namespace1():
- a = ForwardRef('A')
+ a = ForwardRef("A")
+
def fun(x: a):
pass
+
get_type_hints(fun, globals(), locals())
return a
def namespace2():
- a = ForwardRef('A')
+ a = ForwardRef("A")
class A:
pass
+
def fun(x: a):
pass
@@ -1306,23 +1162,29 @@ class ForwardRefTests(unittest.TestCase):
self.assertEqual(namespace1(), namespace2())
def test_forward_repr(self):
- self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]")
- self.assertEqual(repr(List[ForwardRef('int', module='mod')]),
- "typing.List[ForwardRef('int', module='mod')]")
+ self.assertEqual(repr(List["int"]), "typing.List[ForwardRef('int')]")
+ self.assertEqual(
+ repr(List[ForwardRef("int", module="mod")]),
+ "typing.List[ForwardRef('int', module='mod')]",
+ )
def test_forward_recursion_actually(self):
def namespace1():
- a = ForwardRef('A')
+ a = ForwardRef("A")
A = a
- def fun(x: a): pass
+
+ def fun(x: a):
+ pass
ret = get_type_hints(fun, globals(), locals())
return a
def namespace2():
- a = ForwardRef('A')
+ a = ForwardRef("A")
A = a
- def fun(x: a): pass
+
+ def fun(x: a):
+ pass
ret = get_type_hints(fun, globals(), locals())
return a
@@ -1335,11 +1197,11 @@ class ForwardRefTests(unittest.TestCase):
def test_syntax_error(self):
with self.assertRaises(SyntaxError):
- typing.Generic['/T']
+ typing.Generic["/T"]
def test_delayed_syntax_error(self):
- def foo(a: 'Node[T'):
+ def foo(a: "Node[T"):
pass
with self.assertRaises(SyntaxError):
@@ -1349,10 +1211,10 @@ class ForwardRefTests(unittest.TestCase):
for form in [typing.List, typing.Set, typing.Type, typing.Deque]:
with self.subTest(form=form):
with self.assertRaises(SyntaxError):
- form['']
+ form[""]
def test_or(self):
- X = ForwardRef('X')
+ X = ForwardRef("X")
# __or__/__ror__ itself
self.assertEqual(X | "x", Union[X, "x"])
self.assertEqual("x" | X, Union["x", X])
@@ -1364,13 +1226,121 @@ class ForwardRefTests(unittest.TestCase):
self.assertIsInstance(X2, ForwardRef)
self.assertEqual(X1, X2)
+ def test_special_attrs(self):
+ # Forward refs provide a different introspection API. __name__ and
+ # __qualname__ make little sense for forward refs as they can store
+ # complex typing expressions.
+ fr = ForwardRef("set[Any]")
+ self.assertNotHasAttr(fr, "__name__")
+ self.assertNotHasAttr(fr, "__qualname__")
+ self.assertEqual(fr.__module__, "annotationlib")
+ # Forward refs are currently unpicklable once they contain a code object.
+ fr.__forward_code__ # fill the cache
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.assertRaises(TypeError):
+ pickle.dumps(fr, proto)
+
+ def test_evaluate_with_type_params(self):
+ class Gen[T]:
+ alias = int
+
+ with self.assertRaises(NameError):
+ ForwardRef("T").evaluate()
+ with self.assertRaises(NameError):
+ ForwardRef("T").evaluate(type_params=())
+ with self.assertRaises(NameError):
+ ForwardRef("T").evaluate(owner=int)
+
+ (T,) = Gen.__type_params__
+ self.assertIs(ForwardRef("T").evaluate(type_params=Gen.__type_params__), T)
+ self.assertIs(ForwardRef("T").evaluate(owner=Gen), T)
+
+ with self.assertRaises(NameError):
+ ForwardRef("alias").evaluate(type_params=Gen.__type_params__)
+ self.assertIs(ForwardRef("alias").evaluate(owner=Gen), int)
+ # If you pass custom locals, we don't look at the owner's locals
+ with self.assertRaises(NameError):
+ ForwardRef("alias").evaluate(owner=Gen, locals={})
+ # But if the name exists in the locals, it works
+ self.assertIs(
+ ForwardRef("alias").evaluate(owner=Gen, locals={"alias": str}), str
+ )
+
+ def test_fwdref_with_module(self):
+ self.assertIs(ForwardRef("Format", module="annotationlib").evaluate(), Format)
+ self.assertIs(
+ ForwardRef("Counter", module="collections").evaluate(), collections.Counter
+ )
+ self.assertEqual(
+ ForwardRef("Counter[int]", module="collections").evaluate(),
+ collections.Counter[int],
+ )
+
+ with self.assertRaises(NameError):
+ # If globals are passed explicitly, we don't look at the module dict
+ ForwardRef("Format", module="annotationlib").evaluate(globals={})
+
+ def test_fwdref_to_builtin(self):
+ self.assertIs(ForwardRef("int").evaluate(), int)
+ self.assertIs(ForwardRef("int", module="collections").evaluate(), int)
+ self.assertIs(ForwardRef("int", owner=str).evaluate(), int)
+
+ # builtins are still searched with explicit globals
+ self.assertIs(ForwardRef("int").evaluate(globals={}), int)
+
+ # explicit values in globals have precedence
+ obj = object()
+ self.assertIs(ForwardRef("int").evaluate(globals={"int": obj}), obj)
+
+ def test_fwdref_value_is_not_cached(self):
+ fr = ForwardRef("hello")
+ with self.assertRaises(NameError):
+ fr.evaluate()
+ self.assertIs(fr.evaluate(globals={"hello": str}), str)
+ with self.assertRaises(NameError):
+ fr.evaluate()
+
+ def test_fwdref_with_owner(self):
+ self.assertEqual(
+ ForwardRef("Counter[int]", owner=collections).evaluate(),
+ collections.Counter[int],
+ )
+
+ def test_name_lookup_without_eval(self):
+ # test the codepath where we look up simple names directly in the
+ # namespaces without going through eval()
+ self.assertIs(ForwardRef("int").evaluate(), int)
+ self.assertIs(ForwardRef("int").evaluate(locals={"int": str}), str)
+ self.assertIs(
+ ForwardRef("int").evaluate(locals={"int": float}, globals={"int": str}),
+ float,
+ )
+ self.assertIs(ForwardRef("int").evaluate(globals={"int": str}), str)
+ with support.swap_attr(builtins, "int", dict):
+ self.assertIs(ForwardRef("int").evaluate(), dict)
+
+ with self.assertRaises(NameError):
+ ForwardRef("doesntexist").evaluate()
+
+ def test_fwdref_invalid_syntax(self):
+ fr = ForwardRef("if")
+ with self.assertRaises(SyntaxError):
+ fr.evaluate()
+ fr = ForwardRef("1+")
+ with self.assertRaises(SyntaxError):
+ fr.evaluate()
+
class TestAnnotationLib(unittest.TestCase):
def test__all__(self):
support.check__all__(self, annotationlib)
+ @support.cpython_only
def test_lazy_imports(self):
- import_helper.ensure_lazy_imports("annotationlib", {
- "typing",
- "warnings",
- })
+ import_helper.ensure_lazy_imports(
+ "annotationlib",
+ {
+ "typing",
+ "warnings",
+ },
+ )
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 93cc2a8..8c55ba4 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -53,7 +53,10 @@ from test.support import (
captured_stderr, cpython_only, infinite_recursion, requires_docstrings, import_helper, run_code,
EqualToForwardRef,
)
-from test.typinganndata import ann_module695, mod_generics_cache, _typed_dict_helper
+from test.typinganndata import (
+ ann_module695, mod_generics_cache, _typed_dict_helper,
+ ann_module, ann_module2, ann_module3, ann_module5, ann_module6, ann_module8
+)
CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes'
@@ -377,6 +380,7 @@ class LiteralStringTests(BaseTestCase):
self.assertEqual(get_args(alias_2), (LiteralString,))
self.assertEqual(get_args(alias_3), (LiteralString,))
+
class TypeVarTests(BaseTestCase):
def test_basic_plain(self):
T = TypeVar('T')
@@ -629,7 +633,7 @@ class TypeParameterDefaultsTests(BaseTestCase):
def test_typevar(self):
T = TypeVar('T', default=int)
self.assertEqual(T.__default__, int)
- self.assertTrue(T.has_default())
+ self.assertIs(T.has_default(), True)
self.assertIsInstance(T, TypeVar)
class A(Generic[T]): ...
@@ -639,19 +643,19 @@ class TypeParameterDefaultsTests(BaseTestCase):
U = TypeVar('U')
U_None = TypeVar('U_None', default=None)
self.assertIs(U.__default__, NoDefault)
- self.assertFalse(U.has_default())
+ self.assertIs(U.has_default(), False)
self.assertIs(U_None.__default__, None)
- self.assertTrue(U_None.has_default())
+ self.assertIs(U_None.has_default(), True)
class X[T]: ...
T, = X.__type_params__
self.assertIs(T.__default__, NoDefault)
- self.assertFalse(T.has_default())
+ self.assertIs(T.has_default(), False)
def test_paramspec(self):
P = ParamSpec('P', default=(str, int))
self.assertEqual(P.__default__, (str, int))
- self.assertTrue(P.has_default())
+ self.assertIs(P.has_default(), True)
self.assertIsInstance(P, ParamSpec)
class A(Generic[P]): ...
@@ -664,19 +668,19 @@ class TypeParameterDefaultsTests(BaseTestCase):
U = ParamSpec('U')
U_None = ParamSpec('U_None', default=None)
self.assertIs(U.__default__, NoDefault)
- self.assertFalse(U.has_default())
+ self.assertIs(U.has_default(), False)
self.assertIs(U_None.__default__, None)
- self.assertTrue(U_None.has_default())
+ self.assertIs(U_None.has_default(), True)
class X[**P]: ...
P, = X.__type_params__
self.assertIs(P.__default__, NoDefault)
- self.assertFalse(P.has_default())
+ self.assertIs(P.has_default(), False)
def test_typevartuple(self):
Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]])
self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]])
- self.assertTrue(Ts.has_default())
+ self.assertIs(Ts.has_default(), True)
self.assertIsInstance(Ts, TypeVarTuple)
class A(Generic[Unpack[Ts]]): ...
@@ -762,14 +766,14 @@ class TypeParameterDefaultsTests(BaseTestCase):
U = TypeVarTuple('U')
U_None = TypeVarTuple('U_None', default=None)
self.assertIs(U.__default__, NoDefault)
- self.assertFalse(U.has_default())
+ self.assertIs(U.has_default(), False)
self.assertIs(U_None.__default__, None)
- self.assertTrue(U_None.has_default())
+ self.assertIs(U_None.has_default(), True)
class X[**Ts]: ...
Ts, = X.__type_params__
self.assertIs(Ts.__default__, NoDefault)
- self.assertFalse(Ts.has_default())
+ self.assertIs(Ts.has_default(), False)
def test_no_default_after_non_default(self):
DefaultStrT = TypeVar('DefaultStrT', default=str)
@@ -1170,7 +1174,6 @@ class GenericAliasSubstitutionTests(BaseTestCase):
)
-
class UnpackTests(BaseTestCase):
def test_accepts_single_type(self):
@@ -2186,8 +2189,8 @@ class UnionTests(BaseTestCase):
type(u)()
def test_union_generalization(self):
- self.assertFalse(Union[str, typing.Iterable[int]] == str)
- self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int])
+ self.assertNotEqual(Union[str, typing.Iterable[int]], str)
+ self.assertNotEqual(Union[str, typing.Iterable[int]], typing.Iterable[int])
self.assertIn(str, Union[str, typing.Iterable[int]].__args__)
self.assertIn(typing.Iterable[int], Union[str, typing.Iterable[int]].__args__)
@@ -2603,6 +2606,7 @@ class BaseCallableTests:
with self.assertRaisesRegex(TypeError, "few arguments for"):
C1[int]
+
class TypingCallableTests(BaseCallableTests, BaseTestCase):
Callable = typing.Callable
@@ -2780,6 +2784,7 @@ class Coordinate(Protocol):
x: int
y: int
+
@runtime_checkable
class Point(Coordinate, Protocol):
label: str
@@ -4120,12 +4125,12 @@ class ProtocolTests(BaseTestCase):
def meth(self):
pass
- self.assertTrue(P._is_protocol)
- self.assertTrue(PR._is_protocol)
- self.assertTrue(PG._is_protocol)
- self.assertFalse(P._is_runtime_protocol)
- self.assertTrue(PR._is_runtime_protocol)
- self.assertTrue(PG[int]._is_protocol)
+ self.assertIs(P._is_protocol, True)
+ self.assertIs(PR._is_protocol, True)
+ self.assertIs(PG._is_protocol, True)
+ self.assertIs(P._is_runtime_protocol, False)
+ self.assertIs(PR._is_runtime_protocol, True)
+ self.assertIs(PG[int]._is_protocol, True)
self.assertEqual(typing._get_protocol_attrs(P), {'meth'})
self.assertEqual(typing._get_protocol_attrs(PR), {'x'})
self.assertEqual(frozenset(typing._get_protocol_attrs(PG)),
@@ -5838,6 +5843,7 @@ class ClassVarTests(BaseTestCase):
with self.assertRaises(TypeError):
issubclass(int, ClassVar)
+
class FinalTests(BaseTestCase):
def test_basics(self):
@@ -6043,7 +6049,7 @@ class OverrideDecoratorTests(BaseTestCase):
instance = Child()
self.assertEqual(instance.correct, 2)
- self.assertTrue(Child.correct.fget.__override__)
+ self.assertIs(Child.correct.fget.__override__, True)
self.assertEqual(instance.wrong, 2)
self.assertNotHasAttr(Child.wrong, "__override__")
self.assertNotHasAttr(Child.wrong.fset, "__override__")
@@ -6084,9 +6090,9 @@ class OverrideDecoratorTests(BaseTestCase):
instance = WithOverride()
self.assertEqual(instance.on_top(1), 2)
- self.assertTrue(instance.on_top.__override__)
+ self.assertIs(instance.on_top.__override__, True)
self.assertEqual(instance.on_bottom(1), 3)
- self.assertTrue(instance.on_bottom.__override__)
+ self.assertIs(instance.on_bottom.__override__, True)
class CastTests(BaseTestCase):
@@ -6124,8 +6130,6 @@ class AssertTypeTests(BaseTestCase):
# We need this to make sure that `@no_type_check` respects `__module__` attr:
-from test.typinganndata import ann_module8
-
@no_type_check
class NoTypeCheck_Outer:
Inner = ann_module8.NoTypeCheck_Outer.Inner
@@ -6193,7 +6197,7 @@ class NoTypeCheckTests(BaseTestCase):
for klass in [A, A.B, A.B.C, A.D]:
with self.subTest(klass=klass):
- self.assertTrue(klass.__no_type_check__)
+ self.assertIs(klass.__no_type_check__, True)
self.assertEqual(get_type_hints(klass), {})
for not_modified in [Other, B]:
@@ -6210,19 +6214,19 @@ class NoTypeCheckTests(BaseTestCase):
@classmethod
def cl(cls, y: int) -> int: ...
- self.assertTrue(Some.st.__no_type_check__)
+ self.assertIs(Some.st.__no_type_check__, True)
self.assertEqual(get_type_hints(Some.st), {})
- self.assertTrue(Some.cl.__no_type_check__)
+ self.assertIs(Some.cl.__no_type_check__, True)
self.assertEqual(get_type_hints(Some.cl), {})
def test_no_type_check_other_module(self):
- self.assertTrue(NoTypeCheck_Outer.__no_type_check__)
+ self.assertIs(NoTypeCheck_Outer.__no_type_check__, True)
with self.assertRaises(AttributeError):
ann_module8.NoTypeCheck_Outer.__no_type_check__
with self.assertRaises(AttributeError):
ann_module8.NoTypeCheck_Outer.Inner.__no_type_check__
- self.assertTrue(NoTypeCheck_WithFunction.__no_type_check__)
+ self.assertIs(NoTypeCheck_WithFunction.__no_type_check__, True)
with self.assertRaises(AttributeError):
ann_module8.NoTypeCheck_function.__no_type_check__
@@ -6247,7 +6251,7 @@ class NoTypeCheckTests(BaseTestCase):
# Corner case: `lambda` is both an assignment and a function:
bar: Callable[[int], int] = lambda arg: arg
- self.assertTrue(A.bar.__no_type_check__)
+ self.assertIs(A.bar.__no_type_check__, True)
self.assertEqual(get_type_hints(A.bar), {})
def test_no_type_check_TypeError(self):
@@ -6334,6 +6338,7 @@ class InternalsTests(BaseTestCase):
typing._collect_parameters
self.assertEqual(cm.filename, __file__)
+ @cpython_only
def test_lazy_import(self):
import_helper.ensure_lazy_imports("typing", {
"warnings",
@@ -6449,10 +6454,6 @@ class OverloadTests(BaseTestCase):
self.assertEqual(list(get_overloads(impl)), overloads)
-from test.typinganndata import (
- ann_module, ann_module2, ann_module3, ann_module5, ann_module6,
-)
-
T_a = TypeVar('T_a')
class AwaitableWrapper(typing.Awaitable[T_a]):
@@ -6665,8 +6666,8 @@ class GetTypeHintsTests(BaseTestCase):
class NoTpCheck:
class Inn:
def __init__(self, x: 'not a type'): ...
- self.assertTrue(NoTpCheck.__no_type_check__)
- self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__)
+ self.assertIs(NoTpCheck.__no_type_check__, True)
+ self.assertIs(NoTpCheck.Inn.__init__.__no_type_check__, True)
self.assertEqual(gth(ann_module2.NTC.meth), {})
class ABase(Generic[T]):
def meth(x: int): ...
@@ -10196,6 +10197,7 @@ class ConcatenateTests(BaseTestCase):
self.assertEqual(C[Concatenate[str, P2]], Concatenate[int, str, P2])
self.assertEqual(C[...], Concatenate[int, ...])
+
class TypeGuardTests(BaseTestCase):
def test_basics(self):
TypeGuard[int] # OK