Skip to content

Commit 63b01ec

Browse files
authored
Make (GS,LS)Index an indexable type in runtime (#769)
Following 5426ed9, users found themselves having to write some rather unergonomic code to reconcile Python's and a type-checker's perspectives: if TYPE_CHECKING: _MyModelGSI = GlobalSecondaryIndex["MyModel"] else: _MyModelGSI = GlobalSecondaryIndex class MyModelUserIdGSI(_MyModelGSI): """A GSI for looking up by user ID.""" ... class MyModelEmailGSI(_MyModelGSI): """A GSI for looking up by email.""" ... This addresses it by allowing users to rewrite this as: class MyModelUserIdGSI(GlobalSecondaryIndex["MyModel"]): """A GSI for looking up by user ID.""" ... class MyModelEmailGSI(GlobalSecondaryIndex["MyModel"]): """A GSI for looking up by email.""" ... Since we maintain Python 2 compatibility, we cannot assume the typing module is available so we're making a mock Generic class instead.
1 parent 72fd224 commit 63b01ec

File tree

4 files changed

+16
-3
lines changed

4 files changed

+16
-3
lines changed

docs/release_notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Release Notes
22
=============
33

4+
v4.3.2
5+
----------
6+
7+
* Fix discrepancy between runtime and type-checker's perspective of Index and derived types
8+
49
v4.3.1
510
----------
611

pynamodb/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
"""
88
__author__ = 'Jharrod LaFon'
99
__license__ = 'MIT'
10-
__version__ = '4.3.1'
10+
__version__ = '4.3.2'

pynamodb/_compat.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
from inspect import getfullargspec
88

99

10+
class FakeGenericMeta(type):
11+
"""Poor man's Generic[T] that doesn't depend on typing. The real generics are in the type stubs."""
12+
def __getitem__(self, item):
13+
return self
14+
15+
1016
def load_module(name, path):
1117
"""Load module using the Python version compatible function."""
1218
if sys.version_info >= (3, 3):
@@ -23,4 +29,5 @@ def load_module(name, path):
2329
from imp import load_source
2430
return load_source(name, path)
2531

26-
__all__ = ('getfullargspec', 'load_module')
32+
33+
__all__ = ('getfullargspec', 'FakeGenericMeta', 'load_module')

pynamodb/indexes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
from inspect import getmembers
55

6+
from pynamodb._compat import FakeGenericMeta
67
from pynamodb.constants import (
78
INCLUDE, ALL, KEYS_ONLY, ATTR_NAME, ATTR_TYPE, KEY_TYPE, ATTR_TYPE_MAP, KEY_SCHEMA,
89
ATTR_DEFINITIONS, META_CLASS_NAME
@@ -13,7 +14,7 @@
1314
from six import with_metaclass
1415

1516

16-
class IndexMeta(type):
17+
class IndexMeta(FakeGenericMeta):
1718
"""
1819
Index meta class
1920

0 commit comments

Comments
 (0)