aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/dataclass_module_1.py6
-rw-r--r--Lib/test/dataclass_module_1_str.py32
-rw-r--r--Lib/test/dataclass_module_2.py6
-rw-r--r--Lib/test/dataclass_module_2_str.py32
-rw-r--r--Lib/test/dataclass_textanno.py2
-rw-r--r--Lib/test/test_annotations.py228
-rw-r--r--Lib/test/test_coroutines.py8
-rw-r--r--Lib/test/test_dataclasses.py77
-rw-r--r--Lib/test/test_dis.py38
-rw-r--r--Lib/test/test_functools.py4
-rw-r--r--Lib/test/test_grammar.py56
-rw-r--r--Lib/test/test_inspect.py52
-rw-r--r--Lib/test/test_opcodes.py2
-rw-r--r--Lib/test/test_positional_only_arg.py17
-rw-r--r--Lib/test/test_pydoc.py4
-rw-r--r--Lib/test/test_syntax.py8
-rw-r--r--Lib/test/test_types.py4
-rw-r--r--Lib/test/test_typing.py22
18 files changed, 253 insertions, 345 deletions
diff --git a/Lib/test/dataclass_module_1.py b/Lib/test/dataclass_module_1.py
index 9f0aeda67f9..87a33f8191d 100644
--- a/Lib/test/dataclass_module_1.py
+++ b/Lib/test/dataclass_module_1.py
@@ -1,3 +1,9 @@
+#from __future__ import annotations
+USING_STRINGS = False
+
+# dataclass_module_1.py and dataclass_module_1_str.py are identical
+# except only the latter uses string annotations.
+
import dataclasses
import typing
diff --git a/Lib/test/dataclass_module_1_str.py b/Lib/test/dataclass_module_1_str.py
new file mode 100644
index 00000000000..6de490b7ad7
--- /dev/null
+++ b/Lib/test/dataclass_module_1_str.py
@@ -0,0 +1,32 @@
+from __future__ import annotations
+USING_STRINGS = True
+
+# dataclass_module_1.py and dataclass_module_1_str.py are identical
+# except only the latter uses string annotations.
+
+import dataclasses
+import typing
+
+T_CV2 = typing.ClassVar[int]
+T_CV3 = typing.ClassVar
+
+T_IV2 = dataclasses.InitVar[int]
+T_IV3 = dataclasses.InitVar
+
+@dataclasses.dataclass
+class CV:
+ T_CV4 = typing.ClassVar
+ cv0: typing.ClassVar[int] = 20
+ cv1: typing.ClassVar = 30
+ cv2: T_CV2
+ cv3: T_CV3
+ not_cv4: T_CV4 # When using string annotations, this field is not recognized as a ClassVar.
+
+@dataclasses.dataclass
+class IV:
+ T_IV4 = dataclasses.InitVar
+ iv0: dataclasses.InitVar[int]
+ iv1: dataclasses.InitVar
+ iv2: T_IV2
+ iv3: T_IV3
+ not_iv4: T_IV4 # When using string annotations, this field is not recognized as an InitVar.
diff --git a/Lib/test/dataclass_module_2.py b/Lib/test/dataclass_module_2.py
index 8d120d181bd..68fb733e299 100644
--- a/Lib/test/dataclass_module_2.py
+++ b/Lib/test/dataclass_module_2.py
@@ -1,3 +1,9 @@
+#from __future__ import annotations
+USING_STRINGS = False
+
+# dataclass_module_2.py and dataclass_module_2_str.py are identical
+# except only the latter uses string annotations.
+
from dataclasses import dataclass, InitVar
from typing import ClassVar
diff --git a/Lib/test/dataclass_module_2_str.py b/Lib/test/dataclass_module_2_str.py
new file mode 100644
index 00000000000..b363d17c176
--- /dev/null
+++ b/Lib/test/dataclass_module_2_str.py
@@ -0,0 +1,32 @@
+from __future__ import annotations
+USING_STRINGS = True
+
+# dataclass_module_2.py and dataclass_module_2_str.py are identical
+# except only the latter uses string annotations.
+
+from dataclasses import dataclass, InitVar
+from typing import ClassVar
+
+T_CV2 = ClassVar[int]
+T_CV3 = ClassVar
+
+T_IV2 = InitVar[int]
+T_IV3 = InitVar
+
+@dataclass
+class CV:
+ T_CV4 = ClassVar
+ cv0: ClassVar[int] = 20
+ cv1: ClassVar = 30
+ cv2: T_CV2
+ cv3: T_CV3
+ not_cv4: T_CV4 # When using string annotations, this field is not recognized as a ClassVar.
+
+@dataclass
+class IV:
+ T_IV4 = InitVar
+ iv0: InitVar[int]
+ iv1: InitVar
+ iv2: T_IV2
+ iv3: T_IV3
+ not_iv4: T_IV4 # When using string annotations, this field is not recognized as an InitVar.
diff --git a/Lib/test/dataclass_textanno.py b/Lib/test/dataclass_textanno.py
index 589b60f0cd6..3eb6c943d4c 100644
--- a/Lib/test/dataclass_textanno.py
+++ b/Lib/test/dataclass_textanno.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import dataclasses
diff --git a/Lib/test/test_annotations.py b/Lib/test/test_annotations.py
deleted file mode 100644
index 3e6b709fb4f..00000000000
--- a/Lib/test/test_annotations.py
+++ /dev/null
@@ -1,228 +0,0 @@
-import unittest
-import sys
-from textwrap import dedent
-
-class PostponedAnnotationsTestCase(unittest.TestCase):
- template = dedent(
- """
- def f() -> {ann}:
- ...
- def g(arg: {ann}) -> None:
- ...
- async def f2() -> {ann}:
- ...
- async def g2(arg: {ann}) -> None:
- ...
- var: {ann}
- var2: {ann} = None
- """
- )
-
- def getActual(self, annotation):
- scope = {}
- exec(self.template.format(ann=annotation), {}, scope)
- func_ret_ann = scope['f'].__annotations__['return']
- func_arg_ann = scope['g'].__annotations__['arg']
- async_func_ret_ann = scope['f2'].__annotations__['return']
- async_func_arg_ann = scope['g2'].__annotations__['arg']
- var_ann1 = scope['__annotations__']['var']
- var_ann2 = scope['__annotations__']['var2']
- self.assertEqual(func_ret_ann, func_arg_ann)
- self.assertEqual(func_ret_ann, async_func_ret_ann)
- self.assertEqual(func_ret_ann, async_func_arg_ann)
- self.assertEqual(func_ret_ann, var_ann1)
- self.assertEqual(func_ret_ann, var_ann2)
- return func_ret_ann
-
- def assertAnnotationEqual(
- self, annotation, expected=None, drop_parens=False, is_tuple=False,
- ):
- actual = self.getActual(annotation)
- if expected is None:
- expected = annotation if not is_tuple else annotation[1:-1]
- if drop_parens:
- self.assertNotEqual(actual, expected)
- actual = actual.replace("(", "").replace(")", "")
-
- self.assertEqual(actual, expected)
-
- def test_annotations(self):
- eq = self.assertAnnotationEqual
- eq('...')
- eq("'some_string'")
- eq("u'some_string'")
- eq("b'\\xa3'")
- eq('Name')
- eq('None')
- eq('True')
- eq('False')
- eq('1')
- eq('1.0')
- eq('1j')
- eq('True or False')
- eq('True or False or None')
- eq('True and False')
- eq('True and False and None')
- eq('Name1 and Name2 or Name3')
- eq('Name1 and (Name2 or Name3)')
- eq('Name1 or Name2 and Name3')
- eq('(Name1 or Name2) and Name3')
- eq('Name1 and Name2 or Name3 and Name4')
- eq('Name1 or Name2 and Name3 or Name4')
- eq('a + b + (c + d)')
- eq('a * b * (c * d)')
- eq('(a ** b) ** c ** d')
- eq('v1 << 2')
- eq('1 >> v2')
- eq('1 % finished')
- eq('1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8')
- eq('not great')
- eq('not not great')
- eq('~great')
- eq('+value')
- eq('++value')
- eq('-1')
- eq('~int and not v1 ^ 123 + v2 | True')
- eq('a + (not b)')
- eq('lambda: None')
- eq('lambda arg: None')
- eq('lambda a=True: a')
- eq('lambda a, b, c=True: a')
- eq("lambda a, b, c=True, *, d=1 << v2, e='str': a")
- eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b")
- eq("lambda a, /, b, c=True, *vararg, d, e='str', **kwargs: a + b")
- eq('lambda x, /: x')
- eq('lambda x=1, /: x')
- eq('lambda x, /, y: x + y')
- eq('lambda x=1, /, y=2: x + y')
- eq('lambda x, /, y=1: x + y')
- eq('lambda x, /, y=1, *, z=3: x + y + z')
- eq('lambda x=1, /, y=2, *, z=3: x + y + z')
- eq('lambda x=1, /, y=2, *, z: x + y + z')
- eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2: x + y + z + w + l + l2')
- eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2, **kwargs: x + y + z + w + l + l2')
- eq('lambda x, /, y=1, *, z: x + y + z')
- eq('lambda x: lambda y: x + y')
- eq('1 if True else 2')
- eq('str or None if int or True else str or bytes or None')
- eq('str or None if (1 if True else 2) else str or bytes or None')
- eq("0 if not x else 1 if x > 0 else -1")
- eq("(1 if x > 0 else -1) if x else 0")
- eq("{'2.7': dead, '3.7': long_live or die_hard}")
- eq("{'2.7': dead, '3.7': long_live or die_hard, **{'3.6': verygood}}")
- eq("{**a, **b, **c}")
- eq("{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}")
- eq("{*a, *b, *c}")
- eq("({'a': 'b'}, True or False, +value, 'string', b'bytes') or None")
- eq("()")
- eq("(a,)")
- eq("(a, b)")
- eq("(a, b, c)")
- eq("(*a, *b, *c)")
- eq("[]")
- eq("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]")
- eq("[*a, *b, *c]")
- eq("{i for i in (1, 2, 3)}")
- eq("{i ** 2 for i in (1, 2, 3)}")
- eq("{i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}")
- eq("{i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)}")
- eq("[i for i in (1, 2, 3)]")
- eq("[i ** 2 for i in (1, 2, 3)]")
- eq("[i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]")
- eq("[i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)]")
- eq("(i for i in (1, 2, 3))")
- eq("(i ** 2 for i in (1, 2, 3))")
- eq("(i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))")
- eq("(i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3))")
- eq("{i: 0 for i in (1, 2, 3)}")
- eq("{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}")
- eq("[(x, y) for x, y in (a, b)]")
- eq("[(x,) for x, in (a,)]")
- eq("Python3 > Python2 > COBOL")
- eq("Life is Life")
- eq("call()")
- eq("call(arg)")
- eq("call(kwarg='hey')")
- eq("call(arg, kwarg='hey')")
- eq("call(arg, *args, another, kwarg='hey')")
- eq("call(arg, another, kwarg='hey', **kwargs, kwarg2='ho')")
- eq("lukasz.langa.pl")
- eq("call.me(maybe)")
- eq("1 .real")
- eq("1.0.real")
- eq("....__class__")
- eq("list[str]")
- eq("dict[str, int]")
- eq("set[str,]")
- eq("tuple[str, ...]")
- eq("tuple[(str, *types)]")
- eq("tuple[str, int, (str, int)]")
- eq("tuple[(*int, str, str, (str, int))]")
- eq("tuple[str, int, float, dict[str, int]]")
- eq("slice[0]")
- eq("slice[0:1]")
- eq("slice[0:1:2]")
- eq("slice[:]")
- eq("slice[:-1]")
- eq("slice[1:]")
- eq("slice[::-1]")
- eq("slice[:,]")
- eq("slice[1:2,]")
- eq("slice[1:2:3,]")
- eq("slice[1:2, 1]")
- eq("slice[1:2, 2, 3]")
- eq("slice[()]")
- eq("slice[a, b:c, d:e:f]")
- eq("slice[(x for x in a)]")
- eq('str or None if sys.version_info[0] > (3,) else str or bytes or None')
- eq("f'f-string without formatted values is just a string'")
- eq("f'{{NOT a formatted value}}'")
- eq("f'some f-string with {a} {few():.2f} {formatted.values!r}'")
- eq('''f"{f'{nested} inner'} outer"''')
- eq("f'space between opening braces: { {a for a in (1, 2, 3)}}'")
- eq("f'{(lambda x: x)}'")
- eq("f'{(None if a else lambda x: x)}'")
- eq("f'{x}'")
- eq("f'{x!r}'")
- eq("f'{x!a}'")
- eq('(yield from outside_of_generator)')
- eq('(yield)')
- eq('(yield a + b)')
- eq('await some.complicated[0].call(with_args=True or 1 is not 1)')
- eq('[x for x in (a if b else c)]')
- eq('[x for x in a if (b if c else d)]')
- eq('f(x for x in a)')
- eq('f(1, (x for x in a))')
- eq('f((x for x in a), 2)')
- eq('(((a)))', 'a')
- eq('(((a, b)))', '(a, b)')
- eq("(x := 10)")
- eq("f'{(x := 10):=10}'")
- eq("1 + 2")
- eq("1 + 2 + 3")
-
- def test_fstring_debug_annotations(self):
- # f-strings with '=' don't round trip very well, so set the expected
- # result explicitely.
- self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
- self.assertAnnotationEqual("f'{x=:}'", expected="f'x={x:}'")
- self.assertAnnotationEqual("f'{x=:.2f}'", expected="f'x={x:.2f}'")
- self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
- self.assertAnnotationEqual("f'{x=!a}'", expected="f'x={x!a}'")
- self.assertAnnotationEqual("f'{x=!s:*^20}'", expected="f'x={x!s:*^20}'")
-
- def test_infinity_numbers(self):
- inf = "1e" + repr(sys.float_info.max_10_exp + 1)
- infj = f"{inf}j"
- self.assertAnnotationEqual("1e1000", expected=inf)
- self.assertAnnotationEqual("1e1000j", expected=infj)
- self.assertAnnotationEqual("-1e1000", expected=f"-{inf}")
- self.assertAnnotationEqual("3+1e1000j", expected=f"3 + {infj}")
- self.assertAnnotationEqual("(1e1000, 1e1000j)", expected=f"({inf}, {infj})")
- self.assertAnnotationEqual("'inf'")
- self.assertAnnotationEqual("('inf', 1e1000, 'infxxx', 1e1000j)", expected=f"('inf', {inf}, 'infxxx', {infj})")
- self.assertAnnotationEqual("(1e1000, (1e1000j,))", expected=f"({inf}, ({infj},))")
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py
index 40c2eb8d232..145adb67781 100644
--- a/Lib/test/test_coroutines.py
+++ b/Lib/test/test_coroutines.py
@@ -91,6 +91,10 @@ class AsyncBadSyntaxTest(unittest.TestCase):
pass
""",
+ """async def foo(a:await something()):
+ pass
+ """,
+
"""async def foo():
def bar():
[i async for i in els]
@@ -295,6 +299,10 @@ class AsyncBadSyntaxTest(unittest.TestCase):
pass
""",
+ """async def foo(a:await b):
+ pass
+ """,
+
"""def baz():
async def foo(a=await b):
pass
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py
index 4beed69e45b..f35f466125d 100644
--- a/Lib/test/test_dataclasses.py
+++ b/Lib/test/test_dataclasses.py
@@ -9,7 +9,6 @@ import pickle
import inspect
import builtins
import unittest
-from textwrap import dedent
from unittest.mock import Mock
from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional
from typing import get_type_hints
@@ -563,17 +562,17 @@ class TestCase(unittest.TestCase):
self.assertEqual(len(the_fields), 3)
self.assertEqual(the_fields[0].name, 'x')
- self.assertEqual(the_fields[0].type, 'int')
+ self.assertEqual(the_fields[0].type, int)
self.assertFalse(hasattr(C, 'x'))
self.assertTrue (the_fields[0].init)
self.assertTrue (the_fields[0].repr)
self.assertEqual(the_fields[1].name, 'y')
- self.assertEqual(the_fields[1].type, 'str')
+ self.assertEqual(the_fields[1].type, str)
self.assertIsNone(getattr(C, 'y'))
self.assertFalse(the_fields[1].init)
self.assertTrue (the_fields[1].repr)
self.assertEqual(the_fields[2].name, 'z')
- self.assertEqual(the_fields[2].type, 'str')
+ self.assertEqual(the_fields[2].type, str)
self.assertFalse(hasattr(C, 'z'))
self.assertTrue (the_fields[2].init)
self.assertFalse(the_fields[2].repr)
@@ -759,11 +758,11 @@ class TestCase(unittest.TestCase):
def validate_class(cls):
# First, check __annotations__, even though they're not
# function annotations.
- self.assertEqual(cls.__annotations__['i'], 'int')
- self.assertEqual(cls.__annotations__['j'], 'str')
- self.assertEqual(cls.__annotations__['k'], 'F')
- self.assertEqual(cls.__annotations__['l'], 'float')
- self.assertEqual(cls.__annotations__['z'], 'complex')
+ self.assertEqual(cls.__annotations__['i'], int)
+ self.assertEqual(cls.__annotations__['j'], str)
+ self.assertEqual(cls.__annotations__['k'], F)
+ self.assertEqual(cls.__annotations__['l'], float)
+ self.assertEqual(cls.__annotations__['z'], complex)
# Verify __init__.
@@ -778,22 +777,22 @@ class TestCase(unittest.TestCase):
self.assertEqual(param.name, 'self')
param = next(params)
self.assertEqual(param.name, 'i')
- self.assertIs (param.annotation, 'int')
+ self.assertIs (param.annotation, int)
self.assertEqual(param.default, inspect.Parameter.empty)
self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD)
param = next(params)
self.assertEqual(param.name, 'j')
- self.assertIs (param.annotation, 'str')
+ self.assertIs (param.annotation, str)
self.assertEqual(param.default, inspect.Parameter.empty)
self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD)
param = next(params)
self.assertEqual(param.name, 'k')
- self.assertIs (param.annotation, 'F')
+ self.assertIs (param.annotation, F)
# Don't test for the default, since it's set to MISSING.
self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD)
param = next(params)
self.assertEqual(param.name, 'l')
- self.assertIs (param.annotation, 'float')
+ self.assertIs (param.annotation, float)
# Don't test for the default, since it's set to MISSING.
self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD)
self.assertRaises(StopIteration, next, params)
@@ -2855,6 +2854,9 @@ class TestDescriptors(unittest.TestCase):
class TestStringAnnotations(unittest.TestCase):
def test_classvar(self):
+ # Some expressions recognized as ClassVar really aren't. But
+ # if you're using string annotations, it's not an exact
+ # science.
# These tests assume that both "import typing" and "from
# typing import *" have been run in this file.
for typestr in ('ClassVar[int]',
@@ -2869,15 +2871,17 @@ class TestStringAnnotations(unittest.TestCase):
'typing. ClassVar[str]',
'typing.ClassVar [str]',
'typing.ClassVar [ str]',
- # Double stringified
- '"typing.ClassVar[int]"',
+
# Not syntactically valid, but these will
- # be treated as ClassVars.
+ # be treated as ClassVars.
'typing.ClassVar.[int]',
'typing.ClassVar+',
):
with self.subTest(typestr=typestr):
- C = dataclass(type("C", (), {"__annotations__": {"x": typestr}}))
+ @dataclass
+ class C:
+ x: typestr
+
# x is a ClassVar, so C() takes no args.
C()
@@ -2898,7 +2902,9 @@ class TestStringAnnotations(unittest.TestCase):
'typingxClassVar[str]',
):
with self.subTest(typestr=typestr):
- C = dataclass(type("C", (), {"__annotations__": {"x": typestr}}))
+ @dataclass
+ class C:
+ x: typestr
# x is not a ClassVar, so C() takes one arg.
self.assertEqual(C(10).x, 10)
@@ -2918,16 +2924,16 @@ class TestStringAnnotations(unittest.TestCase):
'dataclasses. InitVar[str]',
'dataclasses.InitVar [str]',
'dataclasses.InitVar [ str]',
- # Double stringified
- '"dataclasses.InitVar[int]"',
+
# Not syntactically valid, but these will
# be treated as InitVars.
'dataclasses.InitVar.[int]',
'dataclasses.InitVar+',
):
with self.subTest(typestr=typestr):
- C = dataclass(type("C", (), {"__annotations__": {"x": typestr}}))
-
+ @dataclass
+ class C:
+ x: typestr
# x is an InitVar, so doesn't create a member.
with self.assertRaisesRegex(AttributeError,
@@ -2941,22 +2947,30 @@ class TestStringAnnotations(unittest.TestCase):
'typing.xInitVar[int]',
):
with self.subTest(typestr=typestr):
- C = dataclass(type("C", (), {"__annotations__": {"x": typestr}}))
+ @dataclass
+ class C:
+ x: typestr
# x is not an InitVar, so there will be a member x.
self.assertEqual(C(10).x, 10)
def test_classvar_module_level_import(self):
from test import dataclass_module_1
+ from test import dataclass_module_1_str
from test import dataclass_module_2
+ from test import dataclass_module_2_str
- for m in (dataclass_module_1,
- dataclass_module_2):
+ for m in (dataclass_module_1, dataclass_module_1_str,
+ dataclass_module_2, dataclass_module_2_str,
+ ):
with self.subTest(m=m):
# There's a difference in how the ClassVars are
# interpreted when using string annotations or
# not. See the imported modules for details.
- c = m.CV(10)
+ if m.USING_STRINGS:
+ c = m.CV(10)
+ else:
+ c = m.CV()
self.assertEqual(c.cv0, 20)
@@ -2972,9 +2986,14 @@ class TestStringAnnotations(unittest.TestCase):
# not an instance field.
getattr(c, field_name)
- # iv4 is interpreted as a normal field.
- self.assertIn('not_iv4', c.__dict__)
- self.assertEqual(c.not_iv4, 4)
+ if m.USING_STRINGS:
+ # iv4 is interpreted as a normal field.
+ self.assertIn('not_iv4', c.__dict__)
+ self.assertEqual(c.not_iv4, 4)
+ else:
+ # iv4 is interpreted as an InitVar, so it
+ # won't exist on the instance.
+ self.assertNotIn('not_iv4', c.__dict__)
def test_text_annotations(self):
from test import dataclass_textanno
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 19e5c0f6335..8e36ae266b9 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -237,26 +237,28 @@ dis_annot_stmt_str = """\
2 0 SETUP_ANNOTATIONS
2 LOAD_CONST 0 (1)
4 STORE_NAME 0 (x)
- 6 LOAD_CONST 1 ('int')
- 8 LOAD_NAME 1 (__annotations__)
- 10 LOAD_CONST 2 ('x')
+ 6 LOAD_NAME 1 (int)
+ 8 LOAD_NAME 2 (__annotations__)
+ 10 LOAD_CONST 1 ('x')
12 STORE_SUBSCR
- 3 14 LOAD_CONST 3 ('fun(1)')
- 16 LOAD_NAME 1 (__annotations__)
- 18 LOAD_CONST 4 ('y')
- 20 STORE_SUBSCR
-
- 4 22 LOAD_CONST 0 (1)
- 24 LOAD_NAME 2 (lst)
- 26 LOAD_NAME 3 (fun)
- 28 LOAD_CONST 5 (0)
- 30 CALL_FUNCTION 1
- 32 STORE_SUBSCR
- 34 LOAD_NAME 4 (int)
- 36 POP_TOP
- 38 LOAD_CONST 6 (None)
- 40 RETURN_VALUE
+ 3 14 LOAD_NAME 3 (fun)
+ 16 LOAD_CONST 0 (1)
+ 18 CALL_FUNCTION 1
+ 20 LOAD_NAME 2 (__annotations__)
+ 22 LOAD_CONST 2 ('y')
+ 24 STORE_SUBSCR
+
+ 4 26 LOAD_CONST 0 (1)
+ 28 LOAD_NAME 4 (lst)
+ 30 LOAD_NAME 3 (fun)
+ 32 LOAD_CONST 3 (0)
+ 34 CALL_FUNCTION 1
+ 36 STORE_SUBSCR
+ 38 LOAD_NAME 1 (int)
+ 40 POP_TOP
+ 42 LOAD_CONST 4 (None)
+ 44 RETURN_VALUE
"""
compound_stmt_str = """\
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index caeeb2712a1..fba9281deb3 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -617,7 +617,7 @@ class TestUpdateWrapper(unittest.TestCase):
def _default_update(self):
- def f(a: int):
+ def f(a:'This is a new annotation'):
"""This is a test"""
pass
f.attr = 'This is also a test'
@@ -634,7 +634,7 @@ class TestUpdateWrapper(unittest.TestCase):
self.assertEqual(wrapper.__name__, 'f')
self.assertEqual(wrapper.__qualname__, f.__qualname__)
self.assertEqual(wrapper.attr, 'This is also a test')
- self.assertEqual(wrapper.__annotations__['a'], 'int')
+ self.assertEqual(wrapper.__annotations__['a'], 'This is a new annotation')
self.assertNotIn('b', wrapper.__annotations__)
@unittest.skipIf(sys.flags.optimize >= 2,
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index c15f10b8bc7..6f79e19a544 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -363,7 +363,7 @@ class GrammarTests(unittest.TestCase):
z = 2
def __init__(self, x):
self.x: int = x
- self.assertEqual(C.__annotations__, {'_C__foo': 'int', 's': 'str'})
+ self.assertEqual(C.__annotations__, {'_C__foo': int, 's': str})
with self.assertRaises(NameError):
class CBad:
no_such_name_defined.attr: int = 0
@@ -379,15 +379,15 @@ class GrammarTests(unittest.TestCase):
return {'__annotations__': CNS()}
class CC(metaclass=CMeta):
XX: 'ANNOT'
- self.assertEqual(CC.__annotations__['xx'], repr('ANNOT'))
+ self.assertEqual(CC.__annotations__['xx'], 'ANNOT')
def test_var_annot_module_semantics(self):
with self.assertRaises(AttributeError):
print(test.__annotations__)
self.assertEqual(ann_module.__annotations__,
- {1: 2, 'x': 'int', 'y': 'str', 'f': 'Tuple[int, int]'})
+ {1: 2, 'x': int, 'y': str, 'f': typing.Tuple[int, int]})
self.assertEqual(ann_module.M.__annotations__,
- {'123': 123, 'o': 'type'})
+ {'123': 123, 'o': type})
self.assertEqual(ann_module2.__annotations__, {})
def test_var_annot_in_module(self):
@@ -406,7 +406,7 @@ class GrammarTests(unittest.TestCase):
exec("'docstring'\n"
"__annotations__[1] = 2\n"
"x: int = 5\n", gns, lns)
- self.assertEqual(lns["__annotations__"], {1: 2, 'x': 'int'})
+ self.assertEqual(lns["__annotations__"], {1: 2, 'x': int})
with self.assertRaises(KeyError):
gns['__annotations__']
@@ -414,8 +414,8 @@ class GrammarTests(unittest.TestCase):
# tests with custom locals() and __annotations__
ns = {'__annotations__': CNS()}
exec('X: int; Z: str = "Z"; (w): complex = 1j', ns)
- self.assertEqual(ns['__annotations__']['x'], 'int')
- self.assertEqual(ns['__annotations__']['z'], 'str')
+ self.assertEqual(ns['__annotations__']['x'], int)
+ self.assertEqual(ns['__annotations__']['z'], str)
with self.assertRaises(KeyError):
ns['__annotations__']['w']
nonloc_ns = {}
@@ -429,7 +429,7 @@ class GrammarTests(unittest.TestCase):
def __getitem__(self, item):
return self._dct[item]
exec('x: int = 1', {}, CNS2())
- self.assertEqual(nonloc_ns['__annotations__']['x'], 'int')
+ self.assertEqual(nonloc_ns['__annotations__']['x'], int)
def test_var_annot_refleak(self):
# complex case: custom locals plus custom __annotations__
@@ -446,7 +446,7 @@ class GrammarTests(unittest.TestCase):
def __getitem__(self, item):
return self._dct[item]
exec('X: str', {}, CNS2())
- self.assertEqual(nonloc_ns['__annotations__']['x'], 'str')
+ self.assertEqual(nonloc_ns['__annotations__']['x'], str)
def test_var_annot_rhs(self):
ns = {}
@@ -626,46 +626,50 @@ class GrammarTests(unittest.TestCase):
# argument annotation tests
def f(x) -> list: pass
- self.assertEqual(f.__annotations__, {'return': 'list'})
+ self.assertEqual(f.__annotations__, {'return': list})
def f(x: int): pass
- self.assertEqual(f.__annotations__, {'x': 'int'})
+ self.assertEqual(f.__annotations__, {'x': int})
def f(x: int, /): pass
- self.assertEqual(f.__annotations__, {'x': 'int'})
+ self.assertEqual(f.__annotations__, {'x': int})
def f(x: int = 34, /): pass
- self.assertEqual(f.__annotations__, {'x': 'int'})
+ self.assertEqual(f.__annotations__, {'x': int})
def f(*x: str): pass
- self.assertEqual(f.__annotations__, {'x': 'str'})
+ self.assertEqual(f.__annotations__, {'x': str})
def f(**x: float): pass
- self.assertEqual(f.__annotations__, {'x': 'float'})
+ self.assertEqual(f.__annotations__, {'x': float})
+ def f(x, y: 1+2): pass
+ self.assertEqual(f.__annotations__, {'y': 3})
+ def f(x, y: 1+2, /): pass
+ self.assertEqual(f.__annotations__, {'y': 3})
def f(a, b: 1, c: 2, d): pass
- self.assertEqual(f.__annotations__, {'b': '1', 'c': '2'})
+ self.assertEqual(f.__annotations__, {'b': 1, 'c': 2})
def f(a, b: 1, /, c: 2, d): pass
- self.assertEqual(f.__annotations__, {'b': '1', 'c': '2'})
+ self.assertEqual(f.__annotations__, {'b': 1, 'c': 2})
def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6): pass
self.assertEqual(f.__annotations__,
- {'b': '1', 'c': '2', 'e': '3', 'g': '6'})
+ {'b': 1, 'c': 2, 'e': 3, 'g': 6})
def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6, h: 7, i=8, j: 9 = 10,
**k: 11) -> 12: pass
self.assertEqual(f.__annotations__,
- {'b': '1', 'c': '2', 'e': '3', 'g': '6', 'h': '7', 'j': '9',
- 'k': '11', 'return': '12'})
+ {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
+ 'k': 11, 'return': 12})
def f(a, b: 1, c: 2, d, e: 3 = 4, f: int = 5, /, *g: 6, h: 7, i=8, j: 9 = 10,
**k: 11) -> 12: pass
self.assertEqual(f.__annotations__,
- {'b': '1', 'c': '2', 'e': '3', 'f': 'int', 'g': '6', 'h': '7', 'j': '9',
- 'k': '11', 'return': '12'})
+ {'b': 1, 'c': 2, 'e': 3, 'f': int, 'g': 6, 'h': 7, 'j': 9,
+ 'k': 11, 'return': 12})
# Check for issue #20625 -- annotations mangling
class Spam:
def f(self, *, __kw: 1):
pass
class Ham(Spam): pass
- self.assertEqual(Spam.f.__annotations__, {'_Spam__kw': '1'})
- self.assertEqual(Ham.f.__annotations__, {'_Spam__kw': '1'})
+ self.assertEqual(Spam.f.__annotations__, {'_Spam__kw': 1})
+ self.assertEqual(Ham.f.__annotations__, {'_Spam__kw': 1})
# Check for SF Bug #1697248 - mixing decorators and a return annotation
def null(x): return x
@null
def f(x) -> list: pass
- self.assertEqual(f.__annotations__, {'return': 'list'})
+ self.assertEqual(f.__annotations__, {'return': list})
# Test expressions as decorators (PEP 614):
@False or null
@@ -1113,6 +1117,8 @@ class GrammarTests(unittest.TestCase):
# Not allowed at class scope
check_syntax_error(self, "class foo:yield 1")
check_syntax_error(self, "class foo:yield from ()")
+ # Check annotation refleak on SyntaxError
+ check_syntax_error(self, "def g(a:(yield)): pass")
def test_yield_in_comprehensions(self):
# Check yield in comprehensions
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 35ad0b93e7d..b32b3d37577 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -888,7 +888,7 @@ class TestClassesAndFunctions(unittest.TestCase):
self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
ann_e={'arg1' : list},
- formatted="(arg1: list)")
+ formatted='(arg1: list)')
self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
kwonlyargs_e=['arg'],
formatted='(*, arg)')
@@ -2237,8 +2237,8 @@ class TestSignatureObject(unittest.TestCase):
pass
self.assertEqual(self.signature(test),
((('a', ..., ..., "positional_or_keyword"),
- ('b', ..., repr('foo'), "positional_or_keyword")),
- '123'))
+ ('b', ..., 'foo', "positional_or_keyword")),
+ 123))
def test_signature_on_wkwonly(self):
def test(*, a:float, b:str) -> int:
@@ -2253,11 +2253,11 @@ class TestSignatureObject(unittest.TestCase):
pass
self.assertEqual(self.signature(test),
((('a', ..., ..., "positional_or_keyword"),
- ('b', 10, repr('foo'), "positional_or_keyword"),
- ('args', ..., repr('bar'), "var_positional"),
- ('spam', ..., repr('baz'), "keyword_only"),
+ ('b', 10, 'foo', "positional_or_keyword"),
+ ('args', ..., 'bar', "var_positional"),
+ ('spam', ..., 'baz', "keyword_only"),
('ham', 123, ..., "keyword_only"),
- ('kwargs', ..., 'int', "var_keyword")),
+ ('kwargs', ..., int, "var_keyword")),
...))
def test_signature_without_self(self):
@@ -2666,12 +2666,12 @@ class TestSignatureObject(unittest.TestCase):
self.assertEqual(self.signature(partial(partial(test, 1))),
((('b', ..., ..., "positional_or_keyword"),
- ('c', ..., 'int', "positional_or_keyword")),
- '42'))
+ ('c', ..., int, "positional_or_keyword")),
+ 42))
self.assertEqual(self.signature(partial(partial(test, 1), 2)),
- ((('c', ..., 'int', "positional_or_keyword"),),
- '42'))
+ ((('c', ..., int, "positional_or_keyword"),),
+ 42))
psig = inspect.signature(partial(partial(test, 1), 2))
@@ -2790,12 +2790,12 @@ class TestSignatureObject(unittest.TestCase):
((('it', ..., ..., 'positional_or_keyword'),
('a', ..., ..., 'positional_or_keyword'),
('c', 1, ..., 'keyword_only')),
- repr('spam')))
+ 'spam'))
self.assertEqual(self.signature(Spam().ham),
((('a', ..., ..., 'positional_or_keyword'),
('c', 1, ..., 'keyword_only')),
- repr('spam')))
+ 'spam'))
class Spam:
def test(self: 'anno', x):
@@ -2804,7 +2804,7 @@ class TestSignatureObject(unittest.TestCase):
g = partialmethod(test, 1)
self.assertEqual(self.signature(Spam.g),
- ((('self', ..., repr('anno'), 'positional_or_keyword'),),
+ ((('self', ..., 'anno', 'positional_or_keyword'),),
...))
def test_signature_on_fake_partialmethod(self):
@@ -3142,16 +3142,20 @@ class TestSignatureObject(unittest.TestCase):
with self.assertRaisesRegex(TypeError, 'unhashable type'):
hash(inspect.signature(foo))
+ def foo(a) -> {}: pass
+ with self.assertRaisesRegex(TypeError, 'unhashable type'):
+ hash(inspect.signature(foo))
+
def test_signature_str(self):
def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
pass
self.assertEqual(str(inspect.signature(foo)),
- '(a: \'int\' = 1, *, b, c=None, **kwargs) -> \'42\'')
+ '(a: int = 1, *, b, c=None, **kwargs) -> 42')
def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
pass
self.assertEqual(str(inspect.signature(foo)),
- '(a: \'int\' = 1, *args, b, c=None, **kwargs) -> \'42\'')
+ '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
def foo():
pass
@@ -3194,8 +3198,8 @@ class TestSignatureObject(unittest.TestCase):
self.assertIs(sig.return_annotation, None)
sig = sig.replace(return_annotation=sig.empty)
self.assertIs(sig.return_annotation, sig.empty)
- sig = sig.replace(return_annotation='42')
- self.assertEqual(sig.return_annotation, '42')
+ sig = sig.replace(return_annotation=42)
+ self.assertEqual(sig.return_annotation, 42)
self.assertEqual(sig, inspect.signature(test))
def test_signature_on_mangled_parameters(self):
@@ -3207,8 +3211,8 @@ class TestSignatureObject(unittest.TestCase):
self.assertEqual(self.signature(Spam.foo),
((('self', ..., ..., "positional_or_keyword"),
- ('_Spam__p1', 2, '1', "positional_or_keyword"),
- ('_Spam__p2', 3, '2', "keyword_only")),
+ ('_Spam__p1', 2, 1, "positional_or_keyword"),
+ ('_Spam__p2', 3, 2, "keyword_only")),
...))
self.assertEqual(self.signature(Spam.foo),
@@ -3253,13 +3257,13 @@ class TestSignatureObject(unittest.TestCase):
def test_signature_annotations_with_local_namespaces(self):
class Foo: ...
def func(foo: Foo) -> int: pass
- def func2(foo: Foo, bar: Bar) -> int: pass
+ def func2(foo: Foo, bar: 'Bar') -> int: pass
for signature_func in (inspect.signature, inspect.Signature.from_callable):
with self.subTest(signature_func = signature_func):
sig1 = signature_func(func)
- self.assertEqual(sig1.return_annotation, 'int')
- self.assertEqual(sig1.parameters['foo'].annotation, 'Foo')
+ self.assertEqual(sig1.return_annotation, int)
+ self.assertEqual(sig1.parameters['foo'].annotation, Foo)
sig2 = signature_func(func, localns=locals())
self.assertEqual(sig2.return_annotation, int)
@@ -3268,7 +3272,7 @@ class TestSignatureObject(unittest.TestCase):
sig3 = signature_func(func2, globalns={'Bar': int}, localns=locals())
self.assertEqual(sig3.return_annotation, int)
self.assertEqual(sig3.parameters['foo'].annotation, Foo)
- self.assertEqual(sig3.parameters['bar'].annotation, int)
+ self.assertEqual(sig3.parameters['bar'].annotation, 'Bar')
class TestParameterObject(unittest.TestCase):
diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py
index 4be78a4e62b..d43a8303b17 100644
--- a/Lib/test/test_opcodes.py
+++ b/Lib/test/test_opcodes.py
@@ -39,7 +39,7 @@ class OpcodeTest(unittest.TestCase):
def test_use_existing_annotations(self):
ns = {'__annotations__': {1: 2}}
exec('x: int', ns)
- self.assertEqual(ns['__annotations__'], {'x': 'int', 1: 2})
+ self.assertEqual(ns['__annotations__'], {'x': int, 1: 2})
def test_do_not_recreate_annotations(self):
# Don't rely on the existence of the '__annotations__' global.
diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py
index 1fe8256d46e..0a9503e2025 100644
--- a/Lib/test/test_positional_only_arg.py
+++ b/Lib/test/test_positional_only_arg.py
@@ -302,14 +302,14 @@ class PositionalOnlyTestCase(unittest.TestCase):
def f(x: int, /): ...
return f
- assert inner_has_pos_only().__annotations__ == {'x': 'int'}
+ assert inner_has_pos_only().__annotations__ == {'x': int}
class Something:
def method(self):
def f(x: int, /): ...
return f
- assert Something().method().__annotations__ == {'x': 'int'}
+ assert Something().method().__annotations__ == {'x': int}
def multiple_levels():
def inner_has_pos_only():
@@ -317,7 +317,7 @@ class PositionalOnlyTestCase(unittest.TestCase):
return f
return inner_has_pos_only()
- assert multiple_levels().__annotations__ == {'x': 'int'}
+ assert multiple_levels().__annotations__ == {'x': int}
def test_same_keyword_as_positional_with_kwargs(self):
def f(something,/,**kwargs):
@@ -429,6 +429,17 @@ class PositionalOnlyTestCase(unittest.TestCase):
self.assertEqual(C().method(), sentinel)
+ def test_annotations_constant_fold(self):
+ def g():
+ def f(x: not (int is int), /): ...
+
+ # without constant folding we end up with
+ # COMPARE_OP(is), IS_OP (0)
+ # with constant folding we should expect a IS_OP (1)
+ codes = [(i.opname, i.argval) for i in dis.get_instructions(g)]
+ self.assertNotIn(('UNARY_NOT', None), codes)
+ self.assertIn(('IS_OP', 1), codes)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 9bde0c75bc9..c862a805bbc 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -81,7 +81,7 @@ CLASSES
|\x20\x20
| NO_MEANING = 'eggs'
|\x20\x20
- | __annotations__ = {'NO_MEANING': 'str'}
+ | __annotations__ = {'NO_MEANING': <class 'str'>}
\x20\x20\x20\x20
class C(builtins.object)
| Methods defined here:
@@ -194,7 +194,7 @@ Data descriptors defined here:<br>
Data and other attributes defined here:<br>
<dl><dt><strong>NO_MEANING</strong> = 'eggs'</dl>
-<dl><dt><strong>__annotations__</strong> = {'NO_MEANING': 'str'}</dl>
+<dl><dt><strong>__annotations__</strong> = {'NO_MEANING': &lt;class 'str'&gt;}</dl>
</td></tr></table> <p>
<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 4d8198e5db6..5f622b092f9 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -1018,6 +1018,14 @@ Corner-cases that used to fail to raise the correct error:
Traceback (most recent call last):
SyntaxError: cannot assign to __debug__
+ >>> def f(*args:(lambda __debug__:0)): pass
+ Traceback (most recent call last):
+ SyntaxError: cannot assign to __debug__
+
+ >>> def f(**kwargs:(lambda __debug__:0)): pass
+ Traceback (most recent call last):
+ SyntaxError: cannot assign to __debug__
+
>>> with (lambda *:0): pass
Traceback (most recent call last):
SyntaxError: named arguments must follow bare *
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index d8a48ce36f6..25ebec5fa55 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -671,8 +671,8 @@ class TypesTests(unittest.TestCase):
ForwardBefore = 'Forward' | T
def forward_after(x: ForwardAfter[int]) -> None: ...
def forward_before(x: ForwardBefore[int]) -> None: ...
- assert typing.get_args(typing.get_type_hints(forward_after, localns=locals())['x']) == (int, Forward)
- assert typing.get_args(typing.get_type_hints(forward_before, localns=locals())['x']) == (int, Forward)
+ assert typing.get_args(typing.get_type_hints(forward_after)['x']) == (int, Forward)
+ assert typing.get_args(typing.get_type_hints(forward_before)['x']) == (int, Forward)
def test_or_type_operator_with_Protocol(self):
class Proto(typing.Protocol):
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 50723c4df19..99417d7d364 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -363,7 +363,7 @@ class UnionTests(BaseTestCase):
def test_no_eval_union(self):
u = Union[int, str]
def f(x: u): ...
- self.assertIs(get_type_hints(f, globals(), locals())['x'], u)
+ self.assertIs(get_type_hints(f)['x'], u)
def test_function_repr_union(self):
def fun() -> int: ...
@@ -2876,7 +2876,7 @@ class GetTypeHintTests(BaseTestCase):
self.assertEqual(gth(HasForeignBaseClass),
{'some_xrepr': XRepr, 'other_a': mod_generics_cache.A,
'some_b': mod_generics_cache.B})
- self.assertEqual(gth(XRepr),
+ self.assertEqual(gth(XRepr.__new__),
{'x': int, 'y': int})
self.assertEqual(gth(mod_generics_cache.B),
{'my_inner_a1': mod_generics_cache.B.A,
@@ -3689,7 +3689,7 @@ class NamedTupleTests(BaseTestCase):
self.assertEqual(tim.cool, 9000)
self.assertEqual(CoolEmployee.__name__, 'CoolEmployee')
self.assertEqual(CoolEmployee._fields, ('name', 'cool'))
- self.assertEqual(gth(CoolEmployee),
+ self.assertEqual(CoolEmployee.__annotations__,
collections.OrderedDict(name=str, cool=int))
def test_annotation_usage_with_default(self):
@@ -3703,7 +3703,7 @@ class NamedTupleTests(BaseTestCase):
self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault')
self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool'))
- self.assertEqual(gth(CoolEmployeeWithDefault),
+ self.assertEqual(CoolEmployeeWithDefault.__annotations__,
dict(name=str, cool=int))
self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0))
@@ -3871,7 +3871,7 @@ class TypedDictTests(BaseTestCase):
def test_py36_class_syntax_usage(self):
self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D')
self.assertEqual(LabelPoint2D.__module__, __name__)
- self.assertEqual(gth(LabelPoint2D), {'x': int, 'y': int, 'label': str})
+ self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str})
self.assertEqual(LabelPoint2D.__bases__, (dict,))
self.assertEqual(LabelPoint2D.__total__, True)
self.assertNotIsSubclass(LabelPoint2D, typing.Sequence)
@@ -3934,11 +3934,11 @@ class TypedDictTests(BaseTestCase):
assert BaseAnimal.__required_keys__ == frozenset(['name'])
assert BaseAnimal.__optional_keys__ == frozenset([])
- assert gth(BaseAnimal) == {'name': str}
+ assert BaseAnimal.__annotations__ == {'name': str}
assert Animal.__required_keys__ == frozenset(['name'])
assert Animal.__optional_keys__ == frozenset(['tail', 'voice'])
- assert gth(Animal) == {
+ assert Animal.__annotations__ == {
'name': str,
'tail': bool,
'voice': str,
@@ -3946,7 +3946,7 @@ class TypedDictTests(BaseTestCase):
assert Cat.__required_keys__ == frozenset(['name', 'fur_color'])
assert Cat.__optional_keys__ == frozenset(['tail', 'voice'])
- assert gth(Cat) == {
+ assert Cat.__annotations__ == {
'fur_color': str,
'name': str,
'tail': bool,
@@ -3967,7 +3967,7 @@ class IOTests(BaseTestCase):
def stuff(a: IO) -> AnyStr:
return a.readline()
- a = gth(stuff)['a']
+ a = stuff.__annotations__['a']
self.assertEqual(a.__parameters__, (AnyStr,))
def test_textio(self):
@@ -3975,7 +3975,7 @@ class IOTests(BaseTestCase):
def stuff(a: TextIO) -> str:
return a.readline()
- a = gth(stuff)['a']
+ a = stuff.__annotations__['a']
self.assertEqual(a.__parameters__, ())
def test_binaryio(self):
@@ -3983,7 +3983,7 @@ class IOTests(BaseTestCase):
def stuff(a: BinaryIO) -> bytes:
return a.readline()
- a = gth(stuff)['a']
+ a = stuff.__annotations__['a']
self.assertEqual(a.__parameters__, ())
def test_io_submodule(self):