Compare commits

...

58 Commits

Author SHA1 Message Date
Harshil 0670e42835 initial PoC for code autogeneration 2024-05-31 00:47:53 -04:00
Bibo-Joshi 6ba7a097f4 Update Settings for pre-commit.ci (#4265) 2024-05-22 17:43:45 +02:00
Hinrich Mahler 6fc45a803d Bump version to v21.2 2024-05-20 17:23:38 +02:00
Harshil 512a0b7417 Add Version to PTBDeprecationWarning (#4262) 2024-05-20 16:12:34 +02:00
Bibo-Joshi 7d952d8707 Documentation Improvements (#4217)
Co-authored-by: poolitzer <github@poolitzer.eu>
2024-05-20 15:53:04 +02:00
Bibo-Joshi b496fabf62 Call Application.post_stop Only if Application.stop was called (#4211) 2024-05-20 15:52:30 +02:00
Bibo-Joshi 637b8e260b Handle SystemExit raised in Handlers (#4157) 2024-05-20 15:27:08 +02:00
Bibo-Joshi 912fe45d8c Handle Exceptions in building CallbackContext (#4222) 2024-05-20 15:25:56 +02:00
Bibo-Joshi 805b7bff32 API 7.3 (#4243, #4248, #4247, #4242, #4246, #4260)
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Abdelrahman Elkheir <90580077+aelkheir@users.noreply.github.com>
2024-05-20 15:25:25 +02:00
Harshil f3bd0f1462 Add New Rules to ruff Config (#4250) 2024-05-12 09:13:20 +02:00
dependabot[bot] 5b0e0b5f78 Bump furo from 2024.4.27 to 2024.5.6 (#4252)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-11 15:37:54 +02:00
Bibo-Joshi c4623c4476 Make Birthdate.to_date Return a datetime.date Object (#4251)
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
2024-05-10 22:23:19 +02:00
Bibo-Joshi ee6e82d7ad Remove Functionality Deprecated by Bot API 7.2 (#4245) 2024-05-10 17:42:22 +02:00
pre-commit-ci[bot] c34f4811ea pre-commit autoupdate (#4239)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-07 07:42:09 +02:00
dependabot[bot] d768abdd6b Bump pytest from 8.1.1 to 8.2.0 (#4231)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 22:36:18 +02:00
dependabot[bot] 2561ffd16b Bump dependabot/fetch-metadata from 2.0.0 to 2.1.0 (#4228)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2024-05-06 22:35:52 +02:00
Bibo-Joshi 622fdf7fa3 Adapt Test Suite to Changes in Error Messages (#4238) 2024-05-06 22:35:11 +02:00
dependabot[bot] 615f1bf20b Bump pytest-asyncio from 0.21.1 to 0.21.2 (#4232)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-05 10:03:38 +02:00
dependabot[bot] 7a8b1be5a4 Bump pytest-xdist from 3.6.0 to 3.6.1 (#4233)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 17:30:18 +02:00
dependabot[bot] 3a8ace2e8b Bump furo from 2024.1.29 to 2024.4.27 (#4230)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 11:12:26 +02:00
dependabot[bot] 169bd47de3 Bump srvaroa/labeler from 1.10.0 to 1.10.1 (#4227)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 11:07:21 +02:00
dependabot[bot] a956dcc6a4 Bump pytest from 7.4.4 to 8.1.1 (#4218)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
2024-04-28 22:32:20 +02:00
Bibo-Joshi ee88973fee Bump pytest-xdist from 3.5.0 to 3.6.0
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-20 10:44:39 +02:00
dependabot[bot] 8f9fc65be0 Bump sphinx from 7.2.6 to 7.3.7 (#4215)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-20 09:22:42 +02:00
Hinrich Mahler 75d946e4be Bump version to v21.1.1 2024-04-15 17:00:17 +02:00
Bibo-Joshi fed8d8875e Fix Bug With Parameter message_thread_id of Message.reply_* (#4207) 2024-04-15 16:49:36 +02:00
Nano 42b68f1a70 Remove Deprecation Warning in JobQueue.run_daily (#4206) 2024-04-14 14:14:45 +02:00
marinelay 58b8ef4ce4 Fix Annotation of EncryptedCredentials.decrypted_secret (#4199)
Co-authored-by: marinelay <marinelay@gmail.com>
2024-04-13 20:27:29 +02:00
Hinrich Mahler f6d009d3ac Bump version to v21.1 2024-04-12 12:39:38 +02:00
Bibo-Joshi 153894728c Documentation Improvements (#4171, #4158)
Signed-off-by: teslaedison <qingchengqiushuang@gmail.com>
Co-authored-by: teslaedison <156734008+teslaedison@users.noreply.github.com>
2024-04-12 12:03:01 +02:00
Harshil 5fa457974d API 7.2 (#4180, #4181)
Co-authored-by: Mahdyar Hasanpour <mahdyar@duck.com>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
Co-authored-by: Abdelrahman Elkheir <90580077+aelkheir@users.noreply.github.com>
Co-authored-by: Aditya <adityayadav11082@gmail.com>
2024-04-12 11:58:25 +02:00
Harshil 3ec7bb819c Make ChatAdministratorRights.can_*_stories Required (API 7.1) (#4192)
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
2024-04-06 17:13:43 +02:00
pre-commit-ci[bot] 040cd2c2fc pre-commit autoupdate (#4184)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2024-04-05 17:26:08 +02:00
Abdelrahman Elkheir 474f9c9693 Make Message.reply_* Reply in the Same Topic by Default (#4170)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2024-04-03 11:32:39 +02:00
dependabot[bot] e18ca0d5e1 Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0 (#4185)
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>
2024-04-02 22:19:33 +02:00
Bibo-Joshi 7331fff3fc Temporarily Mark Tests with get_sticker_set as XFAIL due to API 7.2 Update (#4190) 2024-04-02 22:13:54 +02:00
Abdelrahman Elkheir 23536ee759 Add Update.effective_sender (#4168) 2024-03-30 18:21:13 +01:00
Poolitzer 2d8d43f2a5 Accept Socket Objects for Webhooks (#4161) 2024-03-24 21:04:10 +01:00
Bibo-Joshi 8a542e22a0 Refactor Debug logging in Bot to Improve Type Hinting (#4151) 2024-03-24 12:34:08 +01:00
Hinrich Mahler c0716dd344 Bump version to v21.0.1 2024-03-06 22:15:30 +01:00
Bibo-Joshi 668b49b048 Remove docs from Package (#4150) 2024-03-06 22:04:19 +01:00
Hinrich Mahler 22eb434a62 Bump version to v21.0 2024-03-06 21:09:47 +01:00
Bibo-Joshi ae2858783a Documentation Improvements (#4109, #4116)
Co-authored-by: Aditya <adityayadav11082@gmail.com>
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Maurice Banerjee Palmer <31225563+mbanerjeepalmer@users.noreply.github.com>
2024-03-06 14:45:50 +01:00
Bibo-Joshi 2c227d5977 Relax Upper Bound for httpx Dependency (#4148) 2024-03-06 13:20:38 +01:00
Bibo-Joshi 437261f716 Improve HTML Download of Documentation (#4146) 2024-03-05 17:16:14 +01:00
dependabot[bot] 1b98e440fa Bump test-summary/action from 2.2 to 2.3 (#4142)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
2024-03-03 19:28:06 +01:00
Bibo-Joshi d30ba3d1ef Run Unit Tests in PRs on Requirements Changes (#4144) 2024-03-03 19:27:21 +01:00
Bibo-Joshi 20e0f87f6b Make Updater.stop Independent of CancelledError (#4126) 2024-03-03 19:22:42 +01:00
Harshil bd9b0bd126 Handle Properties in TelegramObject.__setstate__ (#4134)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2024-03-03 19:22:26 +01:00
dependabot[bot] 5d11d7fd42 Update cachetools requirement from ~=5.3.2 to ~=5.3.3 (#4141)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2024-03-02 11:34:03 +01:00
Poolitzer 099ab5d9fa API 7.1 (#4118)
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
2024-03-02 10:56:15 +01:00
Bibo-Joshi 26f943771b Apply pre-commit Checks More Widely (#4135) 2024-02-29 19:11:03 +01:00
Bibo-Joshi 9c263fbd1a Add Parameter media_write_timeout to HTTPXRequest and Method ApplicationBuilder.media_write_timeout (#4120) 2024-02-26 17:47:04 +01:00
Bibo-Joshi 277031cfb2 Remove Functionality Deprecated in API 7.0 (#4114) 2024-02-25 10:34:47 +01:00
dependabot[bot] c513d51147 Update httpx requirement from ~=0.26.0 to ~=0.27.0 (#4131)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2024-02-24 15:14:26 +01:00
Harshil bb6c85609a Add Missing Slot to Updater (#4130) 2024-02-24 12:31:50 +01:00
Abdelrahman Elkheir 5b6cd3a33b Update Copyright to 2024 (#4121) 2024-02-19 20:06:25 +01:00
Harshil 1cf63c26c5 Refactor and Overhaul test_official (#4087) 2024-02-09 18:12:13 +01:00
460 changed files with 10873 additions and 3701 deletions
+2 -2
View File
@@ -157,7 +157,7 @@ Check-list for PRs
This checklist is a non-exhaustive reminder of things that should be done before a PR is merged, both for you as contributor and for the maintainers.
Feel free to copy (parts of) the checklist to the PR description to remind you or the maintainers of open points or if you have questions on anything.
- Added ``.. versionadded:: NEXT.VERSION``, ``.. versionchanged:: NEXT.VERSION`` or ``.. deprecated:: NEXT.VERSION`` to the docstrings for user facing changes (for methods/class descriptions, arguments and attributes)
- Added ``.. versionadded:: NEXT.VERSION``, ``.. versionchanged:: NEXT.VERSION``, ``.. deprecated:: NEXT.VERSION`` or ``.. versionremoved:: NEXT.VERSION`` to the docstrings for user facing changes (for methods/class descriptions, arguments and attributes)
- Created new or adapted existing unit tests
- Documented code changes according to the `CSI standard <https://standards.mousepawmedia.com/en/stable/csi.html>`__
- Added myself alphabetically to ``AUTHORS.rst`` (optional)
@@ -276,7 +276,7 @@ This gives us the flexibility to re-order arguments and more importantly
to add new required arguments. It's also more explicit and easier to read.
.. _`Code of Conduct`: https://www.python.org/psf/conduct/
.. _`Code of Conduct`: https://policies.python.org/python.org/code-of-conduct/
.. _`issue tracker`: https://github.com/python-telegram-bot/python-telegram-bot/issues
.. _`Telegram group`: https://telegram.me/pythontelegrambotgroup
.. _`PEP 8 Style Guide`: https://peps.python.org/pep-0008/
+2
View File
@@ -12,6 +12,8 @@ body:
To make it easier for us to help you, please read this [article](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Ask-Right).
Please mind that there is also a users' [Telegram group](https://t.me/pythontelegrambotgroup) for questions about the library. Questions asked there might be answered quicker than here. Moreover, [GitHub Discussions](https://github.com/python-telegram-bot/python-telegram-bot/discussions) offer a slightly better format to discuss usage questions.
If you have asked the same question elsewhere (e.g. the [Telegram group](https://t.me/pythontelegrambotgroup) or [StackOverflow](https://stackoverflow.com/questions/tagged/python-telegram-bot)), provide a link to that thread.
- type: textarea
id: issue-faced
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
- name: Fetch Dependabot metadata
id: dependabot-metadata
uses: dependabot/fetch-metadata@v1.6.0
uses: dependabot/fetch-metadata@v2.1.0
- uses: actions/checkout@v4
with:
+3 -4
View File
@@ -1,13 +1,12 @@
name: Test Documentation Build
on:
pull_request:
branches:
- master
- doc-fixes
paths:
- telegram/**
- docs/**
push:
branches:
- master
- doc-fixes
jobs:
test-sphinx-build:
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
pull-requests: write # for srvaroa/labeler to add labels in PR
runs-on: ubuntu-latest
steps:
- uses: srvaroa/labeler@v1.10.0
- uses: srvaroa/labeler@v1.10.1
# Config file at .github/labeler.yml
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+5 -4
View File
@@ -1,8 +1,9 @@
name: Bot API Tests
on:
pull_request:
branches:
- master
paths:
- telegram/**
- tests/**
push:
branches:
- master
@@ -33,7 +34,7 @@ jobs:
python -W ignore -m pip install -r requirements-dev.txt
- name: Compare to official api
run: |
pytest -v tests/test_official.py --junit-xml=.test_report_official.xml
pytest -v tests/test_official/test_official.py --junit-xml=.test_report_official.xml
exit $?
env:
TEST_OFFICIAL: "true"
@@ -41,7 +42,7 @@ jobs:
- name: Test Summary
id: test_summary
uses: test-summary/action@v2.2
uses: test-summary/action@v2.3
if: always() # always run, even if tests fail
with:
paths: .test_report_official.xml
+4 -2
View File
@@ -1,8 +1,10 @@
name: Check Type Completeness
on:
pull_request:
branches:
- master
paths:
- telegram/**
- requirements.txt
- requirements-opts.txt
push:
branches:
- master
+7 -5
View File
@@ -1,13 +1,15 @@
name: Unit Tests
on:
pull_request:
branches:
- master
paths:
- telegram/**
- tests/**
- requirements.txt
- requirements-opts.txt
- requirements-dev.txt
push:
branches:
- master
schedule:
# Run monday and friday morning at 03:07 - odd time to spread load on GitHub Actions
- cron: '7 3 * * 1,5'
@@ -81,7 +83,7 @@ jobs:
- name: Test Summary
id: test_summary
uses: test-summary/action@v2.2
uses: test-summary/action@v2.3
if: always() # always run, even if tests fail
with:
paths: |
+16 -17
View File
@@ -2,23 +2,23 @@
ci:
autofix_prs: false
autoupdate_schedule: monthly
autoupdate_schedule: quarterly
autoupdate_commit_msg: 'Bump `pre-commit` Hooks to Latest Versions'
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.2.1'
rev: 'v0.4.3'
hooks:
- id: ruff
name: ruff
files: ^(telegram|examples|tests)/.*\.py$
additional_dependencies:
- httpx~=0.26.0
- httpx~=0.27
- tornado~=6.4
- APScheduler~=3.10.4
- cachetools~=5.3.2
- cachetools~=5.3.3
- aiolimiter~=1.1.0
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.1.1
rev: 24.4.2
hooks:
- id: black
args:
@@ -29,31 +29,31 @@ repos:
hooks:
- id: flake8
- repo: https://github.com/PyCQA/pylint
rev: v3.0.3
rev: v3.1.0
hooks:
- id: pylint
files: ^(telegram|examples)/.*\.py$
files: ^(?!(tests|docs)).*\.py$
additional_dependencies:
- httpx~=0.26.0
- httpx~=0.27
- tornado~=6.4
- APScheduler~=3.10.4
- cachetools~=5.3.2
- cachetools~=5.3.3
- aiolimiter~=1.1.0
- . # this basically does `pip install -e .`
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
rev: v1.10.0
hooks:
- id: mypy
name: mypy-ptb
files: ^telegram/.*\.py$
files: ^(?!(tests|examples|docs)).*\.py$
additional_dependencies:
- types-pytz
- types-cryptography
- types-cachetools
- httpx~=0.26.0
- httpx~=0.27
- tornado~=6.4
- APScheduler~=3.10.4
- cachetools~=5.3.2
- cachetools~=5.3.3
- aiolimiter~=1.1.0
- . # this basically does `pip install -e .`
- id: mypy
@@ -65,13 +65,12 @@ repos:
additional_dependencies:
- tornado~=6.4
- APScheduler~=3.10.4
- cachetools~=5.3.2
- cachetools~=5.3.3
- . # this basically does `pip install -e .`
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
rev: v3.15.2
hooks:
- id: pyupgrade
files: ^(telegram|examples|tests|docs)/.*\.py$
args:
- --py38-plus
- repo: https://github.com/pycqa/isort
+41 -31
View File
@@ -7,46 +7,56 @@ version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
configuration: docs/source/conf.py
# Optionally build your docs in additional formats such as PDF
formats:
- pdf
- htmlzip
- pdf
# Optionally set the version of Python and requirements required to build your docs
python:
install:
- method: pip
path: .
- requirements: docs/requirements-docs.txt
install:
- method: pip
path: .
- requirements: docs/requirements-docs.txt
build:
os: ubuntu-22.04
tools:
python: "3" # latest stable cpython version
os: ubuntu-22.04
tools:
python: "3" # latest stable cpython version
jobs:
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
- mkdir --parents $READTHEDOCS_OUTPUT/htmlzip
- cp --recursive $READTHEDOCS_OUTPUT/html $READTHEDOCS_OUTPUT/$READTHEDOCS_PROJECT
# Hide the "other versions" dropdown. This is a workaround for those versions being shown,
# but not being accessible, as they are not built. Also, they hide the actual sidebar menu
# that is relevant only on ReadTheDocs.
- echo "#furo-readthedocs-versions{display:none}" >> $READTHEDOCS_OUTPUT/$READTHEDOCS_PROJECT/_static/styles/furo-extensions.css
- cd $READTHEDOCS_OUTPUT ; zip --recurse-path --symlinks htmlzip/$READTHEDOCS_PROJECT.zip $READTHEDOCS_PROJECT
search:
ranking: # bump up rank of commonly searched pages: (default: 0, values range from -10 to 10)
telegram.bot.html: 7
telegram.message.html: 3
telegram.update.html: 3
telegram.user.html: 2
telegram.chat.html: 2
telegram.ext.application.html: 3
telegram.ext.filters.html: 3
telegram.ext.callbackcontext.html: 2
telegram.ext.inlinekeyboardbutton.html: 1
ranking: # bump up rank of commonly searched pages: (default: 0, values range from -10 to 10)
telegram.bot.html: 7
telegram.message.html: 3
telegram.update.html: 3
telegram.user.html: 2
telegram.chat.html: 2
telegram.ext.application.html: 3
telegram.ext.filters.html: 3
telegram.ext.callbackcontext.html: 2
telegram.ext.inlinekeyboardbutton.html: 1
telegram.passport*.html: -7
telegram.passport*.html: -7
ignore:
- changelog.html
- coc.html
- bot_methods.html#
- bot_methods.html
# Defaults
- search.html
- search/index.html
- 404.html
- 404/index.html'
ignore:
- changelog.html
- coc.html
- bot_methods.html#
- bot_methods.html
# Defaults
- search.html
- search/index.html
- 404.html
- 404/index.html'
+1
View File
@@ -123,6 +123,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `Vorobjev Simon <https://github.com/simonvorobjev>`_
- `Wagner Macedo <https://github.com/wagnerluis1982>`_
- `wjt <https://github.com/wjt>`_
- `Wonseok Oh <https://github.com/marinelay>`_
- `Yaw Danso <https://github.com/dglitxh>`_
- `Yao Kuan <https://github.com/thatguylah>`_
- `zeroone2numeral2 <https://github.com/zeroone2numeral2>`_
+174
View File
@@ -4,6 +4,180 @@
Changelog
=========
Version 21.2
============
*Released 2024-05-20*
This is the technical changelog for version 21.2. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
Major Changes
-------------
- Full Support for Bot API 7.3 (:pr:`4246`, :pr:`4260`, :pr:`4243`, :pr:`4248`, :pr:`4242` closes :issue:`4236`, :pr:`4247` by `aelkheir <https://github.com/aelkheir>`_)
- Remove Functionality Deprecated by Bot API 7.2 (:pr:`4245`)
New Features
------------
- Add Version to ``PTBDeprecationWarning`` (:pr:`4262` closes :issue:`4261`)
- Handle Exceptions in building ``CallbackContext`` (:pr:`4222`)
Bug Fixes
---------
- Call ``Application.post_stop`` Only if ``Application.stop`` was called (:pr:`4211` closes :issue:`4210`)
- Handle ``SystemExit`` raised in Handlers (:pr:`4157` closes :issue:`4155` and :issue:`4156`)
- Make ``Birthdate.to_date`` Return a ``datetime.date`` Object (:pr:`4251`)
Documentation Improvements
--------------------------
- Documentation Improvements (:pr:`4217`)
Internal Changes
----------------
- Add New Rules to ``ruff`` Config (:pr:`4250`)
- Adapt Test Suite to Changes in Error Messages (:pr:`4238`)
Dependency Updates
------------------
- Bump ``furo`` from 2024.4.27 to 2024.5.6 (:pr:`4252`)
- ``pre-commit`` autoupdate (:pr:`4239`)
- Bump ``pytest`` from 8.1.1 to 8.2.0 (:pr:`4231`)
- Bump ``dependabot/fetch-metadata`` from 2.0.0 to 2.1.0 (:pr:`4228`)
- Bump ``pytest-asyncio`` from 0.21.1 to 0.21.2 (:pr:`4232`)
- Bump ``pytest-xdist`` from 3.6.0 to 3.6.1 (:pr:`4233`)
- Bump ``furo`` from 2024.1.29 to 2024.4.27 (:pr:`4230`)
- Bump ``srvaroa/labeler`` from 1.10.0 to 1.10.1 (:pr:`4227`)
- Bump ``pytest`` from 7.4.4 to 8.1.1 (:pr:`4218`)
- Bump ``sphinx`` from 7.2.6 to 7.3.7 (:pr:`4215`)
- Bump ``pytest-xdist`` from 3.5.0 to 3.6.0 (:pr:`4215`)
Version 21.1.1
==============
*Released 2024-04-15*
This is the technical changelog for version 21.1.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
Bug Fixes
---------
- Fix Bug With Parameter ``message_thread_id`` of ``Message.reply_*`` (:pr:`4207` closes :issue:`4205`)
Minor Changes
-------------
- Remove Deprecation Warning in ``JobQueue.run_daily`` (:pr:`4206` by `@Konano <https://github.com/Konano>`__)
- Fix Annotation of ``EncryptedCredentials.decrypted_secret`` (:pr:`4199` by `@marinelay <https://github.com/marinelay>`__ closes :issue:`4198`)
Version 21.1
==============
*Released 2024-04-12*
This is the technical changelog for version 21.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
Major Changes
-------------
- API 7.2 (:pr:`4180` closes :issue:`4179` and :issue:`4181`, :issue:`4181`)
- Make ``ChatAdministratorRights/ChatMemberAdministrator.can_*_stories`` Required (API 7.1) (:pr:`4192`)
Minor Changes
-------------
- Refactor Debug logging in ``Bot`` to Improve Type Hinting (:pr:`4151` closes :issue:`4010`)
New Features
------------
- Make ``Message.reply_*`` Reply in the Same Topic by Default (:pr:`4170` by `@aelkheir <https://github.com/aelkheir>`__ closes :issue:`4139`)
- Accept Socket Objects for Webhooks (:pr:`4161` closes :issue:`4078`)
- Add ``Update.effective_sender`` (:pr:`4168` by `@aelkheir <https://github.com/aelkheir>`__ closes :issue:`4085`)
Documentation Improvements
--------------------------
- Documentation Improvements (:pr:`4171`, :pr:`4158` by `@teslaedison <https://github.com/teslaedison>`__)
Internal Changes
----------------
- Temporarily Mark Tests with ``get_sticker_set`` as XFAIL due to API 7.2 Update (:pr:`4190`)
Dependency Updates
------------------
- ``pre-commit`` autoupdate (:pr:`4184`)
- Bump ``dependabot/fetch-metadata`` from 1.6.0 to 2.0.0 (:pr:`4185`)
Version 21.0.1
==============
*Released 2024-03-06*
This is the technical changelog for version 21.0.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
Bug Fixes
---------
- Remove ``docs`` from Package (:pr:`4150`)
Version 21.0
============
*Released 2024-03-06*
This is the technical changelog for version 21.0. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
Major Changes
-------------
- Remove Functionality Deprecated in API 7.0 (:pr:`4114` closes :issue:`4099`)
- API 7.1 (:pr:`4118`)
New Features
------------
- Add Parameter ``media_write_timeout`` to ``HTTPXRequest`` and Method ``ApplicationBuilder.media_write_timeout`` (:pr:`4120` closes :issue:`3864`)
- Handle Properties in ``TelegramObject.__setstate__`` (:pr:`4134` closes :issue:`4111`)
Bug Fixes
---------
- Add Missing Slot to ``Updater`` (:pr:`4130` closes :issue:`4127`)
Documentation Improvements
--------------------------
- Improve HTML Download of Documentation (:pr:`4146` closes :issue:`4050`)
- Documentation Improvements (:pr:`4109`, :issue:`4116`)
- Update Copyright to 2024 (:pr:`4121` by `@aelkheir <https://github.com/aelkheir>`__ closes :issue:`4041`)
Internal Changes
----------------
- Apply ``pre-commit`` Checks More Widely (:pr:`4135`)
- Refactor and Overhaul ``test_official`` (:pr:`4087` closes :issue:`3874`)
- Run Unit Tests in PRs on Requirements Changes (:pr:`4144`)
- Make ``Updater.stop`` Independent of ``CancelledError`` (:pr:`4126`)
Dependency Updates
------------------
- Relax Upper Bound for ``httpx`` Dependency (:pr:`4148`)
- Bump ``test-summary/action`` from 2.2 to 2.3 (:pr:`4142`)
- Update ``cachetools`` requirement from ~=5.3.2 to ~=5.3.3 (:pr:`4141`)
- Update ``httpx`` requirement from ~=0.26.0 to ~=0.27.0 (:pr:`4131`)
Version 20.8
============
+5 -9
View File
@@ -14,9 +14,9 @@
:target: https://pypi.org/project/python-telegram-bot/
:alt: Supported Python versions
.. image:: https://img.shields.io/badge/Bot%20API-7.0-blue?logo=telegram
.. image:: https://img.shields.io/badge/Bot%20API-7.3-blue?logo=telegram
:target: https://core.telegram.org/bots/api-changelog
:alt: Supported Bot API versions
:alt: Supported Bot API version
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot
:target: https://pypistats.org/packages/python-telegram-bot
@@ -46,10 +46,6 @@
:target: https://app.codacy.com/gh/python-telegram-bot/python-telegram-bot/dashboard
:alt: Code quality: Codacy
.. image:: https://app.deepsource.com/gh/python-telegram-bot/python-telegram-bot.svg/?label=active+issues
:target: https://app.deepsource.com/gh/python-telegram-bot/python-telegram-bot/?ref=repository-badge
:alt: Code quality: DeepSource
.. image:: https://results.pre-commit.ci/badge/github/python-telegram-bot/python-telegram-bot/master.svg
:target: https://results.pre-commit.ci/latest/github/python-telegram-bot/python-telegram-bot/master
:alt: pre-commit.ci status
@@ -93,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
Telegram API support
====================
All types and methods of the Telegram Bot API **7.0** are supported.
All types and methods of the Telegram Bot API **7.3** are supported.
Installing
==========
@@ -135,7 +131,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.26.0 <https://www.python-httpx.org>`_ for
The only required dependency is `httpx ~= 0.27 <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.
@@ -153,7 +149,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.0 <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.2 <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 <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 <https://apscheduler.readthedocs.io/en/3.x/>`_ library and enforces `pytz>=2018.6 <https://pypi.org/project/pytz/>`_, where ``pytz`` is a dependency of ``APScheduler``. 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]"``.
+6 -10
View File
@@ -14,9 +14,9 @@
:target: https://pypi.org/project/python-telegram-bot-raw/
:alt: Supported Python versions
.. image:: https://img.shields.io/badge/Bot%20API-7.0-blue?logo=telegram
.. image:: https://img.shields.io/badge/Bot%20API-7.3-blue?logo=telegram
:target: https://core.telegram.org/bots/api-changelog
:alt: Supported Bot API versions
:alt: Supported Bot API version
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot-raw
:target: https://pypistats.org/packages/python-telegram-bot-raw
@@ -46,10 +46,6 @@
:target: https://app.codacy.com/gh/python-telegram-bot/python-telegram-bot/dashboard
:alt: Code quality: Codacy
.. image:: https://app.deepsource.com/gh/python-telegram-bot/python-telegram-bot.svg/?label=active+issues
:target: https://app.deepsource.com/gh/python-telegram-bot/python-telegram-bot/?ref=repository-badge
:alt: Code quality: DeepSource
.. image:: https://results.pre-commit.ci/badge/github/python-telegram-bot/python-telegram-bot/master.svg
:target: https://results.pre-commit.ci/latest/github/python-telegram-bot/python-telegram-bot/master
:alt: pre-commit.ci status
@@ -89,7 +85,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
Telegram API support
====================
All types and methods of the Telegram Bot API **7.0** are supported.
All types and methods of the Telegram Bot API **7.3** are supported.
Installing
==========
@@ -108,12 +104,12 @@ You can also install ``python-telegram-bot-raw`` from source, though this is usu
$ git clone https://github.com/python-telegram-bot/python-telegram-bot
$ cd python-telegram-bot
$ python setup-raw.py install
$ python setup_raw.py install
Note
----
Installing the ``.tar.gz`` archive available on PyPi directly via ``pip`` will *not* work as expected, as ``pip`` does not recognize that it should use ``setup-raw.py`` instead of ``setup.py``.
Installing the ``.tar.gz`` archive available on PyPi directly via ``pip`` will *not* work as expected, as ``pip`` does not recognize that it should use ``setup_raw.py`` instead of ``setup.py``.
Verifying Releases
------------------
@@ -136,7 +132,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.26.0 <https://www.python-httpx.org>`_ for
The only required dependency is `httpx ~= 0.27 <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.
+11
View File
@@ -0,0 +1,11 @@
## Code autogenerator
This folder is used to run python scripts which can autogenerate code used for adding features of
new Bot API updates.
## Requirements
Requires Python 3.10 and higher, and the package `libcst`.
## Usage
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
import sys
from pathlib import Path
import libcst as cst
from libcst.display import dump
sys.path.insert(0, str(Path.cwd().absolute()))
from tests.test_official.scraper import TelegramParameter
class BotVisitor(cst.CSTVisitor):
def visit_FunctionDef(self, node: cst.FunctionDef) -> bool:
if node.name.value == "send_message":
print("returning true for ", node.name.value)
return True
return False
def visit_Arg(self, node: cst.Arg) -> None:
print(node.value.value)
class BotTransformer(cst.CSTTransformer):
def __init__(self, methods: dict[str, TelegramParameter]) -> None:
self.methods = methods
self.stack: list[tuple[str, ...]] = []
def visit_FunctionDef(self, node: cst.FunctionDef) -> bool:
self.stack.append((node.name.value,))
return node.name.value in self.methods
def leave_FunctionDef(
self, original_node: cst.FunctionDef, updated_node: cst.FunctionDef
) -> cst.FunctionDef:
method_name = self.stack.pop()
if original_node.name.value not in self.methods:
return original_node
print(dump(updated_node))
# get which method we are in
method_name = method_name[0]
tg_param = self.methods.pop(method_name)
# Let's add our parameter now at the last position:
# if the arg is required, we will add it to the end anyway (backward compat) and have a
# type hint of Optional[<type>].
annot = cst.Annotation(
annotation=cst.Subscript(
value=cst.Name(value="Optional"),
slice=[
cst.SubscriptElement(
slice=cst.Index(value=cst.Name(value=tg_param.param_type))
)
],
)
)
new_param = cst.Param(
name=cst.Name(tg_param.param_name),
annotation=annot,
default=cst.Name(value="None"),
comma=original_node.params.params[-1].comma,
whitespace_after_param=original_node.params.params[-1].whitespace_after_param,
)
new_params = (*updated_node.params.params, new_param)
return updated_node.with_changes(
params=updated_node.params.with_changes(params=new_params)
)
def add_param_to_bot_method(method_name: str, param: TelegramParameter) -> None:
"""Add a parameter to a method in the Bot class.
Args:
method_name (str): The name of the method.
param (TelegramParameter): The parameter to add.
"""
# All ast editing is done in place
bot_file = Path("telegram/_bot.py")
with bot_file.open() as file:
source = cst.parse_module(file.read())
# s = dump(source)
mod_tree = source.visit(BotTransformer({method_name: param}))
code = mod_tree.code
with bot_file.open("w") as file:
file.write(code)
if __name__ == "__main__":
add_param_to_bot_method("send_message", TelegramParameter("effect_id", "str", False, "desc"))
# failures = parse_failures()
# missing_method_params = failures[0]
# for method_name, param in missing_method_params.items():
# print("Adding parameter", param.param_name, "to method", method_name)
# add_param_to_bot_method(method_name, param)
# break
+135
View File
@@ -0,0 +1,135 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# 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 file determines which methods/parameters need to be added to the API. It does so by
running test_official.py.
"""
import os
import re
import subprocess
import sys
from pathlib import Path
sys.path.insert(0, str(Path.cwd().absolute()))
os.environ["TEST_OFFICIAL"] = "true"
from functools import cache
from helpers import to_camel_case
from tests.test_official.scraper import TelegramParameter
from tests.test_official.test_official import classes, methods
def run_test_official() -> list:
"""Run test_official.py and gather which errors occured."""
try:
output = subprocess.run(
["pytest", "tests/test_official/test_official.py", "-q", "--no-header", "--tb=line"],
capture_output=True,
check=True,
text=True,
)
except subprocess.CalledProcessError as e: # if test_official.py fails (expected)
output = e.output
else:
output = output.stdout
# truncate part before ===failures===
str_output = output[output.find("====") :]
failures: list[str] = str_output.split("\n")[1:-2]
return failures
def get_telegram_parameter(
param_name: str, method_name: str | None = None, class_name: str | None = None
) -> TelegramParameter:
"""Get a TelegramParameter object from the scraper based on the method and parameter name.
Args:
method_name (str): The name of the method.
param_name (str): The name of the parameter.
Returns:
TelegramParameter: The TelegramParameter object.
"""
if method_name is not None:
for method in methods:
if method.method_name == to_camel_case(method_name):
for param in method.method_parameters:
if param.param_name == param_name:
return param
elif class_name is not None:
for cls in classes:
if cls.class_name == class_name:
for param in cls.class_parameters:
if param.param_name == param_name:
return param
else:
raise ValueError("Either method_name or class_name must be provided.")
raise ValueError(f"Param {param_name} not found in method {method_name} or class {class_name}")
@cache
def parse_failures() -> tuple[dict[str, TelegramParameter], dict[str, TelegramParameter]]:
"""Parse the output of run_test_official() to determine which methods/parameters need to be
added to the API.
Returns:
list[TelegramParameter]: A list of parameters that need to be added to the API.
"""
failures = run_test_official()
# regex patterns
param_missing_str = "AssertionError: Parameter ([a-z_]+) not found in ([a-z_]+)"
attribute_missing_str = "AssertionError: Attribute ([a-z_]+) not found in ([a-zA-Z0-9]+)"
missing_params_in_methods = {} # {method_name: TelegramParameter}
missing_attrs_in_classes = {} # {class_name: TelegramParameter}
for failure in failures:
# We will only count missing parameters/attributes for now:
# missing parameter
if match := re.search(param_missing_str, failure):
param_name = match.group(1)
method_name = match.group(2)
tg_param = get_telegram_parameter(param_name, method_name=method_name)
missing_params_in_methods[method_name] = tg_param
# missing attribute
elif match := re.search(attribute_missing_str, failure):
attr_name = match.group(1)
class_name = match.group(2)
tg_param = get_telegram_parameter(attr_name, class_name=class_name)
missing_attrs_in_classes[class_name] = tg_param
else:
print(f"Unknown failure: {failure}")
return missing_params_in_methods, missing_attrs_in_classes
# run_test_official()
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
def to_camel_case(snake_str: str) -> str:
"""Convert a snake_case string to a CamelCase string.
Args:
snake_str (str): The snake_case string.
Returns:
str: The CamelCase string.
"""
components = snake_str.split("_")
return components[0] + "".join(x.title() for x in components[1:])
+1
View File
@@ -0,0 +1 @@
libcst
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
View File
View File
+32 -29
View File
@@ -1,6 +1,6 @@
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -64,7 +64,7 @@ class AdmonitionInserter:
ForwardRef('DefaultValue[DVValueType]')
"""
METHOD_NAMES_FOR_BOT_AND_APPBUILDER: dict[type, str] = {
METHOD_NAMES_FOR_BOT_AND_APPBUILDER: typing.ClassVar[dict[type, str]] = {
cls: tuple(m[0] for m in _iter_own_public_methods(cls)) # m[0] means we take only names
for cls in (telegram.Bot, telegram.ext.ApplicationBuilder)
}
@@ -159,7 +159,7 @@ class AdmonitionInserter:
telegram.ext, inspect.isclass
)
for class_name, inspected_class in classes_to_inspect:
for _class_name, inspected_class in classes_to_inspect:
# We need to make "<class 'telegram._files.sticker.StickerSet'>" into
# "telegram.StickerSet" because that's the way the classes are mentioned in
# docstrings.
@@ -197,8 +197,8 @@ class AdmonitionInserter:
"Error generating Sphinx 'Available in' admonition "
f"(admonition_inserter.py). Class {name_of_class_in_attr} present in "
f"attribute {target_attr} of class {name_of_inspected_class_in_docstr}"
f" could not be resolved. {str(e)}"
)
f" could not be resolved. {e!s}"
) from e
# Properties need to be parsed separately because they act like attributes but not
# listed as attributes.
@@ -240,8 +240,8 @@ class AdmonitionInserter:
"Error generating Sphinx 'Available in' admonition "
f"(admonition_inserter.py). Class {name_of_class_in_prop} present in "
f"property {prop_name} of class {name_of_inspected_class_in_docstr}"
f" could not be resolved. {str(e)}"
)
f" could not be resolved. {e!s}"
) from e
return self._generate_admonitions(attrs_for_class, admonition_type="available_in")
@@ -271,8 +271,8 @@ class AdmonitionInserter:
raise NotImplementedError(
"Error generating Sphinx 'Returned in' admonition "
f"(admonition_inserter.py). {cls}, method {method_name}. "
f"Couldn't resolve type hint in return annotation {ret_annot}. {str(e)}"
)
f"Couldn't resolve type hint in return annotation {ret_annot}. {e!s}"
) from e
return self._generate_admonitions(methods_for_class, admonition_type="returned_in")
@@ -297,7 +297,7 @@ class AdmonitionInserter:
# inspect methods of all telegram classes for return statements that indicate
# that this given method is a shortcut for a Bot method
for class_name, cls in inspect.getmembers(telegram, predicate=inspect.isclass):
for _class_name, cls in inspect.getmembers(telegram, predicate=inspect.isclass):
# no need to inspect Bot's own methods, as Bot can't have shortcuts in Bot
if cls is telegram.Bot:
continue
@@ -344,8 +344,8 @@ class AdmonitionInserter:
raise NotImplementedError(
"Error generating Sphinx 'Use in' admonition "
f"(admonition_inserter.py). {cls}, method {method_name}, parameter "
f"{param}: Couldn't resolve type hint {param.annotation}. {str(e)}"
)
f"{param}: Couldn't resolve type hint {param.annotation}. {e!s}"
) from e
return self._generate_admonitions(methods_for_class, admonition_type="use_in")
@@ -359,17 +359,19 @@ class AdmonitionInserter:
If no key phrases are found, the admonition will be inserted at the very end.
"""
for idx, value in list(enumerate(lines)):
if (
value.startswith(".. seealso:")
# The docstring contains heading "Examples:", but Sphinx will have it converted
# to ".. admonition: Examples":
or value.startswith(".. admonition:: Examples")
or value.startswith(".. version")
# The space after ":param" is important because docstring can contain ":paramref:"
# in its plain text in the beginning of a line (e.g. ExtBot):
or value.startswith(":param ")
# some classes (like "Credentials") have no params, so insert before attrs:
or value.startswith(".. attribute::")
if value.startswith(
(
".. seealso:",
# The docstring contains heading "Examples:", but Sphinx will have it converted
# to ".. admonition: Examples":
".. admonition:: Examples",
".. version",
# The space after ":param" is important because docstring can contain
# ":paramref:" in its plain text in the beginning of a line (e.g. ExtBot):
":param ",
# some classes (like "Credentials") have no params, so insert before attrs:
".. attribute::",
)
):
return idx
return len(lines) - 1
@@ -411,7 +413,7 @@ class AdmonitionInserter:
# so its page needs no admonitions.
continue
attrs = sorted(attrs)
sorted_attrs = sorted(attrs)
# e.g. for admonition type "use_in" the title will be "Use in" and CSS class "use-in".
admonition = f"""
@@ -419,11 +421,11 @@ class AdmonitionInserter:
.. admonition:: {admonition_type.title().replace("_", " ")}
:class: {admonition_type.replace("_", "-")}
"""
if len(attrs) > 1:
for target_attr in attrs:
if len(sorted_attrs) > 1:
for target_attr in sorted_attrs:
admonition += "\n * " + target_attr
else:
admonition += f"\n {attrs[0]}"
admonition += f"\n {sorted_attrs[0]}"
admonition += "\n " # otherwise an unexpected unindent warning will be issued
admonition_for_class[cls] = admonition
@@ -516,12 +518,12 @@ class AdmonitionInserter:
# If it isn't resolved, we'll have the program throw an exception to be sure.
try:
cls = self._resolve_class(m.group("class_name"))
except AttributeError:
except AttributeError as exc:
# skip known ForwardRef's that need not be resolved to a Telegram class
if self.FORWARD_REF_SKIP_PATTERN.match(str(arg)):
pass
else:
raise NotImplementedError(f"Could not process ForwardRef: {arg}")
raise NotImplementedError(f"Could not process ForwardRef: {arg}") from exc
else:
yield cls
@@ -587,6 +589,7 @@ class AdmonitionInserter:
# If neither option works, this is not a PTB class.
except (NameError, AttributeError):
continue
return None
if __name__ == "__main__":
+4 -4
View File
@@ -1,6 +1,6 @@
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
import inspect
from typing import List
keyword_args = [
"Keyword Arguments:",
@@ -84,13 +85,12 @@ get_updates_read_timeout_addition = [
]
def find_insert_pos_for_kwargs(lines: list[str]) -> int:
def find_insert_pos_for_kwargs(lines: List[str]) -> int:
"""Finds the correct position to insert the keyword arguments and returns the index."""
for idx, value in reversed(list(enumerate(lines))): # reversed since :returns: is at the end
if value.startswith("Returns"):
return idx
else:
return False
return False
def check_timeout_and_api_kwargs_presence(obj: object) -> int:
+6 -4
View File
@@ -1,6 +1,6 @@
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,8 @@ to link to the correct files & lines on github. Can be simplified once
https://github.com/sphinx-doc/sphinx/issues/1556 is closed
"""
import subprocess
from pathlib import Path
from typing import Dict, Tuple
from sphinx.util import logging
@@ -30,7 +32,7 @@ sphinx_logger = logging.getLogger(__name__)
# must be a module-level variable so that it can be written to by the `autodoc-process-docstring`
# event handler in `sphinx_hooks.py`
LINE_NUMBERS = {}
LINE_NUMBERS: Dict[str, Tuple[Path, int, int]] = {}
def _git_branch() -> str:
@@ -52,7 +54,7 @@ git_branch = _git_branch()
base_url = "https://github.com/python-telegram-bot/python-telegram-bot/blob/"
def linkcode_resolve(_, info):
def linkcode_resolve(_, info) -> str:
"""See www.sphinx-doc.org/en/master/usage/extensions/linkcode.html"""
combined = ".".join((info["module"], info["fullname"]))
# special casing for ExtBot which is due to the special structure of extbot.rst
@@ -71,7 +73,7 @@ def linkcode_resolve(_, info):
line_info = LINE_NUMBERS.get(info["module"])
if not line_info:
return
return None
file, start_line, end_line = line_info
return f"{base_url}{git_branch}/{file}#L{start_line}-L{end_line}"
+8 -8
View File
@@ -1,6 +1,6 @@
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -67,9 +67,9 @@ def autodoc_skip_member(app, what, name, obj, skip, options):
return True
break
if name == "filter" and obj.__module__ == "telegram.ext.filters":
if not included_in_obj:
return True # return True to exclude from docs.
if name == "filter" and obj.__module__ == "telegram.ext.filters" and not included_in_obj:
return True # return True to exclude from docs.
return None
def autodoc_process_docstring(
@@ -118,7 +118,7 @@ def autodoc_process_docstring(
):
effective_insert: list[str] = media_write_timeout_deprecation
elif get_updates and to_insert.lstrip().startswith("read_timeout"):
effective_insert = [to_insert] + get_updates_read_timeout_addition
effective_insert = [to_insert, *get_updates_read_timeout_addition]
else:
effective_insert = [to_insert]
@@ -166,11 +166,11 @@ def autodoc_process_docstring(
autodoc_process_docstring(app, "method", f"{name}.__init__", obj.__init__, options, lines)
def autodoc_process_bases(app, name, obj, option, bases: list):
def autodoc_process_bases(app, name, obj, option, bases: list) -> None:
"""Here we fine tune how the base class's classes are displayed."""
for idx, base in enumerate(bases):
for idx, raw_base in enumerate(bases):
# let's use a string representation of the object
base = str(base)
base = str(raw_base)
# Special case for abstract context managers which are wrongly resoled for some reason
if base.startswith("typing.AbstractAsyncContextManager"):
+3 -2
View File
@@ -1,6 +1,6 @@
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -81,11 +81,12 @@ class TGConstXRefRole(PyXRefRole):
):
return repr(value), target
sphinx_logger.warning(
f"%s:%d: WARNING: Did not convert reference %s. :{CONSTANTS_ROLE}: is not supposed"
"%s:%d: WARNING: Did not convert reference %s. :%s: is not supposed"
" to be used with this type of target.",
refnode.source,
refnode.line,
refnode.rawsource,
CONSTANTS_ROLE,
)
return title, target
except Exception as exc:
+3 -3
View File
@@ -1,6 +1,6 @@
sphinx==7.2.6
furo==2024.1.29
git+https://github.com/harshil21/furo-sphinx-search@v0.2.0.1
sphinx==7.3.7
furo==2024.5.6
furo-sphinx-search @ git+https://github.com/harshil21/furo-sphinx-search@v0.2.0.1
sphinx-paramlinks==0.6.0
sphinxcontrib-mermaid==0.9.2
sphinx-copybutton==0.5.2
+10 -15
View File
@@ -1,4 +1,3 @@
import os
import re
import sys
from pathlib import Path
@@ -8,12 +7,12 @@ from pathlib import Path
# documentation root, use os.path.abspath to make it absolute, like shown here.
from sphinx.application import Sphinx
sys.path.insert(0, os.path.abspath("../.."))
sys.path.insert(0, str(Path("../..").resolve().absolute()))
# -- General configuration ------------------------------------------------
# General information about the project.
project = "python-telegram-bot"
copyright = "2015-2023, Leandro Toledo"
copyright = "2015-2024, Leandro Toledo"
author = "Leandro Toledo"
# The version info for the project you're documenting, acts as replacement for
@@ -21,9 +20,9 @@ author = "Leandro Toledo"
# built documents.
#
# The short X.Y version.
version = "20.8" # telegram.__version__[:3]
version = "21.2" # telegram.__version__[:3]
# The full version, including alpha/beta/rc tags.
release = "20.8" # telegram.__version__
release = "21.2" # telegram.__version__
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = "6.1.3"
@@ -68,7 +67,9 @@ source_suffix = ".rst"
master_doc = "index"
# Global substitutions
rst_prolog = (Path.cwd() / "../substitutions/global.rst").read_text(encoding="utf-8")
rst_prolog = ""
for file in Path.cwd().glob("../substitutions/*.rst"):
rst_prolog += "\n" + file.read_text(encoding="utf-8")
# -- Extension settings ------------------------------------------------
napoleon_use_admonition_for_examples = True
@@ -141,12 +142,6 @@ html_theme_options = {
"admonition-title-font-size": "0.95rem",
"admonition-font-size": "0.92rem",
},
"announcement": (
"PTB has undergone significant changes in v20. Please read the documentation "
"carefully and also check out the transition guide in the "
'<a href="https://github.com/python-telegram-bot/python-telegram-bot/wiki/'
'Transition-guide-to-Version-20.0">wiki</a>.'
),
"footer_icons": [
{
# Telegram channel logo
@@ -310,13 +305,13 @@ texinfo_documents = [
# Due to Sphinx behaviour, these imports only work when imported here, not at top of module.
# Not used but must be imported for the linkcode extension to find it
from docs.auxil.link_code import linkcode_resolve
from docs.auxil.sphinx_hooks import (
from docs.auxil.link_code import linkcode_resolve # noqa: E402, F401
from docs.auxil.sphinx_hooks import ( # noqa: E402
autodoc_process_bases,
autodoc_process_docstring,
autodoc_skip_member,
)
from docs.auxil.tg_const_role import CONSTANTS_ROLE, TGConstXRefRole
from docs.auxil.tg_const_role import CONSTANTS_ROLE, TGConstXRefRole # noqa: E402
def setup(app: Sphinx):
+8 -4
View File
@@ -113,6 +113,10 @@
:align: left
:widths: 1 4
* - :meth:`~telegram.Bot.approve_chat_join_request`
- Used for approving a chat join request
* - :meth:`~telegram.Bot.decline_chat_join_request`
- Used for declining a chat join request
* - :meth:`~telegram.Bot.ban_chat_member`
- Used for banning a member from the chat
* - :meth:`~telegram.Bot.unban_chat_member`
@@ -137,10 +141,6 @@
- Used for editing a non-primary invite link
* - :meth:`~telegram.Bot.revoke_chat_invite_link`
- Used for revoking an invite link created by the bot
* - :meth:`~telegram.Bot.approve_chat_join_request`
- Used for approving a chat join request
* - :meth:`~telegram.Bot.decline_chat_join_request`
- Used for declining a chat join request
* - :meth:`~telegram.Bot.set_chat_photo`
- Used for setting a photo to a chat
* - :meth:`~telegram.Bot.delete_chat_photo`
@@ -155,6 +155,8 @@
- Used for unpinning a message
* - :meth:`~telegram.Bot.unpin_all_chat_messages`
- Used for unpinning all pinned chat messages
* - :meth:`~telegram.Bot.get_business_connection`
- Used for getting information about the business account.
* - :meth:`~telegram.Bot.get_user_profile_photos`
- Used for obtaining user's profile pictures
* - :meth:`~telegram.Bot.get_chat`
@@ -237,6 +239,8 @@
- Used for setting a sticker set of a chat
* - :meth:`~telegram.Bot.delete_chat_sticker_set`
- Used for deleting the set sticker set of a chat
* - :meth:`~telegram.Bot.replace_sticker_in_set`
- Used for replacing a sticker in a set
* - :meth:`~telegram.Bot.set_sticker_position_in_set`
- Used for moving a sticker's position in the set
* - :meth:`~telegram.Bot.set_sticker_set_title`
+21 -2
View File
@@ -6,6 +6,7 @@ Available Types
telegram.animation
telegram.audio
telegram.birthdate
telegram.botcommand
telegram.botcommandscope
telegram.botcommandscopeallchatadministrators
@@ -18,16 +19,34 @@ Available Types
telegram.botdescription
telegram.botname
telegram.botshortdescription
telegram.businessconnection
telegram.businessintro
telegram.businesslocation
telegram.businessopeninghours
telegram.businessopeninghoursinterval
telegram.businessmessagesdeleted
telegram.callbackquery
telegram.chat
telegram.chatadministratorrights
telegram.chatbackground
telegram.backgroundtype
telegram.backgroundtypefill
telegram.backgroundtypewallpaper
telegram.backgroundtypepattern
telegram.backgroundtypechattheme
telegram.backgroundfill
telegram.backgroundfillsolid
telegram.backgroundfillgradient
telegram.backgroundfillfreeformgradient
telegram.chatboost
telegram.chatboostadded
telegram.chatboostremoved
telegram.chatboostsource
telegram.chatboostsourcegiftcode
telegram.chatboostsourcegiveaway
telegram.chatboostsourcepremium
telegram.chatboostupdated
telegram.chatfullinfo
telegram.chatinvitelink
telegram.chatjoinrequest
telegram.chatlocation
@@ -69,11 +88,11 @@ Available Types
telegram.inputmediadocument
telegram.inputmediaphoto
telegram.inputmediavideo
telegram.inputpolloption
telegram.inputsticker
telegram.keyboardbutton
telegram.keyboardbuttonpolltype
telegram.keyboardbuttonrequestchat
telegram.keyboardbuttonrequestuser
telegram.keyboardbuttonrequestusers
telegram.linkpreviewoptions
telegram.location
@@ -107,6 +126,7 @@ Available Types
telegram.replykeyboardremove
telegram.replyparameters
telegram.sentwebappmessage
telegram.shareduser
telegram.story
telegram.switchinlinequerychosenchat
telegram.telegramobject
@@ -115,7 +135,6 @@ Available Types
telegram.user
telegram.userchatboosts
telegram.userprofilephotos
telegram.usershared
telegram.usersshared
telegram.venue
telegram.video
+8
View File
@@ -0,0 +1,8 @@
BackgroundFill
==============
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundFill
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundFillFreeformGradient
==============================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundFillFreeformGradient
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundFillGradient
======================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundFillGradient
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundFillSolid
===================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundFillSolid
:members:
:show-inheritance:
+8
View File
@@ -0,0 +1,8 @@
BackgroundType
==============
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundType
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundTypeChatTheme
=======================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundTypeChatTheme
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundTypeFill
==================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundTypeFill
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundTypePattern
=====================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundTypePattern
:members:
:show-inheritance:
@@ -0,0 +1,8 @@
BackgroundTypeWallpaper
=======================
.. versionadded:: 21.2
.. autoclass:: telegram.BackgroundTypeWallpaper
:members:
:show-inheritance:
+7
View File
@@ -0,0 +1,7 @@
Birthdate
=========
.. autoclass:: telegram.Birthdate
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
BusinessConnection
==================
.. autoclass:: telegram.BusinessConnection
:members:
:show-inheritance:
+6
View File
@@ -0,0 +1,6 @@
BusinessIntro
==================
.. autoclass:: telegram.BusinessIntro
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
BusinessLocation
==================
.. autoclass:: telegram.BusinessLocation
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
BusinessMessagesDeleted
=======================
.. autoclass:: telegram.BusinessMessagesDeleted
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
BusinessOpeningHours
====================
.. autoclass:: telegram.BusinessOpeningHours
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
BusinessOpeningHoursInterval
============================
.. autoclass:: telegram.BusinessOpeningHoursInterval
:members:
:show-inheritance:
+8
View File
@@ -0,0 +1,8 @@
ChatBackground
==============
.. versionadded:: 21.2
.. autoclass:: telegram.ChatBackground
:members:
:show-inheritance:
+6
View File
@@ -0,0 +1,6 @@
ChatBoostAdded
==============
.. autoclass:: telegram.ChatBoostAdded
:members:
:show-inheritance:
+6
View File
@@ -0,0 +1,6 @@
ChatFullInfo
============
.. autoclass:: telegram.ChatFullInfo
:members:
:show-inheritance:
+3 -1
View File
@@ -4,4 +4,6 @@ telegram.constants Module
.. automodule:: telegram.constants
:members:
:show-inheritance:
:inherited-members: Enum, EnumMeta
:no-undoc-members:
:inherited-members: Enum, EnumMeta, str, int
:exclude-members: __format__, __new__, __repr__, __str__
@@ -0,0 +1,6 @@
BusinessConnectionHandler
=========================
.. autoclass:: telegram.ext.BusinessConnectionHandler
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
BusinessMessagesDeletedHandler
==============================
.. autoclass:: telegram.ext.BusinessMessagesDeletedHandler
:members:
:show-inheritance:
@@ -5,6 +5,8 @@ Handlers
:titlesonly:
telegram.ext.basehandler
telegram.ext.businessconnectionhandler
telegram.ext.businessmessagesdeletedhandler
telegram.ext.callbackqueryhandler
telegram.ext.chatboosthandler
telegram.ext.chatjoinrequesthandler
+6
View File
@@ -0,0 +1,6 @@
InputPollOption
===============
.. autoclass:: telegram.InputPollOption
:members:
:show-inheritance:
@@ -1,6 +0,0 @@
KeyboardButtonRequestUser
=========================
.. autoclass:: telegram.KeyboardButtonRequestUser
:members:
:show-inheritance:
@@ -1,6 +1,7 @@
UserShared
SharedUser
==========
.. autoclass:: telegram.UserShared
.. autoclass:: telegram.SharedUser
:members:
:show-inheritance:
+1
View File
@@ -0,0 +1 @@
.. |app_run_shutdown| replace:: The app will shut down when :exc:`KeyboardInterrupt` or :exc:`SystemExit` is raised. This also works from within handlers, error handlers and jobs. However, using :meth:`~telegram.ext.Application.stop_running` will give a somewhat cleaner shutdown behavior than manually raising those exceptions. On unix, the app will also shut down on receiving the signals specified by
+5 -1
View File
@@ -68,7 +68,7 @@
.. |rtm_aswr_deprecated| replace:: replacing this argument. PTB will automatically convert this argument to that one, but you should update your code to use the new argument.
.. |keyword_only_arg| replace:: In future versions, this argument will become a keyword-only argument.
.. |keyword_only_arg| replace:: This argument is now a keyword-only argument.
.. |text_html| replace:: The return value of this property is a best-effort approach. Unfortunately, it can not be guaranteed that sending a message with the returned string will render in the same way as the original message produces the same :attr:`~telegram.Message.entities`/:attr:`~telegram.Message.caption_entities` as the original message. For example, Telegram recommends that entities of type :attr:`~telegram.MessageEntity.BLOCKQUOTE` and :attr:`~telegram.MessageEntity.PRE` *should* start and end on a new line, but does not enforce this and leaves rendering decisions up to the clients.
@@ -77,3 +77,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.
.. |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.
.. |business_id_str| replace:: Unique identifier of the business connection on behalf of which the message will be sent.
+10 -2
View File
@@ -20,7 +20,13 @@ bot.
import logging
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, helpers
from telegram import (
InlineKeyboardButton,
InlineKeyboardMarkup,
LinkPreviewOptions,
Update,
helpers,
)
from telegram.constants import ParseMode
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, filters
@@ -70,7 +76,9 @@ async def deep_linked_level_2(update: Update, context: ContextTypes.DEFAULT_TYPE
bot = context.bot
url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
text = f'You can also mask the deep-linked URLs as links: <a href="{url}">▶️ CLICK HERE</a>.'
await update.message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
await update.message.reply_text(
text, parse_mode=ParseMode.HTML, link_preview_options=LinkPreviewOptions(is_disabled=True)
)
async def deep_linked_level_3(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
+8 -3
View File
@@ -20,12 +20,15 @@ explicit-preview-rules = true
ignore = ["PLR2004", "PLR0911", "PLR0912", "PLR0913", "PLR0915", "PERF203"]
select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET", "RSE",
"G", "ISC", "PT", "ASYNC", "TCH", "SLOT", "PERF", "PYI", "FLY", "AIR", "RUF022",
"RUF023", "Q", "INP",]
"RUF023", "Q", "INP", "W", "YTT", "DTZ", "ARG"]
# Add "FURB" after it's out of preview
# Add "A (flake8-builtins)" after we drop pylint
[tool.ruff.lint.per-file-ignores]
"tests/*.py" = ["B018"]
"tests/**.py" = ["RUF012", "ASYNC101"]
"tests/**.py" = ["RUF012", "ASYNC101", "DTZ", "ARG"]
"docs/**.py" = ["INP001", "ARG"]
"examples/**.py" = ["ARG"]
# PYLINT:
[tool.pylint."messages control"]
@@ -47,7 +50,7 @@ exclude-protected = ["_unfrozen"]
# PYTEST:
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--no-success-flaky-report -rsxX"
addopts = "--no-success-flaky-report -rX"
filterwarnings = [
"error",
"ignore::DeprecationWarning",
@@ -64,6 +67,8 @@ markers = [
"req",
]
asyncio_mode = "auto"
log_format = "%(funcName)s - Line %(lineno)d - %(message)s"
# log_level = "DEBUG" # uncomment to see DEBUG logs
# MYPY:
[tool.mypy]
+3 -3
View File
@@ -1,9 +1,9 @@
pre-commit # needed for pre-commit hooks in the git commit command
# For the test suite
pytest==7.4.4
pytest-asyncio==0.21.1 # needed because pytest doesn't come with native support for coroutines as tests
pytest-xdist==3.5.0 # xdist runs tests in parallel
pytest==8.2.0
pytest-asyncio==0.21.2 # needed because pytest doesn't come with native support for coroutines as tests
pytest-xdist==3.6.1 # xdist runs tests in parallel
flaky # Used for flaky tests (flaky decorator)
beautifulsoup4 # used in test_official for parsing tg docs
+1 -1
View File
@@ -20,7 +20,7 @@ tornado~=6.4 # webhooks!ext
# Cachetools and APS don't have a strict stability policy.
# Let's be cautious for now.
cachetools~=5.3.2 # callback-data!ext
cachetools~=5.3.3 # callback-data!ext
APScheduler~=3.10.4 # job-queue!ext
# pytz is required by APS and just needs the lower bound due to #2120
+3 -2
View File
@@ -5,5 +5,6 @@
# When dependencies release new versions and tests succeed, we should try to expand the allowed
# versions and only increase the lower bound if necessary
# httpx has no stable release yet, so let's be cautious for now
httpx ~= 0.26.0
# httpx has no stable release yet, but we've had no stability problems since v20.0a0 either
# Since there have been requests to relax the bound a bit, we allow versions < 1.0.0
httpx ~= 0.27
+1 -1
View File
@@ -5,4 +5,4 @@ license_files = LICENSE, LICENSE.dual, LICENSE.lesser
max-line-length = 99
ignore = W503, W605
extend-ignore = E203, E704
exclude = setup.py, setup-raw.py docs/source/conf.py
exclude = setup.py, setup_raw.py docs/source/conf.py
+44 -44
View File
@@ -4,15 +4,16 @@ import subprocess
import sys
from collections import defaultdict
from pathlib import Path
from typing import Any, Dict, List, Tuple
from setuptools import find_packages, setup
def get_requirements():
def get_requirements() -> List[str]:
"""Build the requirements list for this project"""
requirements_list = []
with Path("requirements.txt").open() as reqs:
with Path("requirements.txt").open(encoding="utf-8") as reqs:
for install in reqs:
if install.startswith("#"):
continue
@@ -21,11 +22,11 @@ def get_requirements():
return requirements_list
def get_packages_requirements(raw=False):
def get_packages_requirements(raw: bool = False) -> Tuple[List[str], List[str]]:
"""Build the package & requirements list for this project"""
reqs = get_requirements()
exclude = ["tests*"]
exclude = ["tests*", "docs*"]
if raw:
exclude.append("telegram.ext*")
@@ -34,68 +35,69 @@ def get_packages_requirements(raw=False):
return packs, reqs
def get_optional_requirements(raw=False):
def get_optional_requirements(raw: bool = False) -> Dict[str, List[str]]:
"""Build the optional dependencies"""
requirements = defaultdict(list)
with Path("requirements-opts.txt").open() as reqs:
with Path("requirements-opts.txt").open(encoding="utf-8") as reqs:
for line in reqs:
line = line.strip()
if not line or line.startswith("#"):
effective_line = line.strip()
if not effective_line or effective_line.startswith("#"):
continue
dependency, names = line.split("#")
dependency, names = effective_line.split("#")
dependency = dependency.strip()
for name in names.split(","):
name = name.strip()
if name.endswith("!ext"):
effective_name = name.strip()
if effective_name.endswith("!ext"):
if raw:
continue
else:
name = name[:-4]
requirements["ext"].append(dependency)
requirements[name].append(dependency)
effective_name = effective_name[:-4]
requirements["ext"].append(dependency)
requirements[effective_name].append(dependency)
requirements["all"].append(dependency)
return requirements
def get_setup_kwargs(raw=False):
def get_setup_kwargs(raw: bool = False) -> Dict[str, Any]:
"""Builds a dictionary of kwargs for the setup function"""
packages, requirements = get_packages_requirements(raw=raw)
raw_ext = "-raw" if raw else ""
readme = Path(f'README{"_RAW" if raw else ""}.rst')
version_file = Path("telegram/_version.py").read_text()
version_file = Path("telegram/_version.py").read_text(encoding="utf-8")
first_part = version_file.split("# SETUP.PY MARKER")[0]
exec(first_part)
exec(first_part) # pylint: disable=exec-used
kwargs = dict(
script_name=f"setup{raw_ext}.py",
name=f"python-telegram-bot{raw_ext}",
version=locals()["__version__"],
author="Leandro Toledo",
author_email="devs@python-telegram-bot.org",
license="LGPLv3",
url="https://python-telegram-bot.org/",
# Keywords supported by PyPI can be found at https://github.com/pypa/warehouse/blob/aafc5185e57e67d43487ce4faa95913dd4573e14/warehouse/templates/packaging/detail.html#L20-L58
project_urls={
return {
"script_name": f"setup{raw_ext}.py",
"name": f"python-telegram-bot{raw_ext}",
"version": locals()["__version__"],
"author": "Leandro Toledo",
"author_email": "devs@python-telegram-bot.org",
"license": "LGPLv3",
"url": "https://python-telegram-bot.org/",
# Keywords supported by PyPI can be found at
# https://github.com/pypa/warehouse/blob/aafc5185e57e67d43487ce4faa95913dd4573e14/
# warehouse/templates/packaging/detail.html#L20-L58
"project_urls": {
"Documentation": "https://docs.python-telegram-bot.org",
"Bug Tracker": "https://github.com/python-telegram-bot/python-telegram-bot/issues",
"Source Code": "https://github.com/python-telegram-bot/python-telegram-bot",
"News": "https://t.me/pythontelegrambotchannel",
"Changelog": "https://docs.python-telegram-bot.org/en/stable/changelog.html",
},
download_url=f"https://pypi.org/project/python-telegram-bot{raw_ext}/",
keywords="python telegram bot api wrapper",
description="We have made you a wrapper you can't refuse",
long_description=readme.read_text(),
long_description_content_type="text/x-rst",
packages=packages,
install_requires=requirements,
extras_require=get_optional_requirements(raw=raw),
include_package_data=True,
classifiers=[
"download_url": f"https://pypi.org/project/python-telegram-bot{raw_ext}/",
"keywords": "python telegram bot api wrapper",
"description": "We have made you a wrapper you can't refuse",
"long_description": readme.read_text(encoding="utf-8"),
"long_description_content_type": "text/x-rst",
"packages": packages,
"install_requires": requirements,
"extras_require": get_optional_requirements(raw=raw),
"include_package_data": True,
"classifiers": [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
@@ -111,16 +113,14 @@ def get_setup_kwargs(raw=False):
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
],
python_requires=">=3.8",
)
return kwargs
"python_requires": ">=3.8",
}
def main():
def main() -> None:
# If we're building, build ptb-raw as well
if set(sys.argv[1:]) in [{"bdist_wheel"}, {"sdist"}, {"sdist", "bdist_wheel"}]:
args = ["python", "setup-raw.py"]
args = ["python", "setup_raw.py"]
args.extend(sys.argv[1:])
subprocess.run(args, check=True, capture_output=True)
View File
+48 -10
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -22,6 +22,16 @@ __author__ = "devs@python-telegram-bot.org"
__all__ = (
"Animation",
"Audio",
"BackgroundFill",
"BackgroundFillFreeformGradient",
"BackgroundFillGradient",
"BackgroundFillSolid",
"BackgroundType",
"BackgroundTypeChatTheme",
"BackgroundTypeFill",
"BackgroundTypePattern",
"BackgroundTypeWallpaper",
"Birthdate",
"Bot",
"BotCommand",
"BotCommandScope",
@@ -35,17 +45,26 @@ __all__ = (
"BotDescription",
"BotName",
"BotShortDescription",
"BusinessConnection",
"BusinessIntro",
"BusinessLocation",
"BusinessMessagesDeleted",
"BusinessOpeningHours",
"BusinessOpeningHoursInterval",
"CallbackGame",
"CallbackQuery",
"Chat",
"ChatAdministratorRights",
"ChatBackground",
"ChatBoost",
"ChatBoostAdded",
"ChatBoostRemoved",
"ChatBoostSource",
"ChatBoostSourceGiftCode",
"ChatBoostSourceGiveaway",
"ChatBoostSourcePremium",
"ChatBoostUpdated",
"ChatFullInfo",
"ChatInviteLink",
"ChatJoinRequest",
"ChatLocation",
@@ -123,6 +142,7 @@ __all__ = (
"InputMediaPhoto",
"InputMediaVideo",
"InputMessageContent",
"InputPollOption",
"InputSticker",
"InputTextMessageContent",
"InputVenueMessageContent",
@@ -130,7 +150,6 @@ __all__ = (
"KeyboardButton",
"KeyboardButtonPollType",
"KeyboardButtonRequestChat",
"KeyboardButtonRequestUser",
"KeyboardButtonRequestUsers",
"LabeledPrice",
"LinkPreviewOptions",
@@ -184,6 +203,7 @@ __all__ = (
"SecureData",
"SecureValue",
"SentWebAppMessage",
"SharedUser",
"ShippingAddress",
"ShippingOption",
"ShippingQuery",
@@ -198,7 +218,6 @@ __all__ = (
"User",
"UserChatBoosts",
"UserProfilePhotos",
"UserShared",
"UsersShared",
"Venue",
"Video",
@@ -225,6 +244,7 @@ __all__ = (
from . import _version, constants, error, helpers, request, warnings
from ._birthdate import Birthdate
from ._bot import Bot
from ._botcommand import BotCommand
from ._botcommandscope import (
@@ -239,11 +259,32 @@ from ._botcommandscope import (
)
from ._botdescription import BotDescription, BotShortDescription
from ._botname import BotName
from ._business import (
BusinessConnection,
BusinessIntro,
BusinessLocation,
BusinessMessagesDeleted,
BusinessOpeningHours,
BusinessOpeningHoursInterval,
)
from ._callbackquery import CallbackQuery
from ._chat import Chat
from ._chatadministratorrights import ChatAdministratorRights
from ._chatbackground import (
BackgroundFill,
BackgroundFillFreeformGradient,
BackgroundFillGradient,
BackgroundFillSolid,
BackgroundType,
BackgroundTypeChatTheme,
BackgroundTypeFill,
BackgroundTypePattern,
BackgroundTypeWallpaper,
ChatBackground,
)
from ._chatboost import (
ChatBoost,
ChatBoostAdded,
ChatBoostRemoved,
ChatBoostSource,
ChatBoostSourceGiftCode,
@@ -252,6 +293,7 @@ from ._chatboost import (
ChatBoostUpdated,
UserChatBoosts,
)
from ._chatfullinfo import ChatFullInfo
from ._chatinvitelink import ChatInviteLink
from ._chatjoinrequest import ChatJoinRequest
from ._chatlocation import ChatLocation
@@ -338,11 +380,7 @@ from ._inline.inputtextmessagecontent import InputTextMessageContent
from ._inline.inputvenuemessagecontent import InputVenueMessageContent
from ._keyboardbutton import KeyboardButton
from ._keyboardbuttonpolltype import KeyboardButtonPollType
from ._keyboardbuttonrequest import (
KeyboardButtonRequestChat,
KeyboardButtonRequestUser,
KeyboardButtonRequestUsers,
)
from ._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUsers
from ._linkpreviewoptions import LinkPreviewOptions
from ._loginurl import LoginUrl
from ._menubutton import MenuButton, MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp
@@ -390,14 +428,14 @@ from ._payment.shippingaddress import ShippingAddress
from ._payment.shippingoption import ShippingOption
from ._payment.shippingquery import ShippingQuery
from ._payment.successfulpayment import SuccessfulPayment
from ._poll import Poll, PollAnswer, PollOption
from ._poll import InputPollOption, Poll, PollAnswer, PollOption
from ._proximityalerttriggered import ProximityAlertTriggered
from ._reaction import ReactionCount, ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
from ._reply import ExternalReplyInfo, ReplyParameters, TextQuote
from ._replykeyboardmarkup import ReplyKeyboardMarkup
from ._replykeyboardremove import ReplyKeyboardRemove
from ._sentwebappmessage import SentWebAppMessage
from ._shared import ChatShared, UserShared, UsersShared
from ._shared import ChatShared, SharedUser, UsersShared
from ._story import Story
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
from ._telegramobject import TelegramObject
+1 -1
View File
@@ -1,7 +1,7 @@
# !/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# 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 Birthday."""
from datetime import date
from typing import Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class Birthdate(TelegramObject):
"""
This object describes the birthdate of a user.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`day`, and :attr:`month` are equal.
.. versionadded:: 21.1
Args:
day (:obj:`int`): Day of the user's birth; 1-31.
month (:obj:`int`): Month of the user's birth; 1-12.
year (:obj:`int`, optional): Year of the user's birth.
Attributes:
day (:obj:`int`): Day of the user's birth; 1-31.
month (:obj:`int`): Month of the user's birth; 1-12.
year (:obj:`int`): Optional. Year of the user's birth.
"""
__slots__ = ("day", "month", "year")
def __init__(
self,
day: int,
month: int,
year: Optional[int] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.day: int = day
self.month: int = month
# Optional
self.year: Optional[int] = year
self._id_attrs = (
self.day,
self.month,
)
self._freeze()
def to_date(self, year: Optional[int] = None) -> date:
"""Return the birthdate as a date object.
.. versionchanged:: 21.2
Now returns a :obj:`datetime.date` object instead of a :obj:`datetime.datetime` object,
as was originally intended.
Args:
year (:obj:`int`, optional): The year to use. Required, if the :attr:`year` was not
present.
Returns:
:obj:`datetime.date`: The birthdate as a date object.
"""
if self.year is None and year is None:
raise ValueError(
"The `year` argument is required if the `year` attribute was not present."
)
return date(year or self.year, self.month, self.day) # type: ignore[arg-type]
+723 -590
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+445
View File
@@ -0,0 +1,445 @@
#!/usr/bin/env python
# pylint: disable=redefined-builtin
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# 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 the Telegram Business related classes."""
from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
from telegram._chat import Chat
from telegram._files.location import Location
from telegram._files.sticker import Sticker
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class BusinessConnection(TelegramObject):
"""
Describes the connection of the bot with a business account.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal if their :attr:`id`, :attr:`user`, :attr:`user_chat_id`, :attr:`date`,
:attr:`can_reply`, and :attr:`is_enabled` are equal.
.. versionadded:: 21.1
Args:
id (:obj:`str`): Unique identifier of the business connection.
user (:class:`telegram.User`): Business account user that created the business connection.
user_chat_id (:obj:`int`): Identifier of a private chat with the user who created the
business connection.
date (:obj:`datetime.datetime`): Date the connection was established in Unix time.
can_reply (:obj:`bool`): True, if the bot can act on behalf of the business account in
chats that were active in the last 24 hours.
is_enabled (:obj:`bool`): True, if the connection is active.
Attributes:
id (:obj:`str`): Unique identifier of the business connection.
user (:class:`telegram.User`): Business account user that created the business connection.
user_chat_id (:obj:`int`): Identifier of a private chat with the user who created the
business connection.
date (:obj:`datetime.datetime`): Date the connection was established in Unix time.
can_reply (:obj:`bool`): True, if the bot can act on behalf of the business account in
chats that were active in the last 24 hours.
is_enabled (:obj:`bool`): True, if the connection is active.
"""
__slots__ = (
"can_reply",
"date",
"id",
"is_enabled",
"user",
"user_chat_id",
)
def __init__(
self,
id: str,
user: "User",
user_chat_id: int,
date: datetime,
can_reply: bool,
is_enabled: bool,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.id: str = id
self.user: User = user
self.user_chat_id: int = user_chat_id
self.date: datetime = date
self.can_reply: bool = can_reply
self.is_enabled: bool = is_enabled
self._id_attrs = (
self.id,
self.user,
self.user_chat_id,
self.date,
self.can_reply,
self.is_enabled,
)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessConnection"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["date"] = from_timestamp(data.get("date"), tzinfo=loc_tzinfo)
data["user"] = User.de_json(data.get("user"), bot)
return super().de_json(data=data, bot=bot)
class BusinessMessagesDeleted(TelegramObject):
"""
This object is received when messages are deleted from a connected business account.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal if their :attr:`business_connection_id`, :attr:`message_ids`, and
:attr:`chat` are equal.
.. versionadded:: 21.1
Args:
business_connection_id (:obj:`str`): Unique identifier of the business connection.
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
may not have access to the chat or the corresponding user.
message_ids (Sequence[:obj:`int`]): A list of identifiers of the deleted messages in the
chat of the business account.
Attributes:
business_connection_id (:obj:`str`): Unique identifier of the business connection.
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
may not have access to the chat or the corresponding user.
message_ids (Tuple[:obj:`int`]): A list of identifiers of the deleted messages in the
chat of the business account.
"""
__slots__ = (
"business_connection_id",
"chat",
"message_ids",
)
def __init__(
self,
business_connection_id: str,
chat: Chat,
message_ids: Sequence[int],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.business_connection_id: str = business_connection_id
self.chat: Chat = chat
self.message_ids: Tuple[int, ...] = parse_sequence_arg(message_ids)
self._id_attrs = (
self.business_connection_id,
self.chat,
self.message_ids,
)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessMessagesDeleted"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["chat"] = Chat.de_json(data.get("chat"), bot)
return super().de_json(data=data, bot=bot)
class BusinessIntro(TelegramObject):
"""
This object contains information about the start page settings of a Telegram Business account.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`title`, :attr:`message` and :attr:`sticker` are equal.
.. versionadded:: 21.1
Args:
title (:obj:`str`, optional): Title text of the business intro.
message (:obj:`str`, optional): Message text of the business intro.
sticker (:class:`telegram.Sticker`, optional): Sticker of the business intro.
Attributes:
title (:obj:`str`): Optional. Title text of the business intro.
message (:obj:`str`): Optional. Message text of the business intro.
sticker (:class:`telegram.Sticker`): Optional. Sticker of the business intro.
"""
__slots__ = (
"message",
"sticker",
"title",
)
def __init__(
self,
title: Optional[str] = None,
message: Optional[str] = None,
sticker: Optional[Sticker] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.title: Optional[str] = title
self.message: Optional[str] = message
self.sticker: Optional[Sticker] = sticker
self._id_attrs = (self.title, self.message, self.sticker)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessIntro"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["sticker"] = Sticker.de_json(data.get("sticker"), bot)
return super().de_json(data=data, bot=bot)
class BusinessLocation(TelegramObject):
"""
This object contains information about the location of a Telegram Business account.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`address` is equal.
.. versionadded:: 21.1
Args:
address (:obj:`str`): Address of the business.
location (:class:`telegram.Location`, optional): Location of the business.
Attributes:
address (:obj:`str`): Address of the business.
location (:class:`telegram.Location`): Optional. Location of the business.
"""
__slots__ = (
"address",
"location",
)
def __init__(
self,
address: str,
location: Optional[Location] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.address: str = address
self.location: Optional[Location] = location
self._id_attrs = (self.address,)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessLocation"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["location"] = Location.de_json(data.get("location"), bot)
return super().de_json(data=data, bot=bot)
class BusinessOpeningHoursInterval(TelegramObject):
"""
This object describes an interval of time during which a business is open.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`opening_minute` and :attr:`closing_minute` are equal.
.. versionadded:: 21.1
Examples:
A day has (24 * 60 =) 1440 minutes, a week has (7 * 1440 =) 10080 minutes.
Starting the the minute's sequence from Monday, example values of
:attr:`opening_minute`, :attr:`closing_minute` will map to the following day times:
* Monday - 8am to 8:30pm:
- ``opening_minute = 480`` :guilabel:`8 * 60`
- ``closing_minute = 1230`` :guilabel:`20 * 60 + 30`
* Tuesday - 24 hours:
- ``opening_minute = 1440`` :guilabel:`24 * 60`
- ``closing_minute = 2879`` :guilabel:`2 * 24 * 60 - 1`
* Sunday - 12am - 11:58pm:
- ``opening_minute = 8640`` :guilabel:`6 * 24 * 60`
- ``closing_minute = 10078`` :guilabel:`7 * 24 * 60 - 2`
Args:
opening_minute (:obj:`int`): The minute's sequence number in a week, starting on Monday,
marking the start of the time interval during which the business is open;
0 - 7 * 24 * 60.
closing_minute (:obj:`int`): The minute's
sequence number in a week, starting on Monday, marking the end of the time interval
during which the business is open; 0 - 8 * 24 * 60
Attributes:
opening_minute (:obj:`int`): The minute's sequence number in a week, starting on Monday,
marking the start of the time interval during which the business is open;
0 - 7 * 24 * 60.
closing_minute (:obj:`int`): The minute's
sequence number in a week, starting on Monday, marking the end of the time interval
during which the business is open; 0 - 8 * 24 * 60
"""
__slots__ = ("_closing_time", "_opening_time", "closing_minute", "opening_minute")
def __init__(
self,
opening_minute: int,
closing_minute: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.opening_minute: int = opening_minute
self.closing_minute: int = closing_minute
self._opening_time: Optional[Tuple[int, int, int]] = None
self._closing_time: Optional[Tuple[int, int, int]] = None
self._id_attrs = (self.opening_minute, self.closing_minute)
self._freeze()
def _parse_minute(self, minute: int) -> Tuple[int, int, int]:
return (minute // 1440, minute % 1440 // 60, minute % 1440 % 60)
@property
def opening_time(self) -> Tuple[int, int, int]:
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`opening_minute`. It contains
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
Returns:
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
"""
if self._opening_time is None:
self._opening_time = self._parse_minute(self.opening_minute)
return self._opening_time
@property
def closing_time(self) -> Tuple[int, int, int]:
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`closing_minute`. It contains
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
Returns:
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
"""
if self._closing_time is None:
self._closing_time = self._parse_minute(self.closing_minute)
return self._closing_time
class BusinessOpeningHours(TelegramObject):
"""
This object describes the opening hours of a business.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`time_zone_name` and :attr:`opening_hours` are equal.
.. versionadded:: 21.1
Args:
time_zone_name (:obj:`str`): Unique name of the time zone for which the opening
hours are defined.
opening_hours (Sequence[:class:`telegram.BusinessOpeningHoursInterval`]): List of
time intervals describing business opening hours.
Attributes:
time_zone_name (:obj:`str`): Unique name of the time zone for which the opening
hours are defined.
opening_hours (Sequence[:class:`telegram.BusinessOpeningHoursInterval`]): List of
time intervals describing business opening hours.
"""
__slots__ = ("opening_hours", "time_zone_name")
def __init__(
self,
time_zone_name: str,
opening_hours: Sequence[BusinessOpeningHoursInterval],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.time_zone_name: str = time_zone_name
self.opening_hours: Sequence[BusinessOpeningHoursInterval] = parse_sequence_arg(
opening_hours
)
self._id_attrs = (self.time_zone_name, self.opening_hours)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessOpeningHours"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["opening_hours"] = BusinessOpeningHoursInterval.de_list(
data.get("opening_hours"), bot
)
return super().de_json(data=data, bot=bot)
+7 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -209,11 +209,11 @@ class CallbackQuery(TelegramObject):
self,
text: str,
parse_mode: ODVInput[str] = DEFAULT_NONE,
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
reply_markup: Optional["InlineKeyboardMarkup"] = None,
entities: Optional[Sequence["MessageEntity"]] = None,
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
*,
disable_web_page_preview: Optional[bool] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -461,6 +461,7 @@ class CallbackQuery(TelegramObject):
horizontal_accuracy: Optional[float] = None,
heading: Optional[int] = None,
proximity_alert_radius: Optional[int] = None,
live_period: Optional[int] = None,
*,
location: Optional[Location] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -509,6 +510,7 @@ class CallbackQuery(TelegramObject):
horizontal_accuracy=horizontal_accuracy,
heading=heading,
proximity_alert_radius=proximity_alert_radius,
live_period=live_period,
chat_id=None,
message_id=None,
)
@@ -525,6 +527,7 @@ class CallbackQuery(TelegramObject):
horizontal_accuracy=horizontal_accuracy,
heading=heading,
proximity_alert_radius=proximity_alert_radius,
live_period=live_period,
)
async def stop_message_live_location(
@@ -808,13 +811,13 @@ class CallbackQuery(TelegramObject):
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None,
disable_notification: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_markup: Optional[ReplyMarkup] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
reply_parameters: Optional["ReplyParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
+538 -52
View File
File diff suppressed because it is too large Load Diff
+51 -34
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -44,12 +44,16 @@ class ChatAdministratorRights(TelegramObject):
:attr:`can_post_stories`, :attr:`can_edit_stories`, and :attr:`can_delete_stories` are
considered as well when comparing objects of this type in terms of equality.
.. versionchanged:: 21.1
As of this version, :attr:`can_post_stories`, :attr:`can_edit_stories`,
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
changed.
Args:
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, chat statistics, boost list in channels, see channel members, report spam
messages, see anonymous administrators in supergroups and ignore slow mode.
Implied by any other administrator privilege.
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the administrator can delete messages of
other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
@@ -61,38 +65,44 @@ class ChatAdministratorRights(TelegramObject):
that they have promoted, directly or indirectly (promoted by administrators that
were appointed by the user).
can_change_info (:obj:`bool`): :obj:`True`, if the user is allowed to change the chat title
,photo and other settings.
, photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to
the chat.
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can post
messages in the channel, or access channel statistics; channels only.
messages in the channel, or access channel statistics; for channels only.
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
messages of other users.
messages of other users and can pin messages; for channels only.
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
messages; groups and supergroups only.
can_post_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can post
stories in the channel; channels only.
messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
can_edit_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
can_delete_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can delete
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; supergroups only.
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
Attributes:
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, chat statistics, boost list in channels, see channel members, report spam
messages, see anonymous administrators in supergroups and ignore slow mode.
Implied by any other administrator privilege.
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the administrator can delete messages of
other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
@@ -108,25 +118,32 @@ class ChatAdministratorRights(TelegramObject):
can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to
the chat.
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
messages in the channel, or access channel statistics; channels only.
messages in the channel, or access channel statistics; for channels only.
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
messages of other users.
messages of other users and can pin messages; for channels only.
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
messages; groups and supergroups only.
can_post_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
stories in the channel; channels only.
messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
can_edit_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
can_delete_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can delete
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; supergroups only.
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
"""
@@ -159,13 +176,13 @@ class ChatAdministratorRights(TelegramObject):
can_promote_members: bool,
can_change_info: bool,
can_invite_users: bool,
can_post_stories: bool,
can_edit_stories: bool,
can_delete_stories: bool,
can_post_messages: Optional[bool] = None,
can_edit_messages: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
can_post_stories: Optional[bool] = None,
can_edit_stories: Optional[bool] = None,
can_delete_stories: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
) -> None:
@@ -179,13 +196,13 @@ class ChatAdministratorRights(TelegramObject):
self.can_promote_members: bool = can_promote_members
self.can_change_info: bool = can_change_info
self.can_invite_users: bool = can_invite_users
self.can_post_stories: bool = can_post_stories
self.can_edit_stories: bool = can_edit_stories
self.can_delete_stories: bool = can_delete_stories
# Optionals
self.can_post_messages: Optional[bool] = can_post_messages
self.can_edit_messages: Optional[bool] = can_edit_messages
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_post_stories: Optional[bool] = can_post_stories
self.can_edit_stories: Optional[bool] = can_edit_stories
self.can_delete_stories: Optional[bool] = can_delete_stories
self.can_manage_topics: Optional[bool] = can_manage_topics
self._id_attrs = (
+540
View File
@@ -0,0 +1,540 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# 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 objects related to chat backgrounds."""
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
from telegram import constants
from telegram._files.document import Document
from telegram._telegramobject import TelegramObject
from telegram._utils import enum
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class BackgroundFill(TelegramObject):
"""Base class for Telegram BackgroundFill Objects. It can be one of:
* :class:`telegram.BackgroundFillSolid`
* :class:`telegram.BackgroundFillGradient`
* :class:`telegram.BackgroundFillFreeformGradient`
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal.
.. versionadded:: 21.2
Args:
type (:obj:`str`): Type of the background fill. Can be one of:
:attr:`~telegram.BackgroundFill.SOLID`, :attr:`~telegram.BackgroundFill.GRADIENT`
or :attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
Attributes:
type (:obj:`str`): Type of the background fill. Can be one of:
:attr:`~telegram.BackgroundFill.SOLID`, :attr:`~telegram.BackgroundFill.GRADIENT`
or :attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
"""
__slots__ = ("type",)
SOLID: Final[constants.BackgroundFillType] = constants.BackgroundFillType.SOLID
""":const:`telegram.constants.BackgroundFillType.SOLID`"""
GRADIENT: Final[constants.BackgroundFillType] = constants.BackgroundFillType.GRADIENT
""":const:`telegram.constants.BackgroundFillType.GRADIENT`"""
FREEFORM_GRADIENT: Final[constants.BackgroundFillType] = (
constants.BackgroundFillType.FREEFORM_GRADIENT
)
""":const:`telegram.constants.BackgroundFillType.FREEFORM_GRADIENT`"""
def __init__(
self,
type: str, # pylint: disable=redefined-builtin
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required by all subclasses
self.type: str = enum.get_member(constants.BackgroundFillType, type, type)
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BackgroundFill"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: Dict[str, Type[BackgroundFill]] = {
cls.SOLID: BackgroundFillSolid,
cls.GRADIENT: BackgroundFillGradient,
cls.FREEFORM_GRADIENT: BackgroundFillFreeformGradient,
}
if cls is BackgroundFill and data.get("type") in _class_mapping:
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
return super().de_json(data=data, bot=bot)
class BackgroundFillSolid(BackgroundFill):
"""
The background is filled using the selected color.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`color` is equal.
.. versionadded:: 21.2
Args:
color (:obj:`int`): The color of the background fill in the `RGB24` format.
Attributes:
type (:obj:`str`): Type of the background fill. Always
:attr:`~telegram.BackgroundFill.SOLID`.
color (:obj:`int`): The color of the background fill in the `RGB24` format.
"""
__slots__ = ("color",)
def __init__(
self,
color: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.SOLID, api_kwargs=api_kwargs)
with self._unfrozen():
self.color: int = color
self._id_attrs = (self.color,)
class BackgroundFillGradient(BackgroundFill):
"""
The background is a gradient fill.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`top_color`, :attr:`bottom_color`
and :attr:`rotation_angle` are equal.
.. versionadded:: 21.2
Args:
top_color (:obj:`int`): Top color of the gradient in the `RGB24` format.
bottom_color (:obj:`int`): Bottom color of the gradient in the `RGB24` format.
rotation_angle (:obj:`int`): Clockwise rotation angle of the background
fill in degrees;
0-:tg-const:`telegram.constants.BackgroundFillLimit.MAX_ROTATION_ANGLE`.
Attributes:
type (:obj:`str`): Type of the background fill. Always
:attr:`~telegram.BackgroundFill.GRADIENT`.
top_color (:obj:`int`): Top color of the gradient in the `RGB24` format.
bottom_color (:obj:`int`): Bottom color of the gradient in the `RGB24` format.
rotation_angle (:obj:`int`): Clockwise rotation angle of the background
fill in degrees;
0-:tg-const:`telegram.constants.BackgroundFillLimit.MAX_ROTATION_ANGLE`.
"""
__slots__ = ("bottom_color", "rotation_angle", "top_color")
def __init__(
self,
top_color: int,
bottom_color: int,
rotation_angle: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.GRADIENT, api_kwargs=api_kwargs)
with self._unfrozen():
self.top_color: int = top_color
self.bottom_color: int = bottom_color
self.rotation_angle: int = rotation_angle
self._id_attrs = (self.top_color, self.bottom_color, self.rotation_angle)
class BackgroundFillFreeformGradient(BackgroundFill):
"""
The background is a freeform gradient that rotates after every message in the chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`colors` is equal.
.. versionadded:: 21.2
Args:
colors (Sequence[:obj:`int`]): A list of the 3 or 4 base colors that are used to
generate the freeform gradient in the `RGB24` format
Attributes:
type (:obj:`str`): Type of the background fill. Always
:attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
colors (Sequence[:obj:`int`]): A list of the 3 or 4 base colors that are used to
generate the freeform gradient in the `RGB24` format
"""
__slots__ = ("colors",)
def __init__(
self,
colors: Sequence[int],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.FREEFORM_GRADIENT, api_kwargs=api_kwargs)
with self._unfrozen():
self.colors: Tuple[int, ...] = parse_sequence_arg(colors)
self._id_attrs = (self.colors,)
class BackgroundType(TelegramObject):
"""Base class for Telegram BackgroundType Objects. It can be one of:
* :class:`telegram.BackgroundTypeFill`
* :class:`telegram.BackgroundTypeWallpaper`
* :class:`telegram.BackgroundTypePattern`
* :class:`telegram.BackgroundTypeChatTheme`.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal.
.. versionadded:: 21.2
Args:
type (:obj:`str`): Type of the background. Can be one of:
:attr:`~telegram.BackgroundType.FILL`, :attr:`~telegram.BackgroundType.WALLPAPER`
:attr:`~telegram.BackgroundType.PATTERN` or
:attr:`~telegram.BackgroundType.CHAT_THEME`.
Attributes:
type (:obj:`str`): Type of the background. Can be one of:
:attr:`~telegram.BackgroundType.FILL`, :attr:`~telegram.BackgroundType.WALLPAPER`
:attr:`~telegram.BackgroundType.PATTERN` or
:attr:`~telegram.BackgroundType.CHAT_THEME`.
"""
__slots__ = ("type",)
FILL: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.FILL
""":const:`telegram.constants.BackgroundTypeType.FILL`"""
WALLPAPER: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.WALLPAPER
""":const:`telegram.constants.BackgroundTypeType.WALLPAPER`"""
PATTERN: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.PATTERN
""":const:`telegram.constants.BackgroundTypeType.PATTERN`"""
CHAT_THEME: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.CHAT_THEME
""":const:`telegram.constants.BackgroundTypeType.CHAT_THEME`"""
def __init__(
self,
type: str, # pylint: disable=redefined-builtin
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required by all subclasses
self.type: str = enum.get_member(constants.BackgroundTypeType, type, type)
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BackgroundType"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: Dict[str, Type[BackgroundType]] = {
cls.FILL: BackgroundTypeFill,
cls.WALLPAPER: BackgroundTypeWallpaper,
cls.PATTERN: BackgroundTypePattern,
cls.CHAT_THEME: BackgroundTypeChatTheme,
}
if cls is BackgroundType and data.get("type") in _class_mapping:
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
if "fill" in data:
data["fill"] = BackgroundFill.de_json(data.get("fill"), bot)
if "document" in data:
data["document"] = Document.de_json(data.get("document"), bot)
return super().de_json(data=data, bot=bot)
class BackgroundTypeFill(BackgroundType):
"""
The background is automatically filled based on the selected colors.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`fill` and :attr:`dark_theme_dimming` are equal.
.. versionadded:: 21.2
Args:
fill (:obj:`telegram.BackgroundFill`): The background fill.
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.FILL`.
fill (:obj:`telegram.BackgroundFill`): The background fill.
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
"""
__slots__ = ("dark_theme_dimming", "fill")
def __init__(
self,
fill: BackgroundFill,
dark_theme_dimming: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.FILL, api_kwargs=api_kwargs)
with self._unfrozen():
self.fill: BackgroundFill = fill
self.dark_theme_dimming: int = dark_theme_dimming
self._id_attrs = (self.fill, self.dark_theme_dimming)
class BackgroundTypeWallpaper(BackgroundType):
"""
The background is a wallpaper in the `JPEG` format.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`document` and :attr:`dark_theme_dimming` are equal.
.. versionadded:: 21.2
Args:
document (:obj:`telegram.Document`): Document with the wallpaper
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
is_blurred (:obj:`bool`, optional): :obj:`True`, if the wallpaper is downscaled to fit
in a 450x450 square and then box-blurred with radius 12
is_moving (:obj:`bool`, optional): :obj:`True`, if the background moves slightly
when the device is tilted
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.WALLPAPER`.
document (:obj:`telegram.Document`): Document with the wallpaper
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
is_blurred (:obj:`bool`): Optional. :obj:`True`, if the wallpaper is downscaled to fit
in a 450x450 square and then box-blurred with radius 12
is_moving (:obj:`bool`): Optional. :obj:`True`, if the background moves slightly
when the device is tilted
"""
__slots__ = ("dark_theme_dimming", "document", "is_blurred", "is_moving")
def __init__(
self,
document: Document,
dark_theme_dimming: int,
is_blurred: Optional[bool] = None,
is_moving: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.WALLPAPER, api_kwargs=api_kwargs)
with self._unfrozen():
# Required
self.document: Document = document
self.dark_theme_dimming: int = dark_theme_dimming
# Optionals
self.is_blurred: Optional[bool] = is_blurred
self.is_moving: Optional[bool] = is_moving
self._id_attrs = (self.document, self.dark_theme_dimming)
class BackgroundTypePattern(BackgroundType):
"""
The background is a `PNG` or `TGV` (gzipped subset of `SVG` with `MIME` type
`"application/x-tgwallpattern"`) pattern to be combined with the background fill
chosen by the user.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`document` and :attr:`fill` and :attr:`intensity` are equal.
.. versionadded:: 21.2
Args:
document (:obj:`telegram.Document`): Document with the pattern.
fill (:obj:`telegram.BackgroundFill`): The background fill that is combined with
the pattern.
intensity (:obj:`int`): Intensity of the pattern when it is shown above the filled
background;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_INTENSITY`.
is_inverted (:obj:`int`, optional): :obj:`True`, if the background fill must be applied
only to the pattern itself. All other pixels are black in this case. For dark
themes only.
is_moving (:obj:`bool`, optional): :obj:`True`, if the background moves slightly
when the device is tilted.
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.PATTERN`.
document (:obj:`telegram.Document`): Document with the pattern.
fill (:obj:`telegram.BackgroundFill`): The background fill that is combined with
the pattern.
intensity (:obj:`int`): Intensity of the pattern when it is shown above the filled
background;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_INTENSITY`.
is_inverted (:obj:`int`): Optional. :obj:`True`, if the background fill must be applied
only to the pattern itself. All other pixels are black in this case. For dark
themes only.
is_moving (:obj:`bool`): Optional. :obj:`True`, if the background moves slightly
when the device is tilted.
"""
__slots__ = (
"document",
"fill",
"intensity",
"is_inverted",
"is_moving",
)
def __init__(
self,
document: Document,
fill: BackgroundFill,
intensity: int,
is_inverted: Optional[bool] = None,
is_moving: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.PATTERN, api_kwargs=api_kwargs)
with self._unfrozen():
# Required
self.document: Document = document
self.fill: BackgroundFill = fill
self.intensity: int = intensity
# Optionals
self.is_inverted: Optional[bool] = is_inverted
self.is_moving: Optional[bool] = is_moving
self._id_attrs = (self.document, self.fill, self.intensity)
class BackgroundTypeChatTheme(BackgroundType):
"""
The background is taken directly from a built-in chat theme.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`theme_name` is equal.
.. versionadded:: 21.2
Args:
theme_name (:obj:`str`): Name of the chat theme, which is usually an emoji.
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.CHAT_THEME`.
theme_name (:obj:`str`): Name of the chat theme, which is usually an emoji.
"""
__slots__ = ("theme_name",)
def __init__(
self,
theme_name: str,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.CHAT_THEME, api_kwargs=api_kwargs)
with self._unfrozen():
self.theme_name: str = theme_name
self._id_attrs = (self.theme_name,)
class ChatBackground(TelegramObject):
"""
This object represents a chat background.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal.
.. versionadded:: 21.2
Args:
type (:obj:`telegram.BackgroundType`): Type of the background.
Attributes:
type (:obj:`telegram.BackgroundType`): Type of the background.
"""
__slots__ = ("type",)
def __init__(
self,
type: BackgroundType, # pylint: disable=redefined-builtin
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.type: BackgroundType = type
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBackground"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["type"] = BackgroundType.de_json(data.get("type"), bot)
return super().de_json(data=data, bot=bot)
+33
View File
@@ -34,6 +34,39 @@ if TYPE_CHECKING:
from telegram import Bot
class ChatBoostAdded(TelegramObject):
"""
This object represents a service message about a user boosting a chat.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`boost_count` are equal.
.. versionadded:: 21.0
Args:
boost_count (:obj:`int`): Number of boosts added by the user.
Attributes:
boost_count (:obj:`int`): Number of boosts added by the user.
"""
__slots__ = ("boost_count",)
def __init__(
self,
boost_count: int,
*,
api_kwargs: Optional[JSONDict] = None,
) -> None:
super().__init__(api_kwargs=api_kwargs)
self.boost_count: int = boost_count
self._id_attrs = (self.boost_count,)
self._freeze()
class ChatBoostSource(TelegramObject):
"""
Base class for Telegram ChatBoostSource objects. It can be one of:
+166
View File
@@ -0,0 +1,166 @@
#!/usr/bin/env python
# pylint: disable=redefined-builtin
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# 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 ChatFullInfo."""
from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence
from telegram._birthdate import Birthdate
from telegram._chat import Chat
from telegram._chatlocation import ChatLocation
from telegram._chatpermissions import ChatPermissions
from telegram._files.chatphoto import ChatPhoto
from telegram._reaction import ReactionType
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import BusinessIntro, BusinessLocation, BusinessOpeningHours, Message
class ChatFullInfo(Chat):
"""
This object contains full information about a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`~telegram.Chat.id` is equal.
Caution:
This class is a subclass of :class:`telegram.Chat` and inherits all attributes and methods
for backwards compatibility. In the future, this class will *NOT* inherit from
:class:`telegram.Chat`.
.. seealso::
All arguments and attributes can be found in :class:`telegram.Chat`.
.. versionadded:: 21.2
Args:
max_reaction_count (:obj:`int`): The maximum number of reactions that can be set on a
message in the chat.
.. versionadded:: 21.2
Attributes:
max_reaction_count (:obj:`int`): The maximum number of reactions that can be set on a
message in the chat.
.. versionadded:: 21.2
"""
__slots__ = ("max_reaction_count",)
def __init__(
self,
id: int,
type: str,
accent_color_id: int, # API 7.3 made this argument required
max_reaction_count: int, # NEW arg in api 7.3 and is required
title: Optional[str] = None,
username: Optional[str] = None,
first_name: Optional[str] = None,
last_name: Optional[str] = None,
is_forum: Optional[bool] = None,
photo: Optional[ChatPhoto] = None,
active_usernames: Optional[Sequence[str]] = None,
birthdate: Optional[Birthdate] = None,
business_intro: Optional["BusinessIntro"] = None,
business_location: Optional["BusinessLocation"] = None,
business_opening_hours: Optional["BusinessOpeningHours"] = None,
personal_chat: Optional["Chat"] = None,
available_reactions: Optional[Sequence[ReactionType]] = None,
background_custom_emoji_id: Optional[str] = None,
profile_accent_color_id: Optional[int] = None,
profile_background_custom_emoji_id: Optional[str] = None,
emoji_status_custom_emoji_id: Optional[str] = None,
emoji_status_expiration_date: Optional[datetime] = None,
bio: Optional[str] = None,
has_private_forwards: Optional[bool] = None,
has_restricted_voice_and_video_messages: Optional[bool] = None,
join_to_send_messages: Optional[bool] = None,
join_by_request: Optional[bool] = None,
description: Optional[str] = None,
invite_link: Optional[str] = None,
pinned_message: Optional["Message"] = None,
permissions: Optional[ChatPermissions] = None,
slow_mode_delay: Optional[int] = None,
unrestrict_boost_count: Optional[int] = None,
message_auto_delete_time: Optional[int] = None,
has_aggressive_anti_spam_enabled: Optional[bool] = None,
has_hidden_members: Optional[bool] = None,
has_protected_content: Optional[bool] = None,
has_visible_history: Optional[bool] = None,
sticker_set_name: Optional[str] = None,
can_set_sticker_set: Optional[bool] = None,
custom_emoji_sticker_set_name: Optional[str] = None,
linked_chat_id: Optional[int] = None,
location: Optional[ChatLocation] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(
id=id,
type=type,
title=title,
username=username,
first_name=first_name,
last_name=last_name,
photo=photo,
description=description,
invite_link=invite_link,
pinned_message=pinned_message,
permissions=permissions,
sticker_set_name=sticker_set_name,
can_set_sticker_set=can_set_sticker_set,
slow_mode_delay=slow_mode_delay,
bio=bio,
linked_chat_id=linked_chat_id,
location=location,
message_auto_delete_time=message_auto_delete_time,
has_private_forwards=has_private_forwards,
has_protected_content=has_protected_content,
join_to_send_messages=join_to_send_messages,
join_by_request=join_by_request,
has_restricted_voice_and_video_messages=has_restricted_voice_and_video_messages,
is_forum=is_forum,
active_usernames=active_usernames,
emoji_status_custom_emoji_id=emoji_status_custom_emoji_id,
emoji_status_expiration_date=emoji_status_expiration_date,
has_aggressive_anti_spam_enabled=has_aggressive_anti_spam_enabled,
has_hidden_members=has_hidden_members,
available_reactions=available_reactions,
accent_color_id=accent_color_id,
background_custom_emoji_id=background_custom_emoji_id,
profile_accent_color_id=profile_accent_color_id,
profile_background_custom_emoji_id=profile_background_custom_emoji_id,
has_visible_history=has_visible_history,
unrestrict_boost_count=unrestrict_boost_count,
custom_emoji_sticker_set_name=custom_emoji_sticker_set_name,
birthdate=birthdate,
personal_chat=personal_chat,
business_intro=business_intro,
business_location=business_location,
business_opening_hours=business_opening_hours,
api_kwargs=api_kwargs,
)
# Required and unique to this class-
with self._unfrozen():
self.max_reaction_count: int = max_reaction_count
self._freeze()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+52 -34
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -191,15 +191,19 @@ class ChatMemberAdministrator(ChatMember):
* The argument :paramref:`can_manage_topics` was added, which changes the position of the
optional argument :paramref:`custom_title`.
.. versionchanged:: 21.1
As of this version, :attr:`can_post_stories`, :attr:`can_edit_stories`,
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
changed.
Args:
user (:class:`telegram.User`): Information about the user.
can_be_edited (:obj:`bool`): :obj:`True`, if the bot
is allowed to edit administrator privileges of that user.
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator
can access the chat event log, chat statistics, message statistics in
channels, see channel members, see anonymous administrators in supergroups
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the
administrator can delete messages of other users.
@@ -218,27 +222,34 @@ class ChatMemberAdministrator(ChatMember):
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
new users to the chat.
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the
administrator can post messages in the channel, or access channel statistics; channels
only.
administrator can post messages in the channel, or access channel statistics;
for channels only.
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the
administrator can edit messages of other users and can pin
messages; channels only.
messages; for channels only.
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to pin messages; groups and supergroups only.
can_post_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can post
stories in the channel; channels only.
to pin messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
can_edit_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
can_delete_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can delete
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; supergroups only.
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
custom_title (:obj:`str`, optional): Custom title for this user.
@@ -252,9 +263,8 @@ class ChatMemberAdministrator(ChatMember):
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, chat statistics, boost list in channels, see channel members, report spam
messages, see anonymous administrators in supergroups and ignore slow mode.
Implied by any other administrator privilege.
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the
administrator can delete messages of other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the
@@ -273,26 +283,33 @@ class ChatMemberAdministrator(ChatMember):
new users to the chat.
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the
administrator can post messages in the channel or access channel statistics;
channels only.
for channels only.
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the
administrator can edit messages of other users and can pin
messages; channels only.
messages; for channels only.
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to pin messages; groups and supergroups only.
can_post_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
stories in the channel; channels only.
to pin messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
can_edit_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
can_delete_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can delete
stories posted by other users; channels only.
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; supergroups only
to create, rename, close, and reopen forum topics; for supergroups only
.. versionadded:: 20.0
custom_title (:obj:`str`): Optional. Custom title for this user.
@@ -330,14 +347,14 @@ class ChatMemberAdministrator(ChatMember):
can_promote_members: bool,
can_change_info: bool,
can_invite_users: bool,
can_post_stories: bool,
can_edit_stories: bool,
can_delete_stories: bool,
can_post_messages: Optional[bool] = None,
can_edit_messages: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
custom_title: Optional[str] = None,
can_post_stories: Optional[bool] = None,
can_edit_stories: Optional[bool] = None,
can_delete_stories: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
@@ -352,14 +369,15 @@ class ChatMemberAdministrator(ChatMember):
self.can_promote_members: bool = can_promote_members
self.can_change_info: bool = can_change_info
self.can_invite_users: bool = can_invite_users
self.can_post_stories: bool = can_post_stories
self.can_edit_stories: bool = can_edit_stories
self.can_delete_stories: bool = can_delete_stories
# Optionals
self.can_post_messages: Optional[bool] = can_post_messages
self.can_edit_messages: Optional[bool] = can_edit_messages
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_manage_topics: Optional[bool] = can_manage_topics
self.custom_title: Optional[str] = custom_title
self.can_post_stories: Optional[bool] = can_post_stories
self.can_edit_stories: Optional[bool] = can_edit_stories
self.can_delete_stories: Optional[bool] = can_delete_stories
class ChatMemberMember(ChatMember):
+14 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -63,6 +63,11 @@ class ChatMemberUpdated(TelegramObject):
chat via a chat folder invite link
.. versionadded:: 20.3
via_join_request (:obj:`bool`, optional): :obj:`True`, if the user joined the chat after
sending a direct join request without using an invite link and being approved by
an administrator
.. versionadded:: 21.2
Attributes:
chat (:class:`telegram.Chat`): Chat the user belongs to.
@@ -80,6 +85,11 @@ class ChatMemberUpdated(TelegramObject):
chat via a chat folder invite link
.. versionadded:: 20.3
via_join_request (:obj:`bool`): Optional. :obj:`True`, if the user joined the chat after
sending a direct join request without using an invite link and being approved
by an administrator
.. versionadded:: 21.2
"""
@@ -91,6 +101,7 @@ class ChatMemberUpdated(TelegramObject):
"new_chat_member",
"old_chat_member",
"via_chat_folder_invite_link",
"via_join_request",
)
def __init__(
@@ -102,6 +113,7 @@ class ChatMemberUpdated(TelegramObject):
new_chat_member: ChatMember,
invite_link: Optional[ChatInviteLink] = None,
via_chat_folder_invite_link: Optional[bool] = None,
via_join_request: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
@@ -116,6 +128,7 @@ class ChatMemberUpdated(TelegramObject):
# Optionals
self.invite_link: Optional[ChatInviteLink] = invite_link
self.via_join_request: Optional[bool] = via_join_request
self._id_attrs = (
self.chat,
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -2,7 +2,7 @@
# pylint: disable=too-many-arguments
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify

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