Skip to content

Conversation

@Iamrodos
Copy link
Contributor

@Iamrodos Iamrodos commented Nov 3, 2025

This PR aligns Python version requirements across documentation, packaging, and CI to prevent compatibility issues and make requirements explicit for contributors.

Changes

  • setup.py: Add python_requires=">=3.8" to enforce minimum version at pip install time
  • README.rst: Explicitly document "Python 3.8 or higher" requirement (was just "Python")
  • CI (lint.yml): Add test matrix for Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, and 3.14

Rationale

This project already declares Python 3.8-3.12 support via setup.py classifiers, but this requirement was not enforced or tested. This PR makes that declaration official and enforceable.

Why Python 3.8+ specifically:

  1. Already declared: setup.py classifiers claim 3.8-3.12 support only
  2. EOL status: Python 3.6 (EOL Dec 2021) and 3.7 (EOL June 2023) are no longer receiving security updates
  3. Usage data: PyPI stats show ~99% of downloads are on Python 3.8+ (5,186/month)
    • Python 3.12: ~60-100+ downloads/day
    • Python 3.8: ~50-65 downloads/day
    • Python 3.6-3.7: <100/month total (likely CI/bots)
    • Python 2.7/3.5: effectively zero usage

Historical context:

  • Before the attachment feature (PR feat: Add attachment download support for issues and pull requests #439), the codebase only used .format() strings and could technically support Python 3.0+
  • The attachment feature introduced f-strings, raising the actual minimum to Python 3.6+
  • Given we could now choose 3.6+, we align with the already-declared 3.8+ to match EOL policies and actual usage

The gap this fixes:

Without explicit enforcement and CI testing, contributors could easily introduce incompatible syntax:

Common Python features that require newer versions:

  • Python 3.6+: f-strings (PEP 498) - f"hello {name}" - Already in codebase
  • Python 3.8+: Walrus operator := (PEP 572) - if (n := len(a)) > 10:
  • Python 3.9+: Dict merge operator | (PEP 584) - d1 | d2
  • Python 3.9+: Type hints with [] (PEP 585) - list[int] instead of List[int]
  • Python 3.10+: Union type syntax X | Y (PEP 604) - def foo(x: int | str):
  • Python 3.10+: match/case statements (PEP 634) - Structural pattern matching

These features are increasingly common in modern Python code. Without CI testing on all supported versions, a PR using these features could pass code review and break users on older Python versions.

Impact

Benefits

  • For users: pip blocks installation on unsupported Python versions, preventing runtime failures
  • For contributors: README clearly documents minimum Python 3.8+ requirement upfront
  • For maintainers: CI automatically catches incompatible syntax across all 7 supported versions (3.8-3.14)
  • Net benefit: Protects 5,000+ monthly active users from future code incompatibilities

Drawbacks

  • Breaking change: Users on Python <3.8 cannot install new versions (pip will error with clear message)
  • Affected users: Minimal impact (~1-2 real users based on download stats, all on EOL Python versions)
  • Migration path: Users on EOL Python versions can continue using current version (0.50.3) indefinitely

Testing

  • All changes are declarative (no code logic changes)
  • CI will automatically test on all 7 Python versions on this PR
  • python_requires is a standard setuptools feature used by thousands of packages

Thank you for reviewing and considering this change.

- Add python_requires=">=3.8" to setup.py to enforce minimum version at install time
- Update README to explicitly document Python 3.8+ requirement
- Add CI matrix to test lint/build on Python 3.8-3.14 (7 versions)
- Aligns with actual usage patterns (~99% of downloads on Python 3.8+)
- Prevents future PRs from inadvertently using incompatible syntax

This change protects users by preventing installation on unsupported Python
versions and ensures contributors can see version requirements clearly.
@josegonzalez
Copy link
Owner

Just a question, are you using AI to write these PRs?

@josegonzalez
Copy link
Owner

Looks like 3.8 and 3.9 fail, and those also aren't supported Python versions anyways. Can you drop those in a separate PR and update this one to only include the passing ones?

@Iamrodos
Copy link
Contributor Author

Iamrodos commented Nov 4, 2025

Just a question, are you using AI to write these PRs?

Yes for research, language and summarisation. Well aware of hallucinations and false facts so I check everything diligently. Aim is clarity over expediency. Worked at Amazon for many years so experienced at crafting documents fur such things. The AI is good if it has a good instructor, otherwise its like the intern you never want near anything. :)

For example analysis of existing python usage was much faster than doing it myself, but I had to litmus test it plus I had a second AI validate the first.

3.8 and 3.9 are failing because the pinned dependencies don't support them:
- autopep8==2.3.2 needs Python 3.9+
- bleach==6.3.0 needs Python 3.10+

Both are EOL now anyway (3.8 in Oct 2024, 3.9 in Oct 2025).

Just fixing CI to test 3.10-3.14 for now. Will do a separate PR to formally
drop 3.8/3.9 support with python_requires and README updates.
@Iamrodos
Copy link
Contributor Author

Iamrodos commented Nov 4, 2025

Removed 3.8 and 3.9 from the CI matrix. As you rightly pick up they too are EOL now (3.9 just last week).

The pinned dependencies don't support them anyway.

This should make the CI pass.

I will do a follow-up PR to drop 3.8 and 3.9 support with the python_requires and README.

@Iamrodos
Copy link
Contributor Author

Iamrodos commented Nov 4, 2025

Can you drop those in a separate PR

Done, see #442 .

Thank for holding my hand, I have not done many PRs for other projects so I am learning a lot as I go.

@Iamrodos Iamrodos changed the title feat: Enforce Python 3.8+ requirement and add multi-version CI testing chore: Enforce Python 3.8+ requirement and add multi-version CI testing Nov 4, 2025
@josegonzalez
Copy link
Owner

I mostly asked because the ticket description reminded me of it and made me eye-roll a bit before I read the PR itself :)

@josegonzalez
Copy link
Owner

Mind rebasing this onto the master branch? I think once thats sorted, I can merge this and we're good to go to review the bigger PR :)

@Iamrodos
Copy link
Contributor Author

Iamrodos commented Nov 5, 2025

Mind rebasing this onto the master branch?

Done.

Hopefully my cause of an eye roll does not taint the attachment feature. It was two days of hard graft, mostly in testing and tracking down corner cases (such as repo renames). Worked hard to make it fit well with the existing code and design the feature with a similar approach to the existing one.

It was actually a really nice puzzle, to work with someone else's code, rather than it all being exclusively my own. As mentioned, I have not made many contributions before, this is my first decent size one. So I am learning. :)

@josegonzalez
Copy link
Owner

No its just I've seen a lot of AI-driven PRs that end up being very poor quality so thats kinda what I was expecting out of this and the other one. That hasn't been the case here at least.

@josegonzalez josegonzalez merged commit 8f859be into josegonzalez:master Nov 6, 2025
5 checks passed
@Iamrodos Iamrodos deleted the feat/python-version-requirements-clean branch November 6, 2025 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants