Skip to main content

tools to make typing more consistent in older versions of python3, and access generic variables at runtime

Project description

RT-Generic

RT-Generic is a typed python module to make accessing the actual runtime types from a generic module more straight forward. It defines a base class RTGeneric which initializes each subclass (at subclass definition) with a mapping from (Class, TypeVar) to the actual type eventually assigned to that TypeVar. This permits me, for example, when creating class GenClass[T,U,V](RTGeneric): to write code which will behave appropriately for when I eventually create class SubClass1(GenClass[int, float, dict[int, float]]): and class SubClass2(GenClass[tuple[str], list[float], dict[tuple[str], list[float]]]):. Repository, PyPI.

The process has 4 steps minimum (with a few optional steps along the way):

  1. Import RTGeneric from rt_generic. Importing * also brings three Literal types which can be useful.
    • all brings in
      • class RTGeneric with class methods tv2type (converts TypeVar to actual type), generic_true (tests if Literal type means "True" or "Yes"), generic_false (tests if Literal type means "No" or "False"), and generic_lit_values (which gives a tuple of all literal values a Literal type represents).
      • TrueT, a Literal type for True.
      • FalseT, a Literal type for False.
      • TypeErrorT, a Literal type RTGeneric functions return when an error occured
  2. (Optionally) from rt_generic.type_setup import * for consistent types across python versions
    • For all python versions supported by rt_generic, ensures that these are defined:
      • TypeAlias, GenericAlias, LiteralGenericAlias
      • TypeVar, ClassVar, Generic, Any, Literal
      • Self
      • Union, Tuple, Dict, List, TYPE_CHECKING
      • get_args, get_origin, get_original_bases
  3. Declare your generic base class, based on Generic and RTGeneric
    • Either class MyClass[T,U,V](RTGeneric):, (python 3.11 or higher) or
    T = TypeVar('T')
    U = TypeVar('U')
    V = TypeVar('V')
    class MyClass(RTGeneric, Generic[T,U,V]) :
    
  4. Add self.tv2type (or cls.tv2type) calls in your base class where you need behavior to depend on actual types.
    • Just to be clear, self.tv2type(MyClass,T) from an instance method, and
    • cls.tv2type(MyClass,T) from a class method.
    • You must specify your base class name for the cls2 argument to tv2type, since you want to resolve TypeVars specified here. For example, using self.class will attempt to resolve them according to the subclass, where there are no remaining TypeVars.
    • This returns a type, so for example you might have self.tv2type(MyClass, U) == List[int], but not self.tv2type(MyClass, U) == [1,2].
    • You can use Literal types to pass in values when you speciallize your class
      • To turn behavior on and off, use actual types TrueT or FalseT, and check in your code with self.generic_true(self.tv2Type(MyClass, U))
      • To set values to be used when you speciallize, for example, try using the actual type Literal["Hello World"], and in your code print(f"Custom Message: {self.generic_lit_values(self.tv2type(MyClass,V))[0]}") (note index to select an element from the tuple returned by generic_lit_values).
  5. (Optionally) declare subclasses which partially assign types to generics
    • For example, class MyClass2[T](MyClass[list[T], dict[str,T], Literal["mode2"]]):. Note that in this case tv2type(MyClass2,T) != tv2type(MyClass,T).
  6. Declare subclasses which fully assign types (possibly subclasses of other subclasses).
    • This is required because RTGeneric works by initializing subclasses, and an anonymous subclass (as in a = MyClass[int,int,dict[str, float]]()) does not get initalized.
    • instead do
    class MyFinalClass(MyClass[int,int,dict[str, float]]) :
        pass
        
    a = MyFinalClass()
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rt_generic-0.2.1.tar.gz (4.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rt_generic-0.2.1-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file rt_generic-0.2.1.tar.gz.

File metadata

  • Download URL: rt_generic-0.2.1.tar.gz
  • Upload date:
  • Size: 4.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.6

File hashes

Hashes for rt_generic-0.2.1.tar.gz
Algorithm Hash digest
SHA256 43c0f891f6d3e34042fc60ba6f721b5863d30251f6cebde59c245bb266518984
MD5 0bb68dc88e011830d13b1e689d866ec4
BLAKE2b-256 216845432cc673e1ec9f5ad693302f8cd1914e1b8aa97ae8ae9ee8aff18ef80b

See more details on using hashes here.

File details

Details for the file rt_generic-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: rt_generic-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.6

File hashes

Hashes for rt_generic-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 578556b5de7e5f25fcf17772363c55215da9165681ac5ffc2fda22caf8be55f9
MD5 02f4cdfb7c6eaebd0dd8f812db751ea2
BLAKE2b-256 ec0d91ff3a64186aeb9385c4a1ff0ae4046222d6accc4365c86363ef996e343b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page