Skip to content

Commit

Permalink
Make (GS,LS)Index an indexable type in runtime (#769)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ikonst committed Apr 22, 2020
1 parent 72fd224 commit 63b01ec
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 3 deletions.
5 changes: 5 additions & 0 deletions docs/release_notes.rst
@@ -1,6 +1,11 @@
Release Notes
=============

v4.3.2
----------

* Fix discrepancy between runtime and type-checker's perspective of Index and derived types

v4.3.1
----------

Expand Down
2 changes: 1 addition & 1 deletion pynamodb/__init__.py
Expand Up @@ -7,4 +7,4 @@
"""
__author__ = 'Jharrod LaFon'
__license__ = 'MIT'
__version__ = '4.3.1'
__version__ = '4.3.2'
9 changes: 8 additions & 1 deletion pynamodb/_compat.py
Expand Up @@ -7,6 +7,12 @@
from inspect import getfullargspec


class FakeGenericMeta(type):
"""Poor man's Generic[T] that doesn't depend on typing. The real generics are in the type stubs."""
def __getitem__(self, item):
return self


def load_module(name, path):
"""Load module using the Python version compatible function."""
if sys.version_info >= (3, 3):
Expand All @@ -23,4 +29,5 @@ def load_module(name, path):
from imp import load_source
return load_source(name, path)

__all__ = ('getfullargspec', 'load_module')

__all__ = ('getfullargspec', 'FakeGenericMeta', 'load_module')
3 changes: 2 additions & 1 deletion pynamodb/indexes.py
Expand Up @@ -3,6 +3,7 @@
"""
from inspect import getmembers

from pynamodb._compat import FakeGenericMeta
from pynamodb.constants import (
INCLUDE, ALL, KEYS_ONLY, ATTR_NAME, ATTR_TYPE, KEY_TYPE, ATTR_TYPE_MAP, KEY_SCHEMA,
ATTR_DEFINITIONS, META_CLASS_NAME
Expand All @@ -13,7 +14,7 @@
from six import with_metaclass


class IndexMeta(type):
class IndexMeta(FakeGenericMeta):
"""
Index meta class
Expand Down

0 comments on commit 63b01ec

Please sign in to comment.