Compare commits

..

21 Commits

Author SHA1 Message Date
Bibo-Joshi b684afab96 Bump Version to v22.2 (#4834) 2025-06-29 20:04:17 +02:00
Bibo-Joshi abe20cf2f3 Documentation Improvements (#4810)
Co-authored-by: Aweryc <93672316+Aweryc@users.noreply.github.com>
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
2025-06-29 18:20:51 +02:00
Abdelrahman Elkheir 979db096b1 Use datetime.timedelta to Represent Time Periods in Classes (#4750) 2025-06-29 18:09:32 +02:00
Bibo-Joshi 22ae75c944 Improve Informativeness of Network Errors (#4822) 2025-06-29 18:06:35 +02:00
dependabot[bot] 1585047b9b Update cachetools requirement from <6.1.0,>=5.3.3 to >=5.3.3,<6.2.0 (#4830)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-28 14:32:26 +02:00
Bibo-Joshi d46ddf7318 Fix Handling of Parameters do_quote and allow_sending_without_reply in Message.reply_* (#4818) 2025-06-19 20:56:43 +02:00
Harshil b15507fc22 Add Python 3.14 Beta To Test Matrix (#4825)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-19 20:18:04 +02:00
locobott 1457679376 Allow for Pattern Matching Empty Inline Queries (#4817)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
Co-authored-by: locobott <25104044+locobott@users.noreply.github.com>
2025-06-15 21:03:47 +02:00
Bibo-Joshi f9bdba18e3 Bump httpx from ~=0.27 to >=0.27,<0.29 (#4820) 2025-06-08 17:17:38 +02:00
Harshil e98e6571d1 Fix Typo in TelegramObject._get_attrs (#4816) 2025-06-07 14:48:02 +02:00
Bibo-Joshi 1fbab91307 Ensure Safe Handler Looping in Application.process_update/error (#4802)
Co-authored-by: Abdelrahman Elkheir <90580077+aelkheir@users.noreply.github.com>
2025-06-04 20:54:29 +02:00
dependabot[bot] 89556d02e3 Bump actions/setup-python from 5.5.0 to 5.6.0 (#4812)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-02 21:36:43 +02:00
dependabot[bot] a0db0415cf Bump codecov/test-results-action from 1.1.0 to 1.1.1 (#4815)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-02 21:20:32 +02:00
dependabot[bot] 862f102b49 Bump codecov/codecov-action from 5.4.2 to 5.4.3 (#4814)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-02 21:06:01 +02:00
dependabot[bot] 1e976557e9 Bump dependabot/fetch-metadata from 2.3.0 to 2.4.0 (#4813)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-02 20:37:44 +02:00
dependabot[bot] 9fa0e69f5a Bump github/codeql-action from 3.28.16 to 3.28.18 (#4811)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-06-02 20:37:06 +02:00
dependabot[bot] d533ea2a72 Update cachetools requirement from <5.6.0,>=5.3.3 to >=5.3.3,<6.1.0 (#4801)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-05-28 21:00:57 +02:00
Bibo-Joshi 828eda7c33 Rework Repository to src Layout (#4798) 2025-05-25 13:50:24 +02:00
Harshil 98e94a187f Implement PEP 735 Dependency Groups (#4800) 2025-05-24 09:48:52 +02:00
Bibo-Joshi 8289a4fda6 Fix Bug in Automated Channel Announcement (#4792) 2025-05-19 20:58:37 +02:00
Bibo-Joshi 8782ae7bb5 Fix a Failing Test Case (#4793) 2025-05-19 20:58:14 +02:00
329 changed files with 2324 additions and 695 deletions
+6 -2
View File
@@ -22,12 +22,16 @@ Setting things up
$ git remote add upstream https://github.com/python-telegram-bot/python-telegram-bot
4. Install dependencies:
4. Install the package in development mode as well as optional dependencies and development dependencies.
Note that the `--group` argument requires `pip` 25.1 or later.
Alternatively, you can use your preferred package manager (such as uv, hatch, poetry, etc.) instead of pip.
.. code-block:: bash
$ pip install -r requirements-dev-all.txt
$ pip install -e .[all] --group all
Installing the package itself is necessary because python-telegram-bot uses a src-based layout where the package code is located in the ``src/`` directory.
5. Install pre-commit hooks:
+2 -2
View File
@@ -45,7 +45,7 @@ jobs:
# Run `chango release` if applicable - needs some additional setup.
- name: Set up Python
if: steps.check_title.outputs.IS_RELEASE_PR == 'true'
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.x"
@@ -54,7 +54,7 @@ jobs:
run: |
cd ./target-repo
git add changes/unreleased/*
pip install . -r docs/requirements-docs.txt
pip install . --group docs
VERSION_TAG=$(python -c "from telegram import __version__; print(f'{__version__}')")
chango release --uid $VERSION_TAG
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
- name: Fetch Dependabot metadata
id: dependabot-metadata
uses: dependabot/fetch-metadata@d7267f607e9d3fb96fc2fbe83e0af444713e90b7 # v2.3.0
uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
+4 -4
View File
@@ -2,7 +2,7 @@ name: Test Admonitions Generation
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- docs/**
- .github/workflows/docs-admonitions.yml
push:
@@ -28,14 +28,14 @@ jobs:
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: '**/requirements*.txt'
cache-dependency-path: 'pyproject.toml'
- name: Install dependencies
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -r requirements-dev-all.txt
python -W ignore -m pip install .[all] --group all
- name: Test autogeneration of admonitions
run: pytest -v --tb=short tests/docs/admonition_inserter.py
+2 -2
View File
@@ -23,13 +23,13 @@ jobs:
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -r requirements-dev-all.txt
python -W ignore -m pip install .[all] --group all
- name: Check Links
run: sphinx-build docs/source docs/build/html --keep-going -j auto -b linkcheck
- name: Upload linkcheck output
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: results.sarif
category: zizmor
+4 -2
View File
@@ -21,7 +21,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.x"
- name: Install pypa/build
@@ -145,7 +145,9 @@ jobs:
telegram-channel:
name: Publish to Telegram Channel
needs:
- github-release
# required to have the output available for the env var
- build
- github-release
runs-on: ubuntu-latest
environment:
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.x"
- name: Install pypa/build
+3 -4
View File
@@ -2,7 +2,7 @@ name: Bot API Tests
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- tests/**
push:
branches:
@@ -27,14 +27,13 @@ jobs:
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install .[all]
python -W ignore -m pip install -r requirements-unit-tests.txt
python -W ignore -m pip install .[all] --group tests
- name: Compare to official api
run: |
pytest -v tests/test_official/test_official.py --junit-xml=.test_report_official.xml
+1 -1
View File
@@ -2,7 +2,7 @@ name: Check Type Completeness
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- pyproject.toml
- .github/workflows/type_completeness.yml
push:
+8 -14
View File
@@ -2,11 +2,10 @@ name: Unit Tests
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- tests/**
- .github/workflows/unit_tests.yml
- pyproject.toml
- requirements-unit-tests.txt
push:
branches:
- master
@@ -22,7 +21,7 @@ jobs:
runs-on: ${{matrix.os}}
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14.0-beta.3']
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: False
steps:
@@ -30,18 +29,14 @@ jobs:
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: '**/requirements*.txt'
- name: Install dependencies
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -U pytest-cov
python -W ignore -m pip install .
python -W ignore -m pip install -r requirements-unit-tests.txt
python -W ignore -m pip install pytest-xdist
python -W ignore -m pip install . --group tests
- name: Test with pytest
# We run 4 different suites here
@@ -63,11 +58,10 @@ jobs:
TO_TEST="test_no_passport.py or test_datetime.py or test_defaults.py or test_jobqueue.py or test_applicationbuilder.py or test_ratelimiter.py or test_updater.py or test_callbackdatacache.py or test_request.py"
pytest -v --cov -k "${TO_TEST}" --junit-xml=.test_report_no_optionals_junit.xml
opt_dep_status=$?
# Test the rest
export TEST_WITH_OPT_DEPS='true'
# need to manually install pytz here, because it's no longer in the optional reqs
pip install .[all] pytz
pip install .[all]
# `-n auto --dist worksteal` uses pytest-xdist to run tests on multiple CPU
# workers. Increasing number of workers has little effect on test duration, but it seems
# to increase flakyness.
@@ -92,14 +86,14 @@ jobs:
.test_report_optionals_junit.xml
- name: Submit coverage
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
env_vars: OS,PYTHON
name: ${{ matrix.os }}-${{ matrix.python-version }}
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload test results to Codecov
uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1.1.0
uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
if: ${{ !cancelled() }}
with:
files: .test_report_no_optionals_junit.xml,.test_report_optionals_junit.xml
+2
View File
@@ -93,6 +93,8 @@ telegram.jpg
# virtual env
venv*
pyvenv.cfg
Scripts/
# environment manager:
.mise.toml
+4 -1
View File
@@ -18,13 +18,16 @@ python:
install:
- method: pip
path: .
- requirements: requirements-dev-all.txt
build:
os: ubuntu-22.04
tools:
python: "3" # latest stable cpython version
jobs:
install:
- pip install -U pip
- pip install .[all] --group 'all' # install all the dependency groups
post_build:
# Based on https://github.com/readthedocs/readthedocs.org/issues/3242#issuecomment-1410321534
# This provides a HTML zip file for download, with the same structure as the hosted website
+2
View File
@@ -80,6 +80,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `Kirill Vasin <https://github.com/vasinkd>`_
- `Kjwon15 <https://github.com/kjwon15>`_
- `Li-aung Yip <https://github.com/LiaungYip>`_
- `locobott <https://github.com/locobott>`_
- `Loo Zheng Yuan <https://github.com/loozhengyuan>`_
- `LRezende <https://github.com/lrezende>`_
- `Luca Bellanti <https://github.com/Trifase>`_
@@ -109,6 +110,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `Patrick Hofmann <https://github.com/PH89>`_
- `Paul Larsen <https://github.com/PaulSonOfLars>`_
- `Pawan <https://github.com/pawanrai9999>`_
- `Philipp Isachenko <https://github.com/Aweryc>`_
- `Pieter Schutz <https://github.com/eldinnie>`_
- `Piraty <https://github.com/piraty>`_
- `Poolitzer <https://github.com/Poolitzer>`_
+4 -2
View File
@@ -114,6 +114,8 @@ You can also install ``python-telegram-bot`` from source, though this is usually
$ pip install build
$ python -m build
You can also use your favored package manager (such as ``uv``, ``hatch``, ``poetry``, etc.) instead of ``pip``.
Verifying Releases
~~~~~~~~~~~~~~~~~~
@@ -139,7 +141,7 @@ As these features are *optional*, the corresponding 3rd party dependencies are n
Instead, they are listed as optional dependencies.
This allows to avoid unnecessary dependency conflicts for users who don't need the optional features.
The only required dependency is `httpx ~= 0.27 <https://www.python-httpx.org>`_ for
The only required dependency is `httpx >=0.27,<0.29 <https://www.python-httpx.org>`_ for
``telegram.request.HTTPXRequest``, the default networking backend.
``python-telegram-bot`` is most useful when used along with additional libraries.
@@ -157,7 +159,7 @@ PTB can be installed with optional dependencies:
* ``pip install "python-telegram-bot[http2]"`` installs `httpx[http2] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to use HTTP/2.
* ``pip install "python-telegram-bot[rate-limiter]"`` installs `aiolimiter~=1.1,<1.3 <https://aiolimiter.readthedocs.io/en/stable/>`_. Use this, if you want to use ``telegram.ext.AIORateLimiter``.
* ``pip install "python-telegram-bot[webhooks]"`` installs the `tornado~=6.4 <https://www.tornadoweb.org/en/stable/>`_ library. Use this, if you want to use ``telegram.ext.Updater.start_webhook``/``telegram.ext.Application.run_webhook``.
* ``pip install "python-telegram-bot[callback-data]"`` installs the `cachetools>=5.3.3,<5.6.0 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
* ``pip install "python-telegram-bot[callback-data]"`` installs the `cachetools>=5.3.3,<6.2.0 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
* ``pip install "python-telegram-bot[job-queue]"`` installs the `APScheduler>=3.10.4,<3.12.0 <https://apscheduler.readthedocs.io/en/3.x/>`_ library. Use this, if you want to use the ``telegram.ext.JobQueue``.
To install multiple optional dependencies, separate them by commas, e.g. ``pip install "python-telegram-bot[socks,webhooks]"``.
@@ -0,0 +1,36 @@
features = "Use `timedelta` to represent time periods in class arguments and attributes"
deprecations = """In this release, we're migrating attributes of Telegram objects that represent durations/time periods from having :obj:`int` type to Python's native :class:`datetime.timedelta`. This change is opt-in for now to allow for a smooth transition phase. It will become opt-out in future releases.
Set ``PTB_TIMEDELTA=true`` or ``PTB_TIMEDELTA=1`` as an environment variable to make these attributes return :obj:`datetime.timedelta` objects instead of integers. Support for :obj:`int` values is deprecated and will be removed in a future major version.
Affected Attributes:
- :attr:`telegram.ChatFullInfo.slow_mode_delay` and :attr:`telegram.ChatFullInfo.message_auto_delete_time`
- :attr:`telegram.Animation.duration`
- :attr:`telegram.Audio.duration`
- :attr:`telegram.Video.duration` and :attr:`telegram.Video.start_timestamp`
- :attr:`telegram.VideoNote.duration`
- :attr:`telegram.Voice.duration`
- :attr:`telegram.PaidMediaPreview.duration`
- :attr:`telegram.VideoChatEnded.duration`
- :attr:`telegram.InputMediaVideo.duration`
- :attr:`telegram.InputMediaAnimation.duration`
- :attr:`telegram.InputMediaAudio.duration`
- :attr:`telegram.InputPaidMediaVideo.duration`
- :attr:`telegram.InlineQueryResultGif.gif_duration`
- :attr:`telegram.InlineQueryResultMpeg4Gif.mpeg4_duration`
- :attr:`telegram.InlineQueryResultVideo.video_duration`
- :attr:`telegram.InlineQueryResultAudio.audio_duration`
- :attr:`telegram.InlineQueryResultVoice.voice_duration`
- :attr:`telegram.InlineQueryResultLocation.live_period`
- :attr:`telegram.Poll.open_period`
- :attr:`telegram.Location.live_period`
- :attr:`telegram.MessageAutoDeleteTimerChanged.message_auto_delete_time`
- :attr:`telegram.ChatInviteLink.subscription_period`
- :attr:`telegram.InputLocationMessageContent.live_period`
- :attr:`telegram.error.RetryAfter.retry_after`
"""
internal = "Modify `test_official` to handle time periods as timedelta automatically."
[[pull_requests]]
uid = "4750"
author_uid = "aelkheir"
closes_threads = ["4575"]
@@ -0,0 +1,5 @@
internal = "Fix Bug in Automated Channel Announcement"
[[pull_requests]]
uid = "4792"
author_uid = "Bibo-Joshi"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Fix a Failing Test Case"
[[pull_requests]]
uid = "4793"
author_uid = "Bibo-Joshi"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Rework Repository to `src` Layout"
[[pull_requests]]
uid = "4798"
author_uid = "Bibo-Joshi"
closes_threads = ["4797"]
@@ -0,0 +1,5 @@
dependencies = "Implement PEP 735 Dependency Groups for Development Dependencies"
[[pull_requests]]
uid = "4800"
author_uid = "harshil21"
closes_threads = ["4795"]
@@ -0,0 +1,5 @@
dependencies = "Update cachetools requirement from <5.6.0,>=5.3.3 to >=5.3.3,<6.1.0"
[[pull_requests]]
uid = "4801"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,14 @@
bugfixes = """
Fixed a bug where calling ``Application.remove/add_handler`` during update handling can cause a ``RuntimeError`` in ``Application.process_update``.
.. hint::
Calling ``Application.add/remove_handler`` now has no influence on calls to :meth:`process_update` that are
already in progress. The same holds for ``Application.add/remove_error_handler`` and ``Application.process_error``, respectively.
.. warning::
This behavior should currently be considered an implementation detail and not as guaranteed behavior.
"""
[[pull_requests]]
uid = "4802"
author_uid = "Bibo-Joshi"
closes_threads = ["4803"]
@@ -0,0 +1,20 @@
documentation = """Documentation Improvements. Among other things
* mention alternative package managers in README and contribution guide
* remove ``furo-sphinx-search``
"""
[[pull_requests]]
uid = "4810"
author_uid = "Bibo-Joshi"
closes_threads = []
[[pull_requests]]
uid = "4824"
author_uid = "Aweryc"
closes_threads = ["4823"]
[[pull_requests]]
uid = "4826"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump github/codeql-action from 3.28.16 to 3.28.18"
[[pull_requests]]
uid = "4811"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump actions/setup-python from 5.5.0 to 5.6.0"
[[pull_requests]]
uid = "4812"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump dependabot/fetch-metadata from 2.3.0 to 2.4.0"
[[pull_requests]]
uid = "4813"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump codecov/codecov-action from 5.4.2 to 5.4.3"
[[pull_requests]]
uid = "4814"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump codecov/test-results-action from 1.1.0 to 1.1.1"
[[pull_requests]]
uid = "4815"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Fix Typo in `TelegramObject._get_attrs`"
[[pull_requests]]
uid = "4816"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
bugfixes = "Allow for pattern matching empty inline queries"
[[pull_requests]]
uid = "4817"
author_uid = "locobott"
closes_threads = []
@@ -0,0 +1,12 @@
bugfixes = """
Correctly parse parameter ``allow_sending_without_reply`` in ``Message.reply_*`` when used in combination with ``do_quote=True``.
.. hint::
Using ``dict`` valued input for ``do_quote`` along with passing ``allow_sending_without_reply`` is not supported and will raise an error.
"""
[[pull_requests]]
uid = "4818"
author_uid = "Bibo-Joshi"
closes_threads = ["4807"]
@@ -0,0 +1,5 @@
dependencies = "Bump ``httpx`` from ~=0.27 to >=0.27,<0.29"
[[pull_requests]]
uid = "4820"
author_uid = "Bibo-Joshi"
closes_threads = ["4819"]
@@ -0,0 +1,5 @@
other = "Improve Informativeness of Network Errors Raised by ``BaseRequest.post/retrieve``"
[[pull_requests]]
uid = "4822"
author_uid = "Bibo-Joshi"
@@ -0,0 +1,5 @@
other = "Add Python 3.14 Beta To Test Matrix. *Python 3.14 is not officially supported by PTB yet!*"
[[pull_requests]]
uid = "4825"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
dependencies = "Update ``cachetools`` requirement from <6.1.0,>=5.3.3 to >=5.3.3,<6.2.0"
[[pull_requests]]
uid = "4830"
author_uid = "dependabot"
@@ -0,0 +1,5 @@
other = "Bump Version to v22.2"
[[pull_requests]]
uid = "4834"
author_uid = "Bibo-Joshi"
closes_threads = []
-10
View File
@@ -1,10 +0,0 @@
chango~=0.4.0
sphinx==8.2.3
furo==2024.8.6
furo-sphinx-search @ git+https://github.com/harshil21/furo-sphinx-search@v0.2.0.1
sphinx-paramlinks==0.6.0
sphinxcontrib-mermaid==1.0.0
sphinx-copybutton==0.5.2
sphinx-inline-tabs==2023.4.21
# Temporary. See #4387
sphinx-build-compatibility @ git+https://github.com/readthedocs/sphinx-build-compatibility.git@58aabc5f207c6c2421f23d3578adc0b14af57047
-1
View File
@@ -51,7 +51,6 @@ extensions = [
"sphinx_copybutton",
"sphinx_inline_tabs",
"sphinxcontrib.mermaid",
"sphinx_search.extension",
]
# Temporary. See #4387
+1 -1
View File
@@ -6,4 +6,4 @@ Animation
.. autoclass:: telegram.Animation
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -6,4 +6,4 @@ Audio
.. autoclass:: telegram.Audio
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -5,4 +5,4 @@ Chat
.. autoclass:: telegram.Chat
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -5,4 +5,4 @@ ChatFullInfo
.. autoclass:: telegram.ChatFullInfo
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -5,4 +5,4 @@ Document
.. autoclass:: telegram.Document
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -5,4 +5,4 @@ PhotoSize
.. autoclass:: telegram.PhotoSize
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
@@ -4,4 +4,3 @@ RevenueWithdrawalState
.. autoclass:: telegram.RevenueWithdrawalState
:members:
:show-inheritance:
:inherited-members: TelegramObject
@@ -4,4 +4,3 @@ RevenueWithdrawalStateFailed
.. autoclass:: telegram.RevenueWithdrawalStateFailed
:members:
:show-inheritance:
:inherited-members: TelegramObject
@@ -4,4 +4,3 @@ RevenueWithdrawalStatePending
.. autoclass:: telegram.RevenueWithdrawalStatePending
:members:
:show-inheritance:
:inherited-members: TelegramObject
@@ -4,4 +4,3 @@ RevenueWithdrawalStateSucceeded
.. autoclass:: telegram.RevenueWithdrawalStateSucceeded
:members:
:show-inheritance:
:inherited-members: TelegramObject
-1
View File
@@ -4,4 +4,3 @@ StarTransaction
.. autoclass:: telegram.StarTransaction
:members:
:show-inheritance:
:inherited-members: TelegramObject
@@ -4,5 +4,4 @@ StarTransactions
.. autoclass:: telegram.StarTransactions
:members:
:show-inheritance:
:inherited-members: TelegramObject
+1 -1
View File
@@ -6,4 +6,4 @@ Sticker
.. autoclass:: telegram.Sticker
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
@@ -4,4 +4,3 @@ TransactionPartner
.. autoclass:: telegram.TransactionPartner
:members:
:show-inheritance:
:inherited-members: TelegramObject
@@ -4,4 +4,3 @@ TransactionPartnerChat
.. autoclass:: telegram.TransactionPartnerChat
:members:
:show-inheritance:
:inherited-members: TransactionPartner
@@ -4,4 +4,3 @@ TransactionPartnerFragment
.. autoclass:: telegram.TransactionPartnerFragment
:members:
:show-inheritance:
:inherited-members: TransactionPartner
@@ -4,4 +4,3 @@ TransactionPartnerOther
.. autoclass:: telegram.TransactionPartnerOther
:members:
:show-inheritance:
:inherited-members: TransactionPartner
@@ -4,4 +4,3 @@ TransactionPartnerTelegramAds
.. autoclass:: telegram.TransactionPartnerTelegramAds
:members:
:show-inheritance:
:inherited-members: TransactionPartner
@@ -4,4 +4,3 @@ TransactionPartnerTelegramApi
.. autoclass:: telegram.TransactionPartnerTelegramApi
:members:
:show-inheritance:
:inherited-members: TransactionPartner
@@ -4,4 +4,3 @@ TransactionPartnerUser
.. autoclass:: telegram.TransactionPartnerUser
:members:
:show-inheritance:
:inherited-members: TransactionPartner
+1 -1
View File
@@ -6,4 +6,4 @@ Video
.. autoclass:: telegram.Video
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -6,4 +6,4 @@ VideoNote
.. autoclass:: telegram.VideoNote
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+1 -1
View File
@@ -6,4 +6,4 @@ Voice
.. autoclass:: telegram.Voice
:members:
:show-inheritance:
:inherited-members: TelegramObject
:inherited-members: TelegramObject, object
+3 -1
View File
@@ -80,7 +80,7 @@
.. |reply_quote| replace:: If set to :obj:`True`, the reply is sent as an actual reply to this message. If ``reply_to_message_id`` is passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
.. |do_quote| replace:: If set to :obj:`True`, the replied message is quoted. For a dict, it must be the output of :meth:`~telegram.Message.build_reply_arguments` to specify exact ``reply_parameters``. If ``reply_to_message_id`` or ``reply_parameters`` are passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
.. |do_quote| replace:: If set to :obj:`True`, the replied message is quoted. For a dict, it must be the output of :meth:`~telegram.Message.build_reply_arguments` to specify exact ``reply_parameters``. If ``reply_to_message_id`` or ``reply_parameters`` are passed, this parameter will be ignored. When passing dict-valued input, ``do_quote`` is mutually exclusive with ``allow_sending_without_reply``. Default: :obj:`True` in group chats and :obj:`False` in private chats.
.. |non_optional_story_argument| replace:: As of this version, this argument is now required. In accordance with our `stability policy <https://docs.python-telegram-bot.org/en/stable/stability_policy.html>`__, the signature will be kept as optional for now, though they are mandatory and an error will be raised if you don't pass it.
@@ -101,3 +101,5 @@
.. |org-verify| replace:: `on behalf of the organization <https://telegram.org/verify#third-party-verification>`__
.. |time-period-input| replace:: :class:`datetime.timedelta` objects are accepted in addition to plain :obj:`int` values.
.. |time-period-int-deprecated| replace:: In a future major version this attribute will be of type :obj:`datetime.timedelta`. You can opt-in early by setting `PTB_TIMEDELTA=true` or ``PTB_TIMEDELTA=1`` as an environment variable.
+4 -1
View File
@@ -7,6 +7,7 @@ This program is dedicated to the public domain under the CC0 license.
"""
import asyncio
import contextlib
import datetime as dtm
import logging
from typing import NoReturn
@@ -47,7 +48,9 @@ async def main() -> NoReturn:
async def echo(bot: Bot, update_id: int) -> int:
"""Echo the message the user sent."""
# Request updates after the last update_id
updates = await bot.get_updates(offset=update_id, timeout=10, allowed_updates=Update.ALL_TYPES)
updates = await bot.get_updates(
offset=update_id, timeout=dtm.timedelta(seconds=10), allowed_updates=Update.ALL_TYPES
)
for update in updates:
next_update_id = update.update_id + 1
+60 -12
View File
@@ -36,9 +36,10 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"httpx ~= 0.27",
"httpx >=0.27,<0.29",
]
[project.urls]
@@ -66,7 +67,7 @@ all = [
]
callback-data = [
# Cachetools doesn't have a strict stability policy. Let's be cautious for now.
"cachetools>=5.3.3,<5.6.0",
"cachetools>=5.3.3,<6.2.0",
]
ext = [
"python-telegram-bot[callback-data,job-queue,rate-limiter,webhooks]",
@@ -91,19 +92,64 @@ socks = [
]
webhooks = [
# tornado is rather stable, but let's not allow the next major release without prior testing
"tornado~=6.4",
"tornado~=6.5",
]
[dependency-groups]
tests = [
# required for building the wheels for releases
"build",
# For the test suite
"pytest==8.4.0",
# needed because pytest doesn't come with native support for coroutines as tests
"pytest-asyncio==0.21.2",
# xdist runs tests in parallel
"pytest-xdist==3.6.1",
# Used for flaky tests (flaky decorator)
"flaky>=3.8.1",
# used in test_official for parsing tg docs
"beautifulsoup4",
# For testing with timezones. Might not be needed on all systems, but to ensure that unit tests
# run correctly on all systems, we include it here.
"tzdata",
# We've deprecated support pytz, but we still need it for testing that it works with the library.
"pytz",
# Install coverage:
"pytest-cov"
]
docs = [
"chango~=0.4.0; python_version >= '3.12'",
"sphinx==8.2.3; python_version >= '3.11'",
"furo==2024.8.6",
"sphinx-paramlinks==0.6.0",
"sphinxcontrib-mermaid==1.0.0",
"sphinx-copybutton==0.5.2",
"sphinx-inline-tabs==2023.4.21",
# Temporary. See #4387
"sphinx-build-compatibility @ git+https://github.com/readthedocs/sphinx-build-compatibility.git@58aabc5f207c6c2421f23d3578adc0b14af57047",
# For python 3.14 support, we need a version of pydantic-core >= 2.35.0, since it upgrades the
# rust toolchain, required for building the project. But there isn't a version of pydantic
# which allows that pydantic-core version yet, so we use the latest commit on the
# pydantic repository, which has the required version of pydantic-core.
# This should ideally be done in `chango`'s dependencies. We can remove this once a new pydantic
# version is released.
"pydantic @ git+https://github.com/pydantic/pydantic ; python_version >= '3.14'"
]
all = ["pre-commit", { include-group = "tests" }, { include-group = "docs" }]
# HATCH
[tool.hatch.version]
# dynamically evaluates the `__version__` variable in that file
source = "code"
path = "telegram/_version.py"
search-paths = ["telegram"]
path = "src/telegram/_version.py"
[tool.hatch.build]
packages = ["telegram"]
# See also https://github.com/pypa/hatch/issues/1230 for discussion
# the source distribution will include most of the files in the root directory
[tool.hatch.build.targets.sdist]
exclude = [".venv*", "venv*", ".github"]
# the wheel will only include the src/telegram package
[tool.hatch.build.targets.wheel]
packages = ["src/telegram"]
# CHANGO
[tool.chango]
@@ -136,9 +182,9 @@ select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET
[tool.ruff.lint.per-file-ignores]
"tests/*.py" = ["B018"]
"tests/**.py" = ["RUF012", "ASYNC230", "DTZ", "ARG", "T201", "ASYNC109", "D", "S", "TRY"]
"telegram/**.py" = ["TRY003"]
"telegram/ext/_applicationbuilder.py" = ["TRY004"]
"telegram/ext/filters.py" = ["D102"]
"src/telegram/**.py" = ["TRY003"]
"src/telegram/ext/_applicationbuilder.py" = ["TRY004"]
"src/telegram/ext/filters.py" = ["D102"]
"docs/**.py" = ["INP001", "ARG", "D", "TRY003", "S"]
"examples/**.py" = ["ARG", "D", "S105", "TRY003"]
@@ -166,6 +212,7 @@ exclude-protected = ["_unfrozen"]
# PYTEST:
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
addopts = "--no-success-flaky-report -rX"
filterwarnings = [
"error",
@@ -188,6 +235,7 @@ log_cli_format = "%(funcName)s - Line %(lineno)d - %(message)s"
# MYPY:
[tool.mypy]
mypy_path = "src"
warn_unused_ignores = true
warn_unused_configs = true
disallow_untyped_defs = true
@@ -230,12 +278,12 @@ ignore_missing_imports = true
# COVERAGE:
[tool.coverage.run]
branch = true
source = ["telegram"]
source = ["src/telegram"]
parallel = true
concurrency = ["thread", "multiprocessing"]
omit = [
"tests/",
"telegram/__main__.py"
"src/telegram/__main__.py"
]
[tool.coverage.report]
-5
View File
@@ -1,5 +0,0 @@
-e .[all]
# needed for pre-commit hooks in the git commit command
pre-commit
-r requirements-unit-tests.txt
-r docs/requirements-docs.txt
-23
View File
@@ -1,23 +0,0 @@
-e .
# required for building the wheels for releases
build
# For the test suite
pytest==8.3.5
# needed because pytest doesn't come with native support for coroutines as tests
pytest-asyncio==0.21.2
# xdist runs tests in parallel
pytest-xdist==3.6.1
# Used for flaky tests (flaky decorator)
flaky>=3.8.1
# used in test_official for parsing tg docs
beautifulsoup4
# For testing with timezones. Might not be needed on all systems, but to ensure that unit tests
# run correctly on all systems, we include it here.
tzdata
+14 -5
View File
@@ -4519,7 +4519,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
self,
offset: Optional[int] = None,
limit: Optional[int] = None,
timeout: Optional[int] = None,
timeout: Optional[TimePeriod] = None,
allowed_updates: Optional[Sequence[str]] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -4554,9 +4554,12 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
between :tg-const:`telegram.constants.PollingLimit.MIN_LIMIT`-
:tg-const:`telegram.constants.PollingLimit.MAX_LIMIT` are accepted.
Defaults to ``100``.
timeout (:obj:`int`, optional): Timeout in seconds for long polling. Defaults to ``0``,
i.e. usual short polling. Should be positive, short polling should be used for
testing purposes only.
timeout (:obj:`int` | :class:`datetime.timedelta`, optional): Timeout in seconds for
long polling. Defaults to ``0``, i.e. usual short polling. Should be positive,
short polling should be used for testing purposes only.
.. versionchanged:: v22.2
|time-period-input|
allowed_updates (Sequence[:obj:`str`]), optional): A sequence the types of
updates you want your bot to receive. For example, specify ["message",
"edited_channel_post", "callback_query"] to only receive updates of these types.
@@ -4591,6 +4594,12 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
else:
arg_read_timeout = self._request[0].read_timeout or 0
read_timeout = (
(arg_read_timeout + timeout.total_seconds())
if isinstance(timeout, dtm.timedelta)
else (arg_read_timeout + timeout if timeout else arg_read_timeout)
)
# Ideally we'd use an aggressive read timeout for the polling. However,
# * Short polling should return within 2 seconds.
# * Long polling poses a different problem: the connection might have been dropped while
@@ -4601,7 +4610,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
await self._post(
"getUpdates",
data,
read_timeout=arg_read_timeout + timeout if timeout else arg_read_timeout,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
@@ -20,7 +20,7 @@
"""This module contains an object that represents a Telegram ChatFullInfo."""
import datetime as dtm
from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, Optional, Union
from telegram._birthdate import Birthdate
from telegram._chat import Chat, _ChatBase
@@ -29,9 +29,18 @@ from telegram._chatpermissions import ChatPermissions
from telegram._files.chatphoto import ChatPhoto
from telegram._gifts import AcceptedGiftTypes
from telegram._reaction import ReactionType
from telegram._utils.argumentparsing import de_json_optional, de_list_optional, parse_sequence_arg
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
from telegram._utils.argumentparsing import (
de_json_optional,
de_list_optional,
parse_sequence_arg,
to_timedelta,
)
from telegram._utils.datetime import (
extract_tzinfo_from_defaults,
from_timestamp,
get_timedelta_value,
)
from telegram._utils.types import JSONDict, TimePeriod
from telegram._utils.warnings import warn
from telegram._utils.warnings_transition import (
build_deprecation_warning_message,
@@ -166,17 +175,23 @@ class ChatFullInfo(_ChatBase):
(by sending date).
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
for groups and supergroups.
slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between
consecutive messages sent by each unprivileged user.
slow_mode_delay (:obj:`int` | :class:`datetime.timedelta`, optional): For supergroups,
the minimum allowed delay between consecutive messages sent by each unprivileged user.
.. versionchanged:: v22.2
|time-period-input|
unrestrict_boost_count (:obj:`int`, optional): For supergroups, the minimum number of
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
permissions.
.. versionadded:: 21.0
message_auto_delete_time (:obj:`int`, optional): The time after which all messages sent to
the chat will be automatically deleted; in seconds.
message_auto_delete_time (:obj:`int` | :class:`datetime.timedelta`, optional): The time
after which all messages sent to the chat will be automatically deleted; in seconds.
.. versionadded:: 13.4
.. versionchanged:: v22.2
|time-period-input|
has_aggressive_anti_spam_enabled (:obj:`bool`, optional): :obj:`True`, if aggressive
anti-spam checks are enabled in the supergroup. The field is only available to chat
administrators.
@@ -331,17 +346,23 @@ class ChatFullInfo(_ChatBase):
(by sending date).
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
for groups and supergroups.
slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between
consecutive messages sent by each unprivileged user.
slow_mode_delay (:obj:`int` | :class:`datetime.timedelta`): Optional. For supergroups,
the minimum allowed delay between consecutive messages sent by each unprivileged user.
.. deprecated:: v22.2
|time-period-int-deprecated|
unrestrict_boost_count (:obj:`int`): Optional. For supergroups, the minimum number of
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
permissions.
.. versionadded:: 21.0
message_auto_delete_time (:obj:`int`): Optional. The time after which all messages sent to
the chat will be automatically deleted; in seconds.
message_auto_delete_time (:obj:`int` | :class:`datetime.timedelta`): Optional. The time
after which all messages sent to the chat will be automatically deleted; in seconds.
.. versionadded:: 13.4
.. deprecated:: v22.2
|time-period-int-deprecated|
has_aggressive_anti_spam_enabled (:obj:`bool`): Optional. :obj:`True`, if aggressive
anti-spam checks are enabled in the supergroup. The field is only available to chat
administrators.
@@ -383,6 +404,8 @@ class ChatFullInfo(_ChatBase):
__slots__ = (
"_can_send_gift",
"_message_auto_delete_time",
"_slow_mode_delay",
"accent_color_id",
"accepted_gift_types",
"active_usernames",
@@ -411,14 +434,12 @@ class ChatFullInfo(_ChatBase):
"linked_chat_id",
"location",
"max_reaction_count",
"message_auto_delete_time",
"permissions",
"personal_chat",
"photo",
"pinned_message",
"profile_accent_color_id",
"profile_background_custom_emoji_id",
"slow_mode_delay",
"sticker_set_name",
"unrestrict_boost_count",
)
@@ -456,9 +477,9 @@ class ChatFullInfo(_ChatBase):
invite_link: Optional[str] = None,
pinned_message: Optional["Message"] = None,
permissions: Optional[ChatPermissions] = None,
slow_mode_delay: Optional[int] = None,
slow_mode_delay: Optional[TimePeriod] = None,
unrestrict_boost_count: Optional[int] = None,
message_auto_delete_time: Optional[int] = None,
message_auto_delete_time: Optional[TimePeriod] = None,
has_aggressive_anti_spam_enabled: Optional[bool] = None,
has_hidden_members: Optional[bool] = None,
has_protected_content: Optional[bool] = None,
@@ -513,9 +534,9 @@ class ChatFullInfo(_ChatBase):
self.invite_link: Optional[str] = invite_link
self.pinned_message: Optional[Message] = pinned_message
self.permissions: Optional[ChatPermissions] = permissions
self.slow_mode_delay: Optional[int] = slow_mode_delay
self.message_auto_delete_time: Optional[int] = (
int(message_auto_delete_time) if message_auto_delete_time is not None else None
self._slow_mode_delay: Optional[dtm.timedelta] = to_timedelta(slow_mode_delay)
self._message_auto_delete_time: Optional[dtm.timedelta] = to_timedelta(
message_auto_delete_time
)
self.has_protected_content: Optional[bool] = has_protected_content
self.has_visible_history: Optional[bool] = has_visible_history
@@ -576,6 +597,16 @@ class ChatFullInfo(_ChatBase):
)
return self._can_send_gift
@property
def slow_mode_delay(self) -> Optional[Union[int, dtm.timedelta]]:
return get_timedelta_value(self._slow_mode_delay, attribute="slow_mode_delay")
@property
def message_auto_delete_time(self) -> Optional[Union[int, dtm.timedelta]]:
return get_timedelta_value(
self._message_auto_delete_time, attribute="message_auto_delete_time"
)
@classmethod
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "ChatFullInfo":
"""See :meth:`telegram.TelegramObject.de_json`."""
@@ -18,13 +18,17 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents an invite link for a chat."""
import datetime as dtm
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, Optional, Union
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.argumentparsing import de_json_optional
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
from telegram._utils.argumentparsing import de_json_optional, to_timedelta
from telegram._utils.datetime import (
extract_tzinfo_from_defaults,
from_timestamp,
get_timedelta_value,
)
from telegram._utils.types import JSONDict, TimePeriod
if TYPE_CHECKING:
from telegram import Bot
@@ -70,10 +74,13 @@ class ChatInviteLink(TelegramObject):
created using this link.
.. versionadded:: 13.8
subscription_period (:obj:`int`, optional): The number of seconds the subscription will be
active for before the next payment.
subscription_period (:obj:`int` | :class:`datetime.timedelta`, optional): The number of
seconds the subscription will be active for before the next payment.
.. versionadded:: 21.5
.. versionchanged:: v22.2
|time-period-input|
subscription_price (:obj:`int`, optional): The amount of Telegram Stars a user must pay
initially and after each subsequent subscription period to be a member of the chat
using the link.
@@ -107,10 +114,13 @@ class ChatInviteLink(TelegramObject):
created using this link.
.. versionadded:: 13.8
subscription_period (:obj:`int`): Optional. The number of seconds the subscription will be
active for before the next payment.
subscription_period (:obj:`int` | :class:`datetime.timedelta`): Optional. The number of
seconds the subscription will be active for before the next payment.
.. versionadded:: 21.5
.. deprecated:: v22.2
|time-period-int-deprecated|
subscription_price (:obj:`int`): Optional. The amount of Telegram Stars a user must pay
initially and after each subsequent subscription period to be a member of the chat
using the link.
@@ -120,6 +130,7 @@ class ChatInviteLink(TelegramObject):
"""
__slots__ = (
"_subscription_period",
"creates_join_request",
"creator",
"expire_date",
@@ -129,7 +140,6 @@ class ChatInviteLink(TelegramObject):
"member_limit",
"name",
"pending_join_request_count",
"subscription_period",
"subscription_price",
)
@@ -144,7 +154,7 @@ class ChatInviteLink(TelegramObject):
member_limit: Optional[int] = None,
name: Optional[str] = None,
pending_join_request_count: Optional[int] = None,
subscription_period: Optional[int] = None,
subscription_period: Optional[TimePeriod] = None,
subscription_price: Optional[int] = None,
*,
api_kwargs: Optional[JSONDict] = None,
@@ -164,7 +174,7 @@ class ChatInviteLink(TelegramObject):
self.pending_join_request_count: Optional[int] = (
int(pending_join_request_count) if pending_join_request_count is not None else None
)
self.subscription_period: Optional[int] = subscription_period
self._subscription_period: Optional[dtm.timedelta] = to_timedelta(subscription_period)
self.subscription_price: Optional[int] = subscription_price
self._id_attrs = (
@@ -177,6 +187,10 @@ class ChatInviteLink(TelegramObject):
self._freeze()
@property
def subscription_period(self) -> Optional[Union[int, dtm.timedelta]]:
return get_timedelta_value(self._subscription_period, attribute="subscription_period")
@classmethod
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "ChatInviteLink":
"""See :meth:`telegram.TelegramObject.de_json`."""
@@ -25,6 +25,7 @@ from telegram import constants
from telegram._files.inputfile import InputFile
from telegram._telegramobject import TelegramObject
from telegram._utils import enum
from telegram._utils.argumentparsing import to_timedelta
from telegram._utils.files import parse_file_input
from telegram._utils.types import FileInput, JSONDict
@@ -158,18 +159,8 @@ class InputStoryContentVideo(InputStoryContent):
with self._unfrozen():
self.video: Union[str, InputFile] = self._parse_file_input(video)
self.duration: Optional[dtm.timedelta] = self._parse_period_arg(duration)
self.cover_frame_timestamp: Optional[dtm.timedelta] = self._parse_period_arg(
self.duration: Optional[dtm.timedelta] = to_timedelta(duration)
self.cover_frame_timestamp: Optional[dtm.timedelta] = to_timedelta(
cover_frame_timestamp
)
self.is_animation: Optional[bool] = is_animation
# This helper is temporarly here until we can use `argumentparsing.parse_period_arg`
# from https://github.com/python-telegram-bot/python-telegram-bot/pull/4750
@staticmethod
def _parse_period_arg(arg: Optional[Union[float, dtm.timedelta]]) -> Optional[dtm.timedelta]:
if arg is None:
return None
if isinstance(arg, dtm.timedelta):
return arg
return dtm.timedelta(seconds=arg)
@@ -17,11 +17,14 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Animation."""
from typing import Optional
import datetime as dtm
from typing import Optional, Union
from telegram._files._basethumbedmedium import _BaseThumbedMedium
from telegram._files.photosize import PhotoSize
from telegram._utils.types import JSONDict
from telegram._utils.argumentparsing import to_timedelta
from telegram._utils.datetime import get_timedelta_value
from telegram._utils.types import JSONDict, TimePeriod
class Animation(_BaseThumbedMedium):
@@ -41,7 +44,11 @@ class Animation(_BaseThumbedMedium):
Can't be used to download or reuse the file.
width (:obj:`int`): Video width as defined by the sender.
height (:obj:`int`): Video height as defined by the sender.
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
duration (:obj:`int` | :class:`datetime.timedelta`, optional): Duration of the video
in seconds as defined by the sender.
.. versionchanged:: v22.2
|time-period-input|
file_name (:obj:`str`, optional): Original animation filename as defined by the sender.
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
file_size (:obj:`int`, optional): File size in bytes.
@@ -58,7 +65,11 @@ class Animation(_BaseThumbedMedium):
Can't be used to download or reuse the file.
width (:obj:`int`): Video width as defined by the sender.
height (:obj:`int`): Video height as defined by the sender.
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the video in seconds
as defined by the sender.
.. deprecated:: v22.2
|time-period-int-deprecated|
file_name (:obj:`str`): Optional. Original animation filename as defined by the sender.
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
file_size (:obj:`int`): Optional. File size in bytes.
@@ -69,7 +80,7 @@ class Animation(_BaseThumbedMedium):
"""
__slots__ = ("duration", "file_name", "height", "mime_type", "width")
__slots__ = ("_duration", "file_name", "height", "mime_type", "width")
def __init__(
self,
@@ -77,7 +88,7 @@ class Animation(_BaseThumbedMedium):
file_unique_id: str,
width: int,
height: int,
duration: int,
duration: TimePeriod,
file_name: Optional[str] = None,
mime_type: Optional[str] = None,
file_size: Optional[int] = None,
@@ -96,7 +107,13 @@ class Animation(_BaseThumbedMedium):
# Required
self.width: int = width
self.height: int = height
self.duration: int = duration
self._duration: dtm.timedelta = to_timedelta(duration)
# Optional
self.mime_type: Optional[str] = mime_type
self.file_name: Optional[str] = file_name
@property
def duration(self) -> Union[int, dtm.timedelta]:
return get_timedelta_value( # type: ignore[return-value]
self._duration, attribute="duration"
)
@@ -17,11 +17,14 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Audio."""
from typing import Optional
import datetime as dtm
from typing import Optional, Union
from telegram._files._basethumbedmedium import _BaseThumbedMedium
from telegram._files.photosize import PhotoSize
from telegram._utils.types import JSONDict
from telegram._utils.argumentparsing import to_timedelta
from telegram._utils.datetime import get_timedelta_value
from telegram._utils.types import JSONDict, TimePeriod
class Audio(_BaseThumbedMedium):
@@ -39,7 +42,11 @@ class Audio(_BaseThumbedMedium):
or reuse the file.
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
the same over time and for different bots. Can't be used to download or reuse the file.
duration (:obj:`int`): Duration of the audio in seconds as defined by the sender.
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the audio in
seconds as defined by the sender.
.. versionchanged:: v22.2
|time-period-input|
performer (:obj:`str`, optional): Performer of the audio as defined by the sender or by
audio tags.
title (:obj:`str`, optional): Title of the audio as defined by the sender or by audio tags.
@@ -56,7 +63,11 @@ class Audio(_BaseThumbedMedium):
or reuse the file.
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
the same over time and for different bots. Can't be used to download or reuse the file.
duration (:obj:`int`): Duration of the audio in seconds as defined by the sender.
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the audio in seconds as
defined by the sender.
.. deprecated:: v22.2
|time-period-int-deprecated|
performer (:obj:`str`): Optional. Performer of the audio as defined by the sender or by
audio tags.
title (:obj:`str`): Optional. Title of the audio as defined by the sender or by audio tags.
@@ -71,13 +82,13 @@ class Audio(_BaseThumbedMedium):
"""
__slots__ = ("duration", "file_name", "mime_type", "performer", "title")
__slots__ = ("_duration", "file_name", "mime_type", "performer", "title")
def __init__(
self,
file_id: str,
file_unique_id: str,
duration: int,
duration: TimePeriod,
performer: Optional[str] = None,
title: Optional[str] = None,
mime_type: Optional[str] = None,
@@ -96,9 +107,15 @@ class Audio(_BaseThumbedMedium):
)
with self._unfrozen():
# Required
self.duration: int = duration
self._duration: dtm.timedelta = to_timedelta(duration)
# Optional
self.performer: Optional[str] = performer
self.title: Optional[str] = title
self.mime_type: Optional[str] = mime_type
self.file_name: Optional[str] = file_name
@property
def duration(self) -> Union[int, dtm.timedelta]:
return get_timedelta_value( # type: ignore[return-value]
self._duration, attribute="duration"
)

Some files were not shown because too many files have changed in this diff Show More