Skip to content

Instantly share code, notes, and snippets.

@MestreLion
Created October 18, 2021 03:05
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 MestreLion/913c6f951a2076db7961deeee9823703 to your computer and use it in GitHub Desktop.
Save MestreLion/913c6f951a2076db7961deeee9823703 to your computer and use it in GitHub Desktop.
How to create a discardable generic
# https://stackoverflow.com/questions/67803260
from typing import Generic, TypeVar, Dict, Any, Union
class DataClassJsonMixin: ...
class Person(DataClassJsonMixin): ...
JSON = Dict[str, Any] # Good enough json type for this demo
T = TypeVar("T", bound=DataClassJsonMixin)
# Solution 1: Union with impossible type that takes a Generic
# JSONOf = Union[JSON, Dict[JSON, T]]
# Solution 2: Union with custom generic class
class JSONFrom(Generic[T]):
# just a crude failsafe to prohibit instantiation
# could be improved with __new__, __init_subclasses__, etc
def __init__(self):
raise TypeError("Just dont!")
JSONOf = Union[JSON, JSONFrom[T]]
def add_person_to_db(person: JSONOf[Person]):
print(person)
try: reveal_type(person)
except NameError: pass
add_person_to_db({'id': 1234, 'name': 'Someone'}) # Checks
add_person_to_db("Not a JSON") # Check error by JSON
add_person_to_db(Person()) # Make sure it does not accept Person
try: someone: JSONFrom = JSONFrom() # Make sure it does not accept JSONFrom
except TypeError as e: print(e) # Nice try!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment