[3.11] gh-115165: Fix typing.Annotated for immutable types (GH-115213) (#115228)

gh-115165: Fix `typing.Annotated` for immutable types (GH-115213)

The return value from an annotated callable can raise any exception from
__setattr__ for the `__orig_class__` property.
(cherry picked from commit 564385612c)

Co-authored-by: dave-shawley <daveshawley@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-02-09 23:43:24 +01:00 committed by GitHub
parent ca3eca1584
commit 7542210a95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 1 deletions

View file

@ -3665,6 +3665,17 @@ class GenericTests(BaseTestCase):
c.bar = 'abc'
self.assertEqual(c.__dict__, {'bar': 'abc'})
def test_setattr_exceptions(self):
T = TypeVar("T")
class Immutable(Generic[T]):
def __setattr__(self, key, value):
raise RuntimeError("immutable")
# gh-115165: This used to cause RuntimeError to be raised
# when we tried to set `__orig_class__` on the `Immutable` instance
# returned by the `Immutable[int]()` call
self.assertIsInstance(Immutable[int](), Immutable)
def test_subscripted_generics_as_proxies(self):
T = TypeVar('T')
class C(Generic[T]):
@ -7397,6 +7408,17 @@ class AnnotatedTests(BaseTestCase):
self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1})
self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1})
def test_instantiate_immutable(self):
class C:
def __setattr__(self, key, value):
raise Exception("should be ignored")
A = Annotated[C, "a decoration"]
# gh-115165: This used to cause RuntimeError to be raised
# when we tried to set `__orig_class__` on the `C` instance
# returned by the `A()` call
self.assertIsInstance(A(), C)
def test_cannot_instantiate_forward(self):
A = Annotated["int", (5, 6)]
with self.assertRaises(TypeError):

View file

@ -1275,7 +1275,9 @@ class _BaseGenericAlias(_Final, _root=True):
result = self.__origin__(*args, **kwargs)
try:
result.__orig_class__ = self
except AttributeError:
# Some objects raise TypeError (or something even more exotic)
# if you try to set attributes on them; we guard against that here
except Exception:
pass
return result

View file

@ -0,0 +1,4 @@
Most exceptions are now ignored when attempting to set the ``__orig_class__``
attribute on objects returned when calling :mod:`typing` generic aliases
(including generic aliases created using :data:`typing.Annotated`).
Previously only :exc:`AttributeError`` was ignored. Patch by Dave Shawley.