Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save higherorderfunctor/6754496a52244f6e0267f60071ac37fa to your computer and use it in GitHub Desktop.
Save higherorderfunctor/6754496a52244f6e0267f60071ac37fa to your computer and use it in GitHub Desktop.
T = TypeVar('T') # pylint: disable=invalid-name
H = TypeVar( # pylint: disable=invalid-name
'H', bound='BaseTimestampedHistoryModel'
)
class Lift:
# pylint: disable=too-few-public-methods
"""Lifts generics to a type with __getitem__."""
def __class_getitem__(cls, item: T) -> T:
"""Return lifted generic."""
# pylint: disable=no-self-use
if TYPE_CHECKING:
return item
class _Lifted:
# pylint: disable=too-few-public-methods
def __getitem__(self, *args):
return item
return _Lifted()
if TYPE_CHECKING:
QuerySet = ( # pylint: disable=invalid-name
models.QuerySet[H] # pylint: disable=unsubscriptable-object
)
else:
QuerySet = Lift[models.QuerySet] # pylint: disable=invalid-name
class TimestampedHistoryQuerySet(Generic[H], QuerySet[H]):
"""QuerySet for TimestampedHistoryModel."""
def update(self, **kwargs: Any) -> int:
# pylint: disable=no-self-use
"""Raise exception on update."""
raise PermissionDenied(
'QuerySet update bypasses history tracking. '
'Use model instance\'s save instead.'
)
def delete(self) -> Tuple[int, Dict[str, int]]:
# pylint: disable=no-self-use
"""Raise exception on delete."""
raise PermissionDenied(
'QuerySet delete bypasses history tracking. '
'Use model instance\'s delete instead.'
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment