mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 15:45:13 +00:00
Compare commits
58 Commits
v20.8
...
autogen-code
| Author | SHA1 | Date | |
|---|---|---|---|
| 0670e42835 | |||
| 6ba7a097f4 | |||
| 6fc45a803d | |||
| 512a0b7417 | |||
| 7d952d8707 | |||
| b496fabf62 | |||
| 637b8e260b | |||
| 912fe45d8c | |||
| 805b7bff32 | |||
| f3bd0f1462 | |||
| 5b0e0b5f78 | |||
| c4623c4476 | |||
| ee6e82d7ad | |||
| c34f4811ea | |||
| d768abdd6b | |||
| 2561ffd16b | |||
| 622fdf7fa3 | |||
| 615f1bf20b | |||
| 7a8b1be5a4 | |||
| 3a8ace2e8b | |||
| 169bd47de3 | |||
| a956dcc6a4 | |||
| ee88973fee | |||
| 8f9fc65be0 | |||
| 75d946e4be | |||
| fed8d8875e | |||
| 42b68f1a70 | |||
| 58b8ef4ce4 | |||
| f6d009d3ac | |||
| 153894728c | |||
| 5fa457974d | |||
| 3ec7bb819c | |||
| 040cd2c2fc | |||
| 474f9c9693 | |||
| e18ca0d5e1 | |||
| 7331fff3fc | |||
| 23536ee759 | |||
| 2d8d43f2a5 | |||
| 8a542e22a0 | |||
| c0716dd344 | |||
| 668b49b048 | |||
| 22eb434a62 | |||
| ae2858783a | |||
| 2c227d5977 | |||
| 437261f716 | |||
| 1b98e440fa | |||
| d30ba3d1ef | |||
| 20e0f87f6b | |||
| bd9b0bd126 | |||
| 5d11d7fd42 | |||
| 099ab5d9fa | |||
| 26f943771b | |||
| 9c263fbd1a | |||
| 277031cfb2 | |||
| c513d51147 | |||
| bb6c85609a | |||
| 5b6cd3a33b | |||
| 1cf63c26c5 |
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 }}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
name: Check Type Completeness
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- telegram/**
|
||||
- requirements.txt
|
||||
- requirements-opts.txt
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
@@ -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
@@ -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
@@ -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'
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/].
|
||||
@@ -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/].
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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:])
|
||||
@@ -0,0 +1 @@
|
||||
libcst
|
||||
@@ -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/].
|
||||
@@ -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__":
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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"):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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):
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -0,0 +1,7 @@
|
||||
Birthdate
|
||||
=========
|
||||
|
||||
.. autoclass:: telegram.Birthdate
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessConnection
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.BusinessConnection
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -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:
|
||||
@@ -0,0 +1,8 @@
|
||||
ChatBackground
|
||||
==============
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.ChatBackground
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
ChatBoostAdded
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ChatBoostAdded
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
ChatFullInfo
|
||||
============
|
||||
|
||||
.. autoclass:: telegram.ChatFullInfo
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
+48
-10
@@ -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,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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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,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,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,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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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 = (
|
||||
|
||||
@@ -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)
|
||||
@@ -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:
|
||||
|
||||
@@ -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,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,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,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
@@ -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):
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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,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,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,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,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,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,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,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,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
Reference in New Issue
Block a user