Skip to content

typed-format-version: Python API Reference

typed_format_version

typed-format-version: load format.version.{major,minor} from a structured file.

This module tries to parse a format.version "section" in some raw data that may have been loaded from a configuration file, and determines whether that section contains valid "major" and "minor" integer values. The caller can then choose the correct schema to validate the loaded data against, e.g. by using the typedload library with the correct top-level dataclass definition.

The most commonly used function will probably be get_version(): it takes a raw data dictionary and returns a Version object with a major and minor integer attributes, if the data contained a valid "format" dictionary with a "version" dictionary within it. Optionally the get_version() function can remove the top-level "format" member, if a true value is passed for the pop argument.

VERSION = '0.2.1' module-attribute

The typed_format_version library's version.

Format dataclass

The format specification.

Source code in typed_format_version/__init__.py
@dataclasses.dataclass(frozen=True)
class Format:
    """The format specification."""

    version: Version
    """The format version."""
version: Version class-attribute

The format version.

LoadError

Bases: ValueError

An error that occurred while looking for the format.version tuple.

Source code in typed_format_version/__init__.py
class LoadError(ValueError):
    """An error that occurred while looking for the format.version tuple."""

Version dataclass

The format version number.

Source code in typed_format_version/__init__.py
@dataclasses.dataclass(frozen=True)
class Version:
    """The format version number."""

    major: int
    """The major version number."""

    minor: int
    """The minor version number."""

    def as_version_tuple(self) -> VersionTuple:
        """Convert to a tuple for easier comparison and matching."""
        return VersionTuple(major=self.major, minor=self.minor)
major: int class-attribute

The major version number.

minor: int class-attribute

The minor version number.

as_version_tuple()

Convert to a tuple for easier comparison and matching.

Source code in typed_format_version/__init__.py
def as_version_tuple(self) -> VersionTuple:
    """Convert to a tuple for easier comparison and matching."""
    return VersionTuple(major=self.major, minor=self.minor)

VersionMatch dataclass

Matched version number and exactness.

Source code in typed_format_version/__init__.py
@dataclasses.dataclass(frozen=True)
class VersionMatch:
    """Matched version number and exactness."""

    version: Version
    """The matched version number."""

    failonextra: bool
    """True if the match was exact, false if the minor version number was higher."""
failonextra: bool class-attribute

True if the match was exact, false if the minor version number was higher.

version: Version class-attribute

The matched version number.

VersionTuple

Bases: NamedTuple

The format version number as a tuple for easier comparison and matching.

Source code in typed_format_version/__init__.py
class VersionTuple(NamedTuple):
    """The format version number as a tuple for easier comparison and matching."""

    major: int
    """The major version number."""

    minor: int
    """The minor version number."""
major: int class-attribute

The major version number.

minor: int class-attribute

The minor version number.

determine_version_match(version, schemas)

Figure out which schema to load and whether to allow extra fields.

If there is an exact major.minor version match, return the specified version and set the failonextra field to true, so that the data matches the specification exactly.

If there is no exact match, but there are versions with the same major number and a minor number that is lower than the specified one, then return the highest one among them (still lower than the specified one) and set the failonextra field to false, so as to allow extra fields ostensibly defined in a later format version.

Source code in typed_format_version/__init__.py
def determine_version_match(version: Version, schemas: Dict[Tuple[int, int], Any]) -> VersionMatch:
    """Figure out which schema to load and whether to allow extra fields.

    If there is an exact major.minor version match, return the specified
    version and set the `failonextra` field to true, so that the data
    matches the specification exactly.

    If there is no exact match, but there are versions with the same major
    number and a minor number that is lower than the specified one, then
    return the highest one among them (still lower than the specified one) and
    set the `failonextra` field to false, so as to allow extra fields ostensibly
    defined in a later format version.
    """
    major, minor = version.as_version_tuple()
    if (major, minor) in schemas:
        return VersionMatch(version=version, failonextra=True)

    try:
        highest_lower_minor = max(
            v_minor for (v_major, v_minor) in schemas if v_major == major and v_minor < minor
        )
    except ValueError as err:
        raise LoadError("match") from err
    return VersionMatch(
        version=Version(
            major=major,
            minor=highest_lower_minor,
        ),
        failonextra=False,
    )

get_format(data, *, pop=False)

Get the known attributes of the format member (only the version).

Source code in typed_format_version/__init__.py
def get_format(data: Dict[str, Any], *, pop: bool = False) -> Format:
    """Get the known attributes of the format member (only the version)."""
    try:
        raw = data.pop("format") if pop else data["format"]
    except (AttributeError, KeyError, TypeError) as err:
        raise LoadError("format") from err

    try:
        return typedload.load(raw, Format, failonextra=False)
    except typedload.exceptions.TypedloadException as err:
        raise LoadError(f"Could not parse the format element: {err}") from err

get_format_and_load(data, dtype, *, pop=False, **kwargs)

Get the format attributes, load and validate the data itself.

Source code in typed_format_version/__init__.py
def get_format_and_load(
    data: Dict[str, Any], dtype: Type[_T], *, pop: bool = False, **kwargs: Any  # noqa: ANN401
) -> Tuple[Format, _T]:
    """Get the format attributes, load and validate the data itself."""
    fmt = get_format(data, pop=pop)
    return fmt, typedload.load(data, dtype, **kwargs)

get_version(data, *, pop=False)

Get the major and minor format.version attributes.

Source code in typed_format_version/__init__.py
def get_version(data: Dict[str, Any], *, pop: bool = False) -> Version:
    """Get the major and minor format.version attributes."""
    return get_format(data, pop=pop).version

get_version_and_load(data, dtype, *, pop=False, **kwargs)

Get the version attributes, load and validate the data itself.

Source code in typed_format_version/__init__.py
def get_version_and_load(
    data: Dict[str, Any], dtype: Type[_T], *, pop: bool = False, **kwargs: Any  # noqa: ANN401
) -> Tuple[Version, _T]:
    """Get the version attributes, load and validate the data itself."""
    fmt, res = get_format_and_load(data, dtype, pop=pop, **kwargs)
    return fmt.version, res

get_version_t(data, *, pop=False)

Get the major and minor format.version attributes.

Source code in typed_format_version/__init__.py
def get_version_t(data: Dict[str, Any], *, pop: bool = False) -> VersionTuple:
    """Get the major and minor format.version attributes."""
    return get_version(data, pop=pop).as_version_tuple()

get_version_t_and_load(data, dtype, *, pop=False, **kwargs)

Get the version attributes, load and validate the data itself.

Source code in typed_format_version/__init__.py
def get_version_t_and_load(
    data: Dict[str, Any], dtype: Type[_T], *, pop: bool = False, **kwargs: Any  # noqa: ANN401
) -> Tuple[VersionTuple, _T]:
    """Get the version attributes, load and validate the data itself."""
    ver, res = get_version_and_load(data, dtype, pop=pop, **kwargs)
    return ver.as_version_tuple(), res