Skip to content

Text annotations

The text adaptor reads two annotations, str and Annotated[str, ...], and nothing else. str is the language of every string, L[unicode]; an Annotated[str, ...] carrying a length marker (MaxLen(80), pydantic's max_length, and the min_length side) is that language refined by the marker, L[unicode, len <= 80], and one with no length marker is L[unicode]. It is how a str parameter with no binding gets a language: the claim needs no for s in ..., and the record's note says the language was inferred and from where. It needs nothing installed beyond mathema and this package.

What it reads

Annotation Language Notes
str L[unicode]
Annotated[str, MaxLen(80)] L[unicode, len <= 80] the markers are read by attribute, max_length and min_length
str \| None, Optional[str] not answered how a missing value is admitted is decided in mathema itself
anything else not answered

A worked claim

Two of the shop's text helpers, from examples/shop/text.py:

from typing import Annotated

from annotated_types import MaxLen


def display_name(username: str) -> str:
    """The username as shown in the header, upper-cased."""
    return username.upper()


def short_title(title: Annotated[str, MaxLen(60)]) -> str:
    """The title, cut to the sixty characters the column holds."""
    return title[:60]
Function Claim Verdict Why
display_name len(f(username)) == len(username) falsified Inferred L[unicode], and 'fi' upper-cases to two code points.
short_title f(title) == title holds Inferred L[unicode, len <= 60], inside which the cut changes nothing.

Enforcing the schema

A function that guards a boundary should refuse a record its schema rejects. excluded_outside_domain feeds it records just outside the language, and the witness names the value and why it is outside, in the library's own words. This function trusts its input, so a record the schema rejects goes straight through:

def display_name(username: str) -> str:
    """The username as shown in the header, upper-cased."""
    return username.upper()
f = display_name
for username in L[ascii], excluded_outside_domain(username)
    falsified   username = '\ufeff' (outside L[ascii] at [0]: ascii alphabet)

The same claim over the function that loads the record, from a request or a database, is the one that should hold.