mafw.devtools.pyversions.config

Canonical Python version configuration model.

This module defines PythonConfig, the in-memory representation of the [tool.mafw] keys that are the single source of truth for the Python version management feature (GitLab issue #247):

  • supported-python — stable, officially supported CPython minor versions;

  • experimental-python — versions under evaluation, not advertised as supported;

  • default-python — the supported interpreter used for primary development;

  • free-threaded-python — the independently selected free-threaded interpreter.

PythonConfig is frozen and validates every configuration invariant required by the feature. It knows how to build itself from a parsed pyproject.toml document, naming every missing key, but performs no file I/O of its own — that responsibility belongs to the synchronization service.

author:

Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)

Functions

base_version(free_threaded)

Return the major.minor base version of a free-threaded selector.

Classes

PythonConfig(supported, experimental, ...)

Immutable canonical Python version policy.

class mafw.devtools.pyversions.config.PythonConfig(supported: tuple[str, ...], experimental: tuple[str, ...], default: str, free_threaded: str)[source]

Bases: object

Immutable canonical Python version policy.

The four fields mirror the [tool.mafw] keys. Lists are stored as tuples so that instances remain hashable and cannot be mutated in place; the version manager produces new instances rather than editing existing ones.

Variables:
  • supported – Stable supported versions, ascending and unique.

  • experimental – Experimental versions, ascending and unique.

  • default – The default development interpreter (a supported version).

  • free_threaded – The free-threaded interpreter selector (e.g. 3.14t).

classmethod from_document(doc: TOMLDocument) → PythonConfig[source]

Build a PythonConfig from a parsed pyproject.toml document.

Every required [tool.mafw] key is checked; if one or more are missing, a single error naming all of them is raised so the operator can fix them in one pass.

Parameters:

doc (tomlkit.TOMLDocument) – The parsed TOML document.

Returns:

The canonical configuration (not yet validated for invariants).

Return type:

PythonConfig

Raises:

DevtoolsError – If any required key is missing or has the wrong type.

static _as_str(value: object, key: str) → str[source]

Coerce a TOML scalar into a plain string, validating its type.

static _as_str_tuple(value: object, key: str) → tuple[str, ...][source]

Coerce a TOML array into a tuple of plain strings, validating its type.

static _validate_list(versions: tuple[str, ...], key: str) → None[source]

Validate format, uniqueness and ascending order of a version list.

validate() → None[source]

Enforce every configuration invariant required by the feature.

The checks mirror Requirement 11 of the specification:

  • each list is free of duplicates;

  • the two lists are mutually exclusive;

  • each list is sorted ascending by (major, minor);

  • default is a stable version present in supported;

  • the base version of free_threaded is present in supported.

The default and free-threaded selections are allowed to differ freely — there is deliberately no coupling constraint between them.

Raises:

DevtoolsError – On the first violated invariant, with a message naming the offending key and value.

mafw.devtools.pyversions.config._version_sort_key(version: str) → tuple[int, int][source]

Return the (major, minor) numeric sort key for a major.minor string.

Used to compare and order stable versions numerically rather than lexically, so that 3.9 sorts before 3.10.

mafw.devtools.pyversions.config.base_version(free_threaded: str) → str[source]

Return the major.minor base version of a free-threaded selector.

For example the base version of 3.14t is 3.14. The function accepts any token the identifier parser understands and extracts its base version.

Parameters:

free_threaded (str) – A free-threaded selector such as "3.14t".

Returns:

The major.minor base version.

Return type:

str

Raises:

DevtoolsError – If free_threaded is not a valid identifier.

mafw.devtools.pyversions.config._REQUIRED_KEYS: Final[tuple[str, ...]] = ('supported-python', 'experimental-python', 'default-python', 'free-threaded-python')

Every [tool.mafw] key required by the Python version management feature.