v1.1.0

Date:

January 1st, 2025

Changes

  • Drop support for Python 3.7.

  • Implement an asynchronous unpacking API.
    • This allows users to unpack asynchronously using coroutines and the await syntax, which may in certain cases be necessary or otherwise desirable.

    • Where there is something that involves unpacking, there will be an asynchronous version of it suffixed with _async, including the following:
    • All Types in Pak provide both the synchronous and asynchronous unpacking APIs, however custom Types are empowered to only provide one or the other, as often only one will be relevant to a certain usecase.

  • Add DeferringType.
    • This allows a Type to defer its behavior to another Type of its choosing depending on the relevant Type.Context. This is useful, for instance, if you are supporting multiple versions of a protocol which might have different fields act like different Types depending on the protocol version.

  • Improve customizing the endianness of StructType.
  • Add LEB128.Limited and ULEB128.Limited.
    • These allow users to limit the maximum number of bytes that a LEB128 or ULEB128 may have, which may be useful to prevent malicious actors from always setting the top bit of each byte to cause unpacking to never end.

  • Reorder the bases of the returned class of Packet.GenericWithID() to have more intuitive behavior.
    • The data field from GenericPacket is now situated at the end of the Packet, so that it will capture any remaining uncaptured data after the rest of the fields.

  • Give EmptyType an alignment of 1.
    • This better allows fields to be effectively “disabled” in an aligned context, such as when using AlignedPacket.

  • Give RawByte an alignment of 1.

  • Refactor Array to use specialized subclasses.
  • Refactor Optional to use specialized subclasses.
  • Add Type.UnsuppressedError.
  • Types in Pak now more consistently raise errors if they are unable to read enough data when unpacking.

  • Make the Type.prepare_types() decorator remove all parameter annotations of Type from its decorated function.
    • This prevents potentially confusing annotations of Type from leaking out into documentation or other tools where those annotations may be misinterpreted. For instance, they could be mistaken as type hints. Parameter annotations of Type when using Type.prepare_types() are only internally relevant, and should not be shown externally.

  • Restrict certain function parameters to being positional-only in order to better enforce caching.

  • Fix typo in the name of PacketHandler.unregister_packet_listener(), which was previously named unregsiter_packet_listener.