pak.types.deferring

Types which defer their behavior to other Types.

class DeferringType[source]

Bases: Type

A Type which defers its behavior to other Types.

A DeferringType will defer all of its marshaling behavior to a certain Type depending on what it decides to return from its _defer_to() method.

This deferring of behavior is useful, for instance, in protocols with multiple versions, where you may want to have a Packet field act like a different Type between different protocol versions.

DeferringType should be preferred to custom Types of a similar nature because DeferringType will forward on all relevant behavior, resulting in a more correct and ergonomic experience.

Examples

>>> import pak
>>> class VersionedPacket(pak.Packet):
...     class Context(pak.Packet.Context):
...         def __init__(self, *, version):
...             self.version = version
...
...             super().__init__()
...
...         def __hash__(self):
...             return hash(self.version)
...
...         def __eq__(self, other):
...             if not isinstance(other, VersionedPacket.Context):
...                 return NotImplemented
...
...             return self.version == other.version
...
>>> class VersionedInteger(pak.DeferringType):
...     @classmethod
...     def _defer_to(cls, *, ctx):
...         # 'Int8' in version 0, 'Int16' in every other version.
...         if ctx.version == 0:
...             return pak.Int8
...
...         return pak.Int16
...
>>> class MyPacket(VersionedPacket):
...     number: VersionedInteger
...
>>> p = MyPacket(number=2)
>>>
>>> # The 'number' field is an 'Int8' in version 0.
>>> p.pack(ctx=VersionedPacket.Context(version=0))
b'\x02'
>>>
>>> # The 'number' field is an 'Int16' in version 1.
>>> p.pack(ctx=VersionedPacket.Context(version=1))
b'\x02\x00'
exception UnableToDeferError[source]

Bases: ValueError, UnsuppressedError

An error indicating that there was no appropriate Type to defer to.

classmethod _defer_to(*, ctx)[source]

Gets the Type which the DeferringType should defer to.

This method should be overridden by subclasses.

Parameters:

ctx (Type.Context) – The context for the Type.

Returns:

The appropriate Type to defer to based on the ctx parameter.

Return type:

subclass of Type

Raises:

UnableToDeferError – If the DeferringType is unable to defer to an appropriate Type.