mafw.devtools.pyversions.derivations

Canonical-to-derived projections for the Python version management feature.

Every location in pyproject.toml that the feature keeps in sync is a pure projection of the canonical PythonConfig. This module gathers those projection functions so that both the synchronization service and the consistency check compute the desired value of each derived location in exactly one place.

It also provides the classification used to distinguish version references that are managed by a given role (and must therefore follow it) from deliberate pinned interpreter selections (which must never be rewritten by a role change), such as the pre-push command hatch test -py 3.12 that intentionally exercises an interpreter without sys._is_gil_enabled.

> ** IMPORTANT NOTE ** > Along with some very stable projections, like for example the project classifiers, > this module is addressing also a few points (gil / nogil environments and pre-push > command definition) that are rather volatile. So everytime we change something in the > pyproject.toml we should verify that there are not drifts with respect to what > is described here.

Added in version 2.4.

author:

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

Functions

classify_pre_push(command, cfg)

Classify a single pre-push command against the managed roles.

desired_classifiers(cfg)

Return the per-version Python classifiers implied by the supported list.

desired_dev_matrix(cfg)

Return the dev environment matrix.

desired_experimental_matrix(cfg)

Return the dedicated experimental environment matrix.

desired_free_threaded_matrix(cfg)

Return the dedicated hatch-test free-threaded matrix row.

desired_gil_python(cfg)

Return the interpreter for the gil environment.

desired_nogil_python(cfg)

Return the interpreter for the nogil environment (the free-threaded one).

desired_standard_matrix(cfg)

Return the hatch-test standard matrix (the supported versions).

desired_types_matrix(cfg)

Return the types environment matrix (the supported versions).

retarget_default_command(command, ...)

Rewrite the default-interpreter selector in a managed pre-push command.

retarget_free_threaded_command(command, ...)

Rewrite the free-threaded selector in a managed pre-push command.

Classes

PrePushClassification(*values)

How a pre-push command relates to the managed Python version roles.

class mafw.devtools.pyversions.derivations.PrePushClassification(*values)[source]

Bases: Enum

How a pre-push command relates to the managed Python version roles.

DEFAULT_MANAGED = 'default_managed'

References the default interpreter and must follow default-python.

FREE_THREADED_MANAGED = 'free_threaded'

References the free-threaded interpreter and must follow free-threaded-python.

PINNED = 'pinned'

A deliberate pin to a specific interpreter; never rewritten by a role change.

UNCLASSIFIED = 'unclassified'

Contains no recognised interpreter selector, or an ambiguous one.

mafw.devtools.pyversions.derivations.classify_pre_push(command: str, cfg: PythonConfig) → PrePushClassification[source]

Classify a single pre-push command against the managed roles.

The classification uses narrowly scoped, anchored patterns that match only the interpreter selector, never the whole command text. A command is:

Parameters:
  • command – The pre-push command string.

  • cfg – The current canonical configuration.

Returns:

The classification of command.

mafw.devtools.pyversions.derivations.desired_classifiers(cfg: PythonConfig) → list[str][source]

Return the per-version Python classifiers implied by the supported list.

Experimental versions are deliberately excluded: a version under evaluation must never be advertised as officially supported.

mafw.devtools.pyversions.derivations.desired_dev_matrix(cfg: PythonConfig) → list[str][source]

Return the dev environment matrix.

The dev environment intentionally omits the free-threaded interpreter (its optional features are incompatible with it), so the matrix is exactly the stable supported versions.

mafw.devtools.pyversions.derivations.desired_experimental_matrix(cfg: PythonConfig) → list[str][source]

Return the dedicated experimental environment matrix.

Experimental versions live only here; they never expand the mandatory standard, dev or types matrices.

mafw.devtools.pyversions.derivations.desired_free_threaded_matrix(cfg: PythonConfig) → list[str][source]

Return the dedicated hatch-test free-threaded matrix row.

mafw.devtools.pyversions.derivations.desired_gil_python(cfg: PythonConfig) → str[source]

Return the interpreter for the gil environment.

The gil environment mirrors nogil but with the standard, GIL-enabled interpreter of the same minor version, so that performance comparisons stay aligned. It therefore tracks the base version of the free-threaded selector.

mafw.devtools.pyversions.derivations.desired_nogil_python(cfg: PythonConfig) → str[source]

Return the interpreter for the nogil environment (the free-threaded one).

mafw.devtools.pyversions.derivations.desired_standard_matrix(cfg: PythonConfig) → list[str][source]

Return the hatch-test standard matrix (the supported versions).

mafw.devtools.pyversions.derivations.desired_types_matrix(cfg: PythonConfig) → list[str][source]

Return the types environment matrix (the supported versions).

mafw.devtools.pyversions.derivations.retarget_default_command(command: str, old_default: str, new_default: str) → str[source]

Rewrite the default-interpreter selector in a managed pre-push command.

Only the interpreter selector that currently equals old_default is rewritten to new_default; the rest of the command (and any other version token) is left untouched. The function is only ever called on commands that have been classified as PrePushClassification.DEFAULT_MANAGED.

Parameters:
  • command – The command to rewrite.

  • old_default – The current default version (e.g. "3.14").

  • new_default – The new default version (e.g. "3.15").

Returns:

The rewritten command.

mafw.devtools.pyversions.derivations.retarget_free_threaded_command(command: str, new_free_threaded: str) → str[source]

Rewrite the free-threaded selector in a managed pre-push command.

Only an X.Yt selector is replaced; stable selectors (pins) are ignored. The function is only ever called on commands classified as PrePushClassification.FREE_THREADED_MANAGED.

Parameters:
  • command – The command to rewrite.

  • new_free_threaded – The new free-threaded selector (e.g. "3.15t").

Returns:

The rewritten command.

mafw.devtools.pyversions.derivations._CLASSIFIER_PREFIX: Final[str] = 'Programming Language :: Python :: '

Prefix of the per-version Python classifiers in [project].classifiers.

mafw.devtools.pyversions.derivations._ENV_PY_REF_RE: Final[Pattern[str]] = re.compile('\\b(dev|types)\\.py(\\d+\\.\\d+)\\b')

Matches a dev.pyX.Y / types.pyX.Y environment reference.

mafw.devtools.pyversions.derivations._HATCH_TEST_PY_RE: Final[Pattern[str]] = re.compile('\\bhatch\\s+test\\s+-py\\s+(\\d+\\.\\d+t?)\\b')

Matches the interpreter selector of a hatch test -py <selector> command.