bpo-38605: Revert making 'from __future__ import annotations' the default (GH-25490)

This reverts commits 044a1048ca and 1be456ae9d, adapting the code to changes that happened after it.
This commit is contained in:
Pablo Galindo 2021-04-21 12:41:19 +01:00 committed by GitHub
parent d35eef3b90
commit b0544ba77c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 436 additions and 523 deletions

View file

@ -9,7 +9,6 @@
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 C:
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 F:
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 @@ def validate_class(cls):
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 C:
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 @@ def test_classvar(self):
'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 @@ def test_isnt_classvar(self):
'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 @@ def test_initvar(self):
'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 @@ def test_isnt_initvar(self):
'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 @@ def test_classvar_module_level_import(self):
# 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