Skip to content

Commit

Permalink
bpo-44524: Fix cryptic TypeError message when trying to subclass spec…
Browse files Browse the repository at this point in the history
…ial forms in `typing` (GH-27710)

This was a Python 3.9 regression.
(cherry picked from commit a3a4d20)

Co-authored-by: Yurii Karabas <[email protected]>
  • Loading branch information
miss-islington and uriyyo authored Aug 28, 2021
1 parent cd986e9 commit 81fa08c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2418,6 +2418,22 @@ def __new__(cls, arg):
self.assertEqual(c.from_b, 'b')
self.assertEqual(c.from_c, 'c')

def test_subclass_special_form(self):
for obj in (
ClassVar[int],
Final[int],
Union[int, float],
Optional[int],
Literal[1, 2],
Concatenate[int, ParamSpec("P")],
TypeGuard[int],
):
with self.subTest(msg=obj):
with self.assertRaisesRegex(
TypeError, f'^{re.escape(f"Cannot subclass {obj!r}")}$'
):
class Foo(obj):
pass

class ClassVarTests(BaseTestCase):

Expand Down
3 changes: 3 additions & 0 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,9 @@ def __reduce__(self):
return operator.getitem, (origin, args)

def __mro_entries__(self, bases):
if isinstance(self.__origin__, _SpecialForm):
raise TypeError(f"Cannot subclass {self!r}")

if self._name: # generic version of an ABC or built-in class
return super().__mro_entries__(bases)
if self.__origin__ is Generic:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Make exception message more useful when subclass from typing special form
alias. Patch provided by Yurii Karabas.

0 comments on commit 81fa08c

Please sign in to comment.