MT016: PythonVersionConsistency

Overview

Property Value
ID MT016
Name PythonVersionConsistency
Group metadata
Severity WARNING

Description

Verifies that the requires-python specifier and Python version classifiers in pyproject.toml are consistent.

Consistency matters because:

  • Inconsistent metadata confuses users about supported Python versions
  • Package installers may behave unexpectedly
  • PyPI displays conflicting information
  • CI/CD pipelines may test wrong versions

What it checks

The check parses requires-python and compares it to Programming Language :: Python :: X.Y classifiers:

  • PASSED: All classifier versions fall within the requires-python range
  • FAILED: Classifiers list versions outside the requires-python range
  • NOT_APPLICABLE: Missing requires-python or no Python version classifiers

Example of inconsistency

# Inconsistent: requires-python says >=3.9 but classifiers include 3.8
[project]
requires-python = ">=3.9"
classifiers = [
    "Programming Language :: Python :: 3.8",  # INVALID: below 3.9
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
]

How to fix

Align classifiers with requires-python

# Consistent: classifiers match requires-python range
[project]
requires-python = ">=3.9"
classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
]

Update requires-python to match tested versions

If you actually support Python 3.8:

[project]
requires-python = ">=3.8"
classifiers = [
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
]

Handle upper bounds

If you have an upper bound on Python version:

# Only supports Python 3.9 through 3.11
[project]
requires-python = ">=3.9,<3.12"
classifiers = [
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    # Don't include 3.12 - outside requires-python range
]

Common mistakes

Including untested versions:

# Bad: claims 3.13 support without testing
[project]
requires-python = ">=3.9"
classifiers = [
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.13",  # Have you tested this?
]

Including deprecated versions:

# Bad: includes EOL Python versions
[project]
requires-python = ">=3.9"
classifiers = [
    "Programming Language :: Python :: 3.6",  # EOL, not in requires-python
    "Programming Language :: Python :: 3.9",
]

Why WARNING severity?

This check is a WARNING because:

  • Inconsistency doesn’t break the package
  • It causes confusion rather than failures
  • Users may attempt installation on unsupported versions
  • Some tools only check requires-python, others check classifiers

Configuration

Skip this check

[tool.pycmdcheck]
skip = ["MT016"]

CLI

pycmdcheck --skip MT016

Best practices

  1. Test all claimed versions: Run CI on every Python version in classifiers
  2. Use version matrices: Define versions in one place and generate both
  3. Update together: When dropping/adding versions, update both fields
  4. Include generic classifier: Add Programming Language :: Python :: 3
  5. Document version policy: Explain which Python versions you support

Matrix example for CI

# .github/workflows/test.yml
strategy:
  matrix:
    python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

Keep classifiers in sync with CI

# pyproject.toml
[project]
requires-python = ">=3.9"
classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
]