Skip to main content

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

Project description

;;; README.md --- Base class for accessing actual types assigned to generics at runtime 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.tar.gz (4.8 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-py3-none-any.whl (2.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: rt_generic-0.2.tar.gz
  • Upload date:
  • Size: 4.8 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.tar.gz
Algorithm Hash digest
SHA256 9c319fba202e0b6d7708216ca69efeecd3b31394f89e4d2242f3b223710eb27d
MD5 9daa95f1175da796f714741454f50148
BLAKE2b-256 48768bf8f24fb4e3deb07dec9fb03c6d2f77f48347859a3669a6381dcae2dc4a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: rt_generic-0.2-py3-none-any.whl
  • Upload date:
  • Size: 2.8 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-py3-none-any.whl
Algorithm Hash digest
SHA256 05b0f446980d62c71633b657ae8376fff0f53226a7dc70d0674d3e9ae108a3c6
MD5 1e26fbfc7603cc2943dc4798236debd2
BLAKE2b-256 2dd5b678677f43bf7c2e28b4c27fd3adb8b265dadd95c8dc71a8ec61692f7aab

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