pak.types.type

Base code for Types.

class Type(typelike)

Bases: object

A definition of how to marshal raw data to and from values.

Typically used for the types of Packet fields.

When Types are called, their _call() classmethod gets called, returning a new Type.

Array types can be constructed using indexing syntax, like so:

>>> import pak
>>> array = pak.Int8[3]
>>> array
<class 'pak.types.array.Int8[3]'>
>>> array.pack([1, 2, 3])
b'\x01\x02\x03'
>>> array.unpack(b"\x01\x02\x03")
[1, 2, 3]

The object within the brackets gets passed as the size parameter to Array.

Parameters:

typelike – The typelike object to convert to a Type.

Raises:

TypeError – If typelike can’t be converted to a Type.

class Context(packet=None, *, ctx=None)

Bases: object

The context for a Type.

Type.Contexts are used to pass arbitrary data to Types. All of that arbitrary data comes from the attributes of the Packet.Context if supplied, and you may access those attributes on the created Type.Context as if it were the Packet.Context itself.

However, a Type.Context also contains a packet attribute which denotes the Packet instance for which a Type utility is being used for, if any is applicable.

Note

Unlike Packet.Context, this should not be customized.

Parameters:
  • packet (Packet) – The packet instance that’s being marshaled.

  • ctx (Packet.Context) –

    The context for the packet that’s being marshaled.

    Getting attributes that are not directly in the Type.Context will be gotten from the packet context.

packet

The packet instance that’s being marshaled.

Type:

Packet or None

packet_ctx

The context for the packet that’s being marshaled.

Getting attributes that are not directly in the Type.Context will be gotten from this.

Type:

Packet.Context or None

STATIC_SIZE = STATIC_SIZE
exception UnpackMethodNotImplementedError(type_cls, *, is_async)

Bases: NotImplementedError, UnsuppressedError

An error indicating a Type has not implemented a certain method for unpacking.

Parameters:
  • type_cls (subclass of Type) – The Type which has not implemented the method.

  • is_async (bool) – Whether the method is asynchronous or not.

exception UnsuppressedError

Bases: Exception

An error that is left unsuppressed by certain Type operations.

Certain Type operations, such as unpacking Array.Unbounded and Optional.Unchecked, involve suppressing a general Exception, preventing its propagation through the program.

Such operations will neglect to suppress a Type.UnsuppressedError however, enabling it to signal that something unambiguously wrong has occurred.

classmethod __class_getitem__(index)

Gets an Array of the Type.

Parameters:

index (int or subclass of Type or str or function or None) – The size argument passed to Array.

Examples

>>> import pak
>>> pak.Int8[3]
<class 'pak.types.array.Int8[3]'>
classmethod _array_default(array_size, *, ctx)

Gets the default value for an Array with the Type as its element.

Parameters:
  • array_size (int) – The number of elements to create a default for.

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

Returns:

The default value for an Array with the Type as its element.

Return type:

any

classmethod _array_ensure_size(value, array_size, *, ctx)

Ensures the value of an Array with the Type as its element is the correct size.

Parameters:
  • value – The value to ensure is the correct size.

  • array_size (int) – The number of elements that the value should hold.

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

Returns:

The value of the Array which has array_size elements.

Return type:

any

classmethod _array_num_elements(value, *, ctx)

Gets the number of elements for an Array with the Type as its element.

This method is only called when the Array is prefixed by a Type or has a size of None, meaning it should read until the end of a Packet, since in all other cases the number of elements is predetermined.

Parameters:
  • value – The value to get the number of elements of.

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

Returns:

The corresponding number of elements for value.

Return type:

int

classmethod _array_pack(value, array_size, *, ctx)

Packs the value of an Array with the Type as its element.

Parameters:
  • value – The value of the Array.

  • array_size (int) – The number of elements in the Array.

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

Returns:

The corresponding raw data of the Array.

This only includes the body of the Array, not length prefixes or anything of that sort.

Return type:

bytes

classmethod _array_static_size(array_size, *, ctx)

Gets the static size of an Array with the Type as its element.

Parameters:
  • array_size (int) – The number of elements to get the size of.

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

Returns:

The size of the raw data of an Array of size array_size.

If None, then no static size exists.

This only includes the body of the Array, not length prefixes or anything of that sort.

Return type:

int or None

classmethod _array_transform_value(value)

Transforms the value of an Array field with the Type as its element.

