Skip to content

v0.3.0: Discovery ⚖️

Choose a tag to compare

@github-actions github-actions released this 28 Jun 11:41
· 18 commits to main since this release
Immutable release. Only release title and notes can be modified.
0a4c0bc

⚖️ Discovery

v0.1.0 put Probatio on the record, v0.2.0 handed you the tools to cross-examine your test data. v0.3.0 is discovery: Probatio now takes in more kinds of evidence, and is sharper about what it does with them.

The temporal family grew up. AsDatetime, AsDate, and AsTime are the object-returning siblings of Datetime/Date/Time: they parse ISO 8601 out of the box (or a strptime format you pass) and hand you a real datetime/date/time, not the string back. Epoch reads a Unix timestamp into a timezone-aware UTC datetime. And Duration now accepts a plain numeric string as seconds, so "90" and 90 finally mean the same thing.

from probatio import Schema, AsDatetime, Epoch

Schema(AsDatetime())("2026-06-25T10:30:00+02:00")
# datetime.datetime(2026, 6, 25, 10, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200)))
Schema(Epoch())(1719571800)
# datetime.datetime(2024, 6, 28, 10, 50, tzinfo=datetime.timezone.utc)

New cross-field rules cover the last gap Home Assistant filled by hand: AtLeastOne, AtMostOne, and ExactlyOne say how many of a set of keys may or must appear, the dict-level form of Inclusive/Exclusive.

from probatio import Schema, All, ExactlyOne

Schema(All(dict, ExactlyOne("token", "password")))({"token": "t"})  # unchanged

The typed string validators gained control over their output. MacAddress, E164, HexColor, CreditCard, and IBAN take normalize=False to validate without rewriting, plus upper/separator where they fit. And two compatibility sharpenings: Coerce of an enum lists the valid values again (expected Color or one of 'red', 'green', 'blue'), and the OpenAPI codec emits format: date for Date() instead of date-time.

⚠️ Breaking change

E164, HexColor, CreditCard, and IBAN now normalize by default, so their output changes: grouping is stripped, IBAN is upper-cased, hex color is lower-cased, and E164 also starts accepting formatted numbers like +1 (415) 555-2671. Pass normalize=False to keep the old pass-through behavior. MacAddress is unaffected; it already normalized.

from probatio import Schema, IBAN

Schema(IBAN())("de89 3704 0044 0532 0130 00")          # 'DE89370400440532013000'
Schema(IBAN(normalize=False))("de89 3704 0044 0532 0130 00")  # unchanged

This is still a 0.x release: a faithful drop-in for voluptuous, validated against its behavior, with some internals still free to move before 1.0.

pip install probatio

📚 Docs: https://probatio.frenck.dev

Put your data to the proof. ⚖️

../Frenck

                       

Blogging my personal ramblings at frenck.dev

What's changed

🚨 Breaking changes

  • Add configurable normalization to typed string validators @frenck (#21)

✨ New features

  • Add AsDatetime/AsDate/AsTime object-returning parsers @frenck (#19)
  • Add Epoch validator for Unix timestamps @frenck (#20)
  • Add configurable normalization to typed string validators @frenck (#21)
  • Add AtLeastOne/AtMostOne/ExactlyOne key-group validators @frenck (#27)

🐛 Bug fixes

  • Fix OpenAPI encoder emitting date-time for Date() @frenck (#13)
  • List an enum's values in the Coerce error message @frenck (#28)

🚀 Enhancements

  • Accept a numeric string as seconds in Duration @frenck (#29)

🧰 Maintenance

  • ⬆️ Update gcr.io/oss-fuzz-base/base-builder-python:latest Docker digest to 66c3a78 @renovate[bot] (#14)
  • Upload test results to Codecov for test analytics @frenck (#23)
  • Use markdown.processor for the rehype plugin @frenck (#25)

📚 Documentation

  • Add a Codecov coverage badge to the README @frenck (#22)
  • Split the codec guide into JSON Schema, OpenAPI, and Field lists @frenck (#24)
  • Give TypedDict schemas their own guide page @frenck (#26)

⬆️ Dependency updates

12 changes