Skip to content

Commit

Permalink
Fix recursive use of Concatenate when mixing modules (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
Daraan authored Dec 13, 2024
1 parent ca41832 commit f9a2055
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ aliases that have a `Concatenate` special form as their argument.
- Fix that lists and ... could not be used for parameter expressions for `TypeAliasType`
instances before Python 3.11.
Patch by [Daraan](https://github.com/Daraan).
- Fix error on Python 3.10 when using `typing.Concatenate` and
`typing_extensions.Concatenate` together. Patch by [Daraan](https://github.com/Daraan).

# Release 4.12.2 (June 7, 2024)

Expand Down
13 changes: 13 additions & 0 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5504,6 +5504,19 @@ class MyClass: ...
self.assertNotEqual(d, c)
self.assertNotEqual(d, Concatenate)

@skipUnless(TYPING_3_10_0, "Concatenate not available in <3.10")
def test_typing_compatibility(self):
P = ParamSpec('P')
C1 = Concatenate[int, P][typing.Concatenate[int, P]]
self.assertEqual(C1, Concatenate[int, int, P])
self.assertEqual(get_args(C1), (int, int, P))

C2 = typing.Concatenate[int, P][Concatenate[int, P]]
with self.subTest("typing compatibility with typing_extensions"):
if sys.version_info < (3, 10, 3):
self.skipTest("Unpacking not introduced until 3.10.3")
self.assertEqual(get_args(C2), (int, int, P))

def test_valid_uses(self):
P = ParamSpec('P')
T = TypeVar('T')
Expand Down
7 changes: 3 additions & 4 deletions src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1908,21 +1908,20 @@ def __getitem__(self, args):

# 3.10
if sys.version_info < (3, 11):
_typing_ConcatenateGenericAlias = _ConcatenateGenericAlias

class _ConcatenateGenericAlias(_typing_ConcatenateGenericAlias, _root=True):
class _ConcatenateGenericAlias(typing._ConcatenateGenericAlias, _root=True):
# needed for checks in collections.abc.Callable to accept this class
__module__ = "typing"

def copy_with(self, params):
if isinstance(params[-1], (list, tuple)):
return (*params[:-1], *params[-1])
if isinstance(params[-1], _ConcatenateGenericAlias):
if isinstance(params[-1], typing._ConcatenateGenericAlias):
params = (*params[:-1], *params[-1].__args__)
elif not (params[-1] is ... or isinstance(params[-1], ParamSpec)):
raise TypeError("The last parameter to Concatenate should be a "
"ParamSpec variable or ellipsis.")
return super(_typing_ConcatenateGenericAlias, self).copy_with(params)
return super(typing._ConcatenateGenericAlias, self).copy_with(params)

def __getitem__(self, args):
value = super().__getitem__(args)
Expand Down

0 comments on commit f9a2055

Please sign in to comment.