Skip to content

Remove support for Python 3.9#4827

Merged
Bibo-Joshi merged 32 commits intomasterfrom
rm-3.9
Oct 16, 2025
Merged

Remove support for Python 3.9#4827
Bibo-Joshi merged 32 commits intomasterfrom
rm-3.9

Conversation

@harshil21
Copy link
Member

@harshil21 harshil21 commented Jun 13, 2025

To be merged after #4825 and after python 3.9 reaches EOL in October

A lot of find and replace along with copilot agent edits.

Didn't use the new TypeGuard feature yet. match statements is also not used right now.

@harshil21 harshil21 requested review from Bibo-Joshi and Copilot June 13, 2025 21:15
@harshil21 harshil21 added the 🔗 python related technology: python label Jun 13, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR removes support for Python 3.9 and fully adopts Python 3.10+ syntax and tooling.

  • Migrated all Optional[...] and Union[...] type hints to PEP 604 union syntax (X | None, A | B).
  • Updated project configuration, CI, pre-commit, and documentation to require Python >= 3.10.
  • Adjusted examples and docs to match the new minimum Python version.

Reviewed Changes

Copilot reviewed 218 out of 218 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/telegram/_chatfullinfo.py Switched Optional[...] annotations to PEP 604 union syntax.
src/telegram/_chatboost.py Updated api_kwargs and type hints to union syntax in boost classes.
src/telegram/_chatbackground.py Migrated Optional to union syntax for chat background classes.
src/telegram/_chatadministratorrights.py Replaced Optional[bool] with `bool
src/telegram/_callbackquery.py Updated function signatures and return types to union syntax.
src/telegram/_business.py Converted Optional annotations to union syntax in business classes.
src/telegram/_botname.py Adjusted api_kwargs type to union syntax.
src/telegram/_botdescription.py Changed api_kwargs annotation to union syntax in description classes.
src/telegram/_botcommandscope.py Removed legacy Optional/Union imports and applied union annotations.
src/telegram/_botcommand.py Updated api_kwargs annotation to union syntax in bot command.
src/telegram/_birthdate.py Migrated Optional[int] to `int
src/telegram/main.py Changed _git_revision return type to `str
pyproject.toml Bumped requires-python to >=3.10 and updated Python version fields.
examples/contexttypesbot.py Updated example optional parameters to union syntax.
examples/chatmemberbot.py Changed return type of extract_status_change to union syntax.
docs/auxil/admonition_inserter.py Adjusted type hints in admonition inserter for union syntax.
changes/config.py Migrated Optional to union syntax in chango config.
README.rst Updated compatibility statement to Python 3.10+.
.pre-commit-config.yaml Adjusted pyupgrade hook args to --py310-plus.
.github/workflows/unit_tests.yml Removed Python 3.9 from test matrix.
Comments suppressed due to low confidence (2)

pyproject.toml:34

  • Update the project classifiers to include Python 3.13 and 3.14 to match the CI test matrix and declared compatibility.
"Programming Language :: Python :: 3.12",

pyproject.toml:11

  • [nitpick] Consider adding an upper bound to the Python requirement (e.g., ">=3.10,<4.0") to prevent unintended installation on Python 4.x releases.
requires-python = ">=3.10"

@harshil21 harshil21 added the 📋 do-not-merge-yet work status: do-not-merge-yet label Jun 13, 2025
@harshil21
Copy link
Member Author

harshil21 commented Jun 14, 2025

So apparently python recommends using X | Y syntax but this fails in subtle ways and makes life harder in instances like these:

>>> from typing import TypeAlias
>>> a: TypeAlias = "int"
>>> def this(arg: a | None):pass
... 
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    def this(arg: a | None):pass
                  ~~^~~~~~
TypeError: unsupported operand type(s) for |: 'str' and 'NoneType'

Now doing def this(arg: "a | None"):pass will work and appear to be fine. However this fails when you try to evaluate the forward reference, which is why test_official fails right now.

TypeAlias is actually deprecated in favor of type (py 3.12+). Using that will now not error on def this(arg: a | None):pass, but still fails test_official, because the types aren't actually evaluated:

type A = int | str
b = A | float
expected = int | float | str

b == expected  # False

b = A.__value__ | float  # Force evaluation
b == expected  # True

Anyway so for now it seems we'll have to settle and keep using Optional/Union in some places...

Base automatically changed from 3.14 to master June 19, 2025 18:18
Copy link
Member

@Bibo-Joshi Bibo-Joshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

October is finally coming up 🥳
I skimmed through the changes - the overwhelming part apparently is intruducing | :D A few files looked more interesting and I've left some comments :)
Thanks for keeping track of this!

@harshil21 harshil21 removed the 📋 do-not-merge-yet work status: do-not-merge-yet label Oct 14, 2025
@harshil21 harshil21 mentioned this pull request Oct 14, 2025
1 task
@harshil21
Copy link
Member Author

Should be good to merge! Hopefully there aren't more subtle merge artifacts in critical files. I would expect the test suite to fail then.

Copy link
Member

@Bibo-Joshi Bibo-Joshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did more skim-reading but found only one file where I have a question. thanks for the updates!

@Bibo-Joshi Bibo-Joshi merged commit 3329e2b into master Oct 16, 2025
29 of 30 checks passed
@Bibo-Joshi Bibo-Joshi deleted the rm-3.9 branch October 16, 2025 06:12
@github-actions github-actions bot locked and limited conversation to collaborators Oct 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

🔗 python related technology: python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants