Skip to content

Commit

Permalink
Increment version, add changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
friedkeenan committed Dec 31, 2024
1 parent f7118a4 commit 7bbabb2
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 11 deletions.
9 changes: 9 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Changelog
=========

See what's new in each version of Pak:

.. toctree::

changelog/v1.1.0
changelog/v1.0.0
9 changes: 9 additions & 0 deletions docs/source/changelog/v1.0.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
v1.0.0
======

:Date: June 16, 2023

Changes
*******

The initial release of Pak. No changes to report!
63 changes: 63 additions & 0 deletions docs/source/changelog/v1.1.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
v1.1.0
======

:Date: TODO

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:
- The :meth:`.Type.unpack_async` method.
- The :meth:`.Packet.unpack_async` method.
- The new functions in the :mod:`.test` module.
- All :class:`.Type`\s in Pak provide both the synchronous and asynchronous unpacking APIs, however custom :class:`.Type`\s are empowered to only provide one or the other, as often only one will be relevant to a certain usecase.

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

- Improve customizing the endianness of :class:`.StructType`.
- The following methods were added to be able to tersely specify the desired endianness of a :class:`.StructType`:
- :meth:`.StructType.little_endian`
- :meth:`.StructType.big_endian`
- :meth:`.StructType.native_endian`
- This allows users to, for instance, call ``pak.UInt16.big_endian()`` in order to use a big-endian :class:`.UInt16`, instead of the default little-endian version.

