Other Modules¶
typing_redirect¶
The typing_redirect module allows usage of Python 3.12 features without breaking support for 3.8 or requiring a dependency on typing-extensions.
typing_redirect.py
- This module allows for Python version-agnostic typing and collections.abc imports.
It uses Python standard library batteries where possible. For older versions, this module will export from typing_extensions.
- class bytemaker.typing_redirect.Any(*args, **kwargs)[source]¶
Bases:
objectSpecial type indicating an unconstrained type.
Any is compatible with every type.
Any assumed to have all methods.
All values assumed to be instances of Any.
Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance checks.
- class bytemaker.typing_redirect.Buffer¶
Bases:
object
- class bytemaker.typing_redirect.Callable¶
Bases:
object
- class bytemaker.typing_redirect.ForwardRef(arg, is_argument=True, module=None, *, is_class=False)[source]¶
Bases:
_FinalInternal wrapper to hold a forward reference.
- class bytemaker.typing_redirect.Hashable¶
Bases:
object
- class bytemaker.typing_redirect.Iterable¶
Bases:
object
- class bytemaker.typing_redirect.Mapping¶
Bases:
CollectionA Mapping is a generic container for associating key/value pairs.
This class provides concrete generic implementations of all methods except for __getitem__, __iter__, and __len__.
- get(k[, d]) D[k] if k in D, else d. d defaults to None.¶
- items() a set-like object providing a view on D's items¶
- keys() a set-like object providing a view on D's keys¶
- values() an object providing a view on D's values¶
- class bytemaker.typing_redirect.MutableMapping¶
Bases:
MappingA MutableMapping is a generic container for associating key/value pairs.
This class provides concrete generic implementations of all methods except for __getitem__, __setitem__, __delitem__, __iter__, and __len__.
- clear() None. Remove all items from D.¶
- pop(k[, d]) v, remove specified key and return the corresponding value.¶
If key is not found, d is returned if given, otherwise KeyError is raised.
- popitem() (k, v), remove and return some (key, value) pair¶
as a 2-tuple; but raise KeyError if D is empty.
- setdefault(k[, d]) D.get(k,d), also set D[k]=d if k not in D¶
- update([E, ]**F) None. Update D from mapping/iterable E and F.¶
If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v
- class bytemaker.typing_redirect.MutableSequence¶
Bases:
SequenceAll the operations on a read-write sequence.
Concrete subclasses must provide __new__ or __init__, __getitem__, __setitem__, __delitem__, __len__, and insert().
- append(value)¶
S.append(value) – append value to the end of the sequence
- clear() None -- remove all items from S¶
- extend(values)¶
S.extend(iterable) – extend sequence by appending elements from the iterable
- abstract insert(index, value)¶
S.insert(index, value) – insert value before index
- pop([index]) item -- remove and return item at index (default last).¶
Raise IndexError if list is empty or index is out of range.
- remove(value)¶
S.remove(value) – remove first occurrence of value. Raise ValueError if the value is not present.
- reverse()¶
S.reverse() – reverse IN PLACE
- class bytemaker.typing_redirect.ParamSpec¶
Bases:
objectParameter specification variable.
The preferred way to construct a parameter specification is via the dedicated syntax for generic functions, classes, and type aliases, where the use of ‘**’ creates a parameter specification:
type IntFunc[**P] = Callable[P, int]
For compatibility with Python 3.11 and earlier, ParamSpec objects can also be created as follows:
P = ParamSpec('P')
Parameter specification variables exist primarily for the benefit of static type checkers. They are used to forward the parameter types of one callable to another callable, a pattern commonly found in higher-order functions and decorators. They are only valid when used in
Concatenate, or as the first argument toCallable, or as parameters for user-defined Generics. See class Generic for more information on generic types.An example for annotating a decorator:
def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]: '''A type-safe decorator to add logging to a function.''' def inner(*args: P.args, **kwargs: P.kwargs) -> T: logging.info(f'{f.__name__} was called') return f(*args, **kwargs) return inner @add_logging def add_two(x: float, y: float) -> float: '''Add two numbers together.''' return x + y
Parameter specification variables can be introspected. e.g.:
>>> P = ParamSpec("P") >>> P.__name__ 'P'
Note that only parameter specification variables defined in the global scope can be pickled.
- args¶
Represents positional arguments.
- kwargs¶
Represents keyword arguments.
- class bytemaker.typing_redirect.Protocol[source]¶
Bases:
GenericBase class for protocol classes.
Protocol classes are defined as:
class Proto(Protocol): def meth(self) -> int: ...
Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing).
For example:
class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Passes static type check
See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:
class GenProto[T](Protocol): def meth(self) -> T: ...
- class bytemaker.typing_redirect.Sequence¶
Bases:
Reversible,CollectionAll the operations on a read-only sequence.
Concrete subclasses must override __new__ or __init__, __getitem__, and __len__.
- count(value) integer -- return number of occurrences of value¶
- index(value[, start[, stop]]) integer -- return first index of value.¶
Raises ValueError if the value is not present.
Supporting start and stop arguments is optional, but recommended.
- class bytemaker.typing_redirect.TypeVar¶
Bases:
objectType variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.
- class bytemaker.typing_redirect.UnionType¶
Bases:
objectRepresent a PEP 604 union type
E.g. for int | str
- bytemaker.typing_redirect.get_args(tp)[source]¶
Get type arguments with all substitutions performed.
For unions, basic simplifications used by Union constructor are performed.
Examples:
>>> T = TypeVar('T') >>> assert get_args(Dict[str, int]) == (str, int) >>> assert get_args(int) == () >>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str) >>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) >>> assert get_args(Callable[[], T][int]) == ([], int)
- bytemaker.typing_redirect.get_origin(tp)[source]¶
Get the unsubscripted version of a type.
This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar, Annotated, and others. Return None for unsupported types.
Examples:
>>> P = ParamSpec('P') >>> assert get_origin(Literal[42]) is Literal >>> assert get_origin(int) is None >>> assert get_origin(ClassVar[int]) is ClassVar >>> assert get_origin(Generic) is Generic >>> assert get_origin(Generic[T]) is Generic >>> assert get_origin(Union[T, int]) is Union >>> assert get_origin(List[Tuple[T, T]][int]) is list >>> assert get_origin(P.args) is P
- bytemaker.typing_redirect.get_type_hints(obj, globalns=None, localns=None, include_extras=False)[source]¶
Return type hints for an object.
This is often the same as obj.__annotations__, but it handles forward references encoded as string literals and recursively replaces all ‘Annotated[T, …]’ with ‘T’ (unless ‘include_extras=True’).
The argument may be a module, class, method, or function. The annotations are returned as a dictionary. For classes, annotations include also inherited members.
TypeError is raised if the argument is not of a type that can contain annotations, and an empty dictionary is returned if no annotations are present.
BEWARE – the behavior of globalns and localns is counterintuitive (unless you are familiar with how eval() and exec() work). The search order is locals first, then globals.
If no dict arguments are passed, an attempt is made to use the globals from obj (or the respective module’s globals for classes), and these are also used as the locals. If the object does not appear to have globals, an empty dictionary is used. For classes, the search order is globals first then locals.
If one dict argument is passed, it is used for both globals and locals.
If two dict arguments are passed, they specify globals and locals, respectively.
- bytemaker.typing_redirect.overload(func)[source]¶
Decorator for overloaded functions/methods.
In a stub file, place two or more stub definitions for the same function in a row, each decorated with @overload.
For example:
@overload def utf8(value: None) -> None: ... @overload def utf8(value: bytes) -> bytes: ... @overload def utf8(value: str) -> bytes: ...
In a non-stub file (i.e. a regular .py file), do the same but follow it with an implementation. The implementation should not be decorated with @overload:
@overload def utf8(value: None) -> None: ... @overload def utf8(value: bytes) -> bytes: ... @overload def utf8(value: str) -> bytes: ... def utf8(value): ... # implementation goes here
The overloads for a function can be retrieved at runtime using the get_overloads() function.
- bytemaker.typing_redirect.runtime_checkable(cls)[source]¶
Mark a protocol class as a runtime protocol.
Such protocol can be used with isinstance() and issubclass(). Raise TypeError if applied to a non-protocol class. This allows a simple-minded structural check very similar to one trick ponies in collections.abc such as Iterable.
For example:
@runtime_checkable class Closable(Protocol): def close(self): ... assert isinstance(open('/some/file'), Closable)
Warning: this will check only the presence of the required methods, not their type signatures!
utils¶
Various helper functions/classes
(bytemaker.utils.Trie, bytemaker.utils.classproperty, bytemaker.utils.instance_of_union(), etc.) exposed for general use.
- class bytemaker.utils.ByteConvertible[source]¶
Bases:
objectHas __instancecheck__ and __subclasscheck__ methods to allow checking whether an object can be converted to a bytes object using
python:bytes
- class bytemaker.utils.FrozenDict(input_dict: Dict[K, V])[source]¶
Bases:
HashableMapping[K,V]
- class bytemaker.utils.classproperty(fget=None, fset=None, fdel=None, doc=None)[source]¶
Bases:
objectEmulate class-level property similar to instance-level property
- bytemaker.utils.is_instance_of_union(obj, union_type: type)[source]¶
- Determines if an object is an instance of a union type
(to support Python versions <3.10).
- Parameters:
obj (object) – The object to check
union_type (type) – The union type to check against
- Returns:
Whether the object is an instance of the union type
- Return type:
bool
- bytemaker.utils.is_subclass_of_union(subtype: type, supertype)[source]¶
- Determines if an object is a subclass of a union type
(to support Python versions <3.10).
- Parameters:
subtype (type) – The object type to check
supertype (type) – The union type to check against
- Returns:
Whether the object is a subclass of the union type
- Return type:
bool
- bytemaker.utils.twos_complement(number, n_bits=32)[source]¶
Convert an integer to its two’s complement representation.
- Parameters:
number – The integer to convert.
bits – The bit width for the two’s complement representation.
- Returns:
A string representing the two’s complement of the number.
- bytemaker.utils.twos_complement_bit_length(n: int)[source]¶
Determines the number of bits required to represent a signed integer in two’s complement.
- Parameters:
n (int) – The (signed) integer for which to determine the number of bits required
- Returns:
The number of bits required to represent the integer in two’s-complement notation
- Return type:
int