Called when the descriptor form of an Array has its value set.

Parameters:

value – The original value.

Returns:

The transformed value.

This transformed value will be the one that gets set.

Return type:

any

classmethod _array_unpack(buf, array_size, *, ctx)

Unpacks an Array with the Type as its element.

Parameters:
  • buf (file object) – The buffer containing the raw data.

  • array_size (int or None) –

    The number of elements to unpack.

    If None, then as many elements as possible should be unpacked from buf.

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

Returns:

The corresponding value for an Array with the Type as its element.

Return type:

any

async classmethod _array_unpack_async(reader, array_size, *, ctx)

Asynchronously unpacks an Array with the Type as its element.

See also

_array_unpack()

Parameters:
  • reader (asyncio.StreamReader) – The stream of data to unpack from.

  • array_size (int or None) –

    The number of elements to unpack.

    If None, then as many elements as possible should be unpacked from reader.

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

Returns:

The corresponding value for an Array with the Type as its element.

Return type:

any

classmethod _call()

Called when the Type is called.

The arguments passed to the Type will be forwarded to this method, which may be overridden to generate a new Type based on the called Type.

classmethod _pack(value, *, ctx)

Packs a value into its corresponding raw data.

To be overridden by subclasses.

Warning

Do not use this method directly, always use pack() instead.

Parameters:
Returns:

The corresponding raw data.

Return type:

bytes

classmethod _unpack(buf, *, ctx)

Unpacks raw data into its corresponding value.

To be overridden by subclasses.

Warning

Do not use this method directly, always use unpack() instead.

Parameters:
  • buf (file object) – The buffer containing the raw data.

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

Returns:

The corresponding value of the raw data.

Return type:

any

async classmethod _unpack_async(reader, *, ctx)

Asynchronously unpacks raw data into its corresponding value.

To be overridden by subclasses.

Warning

Do not use this method directly, always use unpack_async() instead.

Parameters:
  • reader (asyncio.StreamReader) – The stream of data to unpack from.

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

Returns:

The corresponding value of the raw data.

Return type:

any

classmethod alignment(*, ctx=None)

Gets the alignment of the Type.

The alignment of a Type must be a power of two.

The alignment of a Type is typically ignored, unless using something that explicitly utilizes alignment, such as AlignedPacket.

Furthermore, alignment only makes sense for Types with static sizes.

If the _alignment attribute is any value other than None, then that value will be returned.

Else, if the _alignment attribute is a classmethod, then it should look like this:

@classmethod
def _alignment(cls, *, ctx):
    return my_alignment

The return value of the classmethod will be returned from this method.

Otherwise, if the _alignment attribute is a DynamicValue, which it is automatically transformed into on class construction if applicable, then the dynamic value of that is returned.

If any of these give a value of None, then the Type has no alignment and a TypeError will be raised.

Parameters:

ctx (Type.Context or None) –

The context for the Type.

If None, then an empty Type.Context is used.

Returns:

The alignment of the Type.

Return type:

int

Raises:

TypeError – If the Type has no alignment.

static alignment_padding_lengths(*types, total_alignment, ctx=None)

Gets the length of padding after each Type for alignment purposes.

Should rarely be used by users. In most cases AlignedPacket should be used.

Parameters:
  • *types (subclass of Type) – The Types for which to find the padding for.

  • total_alignment (int) – The total alignment that *types should be aligned to, used for the padding at the end.

  • ctx (Type.Context or None) –

    The context for *types.

    If None, then an empty Type.Context is used.

Returns:

The lengths of padding after each Type in *types.

Return type:

list

classmethod default(*, ctx=None)

Gets the default value of the Type.

If the _default attribute is a classmethod, then it should look like this:

@classmethod
def _default(cls, *, ctx):
    return my_default_value

The return value of the classmethod will be returned from this method.

Else, if the _default attribute is a DynamicValue, which it is automatically transformed into on class construction if applicable, then the dynamic value of that is returned.

Otherwise, if the _default attribute is any value other than None, a deepcopy of that value will be returned.

Parameters:

ctx (Type.Context or None) –

The context for the Type.

If None, then an empty Type.Context is used.

Returns:

The default value.

Return type:

any

Raises:

TypeError – If the Type has no default value.

classmethod descriptor()

Gets the descriptor form of the Type.

Returns:

The descriptor form of the Type.

Return type:

Type

classmethod is_typelike(obj)