- Add :class:`.LEB128.Limited` and :class:`.ULEB128.Limited`.
- These allow users to limit the maximum number of bytes that a :class:`.LEB128` or :class:`.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 :meth:`.Packet.GenericWithID` to have more intuitive behavior.
- The ``data`` field from :class:`.GenericPacket` is now situated at the end of the :class:`.Packet`, so that it will capture any remaining uncaptured data after the rest of the fields.

- Give :class:`.EmptyType` an alignment of ``1``.
- This better allows fields to be effectively "disabled" in an aligned context, such as when using :class:`.AlignedPacket`.

- Give :class:`.RawByte` an alignment of ``1``.

- Refactor :class:`.Array` to use specialized subclasses.
- These specialized subclasses are:
- :class:`.Array.FixedSize`
- :class:`.Array.SizePrefixed`
- :class:`.Array.Unbounded`
- :class:`.Array.FunctionSized`

- Refactor :class:`.Optional` to use specialized subclasses.
- These specialized subclasses are:
- :class:`.Optional.PrefixChecked`
- :class:`.Optional.Unchecked`
- :class:`.Optional.FunctionChecked`

- Add :exc:`.Type.UnsuppressedError`.
- Exceptions which inherit from :exc:`.Type.UnsuppressedError` indicate unambiguous errors in logic, which should not be suppressed by certain :class:`.Type` facilities like :class:`.Array.Unbounded` and :class:`.Optional.Unchecked`.

- :class:`.Type`\s in Pak now more consistently raise errors if they are unable to read enough data when unpacking.

- Make the :meth:`.Type.prepare_types` decorator remove all parameter annotations of :class:`.Type` from its decorated function.
- This prevents potentially confusing annotations of :class:`.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 :class:`.Type` when using :meth:`.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 :meth:`.PacketHandler.unregister_packet_listener`, which was previously named ``unregsiter_packet_listener``.
3 changes: 2 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Pak: A General Purpose Packet Marshaling Library
===========================================================
================================================

**Pak** is a simple, yet powerful and extendable Python library
for translating between raw data and usable, meaningful values.
Expand Down Expand Up @@ -64,6 +64,7 @@ Table of Contents

tutorials
reference
changelog


Indices and Tables
Expand Down
2 changes: 1 addition & 1 deletion docs/source/tutorials/protocol_matching/basic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ This code is *much* more readable. It could even be made more readable with ``ma

----

But let's say somehow, when we, the server, try to read the ``CatPicturesRequest`` packet, the data we get is ``b"\x03"``, corresponding to an unsigned byte value of ``3``. This could happen for instance if the client is using a newer version of the protocol that uses the value ``3`` to ask for the number of *hairless* cat pictures, or perhaps we're communicating with a malicious client who's trying to expose flaws in our code by sending unexpected values. Let's see what happens:
But let's say somehow, when we, the server, try to read the ``CatPicturesRequest`` packet, the data we get is ``b"\x03"``, corresponding to an unsigned byte value of ``3``. This could happen, for instance, if the client is using a newer version of the protocol that uses the value ``3`` to ask for the number of *hairless* cat pictures, or perhaps we're communicating with a malicious client who's trying to expose flaws in our code by sending unexpected values. Let's see what happens:

.. testcode::

Expand Down
2 changes: 1 addition & 1 deletion docs/source/tutorials/protocol_matching/handle.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Packet listeners can also be associated with certain "flags" that must match wit
def on_info_request(self, packet):
self.write_packet(CatInfoResponse(...))

This would then let us leverage our packet listening infrastructure for packets we send too, which could for instance be used for debugging purposes to print all the packets we send or to otherwise have special logic for whenever we send a certain packet. Here our listeners would only be called when receiving packets, because they have the ``outgoing`` flag set to ``False``. Since it's annoying and error-prone to always specify the ``outgoing`` flag, we can make it default to ``False`` (or make specifying it required if we wanted to) by overriding the :meth:`.PacketHandler.register_packet_listener` method, like so::
This would then let us leverage our packet listening infrastructure for packets we send too, which could, for instance, be used for debugging purposes to print all the packets we send or to otherwise have special logic for whenever we send a certain packet. Here our listeners would only be called when receiving packets, because they have the ``outgoing`` flag set to ``False``. Since it's annoying and error-prone to always specify the ``outgoing`` flag, we can make it default to ``False`` (or make specifying it required if we wanted to) by overriding the :meth:`.PacketHandler.register_packet_listener` method, like so::

class FelinePacketHandler(pak.PacketHandler):
def register_packet_listener(self, listener, *packet_types, outgoing=False, **flags):
Expand Down
8 changes: 4 additions & 4 deletions pak/packets/packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,12 @@ def GenericWithID(cls, id, /):
Parameters
----------
id
The ID of the generated :class:`GenericPacket`.
The ID of the generated :class:`Packet`.
Returns
-------
:class:`GenericPacket`
The generated :class:`GenericPacket`.
subclass of :class:`Packet`
The generated :class:`Packet`.
Examples
--------
Expand Down Expand Up @@ -414,7 +414,7 @@ def EmptyWithID(cls, id, /):
Returns
-------
:class:`Packet`
subclass of :class:`Packet`
The generated :class:`Packet`.
Examples
Expand Down
4 changes: 3 additions & 1 deletion pak/packets/packet_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,14 @@ def has_packet_listener(self, packet, **flags):
>>> ex = Example()
>>> ex.has_packet_listener(MyPacket())
True
>>> ex.has_packet_listener(pak.Packet)
>>> ex.has_packet_listener(pak.Packet())
False
>>>
>>> # You can also get whether a 'Packet' class has a listener:
>>> ex.has_packet_listener(MyPacket)
True
>>> ex.has_packet_listener(pak.Packet)
False
"""

for packet_types, listener_flags in self._packet_listeners.values():
Expand Down
2 changes: 1 addition & 1 deletion pak/types/deferring.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class DeferringType(Type):
to a certain :class:`.Type` depending on what it decides to return
from its :meth:`_defer_to` method.
This deferring of behavior is useful for instance in
This deferring of behavior is useful, for instance, in
protocols with multiple versions, where you may want
to have a :class:`.Packet` field act like a different
:class:`.Type` between different protocol versions.
Expand Down
2 changes: 1 addition & 1 deletion pak/types/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class EmptyType(Type):
It always unpacks to ``None`` and always packs
to ``b""``. It is useful in certain cases when you
would want to "disable" a packet field for instance.
would want to "disable" a packet field, for instance.
``None`` is a typelike value that translates to
:class:`EmptyType`.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pak"
version = "1.0.0"
version = "1.1.0"
description = "A general purpose packet marshaling library"
readme = "README.md"
requires-python = ">=3.8"
Expand Down

0 comments on commit 7bbabb2

Please sign in to comment.