Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python 3.12 beta to test matrix #3751

Merged
merged 26 commits into from Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c7ea5fd
Remove Python 3.7 from testing, docs and packaging
Bibo-Joshi Jun 2, 2023
f1784b5
Re-add note on CI bots
Bibo-Joshi Jun 3, 2023
03d3c33
temporarily run tests on this branch
harshil21 Jun 3, 2023
4de4643
Add missing new line
Bibo-Joshi Jun 4, 2023
457e4ef
Adopt Py3.8+ features: `missing_ok` Parameter (#3742)
Trifase Jun 4, 2023
a1c2fe7
Introduce Walrus Operator (#3749)
thefunkycat Jun 8, 2023
f663f37
Add python 3.12 to test matrix
harshil21 Jun 9, 2023
b49d03f
correct typo
harshil21 Jun 9, 2023
9d3345c
Remove Python 3.7 Workaround for `PicklePersistence` (#3740)
harshil21 Jun 9, 2023
1a3e4f7
Fix tests on py 3.12
harshil21 Jun 9, 2023
8c86a34
Merge branch 'master' into drop-py-37
Bibo-Joshi Jun 12, 2023
cf71a38
Drop `CancelledError` (#3754)
clot27 Jun 17, 2023
9181369
Make use of `@final`, `Final` and `Literal` (#3753)
Bibo-Joshi Jun 17, 2023
27a8683
fix error with `Literal`, causing tests/docs to fail (#3764)
lemontree210 Jun 19, 2023
b44e4af
Review: don't drop support for async gens for py < 3.12
harshil21 Jun 20, 2023
40c2cf3
Merge branch 'drop-py-37' into add-py-312
harshil21 Jun 20, 2023
8234f3c
Bump mypy and address review
harshil21 Jun 20, 2023
162004f
Review: Add deprecation warning & modify type hints
harshil21 Jul 2, 2023
8b73410
use 3.12 beta 3
harshil21 Jul 2, 2023
4962c48
merge master and fix conflicts
harshil21 Jul 2, 2023
9d0c980
try to fix type completeness CI check
harshil21 Jul 2, 2023
e753dd7
fix a leftover merge conflict
harshil21 Jul 2, 2023
0755fe1
bump mypy again
harshil21 Jul 2, 2023
316e500
try bumping pyright
harshil21 Jul 2, 2023
69ef58b
review: fix pyright by applying 'RT' generic
harshil21 Jul 4, 2023
816f020
Merge branch 'master' into add-py-312
Bibo-Joshi Jul 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ${{matrix.os}}
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12.0-beta.3']
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: False
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/type_completeness.yml
Expand Up @@ -22,7 +22,7 @@ jobs:
cache-dependency-path: '**/requirements*.txt'
- name: Install Pyright
run: |
python -W ignore -m pip install pyright~=1.1.291
python -W ignore -m pip install pyright~=1.1.316
- name: Get PR Completeness
# Must run before base completeness, as base completeness will checkout the base branch
# And we can't go back to the PR branch after that in case the PR is coming from a fork
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Expand Up @@ -35,7 +35,7 @@ repos:
- aiolimiter~=1.1.0
- . # this basically does `pip install -e .`
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
rev: v1.4.1
hooks:
- id: mypy
name: mypy-ptb
Expand Down
37 changes: 29 additions & 8 deletions telegram/ext/_application.py
Expand Up @@ -23,6 +23,7 @@
import itertools
import platform
import signal
import sys
from collections import defaultdict
from copy import deepcopy
from pathlib import Path
Expand Down Expand Up @@ -64,6 +65,7 @@
from telegram.ext._utils.stack import was_called_by
from telegram.ext._utils.trackingdict import TrackingDict
from telegram.ext._utils.types import BD, BT, CCT, CD, JQ, RT, UD, ConversationKey, HandlerCallback
from telegram.warnings import PTBDeprecationWarning

if TYPE_CHECKING:
from telegram import Message
Expand All @@ -78,6 +80,17 @@
_STOP_SIGNAL = object()
_DEFAULT_0 = DefaultValue(0)


# Since python 3.12, the coroutine passed to create_task should not be an (async) generator. Remove
# this check when we drop support for python 3.11.
if sys.version_info >= (3, 12):
harshil21 marked this conversation as resolved.
Show resolved Hide resolved
_CoroType = Awaitable[RT]

Check warning on line 87 in telegram/ext/_application.py

View check run for this annotation

Codecov / codecov/patch

telegram/ext/_application.py#L87

Added line #L87 was not covered by tests
else:
_CoroType = Union[Generator["asyncio.Future[object]", None, RT], Awaitable[RT]]

_ErrorCoroType = Optional[_CoroType[RT]]


_LOGGER = get_logger(__name__)


Expand Down Expand Up @@ -950,7 +963,7 @@

def create_task(
self,
coroutine: Union[Generator[Optional["asyncio.Future[object]"], None, RT], Awaitable[RT]],
coroutine: _CoroType[RT],
update: Optional[object] = None,
*,
name: Optional[str] = None,
Expand All @@ -971,6 +984,8 @@

.. versionchanged:: 20.2
Accepts :class:`asyncio.Future` and generator-based coroutine functions.
.. deprecated:: NEXT.VERSION
Since Python 3.12, generator-based coroutine functions are no longer accepted.
update (:obj:`object`, optional): If set, will be passed to :meth:`process_error`
as additional information for the error handlers. Moreover, the corresponding
:attr:`chat_data` and :attr:`user_data` entries will be updated in the next run of
Expand All @@ -988,7 +1003,7 @@

def __create_task(
self,
coroutine: Union[Generator[Optional["asyncio.Future[object]"], None, RT], Awaitable[RT]],
coroutine: _CoroType[RT],
update: Optional[object] = None,
is_error_handler: bool = False,
name: Optional[str] = None,
Expand Down Expand Up @@ -1025,14 +1040,22 @@

async def __create_task_callback(
self,
coroutine: Union[Generator[Optional["asyncio.Future[object]"], None, RT], Awaitable[RT]],
coroutine: _CoroType[RT],
update: Optional[object] = None,
is_error_handler: bool = False,
) -> RT:
try:
if isinstance(coroutine, Generator):
# Generator-based coroutines are not supported in Python 3.12+
if sys.version_info < (3, 12) and isinstance(coroutine, Generator):
harshil21 marked this conversation as resolved.
Show resolved Hide resolved
warn(
"Generator-based coroutines are deprecated in create_task and will not work"
" in Python 3.12+",
category=PTBDeprecationWarning,
)
return await asyncio.create_task(coroutine)
return await coroutine
# If user uses generator in python 3.12+, Exception will happen and we cannot do
# anything about it. (hence the type ignore if mypy is run on python 3.12-)
return await coroutine # type: ignore
except Exception as exception:
if isinstance(exception, ApplicationHandlerStop):
warn(
Expand Down Expand Up @@ -1648,9 +1671,7 @@
update: Optional[object],
error: Exception,
job: Optional["Job[CCT]"] = None,
coroutine: Optional[
Union[Generator[Optional["asyncio.Future[object]"], None, RT], Awaitable[RT]]
] = None,
coroutine: _ErrorCoroType[RT] = None, # noqa: RUF013
) -> bool:
"""Processes an error by passing it to all error handlers registered with
:meth:`add_error_handler`. If one of the error handlers raises
Expand Down
9 changes: 7 additions & 2 deletions tests/ext/test_application.py
Expand Up @@ -24,6 +24,7 @@
import os
import platform
import signal
import sys
import threading
import time
from collections import defaultdict
Expand Down Expand Up @@ -54,7 +55,7 @@
Updater,
filters,
)
from telegram.warnings import PTBUserWarning
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
from tests.auxil.asyncio_helpers import call_after
from tests.auxil.build_messages import make_message_update
from tests.auxil.files import PROJECT_ROOT_PATH
Expand Down Expand Up @@ -1319,7 +1320,8 @@ async def callback():
out = await app.create_task(asyncio.gather(callback()))
assert out == [42]

async def test_create_task_awaiting_generator(self, app):
@pytest.mark.skipif(sys.version_info >= (3, 12), reason="generator coroutines are deprecated")
async def test_create_task_awaiting_generator(self, app, recwarn):
event = asyncio.Event()

def gen():
Expand All @@ -1328,6 +1330,9 @@ def gen():

await app.create_task(gen())
assert event.is_set()
assert len(recwarn) == 2 # 1st warning is: tasks not being awaited when app isn't running
assert recwarn[1].category is PTBDeprecationWarning
assert "Generator-based coroutines are deprecated" in str(recwarn[1].message)

async def test_no_update_processor(self, app):
queue = asyncio.Queue()
Expand Down
13 changes: 6 additions & 7 deletions tests/ext/test_basepersistence.py
Expand Up @@ -22,6 +22,7 @@
import enum
import functools
import logging
import sys
import time
from pathlib import Path
from typing import NamedTuple, Optional
Expand Down Expand Up @@ -377,15 +378,13 @@ def test_init_store_data_update_interval(self, bot_data, chat_data, user_data, c
assert persistence.store_data.callback_data == callback_data

def test_abstract_methods(self):
methods = list(BasePersistence.__abstractmethods__)
methods.sort()
with pytest.raises(
TypeError,
match=(
"drop_chat_data, drop_user_data, flush, get_bot_data, get_callback_data, "
"get_chat_data, get_conversations, "
"get_user_data, refresh_bot_data, refresh_chat_data, "
"refresh_user_data, update_bot_data, update_callback_data, "
"update_chat_data, update_conversation, update_user_data"
),
match=", ".join(methods)
if sys.version_info < (3, 12)
else ", ".join(f"'{i}'" for i in methods),
):
BasePersistence()

Expand Down
4 changes: 3 additions & 1 deletion tests/ext/test_picklepersistence.py
Expand Up @@ -20,6 +20,7 @@
import gzip
import os
import pickle
import sys
from pathlib import Path

import pytest
Expand Down Expand Up @@ -872,7 +873,8 @@ async def test_custom_pickler_unpickler_simple(
"function was specified."
)
with Path("pickletest_chat_data").open("rb") as f, pytest.raises(
pickle.UnpicklingError, match=err_msg
pickle.UnpicklingError,
match=err_msg if sys.version_info < (3, 12) else err_msg.replace("\n", " "),
):
pickle.load(f)

Expand Down