8000 [3.11] gh-115165: Fix `typing.Annotated` for immutable types (GH-1152… · python/cpython@7542210 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 7542210

Browse files
[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 5643856) Co-authored-by: dave-shawley <daveshawley@gmail.com>
1 parent ca3eca1 commit 7542210

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

Lib/test/test_typing.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,17 @@ class C(B[int]):
36653665
c.bar = 'abc'
36663666
self.assertEqual(c.__dict__, {'bar': 'abc'})
36673667

3668+
def test_setattr_exceptions(self):
3669+
T = TypeVar("T")
3670+
class Immutable(Generic[T]):
3671+
def __setattr__(self, key, value):
3672+
raise RuntimeError("immutable")
3673+
3674+
# gh-115165: This used to cause RuntimeError to be raised
3675+
# when we tried to set `__orig_class__` on the `Immutable` instance
3676+
# returned by the `Immutable[int]()` call
3677+
self.assertIsInstance(Immutable[int](), Immutable)
3678+
36683679
def test_subscripted_generics_as_proxies(self):
36693680
T = TypeVar('T')
36703681
class C(Generic[T]):
@@ -7397,6 +7408,17 @@ def test_instantiate_generic(self):
73977408
self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1})
73987409
self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1})
73997410

7411+
def test_instantiate_immutable(self):
7412+
class C:
7413+
def __setattr__(self, key, value):
7414+
raise Exception("should be ignored")
7415+
7416+
A = Annotated[C, "a decoration"]
7417+
# gh-115165: This used to cause RuntimeError to be raised
7418+
# when we tried to set `__orig_class__` on the `C` instance
7419+
# returned by the `A()` call
7420+
self.assertIsInstance(A(), C)
7421+
74007422
def test_cannot_instantiate_forward(self):
74017423
A = Annotated["int", (5, 6)]
74027424
with self.assertRaises(TypeError):

Lib/typing.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,9 @@ def __call__(self, *args, **kwargs):
12751275
result = self.__origin__(*args, **kwargs)
12761276
try:
12771277
result.__orig_class__ = self
1278-
except AttributeError:
1278+
# Some objects raise TypeError (or something even more exotic)
1279+
# if you try to set attributes on them; we guard against that here
1280+
except Exception:
12791281
pass
12801282
return result
12811283

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Most exceptions are now ignored when attempting to set the ``__orig_class__``
2+
attribute on objects returned when calling :mod:`typing` generic aliases
3+
(including generic aliases created using :data:`typing.Annotated`).
4+
Previously only :exc:`AttributeError`` was ignored. Patch by Dave Shawley.

0 commit comments

Comments
 (0)
0