Gets whether an object is typelike.

Parameters:

obj – The object to check.

Returns:

Whether obj is typelike.

Return type:

bool

classmethod make_type(name, bases=None, /, **namespace)

Utility for generating new types.

The generated type’s __module__ attribute is set to be the same as the origin type’s. This is done to get around an issue where generated types would have their __module__ attribute be otherwise unintuitve.

This method is cached so a new type is only made if it hasn’t been made before.

Parameters:
  • name (str) – The generated type’s name.

  • bases (tuple or None) –

    The generated type’s base classes.

    If None, the origin type is the sole base class.

  • **namespace – The attributes and corresponding values of the generated type.

Returns:

The generated type.

Return type:

subclass of Type

classmethod pack(value, *, ctx=None)

Packs a value into its corresponding raw data.

Warning

Do not override this method. Instead override _pack().

Parameters:
Returns:

The corresponding raw data.

Return type:

bytes

static prepare_types(func)

A decorator that converts arguments annotated with Type to a Type.

Note

The decorated function will not retain its annotations of parameters that are annotated with Type, as the purpose of annotating a parameter with Type in this context is not for type hinting, and is only really relevant to the implementation of the function, and otherwise could be confusing.

Examples

>>> import pak
>>> @pak.Type.prepare_types
... def example(arg: pak.Type):
...     print(arg.__qualname__)
...
>>> example(pak.Int8)
Int8
>>> example(None)
EmptyType
classmethod register_typelike(typelike_cls, converter)

Registers a class as being convertible to a Type.

Parameters:
  • typelike_cls (type) – The convertible type.

  • converter (callable) – The object called to convert the object to a Type.

classmethod size(value=STATIC_SIZE, /, *, ctx=None)

Gets the size of the Type when packed.

Worst case this will perform as badly as packing the value and getting the length of the raw data performs. However, Types may often be able to optimize finding their packed sizes.

If the _size attribute is any value other than None, then that value will be returned.

Else, If the _size attribute is a classmethod, then it should look like this:

@classmethod
def _size(cls, value, *, ctx):
    return my_size

The return value of the classmethod will be returned from this method.

Otherwise, if the _size attribute is a DynamicValue, which it is automatically transformed into on class construction if applicable, then the dynamic value of that is returned.

If any of these give a size of None or raise NoStaticSizeError, then if value is not STATIC_SIZE, then the value will be packed in order to get the size.

Parameters:
  • value (any) –

    If STATIC_SIZE, then a size irrespective of any value is returned, if possible.

    Otherwise,

  • ctx (Type.Context or None) –

    The context for the Type.

    If None, then an empty Type.Context is used.

Returns:

The size of the Type when packed.

Return type:

int

Raises:

NoStaticSizeError – If the Type has no static size but is asked for one.

classmethod unpack(buf, *, ctx=None)

Unpacks raw data into its corresponding value.

Warning

Do not override this method. Instead override _unpack().

See also

unpack_async()

Parameters:
  • buf (file object or bytes or bytearray) – The buffer containing the raw data.

  • ctx (Type.Context or None) –

    The context for the Type.

    If None, then an empty Type.Context is used.

Returns:

The corresponding value of the raw data.

Return type:

any

async classmethod unpack_async(reader, *, ctx=None)

Asynchronously unpacks raw data into its corresponding value.

Warning

Do not override this method. Instead override _unpack_async().

See also

unpack()

Parameters:
  • reader (asyncio.StreamReader or bytes or bytearray) –

    The stream of data to unpack from.

    Warning

    Nothing else should read from reader until this coroutine finishes executing.

    If bytes or bytearray, then reader is turned into an io.ByteStreamReader.

  • ctx (Type.Context or None) –

    The context for the Type.

    If None, then an empty Type.Context is used.

Returns:

The corresponding value of the raw data.

Return type:

any

classmethod unregister_typelike(typelike_cls)

Unregisters a class as being convertible to a Type.

Parameters:

typelike_cls (type) – The type to unregister.

exception NoStaticSizeError(type_cls)

Bases: Exception

An error indicating a Type has no static size.

Parameters:

type_cls (subclass of Type) – The Type which has no static size.

exception MaxBytesExceededError(type_cls)

Bases: UnsuppressedError

An error indicating a Type has exceeded its maximum number of bytes when unpacking.

Parameters:

type_cls (subclass of Type) – The Type which exceeded its maximum number of bytes.