Skip to content

Commit 9ce64c5

Browse files
authored
Add PEP 585 GenericAlias support (#101)
Closes #83
1 parent a952730 commit 9ce64c5

File tree

4 files changed

+27
-8
lines changed

4 files changed

+27
-8
lines changed

immutables/_map.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3373,12 +3373,14 @@ map_reduce(MapObject *self)
33733373
return tup;
33743374
}
33753375

3376+
#if PY_VERSION_HEX < 0x030900A6
33763377
static PyObject *
33773378
map_py_class_getitem(PyObject *type, PyObject *item)
33783379
{
33793380
Py_INCREF(type);
33803381
return type;
33813382
}
3383+
#endif
33823384

33833385
static PyMethodDef Map_methods[] = {
33843386
{"set", (PyCFunction)map_py_set, METH_VARARGS, NULL},
@@ -3393,9 +3395,13 @@ static PyMethodDef Map_methods[] = {
33933395
{"__dump__", (PyCFunction)map_py_dump, METH_NOARGS, NULL},
33943396
{
33953397
"__class_getitem__",
3398+
#if PY_VERSION_HEX < 0x030900A6
33963399
(PyCFunction)map_py_class_getitem,
3400+
#else
3401+
Py_GenericAlias,
3402+
#endif
33973403
METH_O|METH_CLASS,
3398-
NULL
3404+
"See PEP 585"
33993405
},
34003406
{NULL, NULL}
34013407
};

immutables/_map.pyi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
from typing import Any
23
from typing import Dict
34
from typing import Generic
@@ -10,6 +11,9 @@ from typing import Type
1011
from typing import Union
1112
from typing import overload
1213

14+
if sys.version_info >= (3, 9):
15+
from types import GenericAlias
16+
1317
from ._protocols import IterableItems
1418
from ._protocols import MapItems
1519
from ._protocols import MapKeys
@@ -70,4 +74,7 @@ class Map(Mapping[KT, VT_co]):
7074
def items(self) -> MapItems[KT, VT_co]: ... # type: ignore[override]
7175
def __hash__(self) -> int: ...
7276
def __dump__(self) -> str: ...
73-
def __class_getitem__(cls, item: Any) -> Type[Map[Any, Any]]: ...
77+
if sys.version_info >= (3, 9):
78+
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
79+
else:
80+
def __class_getitem__(cls, item: Any) -> Type[Map[Any, Any]]: ...

immutables/map.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import itertools
33
import reprlib
44
import sys
5+
import types
56

67

78
__all__ = ('Map',)
@@ -661,8 +662,11 @@ def __dump__(self): # pragma: no cover
661662
self.__root.dump(buf, 0)
662663
return '\n'.join(buf)
663664

664-
def __class_getitem__(cls, item):
665-
return cls
665+
if sys.version_info >= (3, 9):
666+
__class_getitem__ = classmethod(types.GenericAlias)
667+
else:
668+
def __class_getitem__(cls, item):
669+
return cls
666670

667671

668672
class MapMutation:

tests/test_map.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,11 +1384,13 @@ def test_map_pickle(self):
13841384
with self.assertRaisesRegex(TypeError, "can('t|not) pickle"):
13851385
pickle.dumps(h.mutate())
13861386

1387-
@unittest.skipIf(
1388-
sys.version_info < (3, 7, 0), "__class_getitem__ is not available"
1389-
)
13901387
def test_map_is_subscriptable(self):
1391-
self.assertIs(self.Map[int, str], self.Map)
1388+
if sys.version_info >= (3, 9):
1389+
with_args = self.Map[int, str]
1390+
self.assertIs(with_args.__origin__, self.Map)
1391+
self.assertEqual(with_args.__args__, (int, str))
1392+
else:
1393+
self.assertIs(self.Map[int, str], self.Map)
13921394

13931395
def test_kwarg_named_col(self):
13941396
self.assertEqual(dict(self.Map(col=0)), {"col": 0})

0 commit comments

Comments
 (0)