Registry / serialization / annotated-types

annotated-types

JSON →
library0.8.0pypypi✓ verified 10d ago

annotated-types provides reusable constraint metadata objects—such as Gt, Lt, Len, MultipleOf, Timezone, Predicate, and more—to be used with typing.Annotated (PEP 593). It does not enforce constraints itself; enforcement is left to consuming libraries like Pydantic, Hypothesis, or custom validators. Current version is 0.7.0 (released 2024). The project follows an irregular, feature-driven release cadence and was created at PyCon 2022 by the Pydantic and Hypothesis maintainers.

pip install annotated-types
INSTALL
IMPORT
SIG · ANNOTATED-TYPES
A
annotated-types
serializationpythonv0.8.0
Install
1.7s avg
Import
64ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.8.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.068s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.060s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Gt, Lt, Ge, Le, Interval
from annotated_types import Gt, Lt, Ge, Le, Interval
from annotated-types import Gt
PyPI slug uses a hyphen (annotated-types) but the importable package uses an underscore (annotated_types). Hyphenated import will raise a SyntaxError.
Len, MinLen, MaxLen
from annotated_types import Len, MinLen, MaxLen
from annotated_types import Len; Len(min_inclusive=0, max_exclusive=10)
Before v0.4.0, Len used min_inclusive/max_exclusive kwargs and max was exclusive. Since v0.4.0, use min_length/max_length (both inclusive). MinLen and MaxLen were added in v0.4.0 as convenience helpers.
Predicate
from annotated_types import Predicate
Predicate wraps a callable; prefer introspectable callables (e.g. str.isdigit) over lambdas so consuming libraries can reflect on the predicate and generate schemas.
Timezone
from annotated_types import Timezone
Since v0.7.0 accepts tzinfo objects (e.g. Timezone(timezone.utc)) in addition to strings. Use Timezone(...) for any-aware and Timezone(None) for naive datetimes.
IsDigits
from annotated_types import IsDigits
from annotated_types import IsDigit
Renamed from IsDigit to IsDigits in v0.7.0. Importing IsDigit will raise an ImportError on 0.7.0+.
Unit
from annotated_types import Unit
Added in v0.7.0. annotated_types itself does not validate or parse the unit string; that is left to downstream consumers.
GroupedMetadata
from annotated_types import GroupedMetadata
Protocol for custom grouped metadata. Interval and Len both implement it. Consumers must unpack GroupedMetadata and handle or ignore unknown items gracefully.

Demonstrates scalar bounds, collection length constraints, predicates, IsDigits, and Timezone usage, plus how to introspect annotations from Annotated types. No auth required.

from typing import Annotated, get_args, get_origin import math from annotated_types import Gt, Lt, Len, MinLen, MaxLen, MultipleOf, Predicate, Interval, Timezone, IsDigits from datetime import datetime, timezone # Scalar bounds PositiveInt = Annotated[int, Gt(0)] SmallFloat = Annotated[float, Interval(ge=0.0, le=1.0)] # Collection length (both bounds inclusive since v0.4.0) ShortList = Annotated[list, Len(1, 10)] NonEmptyStr = Annotated[str, MinLen(1)] CappedStr = Annotated[str, MaxLen(255)] # Predicate — prefer introspectable callables over lambdas FiniteFloat = Annotated[float, Predicate(math.isfinite)] DigitOnly = Annotated[str, IsDigits] # Timezone (v0.7.0+: accepts tzinfo objects) UTCDatetime = Annotated[datetime, Timezone(timezone.utc)] AwareDatetime = Annotated[datetime, Timezone(...)] NaiveDatetime = Annotated[datetime, Timezone(None)] # Reading metadata back (for library authors) def show_constraints(tp): if get_origin(tp) is Annotated: base, *metadata = get_args(tp) print(f"Base type: {base}, constraints: {metadata}") show_constraints(Annotated[int, Gt(0), Lt(100)])
Debug
Known issues
breakingImport module name uses underscores: `annotated_types`, not `annotated-types`. Using a hyphen causes a SyntaxError.
fix
Use `from annotated_types import ...` (underscore) in all import statements.
affects: all
breakingIn v0.4.0, Len's kwargs were renamed and the semantics of the upper bound changed: `min_inclusive` → `min_length` (same meaning), `max_exclusive` → `max_length` (now INCLUSIVE). Code using old kwargs or assuming exclusive upper bound will silently produce wrong constraints.
fix
Replace Len(min_inclusive=a, max_exclusive=b) with Len(min_length=a, max_length=b-1) if exclusive semantics were intended, or Len(min_length=a, max_length=b) if inclusive was the intent.
affects: <0.4.0
breaking`IsDigit` was renamed to `IsDigits` in v0.7.0. Importing `IsDigit` raises an ImportError on 0.7.0+.
fix
Replace `from annotated_types import IsDigit` with `from annotated_types import IsDigits`.
affects: <0.7.0
breakingPython 3.7 support was dropped in v0.6.0. The minimum required Python version is now 3.8.
fix
Upgrade to Python 3.8+ or pin annotated-types <0.6.0 for Python 3.7 environments.
affects: >=0.6.0
gotchaannotated-types does NOT enforce constraints at runtime itself. Metadata is purely declarative; enforcement depends entirely on the consuming library (e.g. Pydantic, Hypothesis). Annotating a field does not validate values without an active consumer.
fix
Pair annotated-types constraints with a runtime enforcement library such as Pydantic v2 or a custom get_args() inspector.
affects: all
gotchaMultipleOf has two semantically different interpretations: Python modulo (`value % multiple_of == 0`) vs. JSONSchema (`int(value / multiple_of) == value / multiple_of`). For floats, these can silently diverge due to floating-point imprecision.
fix
Check which interpretation your consuming library implements. Avoid using MultipleOf with non-integer or very large float values unless the library's behavior is explicitly documented.
affects: all
gotchaUsing lambda functions in Predicate prevents consuming libraries from introspecting the predicate for schema generation or targeted optimisations. Libraries may silently ignore or mishandle opaque lambdas.
fix
Use introspectable callables such as `str.isdigit`, `math.isfinite`, or `re.compile(...).search` instead of `lambda` wrappers inside Predicate.
affects: all
gotchaThe test output does not indicate a failure of the `annotated-types` library; it shows successful definition of constraints and includes unrelated `pip` warnings/notices.
fix
Focus on the behavior of the `annotated-types` library for failure diagnosis, disregarding unrelated output from package managers like pip.
affects: all
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'annotated_types'
The 'annotated-types' package is not installed in the Python environment.
fix
Install the package using 'pip install annotated-types'.
ImportError: cannot import name 'Gt' from 'annotated_types'
The 'Gt' class is not available in the installed version of 'annotated-types'.
fix
Ensure you have the latest version by running 'pip install --upgrade annotated-types'.
TypeError: 'Len' object is not callable
Attempting to call 'Len' as a function instead of using it as a type annotation.
fix
Use 'Len' within 'Annotated' for type annotations, e.g., 'Annotated[list[int], Len(0, 10)]'.
AttributeError: module 'annotated_types' has no attribute 'Predicate'
The 'Predicate' attribute is not present in the 'annotated-types' module.
fix
Verify the module's documentation for the correct usage or alternative implementations.
NameError: name 'Annotated' is not defined
The 'Annotated' type is not imported from the 'typing' module.
fix
Add 'from typing import Annotated' at the beginning of your script.
Upgrade
Version history
0.8.0latest on PyPI · released Jul 23, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
39 hits · last 30 days
node
32
Amazon
2
Resources
annotated-types — pip install annotated-types · libregistry