Skip to content

0.11.0

Compare
Choose a tag to compare
@dargueta dargueta released this 14 Feb 16:25
· 53 commits to master since this release
55baf2d

New Features

  • New Field!: UUID4: Store a UUID4 in four different formats: variant 1 (the most common), Microsoft format (variant 2), the canonical string representation, or as a hexadecimal string.
  • Official support for CPython 3.10, 3.11, PyPy 3.8, and PyPy 3.9.
  • New exception BuggyFieldImplementationError to give better information to people who are implementing custom fields.
  • Field implementations now no longer need to handle None in _size_for_value(). The method is now guaranteed to never be called with None.
  • Field.compute_value_for_dump() gained a context argument, so you can now pass your context object in and it'll get passed through to the present check.

Breaking Changes

  • Dropped support for Python 3.5 and 3.6 as per the deprecation policy (when Pip drops support for a Python version, I no longer guarantee support).
  • Switching to pyproject.toml breaks support for Pip older than 19.0. I consider this acceptable because Pip 19.0 is over four years old at this point, and predates the sunsetting of 3.5 and 3.6.

Deprecations

Callable Defaults

Specifying a callable as a default argument was a terrible idea in retrospect. Even at the time in the release notes I said it "[...] looks confusing and is not recommended. This may throw an exception in the future if I decide it's too egregious."

Thus, please don't do this:

    @binobj.dataclass
    class MyStruct(binobj.Struct):
        username: StringZ = getpass.getusername

For now it will only issue a DeprecationWarning, but will crash in the future. Instead, use the new factory argument:

    @binobj.dataclass
    class MyStruct(binobj.Struct):
        username: StringZ(factory=getpass.getusername)

Mixing Naive/Aware Timestamps

Passing a timezone-aware timestamp to a Timestamp field that was naive, or passing a naive timestamp to a timezone-aware Timestamp field is deprecated. In the future, doing so will trigger an error.

Bugfixes

  • Field.compute_value_for_dump() now returns NOT_PRESENT in call cases where the field should be omitted. Before, it only checked to see if the field should be omitted if a value wasn't explicitly set for that field.

  • Circular references involving a computed field are now handled properly and won't crash with a MissingRequiredValueError.

  • Fixed a bug where StringZ would trigger a stack overflow when dumping if all the following conditions were met:

    • The default value was None (either from default or factory)
    • The default was used
    • null_value was set to a string (not bytes).

Other Changes

  • Attempting to change the name of an already-bound field will throw a ConfigurationError.
  • If a field depends on another field to give its size, and that other field has a non-integer value, a TypeError is thrown upon loading or dumping.
  • Codec information for variable-length integers now uses dataclasses instead of dicts. This gives us the ability to add in stricter typing information and remove a number of typecasts.
  • Endianness arguments to functions now have stricter, more accurate typing. If you use
    MyPy, it may get angry.

Internal Changes

  • Removed struct metaclass in favor of __init_subclass__().
  • Dropping 3.5 support allowed for some changes to the type declarations so they're more accurate.
  • Minor code hygiene changes.
  • Removed attrs as a dependency in favor of dataclasses from the Python standard library.
  • Moved to Poetry for handling installation.