mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-20 08:05:27 +00:00
Compare commits
136 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 49ea8d39fb | |||
| 7e86e8be14 | |||
| 5cff9adb55 | |||
| 217a5f929e | |||
| 007f432ee4 | |||
| 23a685335b | |||
| 9953216980 | |||
| bacdeb37fd | |||
| a0f98b241e | |||
| 23d0bd8fe3 | |||
| 1701950a1d | |||
| 851f7ff0b3 | |||
| 359232e6c7 | |||
| 9782510779 | |||
| deb6cb19b3 | |||
| 21ebdbc973 | |||
| 54d0294f92 | |||
| 5693add136 | |||
| 3dd7d84fa5 | |||
| 4ebcec2b91 | |||
| 200b623263 | |||
| c64bd7a715 | |||
| bbb9fcaaa5 | |||
| d48fa71ec5 | |||
| f9cbddd10a | |||
| 2797d9d305 | |||
| 19302bce25 | |||
| 3507cb13e6 | |||
| 6b59365464 | |||
| 74da17153b | |||
| 97e6e7e206 | |||
| d1159cd5ac | |||
| 51ad4d76d0 | |||
| 171953f109 | |||
| 606773d8f0 | |||
| f408b1a2dd | |||
| 3e7ab7e7af | |||
| 456b81d22a | |||
| cb90814829 | |||
| 7b61a30fb1 | |||
| f3a9b74445 | |||
| d996e8f9c9 | |||
| 0a6725852f | |||
| b8fbb89fae | |||
| f3650364b9 | |||
| 5b629ede56 | |||
| 28afeccf70 | |||
| 9467847d74 | |||
| b11a0c7778 | |||
| ff645c6fe2 | |||
| 9c3053b3f9 | |||
| 5a6c9cc777 | |||
| 6e4a1f0a21 | |||
| f8be97c12c | |||
| 4123e7aa57 | |||
| 637cc574ab | |||
| 3042f187ed | |||
| 867f742d08 | |||
| 1724212458 | |||
| 05c6ca06f8 | |||
| 8c03f0e2eb | |||
| 20c3532e01 | |||
| 6cba7f164e | |||
| c3f8fcd7b7 | |||
| caacafa090 | |||
| 0a614e4bab | |||
| c12a04c224 | |||
| 5c3b06f015 | |||
| 9520c6eeba | |||
| 70aa674226 | |||
| 422aa86874 | |||
| b44af136e7 | |||
| e54c6a04de | |||
| e1d56178c8 | |||
| 1d1d774d9f | |||
| 8dead11a25 | |||
| 53c3a130ab | |||
| 834568d7f4 | |||
| d2c6c4b369 | |||
| 636654cb71 | |||
| 55106d6d57 | |||
| a1e6a6e779 | |||
| e58cbcdb17 | |||
| 9e42dab184 | |||
| 25dc87a633 | |||
| f68663af7e | |||
| 07f8dd1cb1 | |||
| 18c15ed8d1 | |||
| 959e6a8470 | |||
| 76c2fc1776 | |||
| 6340d6652a | |||
| 87b2e29d60 | |||
| 24d390e1aa | |||
| 210f9afd66 | |||
| eb818da93f | |||
| 1c20ff3fb9 | |||
| fb87418473 | |||
| 870a20e834 | |||
| 5b7356d905 | |||
| 918c486c65 | |||
| 26e7cd2afb | |||
| 2eda63e9ae | |||
| b2902a0789 | |||
| edc3e2be84 | |||
| c6721a799d | |||
| fdfbcdf51e | |||
| aed8e68fca | |||
| 50249206df | |||
| 5480be4c25 | |||
| 436b5ff7a8 | |||
| 3536bb247e | |||
| a80a053b0a | |||
| 2642ecc737 | |||
| abfcf72a56 | |||
| 0e044804d2 | |||
| 5b9afd5329 | |||
| a983a89964 | |||
| 741a50ab97 | |||
| cf6c298b82 | |||
| 90c0fe948b | |||
| 2c84122654 | |||
| 143db5fc9d | |||
| c28ad86214 | |||
| 15f153474a | |||
| 55d66a9ea3 | |||
| 14c86daf23 | |||
| 460aaf8bb6 | |||
| 1e703a0be5 | |||
| 142e3c0177 | |||
| d4b7a2b3e9 | |||
| dac6d03666 | |||
| 3bfd58dfd9 | |||
| 2d6459b290 | |||
| 1f0f6a8d3d | |||
| 2ecb8d5413 | |||
| f1d03393de |
@@ -13,7 +13,7 @@ Setting things up
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git clone https://github.com/<your username>/python-telegram-bot --recursive
|
||||
$ git clone https://github.com/<your username>/python-telegram-bot
|
||||
$ cd python-telegram-bot
|
||||
|
||||
3. Add a track to the original repository:
|
||||
@@ -26,7 +26,7 @@ Setting things up
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install -r requirements.txt -r requirements-dev.txt
|
||||
$ pip install -r requirements-all.txt
|
||||
|
||||
|
||||
5. Install pre-commit hooks:
|
||||
@@ -82,7 +82,7 @@ Here's how to make a one-off code change.
|
||||
|
||||
- Documenting types of global variables and complex types of class members can be done using the Sphinx docstring convention.
|
||||
|
||||
- In addition, PTB uses the `Black`_ coder formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything.
|
||||
- In addition, PTB uses some formatting/styling and linting tools in the pre-commit setup. Some of those tools also have command line tools that can help to run these tools outside of the pre-commit step. If you'd like to leverage that, please have a look at the `pre-commit config file`_ for an overview of which tools (and which versions of them) are used. For example, we use `Black`_ for code formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything.
|
||||
|
||||
- Please ensure that the code you write is well-tested.
|
||||
|
||||
@@ -98,6 +98,13 @@ Here's how to make a one-off code change.
|
||||
|
||||
$ pytest -v
|
||||
|
||||
Since the tests can take a while to run, you can speed things up by running them in parallel
|
||||
using `pytest-xdist`_ (note that this may effect the result of the test in some rare cases):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pytest -v -n auto --dist=loadfile
|
||||
|
||||
To run ``test_official`` (particularly useful if you made API changes), run
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -178,7 +185,7 @@ doc strings don't have a separate documentation site they generate, instead, the
|
||||
|
||||
User facing documentation
|
||||
-------------------------
|
||||
We use `sphinx`_ to generate static HTML docs. To build them, first make sure you have the required dependencies:
|
||||
We use `sphinx`_ to generate static HTML docs. To build them, first make sure you're running Python 3.9 or above and have the required dependencies:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -273,9 +280,11 @@ break the API classes. For example:
|
||||
.. _AUTHORS.rst: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/AUTHORS.rst
|
||||
.. _`MyPy`: https://mypy.readthedocs.io/en/stable/index.html
|
||||
.. _`here`: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
|
||||
.. _`pre-commit config file`: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.pre-commit-config.yaml
|
||||
.. _`Black`: https://black.readthedocs.io/en/stable/index.html
|
||||
.. _`popular editors`: https://black.readthedocs.io/en/stable/integrations/editors.html
|
||||
.. _`RTD`: https://docs.python-telegram-bot.org/
|
||||
.. _`RTD build`: https://docs.python-telegram-bot.org/en/doc-fixes
|
||||
.. _`CSI`: https://standards.mousepawmedia.com/en/stable/csi.html
|
||||
.. _`section`: #documenting
|
||||
.. _`pytest-xdist`: https://github.com/pytest-dev/pytest-xdist
|
||||
|
||||
@@ -15,14 +15,14 @@ Hey! You're PRing? Cool! Please have a look at the below checklist. It's here to
|
||||
|
||||
* New classes:
|
||||
- [ ] Added `self._id_attrs` and corresponding documentation
|
||||
- [ ] `__init__` accepts `**_kwargs`
|
||||
|
||||
- [ ] `__init__` accepts `api_kwargs` as kw-only
|
||||
|
||||
* Added new shortcuts:
|
||||
- [ ] In `Chat` & `User` for all methods that accept `chat/user_id`
|
||||
- [ ] In `Message` for all methods that accept `chat_id` and `message_id`
|
||||
- [ ] For new `Message` shortcuts: Added `quote` argument if methods accepts `reply_to_message_id`
|
||||
- [ ] In `CallbackQuery` for all methods that accept either `chat_id` and `message_id` or `inline_message_id`
|
||||
|
||||
|
||||
* If relevant:
|
||||
|
||||
- [ ] Added new constants at `telegram.constants` and shortcuts to them as class variables
|
||||
@@ -32,6 +32,7 @@ Hey! You're PRing? Cool! Please have a look at the below checklist. It's here to
|
||||
- [ ] Add the handlers to the warning loop in the `ConversationHandler`
|
||||
- [ ] Added new filters for new message (sub)types
|
||||
- [ ] Added or updated documentation for the changed class(es) and/or method(s)
|
||||
- [ ] Added the new method(s) to `_extbot.py`
|
||||
- [ ] Added or updated `bot_methods.rst`
|
||||
- [ ] Updated the Bot API version number in all places: `README.rst` and `README_RAW.rst` (including the badge), as well as `telegram.constants.BOT_API_VERSION`
|
||||
- [ ] Updated the Bot API version number in all places: `README.rst` and `README_RAW.rst` (including the badge), as well as `telegram.constants.BOT_API_VERSION_INFO`
|
||||
- [ ] Added logic for arbitrary callback data in `tg.ext.Bot` for new methods that either accept a `reply_markup` in some form or have a return type that is/contains `telegram.Message`
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 3
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 2
|
||||
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
||||
onlyLabels: question
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: false
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed due to inactivity. Feel free to comment in order to reopen
|
||||
or ask again in our Telegram support group at https://t.me/pythontelegrambotgroup.
|
||||
@@ -10,20 +10,18 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.9]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
python -W ignore -m pip install -r docs/requirements-docs.txt
|
||||
python -W ignore -m pip install -r requirements-all.txt
|
||||
- name: Check Links
|
||||
run: sphinx-build docs/source docs/build/html -W --keep-going -j auto -b linkcheck
|
||||
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
- master
|
||||
- doc-fixes
|
||||
push:
|
||||
branches:
|
||||
branches:
|
||||
- master
|
||||
- doc-fixes
|
||||
|
||||
@@ -15,20 +15,33 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.9]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: '**/requirements*.txt'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
python -W ignore -m pip install -r docs/requirements-docs.txt
|
||||
python -W ignore -m pip install -r requirements-all.txt
|
||||
- name: Test autogeneration of admonitions
|
||||
run: pytest -v --tb=short tests/docs/admonition_inserter.py
|
||||
- name: Build docs
|
||||
run: sphinx-build docs/source docs/build/html -W --keep-going -j auto
|
||||
- name: Upload docs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: HTML Docs
|
||||
retention-days: 7
|
||||
path: |
|
||||
# Exclude the .doctrees folder and .buildinfo file from the artifact
|
||||
# since they are not needed and add to the size
|
||||
docs/build/html/*
|
||||
!docs/build/html/.doctrees
|
||||
!docs/build/html/.buildinfo
|
||||
|
||||
@@ -3,13 +3,12 @@ name: 'Lock Closed Threads'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '8 4 * * *'
|
||||
- cron: '42 17 * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v3.0.0
|
||||
- uses: dessant/lock-threads@v4.0.0
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-inactive-days: '7'
|
||||
|
||||
@@ -3,7 +3,7 @@ on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- requirements.txt
|
||||
- requirements-dev.txt
|
||||
- requirements-opts.txt
|
||||
- .pre-commit-config.yaml
|
||||
permissions:
|
||||
pull-requests: write
|
||||
@@ -15,5 +15,5 @@ jobs:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey! Looks like you edited the (dev) requirements or the pre-commit hooks. I'm just a friendly reminder to keep the pre-commit hook versions in sync with the dev requirements and the additional dependencies for the hooks in sync with the requirements :)
|
||||
notify-message: Hey! Looks like you edited the (optional) requirements or the pre-commit hooks. I'm just a friendly reminder to keep the additional dependencies for the hooks in sync with the requirements :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
name: 'Mark & close stale questions'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '42 2 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v7
|
||||
with:
|
||||
# PRs never get stale
|
||||
days-before-stale: 3
|
||||
days-before-close: 2
|
||||
days-before-pr-stale: -1
|
||||
stale-issue-label: 'stale'
|
||||
only-labels: 'question'
|
||||
stale-issue-message: ''
|
||||
close-issue-message: 'This issue has been automatically closed due to inactivity. Feel free to comment in order to reopen or ask again in our Telegram support group at https://t.me/pythontelegrambotgroup.'
|
||||
+51
-19
File diff suppressed because one or more lines are too long
@@ -0,0 +1,68 @@
|
||||
name: Check Type Completeness
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
test-type-completeness:
|
||||
name: test-type-completeness
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: git fetch --depth=1 # https://github.com/actions/checkout/issues/329#issuecomment-674881489
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: 'pip'
|
||||
cache-dependency-path: '**/requirements*.txt'
|
||||
- name: Install Pyright
|
||||
run: |
|
||||
python -W ignore -m pip install pyright~=1.1.291
|
||||
- name: Get Base Completeness
|
||||
run: |
|
||||
git checkout ${{ github.base_ref }}
|
||||
pip install . -U
|
||||
pyright --verifytypes telegram --ignoreexternal --outputjson > base.json || true
|
||||
- name: Get PR Completeness
|
||||
run: |
|
||||
git checkout ${{ github.head_ref }}
|
||||
pip install . -U
|
||||
pyright --verifytypes telegram --ignoreexternal --outputjson > pr.json || true
|
||||
pyright --verifytypes telegram --ignoreexternal > pr.readable || true
|
||||
- name: Compare Completeness
|
||||
uses: jannekem/run-python-script-action@v1
|
||||
with:
|
||||
script: |
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
base = float(
|
||||
json.load(open("base.json", "rb"))["typeCompleteness"]["completenessScore"]
|
||||
)
|
||||
pr = float(
|
||||
json.load(open("pr.json", "rb"))["typeCompleteness"]["completenessScore"]
|
||||
)
|
||||
base_text = f"After this PR, type completeness will be {round(pr, 3)}."
|
||||
if pr < (base - 0.1):
|
||||
text = f"This PR decreases type completeness by {round(base - pr, 3)}. ❌"
|
||||
set_summary(text)
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
error(f"{text}\n{base_text}")
|
||||
exit(1)
|
||||
elif pr > (base + 0.1):
|
||||
text = f"This PR increases type completeness by {round(pr - base, 3)}. ✨"
|
||||
set_summary(text)
|
||||
if pr < 1:
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
print(f"{text}\n{base_text}")
|
||||
else:
|
||||
text = f"This PR does not change type completeness by more than 0.1. ✅"
|
||||
set_summary(text)
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
print(f"{text}\n{base_text}")
|
||||
+34
-23
@@ -1,6 +1,4 @@
|
||||
# Make sure that
|
||||
# * the revs specified here match requirements-dev.txt
|
||||
# * the additional_dependencies here match requirements.txt
|
||||
# Make sure that the additional_dependencies here match requirements.txt
|
||||
|
||||
ci:
|
||||
autofix_prs: false
|
||||
@@ -11,18 +9,18 @@ ci:
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.3.0
|
||||
rev: 23.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
args:
|
||||
- --diff
|
||||
- --check
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 4.0.1
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v2.13.9
|
||||
rev: v2.16.1
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
@@ -33,26 +31,27 @@ repos:
|
||||
- --jobs=0
|
||||
|
||||
additional_dependencies:
|
||||
- httpx~=0.23.0
|
||||
- tornado~=6.1
|
||||
- APScheduler~=3.9.1
|
||||
- cachetools~=5.2.0
|
||||
- httpx~=0.23.3
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.0
|
||||
- cachetools~=5.3.0
|
||||
- aiolimiter~=1.0.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.961
|
||||
rev: v0.991
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy-ptb
|
||||
files: ^telegram/.*\.py$
|
||||
additional_dependencies:
|
||||
- types-ujson
|
||||
- types-pytz
|
||||
- types-cryptography
|
||||
- types-cachetools
|
||||
- httpx~=0.23.0
|
||||
- tornado~=6.1
|
||||
- APScheduler~=3.9.1
|
||||
- cachetools~=5.2.0
|
||||
- httpx~=0.23.3
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.0
|
||||
- cachetools~=5.3.0
|
||||
- aiolimiter~=1.0.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- id: mypy
|
||||
name: mypy-examples
|
||||
@@ -61,22 +60,34 @@ repos:
|
||||
- --no-strict-optional
|
||||
- --follow-imports=silent
|
||||
additional_dependencies:
|
||||
- tornado~=6.1
|
||||
- APScheduler~=3.9.1
|
||||
- cachetools~=5.2.0
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.0
|
||||
- cachetools~=5.3.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.34.0
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
files: ^(telegram|examples|tests)/.*\.py$
|
||||
files: ^(telegram|examples|tests|docs)/.*\.py$
|
||||
args:
|
||||
- --py37-plus
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.10.1
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort
|
||||
args:
|
||||
- --diff
|
||||
- --check
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: 'v0.0.243'
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: ruff
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
additional_dependencies:
|
||||
- httpx~=0.23.3
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.0
|
||||
- cachetools~=5.3.0
|
||||
- aiolimiter~=1.0.0
|
||||
|
||||
+26
-1
@@ -21,6 +21,31 @@ python:
|
||||
- requirements: docs/requirements-docs.txt
|
||||
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3" # latest stable cpython version
|
||||
|
||||
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
|
||||
|
||||
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'
|
||||
|
||||
@@ -9,6 +9,8 @@ The current development team includes
|
||||
- `Poolitzer <https://github.com/Poolitzer>`_ (community liaison)
|
||||
- `Shivam <https://github.com/Starry69>`_
|
||||
- `Harshil <https://github.com/harshil21>`_
|
||||
- `Dmitry Kolomatskiy <https://github.com/lemontree210>`_
|
||||
- `Aditya <https://github.com/clot27>`_
|
||||
|
||||
Emeritus maintainers include
|
||||
`Jannes Höke <https://github.com/jh0ker>`_ (`@jh0ker <https://t.me/jh0ker>`_ on Telegram),
|
||||
@@ -28,6 +30,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Avanatiker <https://github.com/Avanatiker>`_
|
||||
- `Balduro <https://github.com/Balduro>`_
|
||||
- `Bibo-Joshi <https://github.com/Bibo-Joshi>`_
|
||||
- `Biruk Alamirew <https://github.com/BAcode-X>`_
|
||||
- `bimmlerd <https://github.com/bimmlerd>`_
|
||||
- `cyc8 <https://github.com/cyc8>`_
|
||||
- `d-qoi <https://github.com/d-qoi>`_
|
||||
@@ -71,7 +74,9 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `LRezende <https://github.com/lrezende>`_
|
||||
- `macrojames <https://github.com/macrojames>`_
|
||||
- `Matheus Lemos <https://github.com/mlemosf>`_
|
||||
- `Michael Dix <https://github.com/Eisberge>`_
|
||||
- `Michael Elovskikh <https://github.com/wronglink>`_
|
||||
- `miles <https://github.com/miles170>`_
|
||||
- `Mischa Krüger <https://github.com/Makman2>`_
|
||||
- `naveenvhegde <https://github.com/naveenvhegde>`_
|
||||
- `neurrone <https://github.com/neurrone>`_
|
||||
@@ -86,6 +91,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Paradox <https://github.com/paradox70>`_
|
||||
- `Patrick Hofmann <https://github.com/PH89>`_
|
||||
- `Paul Larsen <https://github.com/PaulSonOfLars>`_
|
||||
- `Pawan <https://github.com/pawanrai9999>`_
|
||||
- `Pieter Schutz <https://github.com/eldinnie>`_
|
||||
- `Piraty <https://github.com/piraty>`_
|
||||
- `Poolitzer <https://github.com/Poolitzer>`_
|
||||
@@ -96,6 +102,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Sahil Sharma <https://github.com/sahilsharma811>`_
|
||||
- `Sascha <https://github.com/saschalalala>`_
|
||||
- `Shelomentsev D <https://github.com/shelomentsevd>`_
|
||||
- `Shivam Saini <https://github.com/shivamsn97>`_
|
||||
- `Simon Schürrle <https://github.com/SitiSchu>`_
|
||||
- `sooyhwang <https://github.com/sooyhwang>`_
|
||||
- `syntx <https://github.com/syntx>`_
|
||||
|
||||
+444
@@ -2,6 +2,450 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 20.1
|
||||
============
|
||||
*Released 2023-02-09*
|
||||
|
||||
This is the technical changelog for version 20.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 6.5 (`#3530`_)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add ``Application(Builder).post_stop`` (`#3466`_)
|
||||
- Add ``Chat.effective_name`` Convenience Property (`#3485`_)
|
||||
- Allow to Adjust HTTP Version and Use HTTP/2 by Default (`#3506`_)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Enhance ``chatmemberbot`` Example (`#3500`_)
|
||||
- Automatically Generate Cross-Reference Links (`#3501`_, `#3529`_, `#3523`_)
|
||||
- Add Some Graphic Elements to Docs (`#3535`_)
|
||||
- Various Smaller Improvements (`#3464`_, `#3483`_, `#3484`_, `#3497`_, `#3512`_, `#3515`_, `#3498`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI
|
||||
------------------------------------------------
|
||||
|
||||
- Update Copyright to 2023 (`#3459`_)
|
||||
- Stabilize Tests on Closing and Hiding the General Forum Topic (`#3460`_)
|
||||
- Fix Dependency Warning Typo (`#3474`_)
|
||||
- Cache Dependencies on ``GitHub`` Actions (`#3469`_)
|
||||
- Store Documentation Builts as ``GitHub`` Actions Artifacts (`#3468`_)
|
||||
- Add ``ruff`` to ``pre-commit`` Hooks (`#3488`_)
|
||||
- Improve Warning for ``days`` Parameter of ``JobQueue.run_daily`` (`#3503`_)
|
||||
- Improve Error Message for ``NetworkError`` (`#3505`_)
|
||||
- Lock Inactive Threads Only Once Each Day (`#3510`_)
|
||||
- Bump ``pytest`` from 7.2.0 to 7.2.1 (`#3513`_)
|
||||
- Check for 3D Arrays in ``check_keyboard_type`` (`#3514`_)
|
||||
- Explicit Type Annotations (`#3508`_)
|
||||
- Increase Verbosity of Type Completeness CI Job (`#3531`_)
|
||||
- Fix CI on Python 3.11 + Windows (`#3547`_)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- Bump ``actions/stale`` from 6 to 7 (`#3461`_)
|
||||
- Bump ``dessant/lock-threads`` from 3.0.0 to 4.0.0 (`#3462`_)
|
||||
- ``pre-commit`` autoupdate (`#3470`_)
|
||||
- Update ``httpx`` requirement from ~=0.23.1 to ~=0.23.3 (`#3489`_)
|
||||
- Update ``cachetools`` requirement from ~=5.2.0 to ~=5.2.1 (`#3502`_)
|
||||
- Improve Config for ``ruff`` and Bump to ``v0.0.222`` (`#3507`_)
|
||||
- Update ``cachetools`` requirement from ~=5.2.1 to ~=5.3.0 (`#3520`_)
|
||||
- Bump ``isort`` to 5.12.0 (`#3525`_)
|
||||
- Update ``apscheduler`` requirement from ~=3.9.1 to ~=3.10.0 (`#3532`_)
|
||||
- ``pre-commit`` autoupdate (`#3537`_)
|
||||
- Update ``cryptography`` requirement to >=39.0.1 to address Vulnerability (`#3539`_)
|
||||
|
||||
|
||||
|
||||
.. _`#3530`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3530
|
||||
.. _`#3466`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3466
|
||||
.. _`#3485`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3485
|
||||
.. _`#3506`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3506
|
||||
.. _`#3500`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3500
|
||||
.. _`#3501`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3501
|
||||
.. _`#3529`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3529
|
||||
.. _`#3523`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3523
|
||||
.. _`#3535`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3535
|
||||
.. _`#3464`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3464
|
||||
.. _`#3483`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3483
|
||||
.. _`#3484`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3484
|
||||
.. _`#3497`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3497
|
||||
.. _`#3512`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3512
|
||||
.. _`#3515`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3515
|
||||
.. _`#3498`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3498
|
||||
.. _`#3459`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3459
|
||||
.. _`#3460`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3460
|
||||
.. _`#3474`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3474
|
||||
.. _`#3469`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3469
|
||||
.. _`#3468`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3468
|
||||
.. _`#3488`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3488
|
||||
.. _`#3503`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3503
|
||||
.. _`#3505`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3505
|
||||
.. _`#3510`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3510
|
||||
.. _`#3513`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3513
|
||||
.. _`#3514`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3514
|
||||
.. _`#3508`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3508
|
||||
.. _`#3531`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3531
|
||||
.. _`#3547`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3547
|
||||
.. _`#3461`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3461
|
||||
.. _`#3462`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3462
|
||||
.. _`#3470`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3470
|
||||
.. _`#3489`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3489
|
||||
.. _`#3502`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3502
|
||||
.. _`#3507`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3507
|
||||
.. _`#3520`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3520
|
||||
.. _`#3525`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3525
|
||||
.. _`#3532`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3532
|
||||
.. _`#3537`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3537
|
||||
.. _`#3539`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3539
|
||||
|
||||
Version 20.0
|
||||
============
|
||||
*Released 2023-01-01*
|
||||
|
||||
This is the technical changelog for version 20.0. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support For Bot API 6.4 (`#3449`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI
|
||||
------------------------------------------------
|
||||
|
||||
- Documentation Improvements (`#3428`_, `#3423`_, `#3429`_, `#3441`_, `#3404`_, `#3443`_)
|
||||
- Allow ``Sequence`` Input for Bot Methods (`#3412`_)
|
||||
- Update Link-Check CI and Replace a Dead Link (`#3456`_)
|
||||
- Freeze Classes Without Arguments (`#3453`_)
|
||||
- Add New Constants (`#3444`_)
|
||||
- Override ``Bot.__deepcopy__`` to Raise ``TypeError`` (`#3446`_)
|
||||
- Add Log Decorator to ``Bot.get_webhook_info`` (`#3442`_)
|
||||
- Add Documentation On Verifying Releases (`#3436`_)
|
||||
- Drop Undocumented ``Job.__lt__`` (`#3432`_)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- Downgrade ``sphinx`` to 5.3.0 to Fix Search (`#3457`_)
|
||||
- Bump ``sphinx`` from 5.3.0 to 6.0.0 (`#3450`_)
|
||||
|
||||
.. _`#3449`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3449
|
||||
.. _`#3428`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3428
|
||||
.. _`#3423`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3423
|
||||
.. _`#3429`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3429
|
||||
.. _`#3441`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3441
|
||||
.. _`#3404`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3404
|
||||
.. _`#3443`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3443
|
||||
.. _`#3412`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3412
|
||||
.. _`#3456`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3456
|
||||
.. _`#3453`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3453
|
||||
.. _`#3444`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3444
|
||||
.. _`#3446`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3446
|
||||
.. _`#3442`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3442
|
||||
.. _`#3436`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3436
|
||||
.. _`#3432`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3432
|
||||
.. _`#3457`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3457
|
||||
.. _`#3450`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3450
|
||||
|
||||
Version 20.0b0
|
||||
==============
|
||||
*Released 2022-12-15*
|
||||
|
||||
This is the technical changelog for version 20.0b0. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Make ``TelegramObject`` Immutable (`#3249`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI
|
||||
------------------------------------------------
|
||||
|
||||
- Reduce Code Duplication in Testing ``Defaults`` (`#3419`_)
|
||||
- Add Notes and Warnings About Optional Dependencies (`#3393`_)
|
||||
- Simplify Internals of ``Bot`` Methods (`#3396`_)
|
||||
- Reduce Code Duplication in Several ``Bot`` Methods (`#3385`_)
|
||||
- Documentation Improvements (`#3386`_, `#3395`_, `#3398`_, `#3403`_)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- Bump ``pytest-xdist`` from 3.0.2 to 3.1.0 (`#3415`_)
|
||||
- Bump ``pytest-asyncio`` from 0.20.2 to 0.20.3 (`#3417`_)
|
||||
- ``pre-commit`` autoupdate (`#3409`_)
|
||||
|
||||
.. _`#3249`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3249
|
||||
.. _`#3419`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3419
|
||||
.. _`#3393`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3393
|
||||
.. _`#3396`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3396
|
||||
.. _`#3385`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3385
|
||||
.. _`#3386`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3386
|
||||
.. _`#3395`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3395
|
||||
.. _`#3398`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3398
|
||||
.. _`#3403`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3403
|
||||
.. _`#3415`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3415
|
||||
.. _`#3417`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3417
|
||||
.. _`#3409`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3409
|
||||
|
||||
Version 20.0a6
|
||||
==============
|
||||
*Released 2022-11-24*
|
||||
|
||||
This is the technical changelog for version 20.0a6. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Only Persist Arbitrary ``callback_data`` if ``ExtBot.callback_data_cache`` is Present (`#3384`_)
|
||||
- Improve Backwards Compatibility of ``TelegramObjects`` Pickle Behavior (`#3382`_)
|
||||
- Fix Naming and Keyword Arguments of ``File.download_*`` Methods (`#3380`_)
|
||||
- Fix Return Value Annotation of ``Chat.create_forum_topic`` (`#3381`_)
|
||||
|
||||
.. _`#3384`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3384
|
||||
.. _`#3382`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3382
|
||||
.. _`#3380`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3380
|
||||
.. _`#3381`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3381
|
||||
|
||||
Version 20.0a5
|
||||
==============
|
||||
*Released 2022-11-22*
|
||||
|
||||
This is the technical changelog for version 20.0a5. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- API 6.3 (`#3346`_, `#3343`_, `#3342`_, `#3360`_)
|
||||
- Explicit ``local_mode`` Setting (`#3154`_)
|
||||
- Make Almost All 3rd Party Dependencies Optional (`#3267`_)
|
||||
- Split ``File.download`` Into ``File.download_to_drive`` And ``File.download_to_memory`` (`#3223`_)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add Properties for API Settings of ``Bot`` (`#3247`_)
|
||||
- Add ``chat_id`` and ``username`` Parameters to ``ChatJoinRequestHandler`` (`#3261`_)
|
||||
- Introduce ``TelegramObject.api_kwargs`` (`#3233`_)
|
||||
- Add Two Constants Related to Local Bot API Servers (`#3296`_)
|
||||
- Add ``recursive`` Parameter to ``TelegramObject.to_dict()`` (`#3276`_)
|
||||
- Overhaul String Representation of ``TelegramObject`` (`#3234`_)
|
||||
- Add Methods ``Chat.mention_{html, markdown, markdown_v2}`` (`#3308`_)
|
||||
- Add ``constants.MessageLimit.DEEP_LINK_LENGTH`` (`#3315`_)
|
||||
- Add Shortcut Parameters ``caption``, ``parse_mode`` and ``caption_entities`` to ``Bot.send_media_group`` (`#3295`_)
|
||||
- Add Several New Enums To Constants (`#3351`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix ``CallbackQueryHandler`` Not Handling Non-String Data Correctly With Regex Patterns (`#3252`_)
|
||||
- Fix Defaults Handling in ``Bot.answer_web_app_query`` (`#3362`_)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Update PR Template (`#3361`_)
|
||||
- Document Dunder Methods of ``TelegramObject`` (`#3319`_)
|
||||
- Add Several References to Wiki pages (`#3306`_)
|
||||
- Overhaul Search bar (`#3218`_)
|
||||
- Unify Documentation of Arguments and Attributes of Telegram Classes (`#3217`_, `#3292`_, `#3303`_, `#3312`_, `#3314`_)
|
||||
- Several Smaller Improvements (`#3214`_, `#3271`_, `#3289`_, `#3326`_, `#3370`_, `#3376`_, `#3366`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI
|
||||
------------------------------------------------
|
||||
|
||||
- Improve Warning About Unknown ``ConversationHandler`` States (`#3242`_)
|
||||
- Switch from Stale Bot to ``GitHub`` Actions (`#3243`_)
|
||||
- Bump Python 3.11 to RC2 in Test Matrix (`#3246`_)
|
||||
- Make ``Job.job`` a Property and Make ``Jobs`` Hashable (`#3250`_)
|
||||
- Skip ``JobQueue`` Tests on Windows Again (`#3280`_)
|
||||
- Read-Only ``CallbackDataCache`` (`#3266`_)
|
||||
- Type Hinting Fix for ``Message.effective_attachment`` (`#3294`_)
|
||||
- Run Unit Tests in Parallel (`#3283`_)
|
||||
- Update Test Matrix to Use Stable Python 3.11 (`#3313`_)
|
||||
- Don't Edit Objects In-Place When Inserting ``ext.Defaults`` (`#3311`_)
|
||||
- Add a Test for ``MessageAttachmentType`` (`#3335`_)
|
||||
- Add Three New Test Bots (`#3347`_)
|
||||
- Improve Unit Tests Regarding ``ChatMemberUpdated.difference`` (`#3352`_)
|
||||
- Flaky Unit Tests: Use ``pytest`` Marker (`#3354`_)
|
||||
- Fix ``DeepSource`` Issues (`#3357`_)
|
||||
- Handle Lists and Tuples and Datetimes Directly in ``TelegramObject.to_dict`` (`#3353`_)
|
||||
- Update Meta Config (`#3365`_)
|
||||
- Merge ``ChatDescriptionLimit`` Enum Into ``ChatLimit`` (`#3377`_)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- Bump ``pytest`` from 7.1.2 to 7.1.3 (`#3228`_)
|
||||
- ``pre-commit`` Updates (`#3221`_)
|
||||
- Bump ``sphinx`` from 5.1.1 to 5.2.3 (`#3269`_)
|
||||
- Bump ``furo`` from 2022.6.21 to 2022.9.29 (`#3268`_)
|
||||
- Bump ``actions/stale`` from 5 to 6 (`#3277`_)
|
||||
- ``pre-commit`` autoupdate (`#3282`_)
|
||||
- Bump ``sphinx`` from 5.2.3 to 5.3.0 (`#3300`_)
|
||||
- Bump ``pytest-asyncio`` from 0.19.0 to 0.20.1 (`#3299`_)
|
||||
- Bump ``pytest`` from 7.1.3 to 7.2.0 (`#3318`_)
|
||||
- Bump ``pytest-xdist`` from 2.5.0 to 3.0.2 (`#3317`_)
|
||||
- ``pre-commit`` autoupdate (`#3325`_)
|
||||
- Bump ``pytest-asyncio`` from 0.20.1 to 0.20.2 (`#3359`_)
|
||||
- Update ``httpx`` requirement from ~=0.23.0 to ~=0.23.1 (`#3373`_)
|
||||
|
||||
.. _`#3346`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3346
|
||||
.. _`#3343`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3343
|
||||
.. _`#3342`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3342
|
||||
.. _`#3360`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3360
|
||||
.. _`#3154`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3154
|
||||
.. _`#3267`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3267
|
||||
.. _`#3223`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3223
|
||||
.. _`#3247`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3247
|
||||
.. _`#3261`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3261
|
||||
.. _`#3233`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3233
|
||||
.. _`#3296`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3296
|
||||
.. _`#3276`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3276
|
||||
.. _`#3234`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3234
|
||||
.. _`#3308`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3308
|
||||
.. _`#3315`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3315
|
||||
.. _`#3295`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3295
|
||||
.. _`#3351`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3351
|
||||
.. _`#3252`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3252
|
||||
.. _`#3362`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3362
|
||||
.. _`#3361`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3361
|
||||
.. _`#3319`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3319
|
||||
.. _`#3306`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3306
|
||||
.. _`#3218`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3218
|
||||
.. _`#3217`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3217
|
||||
.. _`#3292`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3292
|
||||
.. _`#3303`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3303
|
||||
.. _`#3312`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3312
|
||||
.. _`#3314`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3314
|
||||
.. _`#3214`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3214
|
||||
.. _`#3271`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3271
|
||||
.. _`#3289`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3289
|
||||
.. _`#3326`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3326
|
||||
.. _`#3370`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3370
|
||||
.. _`#3376`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3376
|
||||
.. _`#3366`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3366
|
||||
.. _`#3242`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3242
|
||||
.. _`#3243`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3243
|
||||
.. _`#3246`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3246
|
||||
.. _`#3250`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3250
|
||||
.. _`#3280`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3280
|
||||
.. _`#3266`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3266
|
||||
.. _`#3294`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3294
|
||||
.. _`#3283`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3283
|
||||
.. _`#3313`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3313
|
||||
.. _`#3311`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3311
|
||||
.. _`#3335`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3335
|
||||
.. _`#3347`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3347
|
||||
.. _`#3352`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3352
|
||||
.. _`#3354`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3354
|
||||
.. _`#3357`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3357
|
||||
.. _`#3353`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3353
|
||||
.. _`#3365`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3365
|
||||
.. _`#3377`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3377
|
||||
.. _`#3228`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3228
|
||||
.. _`#3221`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3221
|
||||
.. _`#3269`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3269
|
||||
.. _`#3268`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3268
|
||||
.. _`#3277`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3277
|
||||
.. _`#3282`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3282
|
||||
.. _`#3300`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3300
|
||||
.. _`#3299`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3299
|
||||
.. _`#3318`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3318
|
||||
.. _`#3317`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3317
|
||||
.. _`#3325`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3325
|
||||
.. _`#3359`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3359
|
||||
.. _`#3373`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3373
|
||||
|
||||
Version 20.0a4
|
||||
==============
|
||||
*Released 2022-08-27*
|
||||
|
||||
This is the technical changelog for version 20.0a4. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Hot Fixes
|
||||
---------
|
||||
|
||||
* Fix a Bug in ``setup.py`` Regarding Optional Dependencies (`#3209`_)
|
||||
|
||||
.. _`#3209`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3209
|
||||
|
||||
Version 20.0a3
|
||||
==============
|
||||
*Released 2022-08-27*
|
||||
|
||||
This is the technical changelog for version 20.0a3. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for API 6.2 (`#3195`_)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- New Rate Limiting Mechanism (`#3148`_)
|
||||
- Make ``chat/user_data`` Available in Error Handler for Errors in Jobs (`#3152`_)
|
||||
- Add ``Application.post_shutdown`` (`#3126`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix ``helpers.mention_markdown`` for Markdown V1 and Improve Related Unit Tests (`#3155`_)
|
||||
- Add ``api_kwargs`` Parameter to ``Bot.log_out`` and Improve Related Unit Tests (`#3147`_)
|
||||
- Make ``Bot.delete_my_commands`` a Coroutine Function (`#3136`_)
|
||||
- Fix ``ConversationHandler.check_update`` not respecting ``per_user`` (`#3128`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI
|
||||
------------------------------------------------
|
||||
|
||||
- Add Python 3.11 to Test Suite & Adapt Enum Behaviour (`#3168`_)
|
||||
- Drop Manual Token Validation (`#3167`_)
|
||||
- Simplify Unit Tests for ``Bot.send_chat_action`` (`#3151`_)
|
||||
- Drop ``pre-commit`` Dependencies from ``requirements-dev.txt`` (`#3120`_)
|
||||
- Change Default Values for ``concurrent_updates`` and ``connection_pool_size`` (`#3127`_)
|
||||
- Documentation Improvements (`#3139`_, `#3153`_, `#3135`_)
|
||||
- Type Hinting Fixes (`#3202`_)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- Bump ``sphinx`` from 5.0.2 to 5.1.1 (`#3177`_)
|
||||
- Update ``pre-commit`` Dependencies (`#3085`_)
|
||||
- Bump ``pytest-asyncio`` from 0.18.3 to 0.19.0 (`#3158`_)
|
||||
- Update ``tornado`` requirement from ~=6.1 to ~=6.2 (`#3149`_)
|
||||
- Bump ``black`` from 22.3.0 to 22.6.0 (`#3132`_)
|
||||
- Bump ``actions/setup-python`` from 3 to 4 (`#3131`_)
|
||||
|
||||
.. _`#3195`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3195
|
||||
.. _`#3148`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3148
|
||||
.. _`#3152`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3152
|
||||
.. _`#3126`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3126
|
||||
.. _`#3155`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3155
|
||||
.. _`#3147`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3147
|
||||
.. _`#3136`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3136
|
||||
.. _`#3128`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3128
|
||||
.. _`#3168`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3168
|
||||
.. _`#3167`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3167
|
||||
.. _`#3151`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3151
|
||||
.. _`#3120`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3120
|
||||
.. _`#3127`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3127
|
||||
.. _`#3139`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3139
|
||||
.. _`#3153`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3153
|
||||
.. _`#3135`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3135
|
||||
.. _`#3202`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3202
|
||||
.. _`#3177`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3177
|
||||
.. _`#3085`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3085
|
||||
.. _`#3158`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3158
|
||||
.. _`#3149`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3149
|
||||
.. _`#3132`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3132
|
||||
.. _`#3131`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3131
|
||||
|
||||
Version 20.0a2
|
||||
==============
|
||||
*Released 2022-06-27*
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
include LICENSE LICENSE.lesser Makefile requirements.txt README_RAW.rst telegram/py.typed
|
||||
include LICENSE LICENSE.lesser requirements.txt requirements-opts.txt README_RAW.rst telegram/py.typed
|
||||
|
||||
+35
-11
@@ -14,7 +14,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.1-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.5-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -93,7 +93,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 **6.1** are supported.
|
||||
All types and methods of the Telegram Bot API **6.5** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
@@ -114,30 +114,54 @@ You can also install ``python-telegram-bot`` from source, though this is usually
|
||||
$ cd python-telegram-bot
|
||||
$ python setup.py install
|
||||
|
||||
Verifying Releases
|
||||
------------------
|
||||
|
||||
We sign all the releases with a GPG key.
|
||||
The signatures are uploaded to both the `GitHub releases page <https://github.com/python-telegram-bot/python-telegram-bot/releases>`_ and the `PyPI project <https://pypi.org/project/python-telegram-bot/>`_ and end with a suffix ``.asc``.
|
||||
Please find the public keys `here <https://github.com/python-telegram-bot/python-telegram-bot/tree/master/public_keys>`_.
|
||||
The keys are named in the format ``<first_version>-<last_version>.gpg`` or ``<first_version>-current.gpg`` if the key is currently being used for new releases.
|
||||
|
||||
In addition, the GitHub release page also contains the sha1 hashes of the release files in the files with the suffix ``.sha1``.
|
||||
|
||||
This allows you to verify that a release file that you downloaded was indeed provided by the ``python-telegram-bot`` team.
|
||||
|
||||
Dependencies & Their Versions
|
||||
-----------------------------
|
||||
|
||||
``python-telegram-bot`` tries to use as few 3rd party dependencies as possible.
|
||||
However, for some features using a 3rd party library is more sane than implementing the functionality again.
|
||||
The dependencies are:
|
||||
As these features are *optional*, the corresponding 3rd party dependencies are not installed by default.
|
||||
Instead, they are listed as optional dependencies.
|
||||
This allows to avoid unnecessary dependency conflicts for users who don't need the optional features.
|
||||
|
||||
* `httpx ~= 0.23.0 <https://www.python-httpx.org>`_ for ``telegram.request.HTTPXRequest``, the default networking backend
|
||||
* `tornado~=6.1 <https://www.tornadoweb.org/en/stable/>`_ for ``telegram.ext.Updater.start_webhook``
|
||||
* `cachetools~=5.2.0 <https://cachetools.readthedocs.io/en/latest/>`_ for ``telegram.ext.CallbackDataCache``
|
||||
* `APScheduler~=3.9.1 <https://apscheduler.readthedocs.io/en/3.x/>`_ for ``telegram.ext.JobQueue``
|
||||
The only required dependency is `httpx[http2] ~= 0.23.3 <https://www.python-httpx.org>`_ for
|
||||
``telegram.request.HTTPXRequest``, the default networking backend. By default, HTTP/2 is used, as it
|
||||
provides greater performance and stability, specially for concurrent requests.
|
||||
|
||||
``python-telegram-bot`` is most useful when used along with additional libraries.
|
||||
To minimize dependency conflicts, we try to be liberal in terms of version requirements on the dependencies.
|
||||
To minimize dependency conflicts, we try to be liberal in terms of version requirements on the (optional) dependencies.
|
||||
On the other hand, we have to ensure stability of ``python-telegram-bot``, which is why we do apply version bounds.
|
||||
If you encounter dependency conflicts due to these bounds, feel free to reach out.
|
||||
|
||||
Optional Dependencies
|
||||
---------------------
|
||||
#####################
|
||||
|
||||
PTB can be installed with optional dependencies:
|
||||
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography>=3.0 <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[socks]`` installs ``httpx[socks]``. Use this, if you want to work behind a Socks5 server.
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography>=39.0.1 <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[socks]`` installs `httpx[socks] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to work behind a Socks5 server.
|
||||
* ``pip install python-telegram-bot[rate-limiter]`` installs `aiolimiter~=1.0.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.2 <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.0 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
|
||||
* ``pip install python-telegram-bot[job-queue]`` installs the `APScheduler~=3.10.0 <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]``.
|
||||
|
||||
Additionally, two shortcuts are provided:
|
||||
|
||||
* ``pip install python-telegram-bot[all]`` installs all optional dependencies.
|
||||
* ``pip install python-telegram-bot[ext]`` installs all optional dependencies that are related to ``telegram.ext``, i.e. ``[rate-limiter, webhooks, callback-data, job-queue]``.
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
+30
-10
@@ -14,7 +14,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.1-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.5-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
.. image:: https://app.codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
.. image:: https://codecov.io/gh/python-telegram-bot/python-telegram-bot/branch/master/graph/badge.svg
|
||||
:target: https://app.codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:alt: Code coverage
|
||||
|
||||
@@ -89,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 **6.1** are supported.
|
||||
All types and methods of the Telegram Bot API **6.5** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
@@ -115,27 +115,47 @@ 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``.
|
||||
|
||||
Verifying Releases
|
||||
------------------
|
||||
|
||||
We sign all the releases with a GPG key.
|
||||
The signatures are uploaded to both the `GitHub releases page <https://github.com/python-telegram-bot/python-telegram-bot/releases>`_ and the `PyPI project <https://pypi.org/project/python-telegram-bot/>`_ and end with a suffix ``.asc``.
|
||||
Please find the public keys `here <https://github.com/python-telegram-bot/python-telegram-bot/tree/master/public_keys>`_.
|
||||
The keys are named in the format ``<first_version>-<last_version>.gpg`` or ``<first_version>-current.gpg`` if the key is currently being used for new releases.
|
||||
|
||||
In addition, the GitHub release page also contains the sha1 hashes of the release files in the files with the suffix ``.sha1``.
|
||||
|
||||
This allows you to verify that a release file that you downloaded was indeed provided by the ``python-telegram-bot`` team.
|
||||
|
||||
Dependencies & Their Versions
|
||||
-----------------------------
|
||||
|
||||
``python-telegram-bot`` tries to use as few 3rd party dependencies as possible.
|
||||
However, for some features using a 3rd party library is more sane than implementing the functionality again.
|
||||
The dependencies are:
|
||||
As these features are *optional*, the corresponding 3rd party dependencies are not installed by default.
|
||||
Instead, they are listed as optional dependencies.
|
||||
This allows to avoid unnecessary dependency conflicts for users who don't need the optional features.
|
||||
|
||||
* `httpx ~= 0.23.0 <https://www.python-httpx.org>`_ for ``telegram.request.HTTPXRequest``, the default networking backend
|
||||
The only required dependency is `httpx[http2] ~= 0.23.3 <https://www.python-httpx.org>`_ for
|
||||
``telegram.request.HTTPXRequest``, the default networking backend. By default, HTTP/2 is used, as
|
||||
it provides greater performance and stability, specially for concurrent requests.
|
||||
|
||||
``python-telegram-bot`` is most useful when used along with additional libraries.
|
||||
To minimize dependency conflicts, we try to be liberal in terms of version requirements on the dependencies.
|
||||
To minimize dependency conflicts, we try to be liberal in terms of version requirements on the (optional) dependencies.
|
||||
On the other hand, we have to ensure stability of ``python-telegram-bot``, which is why we do apply version bounds.
|
||||
If you encounter dependency conflicts due to these bounds, feel free to reach out.
|
||||
|
||||
Optional Dependencies
|
||||
---------------------
|
||||
#####################
|
||||
|
||||
``python-telegram-bot-raw`` can be installed with optional dependencies:
|
||||
PTB can be installed with optional dependencies:
|
||||
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[socks]`` installs the `PySocks <https://pypi.org/project/PySocks/>`_ library. Use this, if you want to work behind a Socks5 server.
|
||||
* ``pip install python-telegram-bot-raw[passport]`` installs the `cryptography>=39.0.1 <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot-raw[socks]`` installs `httpx[socks] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to work behind a Socks5 server.
|
||||
|
||||
To install multiple optional dependencies, separate them by commas, e.g. ``pip install python-telegram-bot-raw[passport,socks]``.
|
||||
|
||||
Additionally, the shortcut ``pip install python-telegram-bot-raw[all]`` installs all optional dependencies.
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
@@ -56,6 +56,8 @@ html:
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
rebuild: clean html
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
|
||||
@@ -0,0 +1,591 @@
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 collections.abc
|
||||
import inspect
|
||||
import re
|
||||
import typing
|
||||
from collections import defaultdict
|
||||
from typing import Any, Iterator, Union
|
||||
|
||||
import telegram
|
||||
import telegram.ext
|
||||
|
||||
|
||||
def _iter_own_public_methods(cls: type) -> Iterator[tuple[str, type]]:
|
||||
"""Iterates over methods of a class that are not protected/private,
|
||||
not camelCase and not inherited from the parent class.
|
||||
|
||||
Returns pairs of method names and methods.
|
||||
|
||||
This function is defined outside the class because it is used to create class constants.
|
||||
"""
|
||||
return (
|
||||
m
|
||||
for m in inspect.getmembers(cls, predicate=inspect.isfunction) # not .ismethod
|
||||
if not m[0].startswith("_")
|
||||
and m[0].islower() # to avoid camelCase methods
|
||||
and m[0] in cls.__dict__ # method is not inherited from parent class
|
||||
)
|
||||
|
||||
|
||||
class AdmonitionInserter:
|
||||
"""Class for inserting admonitions into docs of Telegram classes."""
|
||||
|
||||
CLASS_ADMONITION_TYPES = ("use_in", "available_in", "returned_in")
|
||||
METHOD_ADMONITION_TYPES = ("shortcuts",)
|
||||
ALL_ADMONITION_TYPES = CLASS_ADMONITION_TYPES + METHOD_ADMONITION_TYPES
|
||||
|
||||
FORWARD_REF_PATTERN = re.compile(r"^ForwardRef\('(?P<class_name>\w+)'\)$")
|
||||
""" A pattern to find a class name in a ForwardRef typing annotation.
|
||||
Class name (in a named group) is surrounded by parentheses and single quotes.
|
||||
Note that since we're analyzing argument by argument, the pattern can be strict, with
|
||||
start and end markers.
|
||||
"""
|
||||
|
||||
FORWARD_REF_SKIP_PATTERN = re.compile(r"^ForwardRef\('DefaultValue\[\w+]'\)$")
|
||||
"""A pattern that will be used to skip known ForwardRef's that need not be resolved
|
||||
to a Telegram class, e.g.:
|
||||
ForwardRef('DefaultValue[None]')
|
||||
ForwardRef('DefaultValue[DVValueType]')
|
||||
"""
|
||||
|
||||
METHOD_NAMES_FOR_BOT_AND_APPBUILDER: 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)
|
||||
}
|
||||
"""A dictionary mapping Bot and ApplicationBuilder classes to their relevant methods that will
|
||||
be mentioned in 'Returned in' and 'Use in' admonitions in other classes' docstrings.
|
||||
Methods must be public, not aliases, not inherited from TelegramObject.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.admonitions: dict[str, dict[Union[type, collections.abc.Callable], str]] = {
|
||||
# dynamically determine which method to use to create a sub-dictionary
|
||||
admonition_type: getattr(self, f"_create_{admonition_type}")()
|
||||
for admonition_type in self.ALL_ADMONITION_TYPES
|
||||
}
|
||||
"""Dictionary with admonitions. Contains sub-dictionaries, one per admonition type.
|
||||
Each sub-dictionary matches bot methods (for "Shortcuts") or telegram classes (for other
|
||||
admonition types) to texts of admonitions, e.g.:
|
||||
```
|
||||
{
|
||||
"use_in": {<class 'telegram._chatinvitelink.ChatInviteLink'>:
|
||||
<"Use in" admonition for ChatInviteLink>, ...},
|
||||
"available_in": {<class 'telegram._chatinvitelink.ChatInviteLink'>:
|
||||
<"Available in" admonition">, ...},
|
||||
"returned_in": {...}
|
||||
}
|
||||
```
|
||||
"""
|
||||
|
||||
def insert_admonitions(
|
||||
self,
|
||||
obj: Union[type, collections.abc.Callable],
|
||||
docstring_lines: list[str],
|
||||
):
|
||||
"""Inserts admonitions into docstring lines for a given class or method.
|
||||
|
||||
**Modifies lines in place**.
|
||||
"""
|
||||
# A better way would be to copy the lines and return them, but that will not work with
|
||||
# docs.auxil.sphinx_hooks.autodoc_process_docstring()
|
||||
|
||||
for admonition_type in self.ALL_ADMONITION_TYPES:
|
||||
# If there is no admonition of the given type for the given class or method,
|
||||
# continue to the next admonition type, maybe the class/method is listed there.
|
||||
if obj not in self.admonitions[admonition_type]:
|
||||
continue
|
||||
|
||||
insert_idx = self._find_insert_pos_for_admonition(docstring_lines)
|
||||
admonition_lines = self.admonitions[admonition_type][obj].splitlines()
|
||||
|
||||
for idx in range(insert_idx, insert_idx + len(admonition_lines)):
|
||||
docstring_lines.insert(idx, admonition_lines[idx - insert_idx])
|
||||
|
||||
def _create_available_in(self) -> dict[type, str]:
|
||||
"""Creates a dictionary with 'Available in' admonitions for classes that are available
|
||||
in attributes of other classes.
|
||||
"""
|
||||
|
||||
# Generate a mapping of classes to ReST links to attributes in other classes that
|
||||
# correspond to instances of a given class
|
||||
# i.e. {telegram._files.sticker.Sticker: {":attr:`telegram.Message.sticker`", ...}}
|
||||
attrs_for_class = defaultdict(set)
|
||||
|
||||
# The following regex is supposed to capture a class name in a line like this:
|
||||
# media (:obj:`str` | :class:`telegram.InputFile`): Audio file to send.
|
||||
#
|
||||
# Note that even if such typing description spans over multiple lines but each line ends
|
||||
# with a backslash (otherwise Sphinx will throw an error)
|
||||
# (e.g. EncryptedPassportElement.data), then Sphinx will combine these lines into a single
|
||||
# line automatically, and it will contain no backslash (only some extra many whitespaces
|
||||
# from the indentation).
|
||||
|
||||
attr_docstr_pattern = re.compile(
|
||||
r"^\s*(?P<attr_name>[a-z_]+)" # Any number of spaces, named group for attribute
|
||||
r"\s?\(" # Optional whitespace, opening parenthesis
|
||||
r".*" # Any number of characters (that could denote a built-in type)
|
||||
r":class:`.+`" # Marker of a classref, class name in backticks
|
||||
r".*\):" # Any number of characters, closing parenthesis, colon.
|
||||
# The ^ colon above along with parenthesis is important because it makes sure that
|
||||
# the class is mentioned in the attribute description, not in free text.
|
||||
r".*$", # Any number of characters, end of string (end of line)
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
# for properties: there is no attr name in docstring. Just check if there's a class name.
|
||||
prop_docstring_pattern = re.compile(r":class:`.+`.*:")
|
||||
|
||||
# pattern for iterating over potentially many class names in docstring for one attribute.
|
||||
# Tilde is optional (sometimes it is in the docstring, sometimes not).
|
||||
single_class_name_pattern = re.compile(r":class:`~?(?P<class_name>[\w.]*)`")
|
||||
|
||||
classes_to_inspect = inspect.getmembers(telegram, inspect.isclass) + inspect.getmembers(
|
||||
telegram.ext, inspect.isclass
|
||||
)
|
||||
|
||||
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.
|
||||
name_of_inspected_class_in_docstr = self._generate_class_name_for_link(inspected_class)
|
||||
|
||||
# Parsing part of the docstring with attributes (parsing of properties follows later)
|
||||
docstring_lines = inspect.getdoc(inspected_class).splitlines()
|
||||
lines_with_attrs = []
|
||||
for idx, line in enumerate(docstring_lines):
|
||||
if line.strip() == "Attributes:":
|
||||
lines_with_attrs = docstring_lines[idx + 1 :]
|
||||
break
|
||||
|
||||
for line in lines_with_attrs:
|
||||
line_match = attr_docstr_pattern.match(line)
|
||||
if not line_match:
|
||||
continue
|
||||
|
||||
target_attr = line_match.group("attr_name")
|
||||
# a typing description of one attribute can contain multiple classes
|
||||
for match in single_class_name_pattern.finditer(line):
|
||||
name_of_class_in_attr = match.group("class_name")
|
||||
|
||||
# Writing to dictionary: matching the class found in the docstring
|
||||
# and its subclasses to the attribute of the class being inspected.
|
||||
# The class in the attribute docstring (or its subclass) is the key,
|
||||
# ReST link to attribute of the class currently being inspected is the value.
|
||||
try:
|
||||
self._resolve_arg_and_add_link(
|
||||
arg=name_of_class_in_attr,
|
||||
dict_of_methods_for_class=attrs_for_class,
|
||||
link=f":attr:`{name_of_inspected_class_in_docstr}.{target_attr}`",
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"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)}"
|
||||
)
|
||||
|
||||
# Properties need to be parsed separately because they act like attributes but not
|
||||
# listed as attributes.
|
||||
properties = inspect.getmembers(inspected_class, lambda o: isinstance(o, property))
|
||||
for prop_name, _ in properties:
|
||||
# Make sure this property is really defined in the class being inspected.
|
||||
# A property can be inherited from a parent class, then a link to it will not work.
|
||||
if prop_name not in inspected_class.__dict__:
|
||||
continue
|
||||
|
||||
# 1. Can't use typing.get_type_hints because double-quoted type hints
|
||||
# (like "Application") will throw a NameError
|
||||
# 2. Can't use inspect.signature because return annotations of properties can be
|
||||
# hard to parse (like "(self) -> BD").
|
||||
# 3. fget is used to access the actual function under the property wrapper
|
||||
docstring = inspect.getdoc(getattr(inspected_class, prop_name).fget)
|
||||
if docstring is None:
|
||||
continue
|
||||
|
||||
first_line = docstring.splitlines()[0]
|
||||
if not prop_docstring_pattern.match(first_line):
|
||||
continue
|
||||
|
||||
for match in single_class_name_pattern.finditer(first_line):
|
||||
name_of_class_in_prop = match.group("class_name")
|
||||
|
||||
# Writing to dictionary: matching the class found in the docstring and its
|
||||
# subclasses to the property of the class being inspected.
|
||||
# The class in the property docstring (or its subclass) is the key,
|
||||
# ReST link to property of the class currently being inspected is the value.
|
||||
try:
|
||||
self._resolve_arg_and_add_link(
|
||||
arg=name_of_class_in_prop,
|
||||
dict_of_methods_for_class=attrs_for_class,
|
||||
link=f":attr:`{name_of_inspected_class_in_docstr}.{prop_name}`",
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"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)}"
|
||||
)
|
||||
|
||||
return self._generate_admonitions(attrs_for_class, admonition_type="available_in")
|
||||
|
||||
def _create_returned_in(self) -> dict[type, str]:
|
||||
"""Creates a dictionary with 'Returned in' admonitions for classes that are returned
|
||||
in Bot's and ApplicationBuilder's methods.
|
||||
"""
|
||||
|
||||
# Generate a mapping of classes to ReST links to Bot methods which return it,
|
||||
# i.e. {<class 'telegram._message.Message'>: {:meth:`telegram.Bot.send_message`, ...}}
|
||||
methods_for_class = defaultdict(set)
|
||||
|
||||
for cls, method_names in self.METHOD_NAMES_FOR_BOT_AND_APPBUILDER.items():
|
||||
for method_name in method_names:
|
||||
sig = inspect.signature(getattr(cls, method_name))
|
||||
ret_annot = sig.return_annotation
|
||||
|
||||
method_link = self._generate_link_to_method(method_name, cls)
|
||||
|
||||
try:
|
||||
self._resolve_arg_and_add_link(
|
||||
arg=ret_annot,
|
||||
dict_of_methods_for_class=methods_for_class,
|
||||
link=method_link,
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"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)}"
|
||||
)
|
||||
|
||||
return self._generate_admonitions(methods_for_class, admonition_type="returned_in")
|
||||
|
||||
def _create_shortcuts(self) -> dict[collections.abc.Callable, str]:
|
||||
"""Creates a dictionary with 'Shortcuts' admonitions for Bot methods that
|
||||
have shortcuts in other classes.
|
||||
"""
|
||||
|
||||
# pattern for looking for calls to Bot methods only
|
||||
bot_method_pattern = re.compile(
|
||||
r"""\s* # any number of whitespaces
|
||||
(?<=return\sawait\sself\.get_bot\(\)\.) # lookbehind
|
||||
\w+ # the method name we are looking for, letters/underscores
|
||||
(?=\() # lookahead: opening bracket before the args of the method start
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
# Generate a mapping of methods of classes to links to Bot methods which they are shortcuts
|
||||
# for, i.e. {<function Bot.send_voice at ...>: {:meth:`telegram.User.send_voice`, ...}
|
||||
shortcuts_for_bot_method = defaultdict(set)
|
||||
|
||||
# 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):
|
||||
# no need to inspect Bot's own methods, as Bot can't have shortcuts in Bot
|
||||
if cls is telegram.Bot:
|
||||
continue
|
||||
|
||||
for method_name, method in _iter_own_public_methods(cls):
|
||||
# .getsourcelines() returns a tuple. Item [1] is an int
|
||||
for line in inspect.getsourcelines(method)[0]:
|
||||
if not (bot_method_match := bot_method_pattern.search(line)):
|
||||
continue
|
||||
|
||||
bot_method = getattr(telegram.Bot, bot_method_match.group())
|
||||
|
||||
link_to_shortcut_method = self._generate_link_to_method(method_name, cls)
|
||||
|
||||
shortcuts_for_bot_method[bot_method].add(link_to_shortcut_method)
|
||||
|
||||
return self._generate_admonitions(shortcuts_for_bot_method, admonition_type="shortcuts")
|
||||
|
||||
def _create_use_in(self) -> dict[type, str]:
|
||||
"""Creates a dictionary with 'Use in' admonitions for classes whose instances are
|
||||
accepted as arguments for Bot's and ApplicationBuilder's methods.
|
||||
"""
|
||||
|
||||
# Generate a mapping of classes to links to Bot methods which accept them as arguments,
|
||||
# i.e. {<class 'telegram._inline.inlinequeryresult.InlineQueryResult'>:
|
||||
# {:meth:`telegram.Bot.answer_inline_query`, ...}}
|
||||
methods_for_class = defaultdict(set)
|
||||
|
||||
for cls, method_names in self.METHOD_NAMES_FOR_BOT_AND_APPBUILDER.items():
|
||||
for method_name in method_names:
|
||||
method_link = self._generate_link_to_method(method_name, cls)
|
||||
|
||||
sig = inspect.signature(getattr(cls, method_name))
|
||||
parameters = sig.parameters
|
||||
|
||||
for param in parameters.values():
|
||||
try:
|
||||
self._resolve_arg_and_add_link(
|
||||
arg=param.annotation,
|
||||
dict_of_methods_for_class=methods_for_class,
|
||||
link=method_link,
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"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)}"
|
||||
)
|
||||
|
||||
return self._generate_admonitions(methods_for_class, admonition_type="use_in")
|
||||
|
||||
@staticmethod
|
||||
def _find_insert_pos_for_admonition(lines: list[str]) -> int:
|
||||
"""Finds the correct position to insert the class admonition and returns the index.
|
||||
|
||||
The admonition will be insert above "See also", "Examples:", version added/changed notes
|
||||
and args, whatever comes first.
|
||||
|
||||
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::")
|
||||
):
|
||||
return idx
|
||||
return len(lines) - 1
|
||||
|
||||
def _generate_admonitions(
|
||||
self,
|
||||
attrs_or_methods_for_class: dict[type, set[str]],
|
||||
admonition_type: str,
|
||||
) -> dict[type, str]:
|
||||
"""Generates admonitions of a given type.
|
||||
Takes a dictionary of classes matched to ReST links to methods or attributes, e.g.:
|
||||
|
||||
```
|
||||
{<class 'telegram._files.sticker.StickerSet'>:
|
||||
[":meth: `telegram.Bot.get_sticker_set`", ...]}.
|
||||
```
|
||||
|
||||
Returns a dictionary of classes matched to full admonitions, e.g.
|
||||
for `admonition_type` "returned_in" (note that title and CSS class are generated
|
||||
automatically):
|
||||
|
||||
```
|
||||
{<class 'telegram._files.sticker.StickerSet'>:
|
||||
".. admonition:: Returned in:
|
||||
:class: returned-in
|
||||
|
||||
:meth: `telegram.Bot.get_sticker_set`"}.
|
||||
```
|
||||
"""
|
||||
|
||||
if admonition_type not in self.ALL_ADMONITION_TYPES:
|
||||
raise TypeError(f"Admonition type {admonition_type} not supported.")
|
||||
|
||||
admonition_for_class = {}
|
||||
|
||||
for cls, attrs in attrs_or_methods_for_class.items():
|
||||
if cls is telegram.ext.ApplicationBuilder:
|
||||
# ApplicationBuilder is only used in and returned from its own methods,
|
||||
# so its page needs no admonitions.
|
||||
continue
|
||||
|
||||
attrs = sorted(attrs)
|
||||
|
||||
# e.g. for admonition type "use_in" the title will be "Use in" and CSS class "use-in".
|
||||
admonition = f"""
|
||||
|
||||
.. admonition:: {admonition_type.title().replace("_", " ")}
|
||||
:class: {admonition_type.replace("_", "-")}
|
||||
"""
|
||||
if len(attrs) > 1:
|
||||
for target_attr in attrs:
|
||||
admonition += "\n * " + target_attr
|
||||
else:
|
||||
admonition += f"\n {attrs[0]}"
|
||||
|
||||
admonition += "\n " # otherwise an unexpected unindent warning will be issued
|
||||
admonition_for_class[cls] = admonition
|
||||
|
||||
return admonition_for_class
|
||||
|
||||
@staticmethod
|
||||
def _generate_class_name_for_link(cls: type) -> str:
|
||||
"""Generates class name that can be used in a ReST link."""
|
||||
|
||||
# Check for potential presence of ".ext.", we will need to keep it.
|
||||
ext = ".ext" if ".ext." in str(cls) else ""
|
||||
return f"telegram{ext}.{cls.__name__}"
|
||||
|
||||
def _generate_link_to_method(self, method_name: str, cls: type) -> str:
|
||||
"""Generates a ReST link to a method of a telegram class."""
|
||||
|
||||
return f":meth:`{self._generate_class_name_for_link(cls)}.{method_name}`"
|
||||
|
||||
@staticmethod
|
||||
def _iter_subclasses(cls: type) -> Iterator:
|
||||
return (
|
||||
# exclude private classes
|
||||
c
|
||||
for c in cls.__subclasses__()
|
||||
if not str(c).split(".")[-1].startswith("_")
|
||||
)
|
||||
|
||||
def _resolve_arg_and_add_link(
|
||||
self,
|
||||
arg: Any,
|
||||
dict_of_methods_for_class: defaultdict,
|
||||
link: str,
|
||||
) -> None:
|
||||
"""A helper method. Tries to resolve the arg into a valid class. In case of success,
|
||||
adds the link (to a method, attribute, or property) for that class' and its subclasses'
|
||||
sets of links in the dictionary of admonitions.
|
||||
|
||||
**Modifies dictionary in place.**
|
||||
"""
|
||||
for cls in self._resolve_arg(arg):
|
||||
# When trying to resolve an argument from args or return annotation,
|
||||
# the method _resolve_arg returns None if nothing could be resolved.
|
||||
# Also, if class was resolved correctly, "telegram" will definitely be in its str().
|
||||
if cls is None or "telegram" not in str(cls):
|
||||
continue
|
||||
|
||||
dict_of_methods_for_class[cls].add(link)
|
||||
|
||||
for subclass in self._iter_subclasses(cls):
|
||||
dict_of_methods_for_class[subclass].add(link)
|
||||
|
||||
def _resolve_arg(self, arg: Any) -> Iterator[Union[type, None]]:
|
||||
"""Analyzes an argument of a method and recursively yields classes that the argument
|
||||
or its sub-arguments (in cases like Union[...]) belong to, if they can be resolved to
|
||||
telegram or telegram.ext classes.
|
||||
|
||||
Raises `NotImplementedError`.
|
||||
"""
|
||||
|
||||
origin = typing.get_origin(arg)
|
||||
|
||||
if (
|
||||
origin in (collections.abc.Callable, typing.IO)
|
||||
or arg is None
|
||||
# no other check available (by type or origin) for these:
|
||||
or str(type(arg)) in ("<class 'typing._SpecialForm'>", "<class 'ellipsis'>")
|
||||
):
|
||||
pass
|
||||
|
||||
# RECURSIVE CALLS
|
||||
# for cases like Union[Sequence....
|
||||
elif origin in (
|
||||
Union,
|
||||
collections.abc.Coroutine,
|
||||
collections.abc.Sequence,
|
||||
):
|
||||
for sub_arg in typing.get_args(arg):
|
||||
yield from self._resolve_arg(sub_arg)
|
||||
|
||||
elif isinstance(arg, typing.TypeVar):
|
||||
# gets access to the "bound=..." parameter
|
||||
yield from self._resolve_arg(arg.__bound__)
|
||||
# END RECURSIVE CALLS
|
||||
|
||||
elif isinstance(arg, typing.ForwardRef):
|
||||
m = self.FORWARD_REF_PATTERN.match(str(arg))
|
||||
# We're sure it's a ForwardRef, so, unless it belongs to known exceptions,
|
||||
# the class must be resolved.
|
||||
# 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:
|
||||
# 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}")
|
||||
else:
|
||||
yield cls
|
||||
|
||||
# For custom generics like telegram.ext._application.Application[~BT, ~CCT, ~UD...].
|
||||
# This must come before the check for isinstance(type) because GenericAlias can also be
|
||||
# recognized as type if it belongs to <class 'types.GenericAlias'>.
|
||||
elif str(type(arg)) in ("<class 'typing._GenericAlias'>", "<class 'types.GenericAlias'>"):
|
||||
if "telegram" in str(arg):
|
||||
# get_origin() of telegram.ext._application.Application[~BT, ~CCT, ~UD...]
|
||||
# will produce <class 'telegram.ext._application.Application'>
|
||||
yield origin
|
||||
|
||||
elif isinstance(arg, type):
|
||||
if "telegram" in str(arg):
|
||||
yield arg
|
||||
|
||||
# For some reason "InlineQueryResult", "InputMedia" & some others are currently not
|
||||
# recognized as ForwardRefs and are identified as plain strings.
|
||||
elif isinstance(arg, str):
|
||||
# args like "ApplicationBuilder[BT, CCT, UD, CD, BD, JQ]" can be recognized as strings.
|
||||
# Remove whatever is in the square brackets because it doesn't need to be parsed.
|
||||
arg = re.sub(r"\[.+]", "", arg)
|
||||
|
||||
cls = self._resolve_class(arg)
|
||||
# Here we don't want an exception to be thrown since we're not sure it's ForwardRef
|
||||
if cls is not None:
|
||||
yield cls
|
||||
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
f"Cannot process argument {arg} of type {type(arg)} (origin {origin})"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _resolve_class(name: str) -> Union[type, None]:
|
||||
"""The keys in the admonitions dictionary are not strings like "telegram.StickerSet"
|
||||
but classes like <class 'telegram._files.sticker.StickerSet'>.
|
||||
|
||||
This method attempts to resolve a PTB class from a name that does or does not
|
||||
contain the word 'telegram', e.g.
|
||||
<class 'telegram._files.sticker.StickerSet'> from "telegram.StickerSet" or "StickerSet".
|
||||
|
||||
Returns a class on success, :obj:`None` if nothing could be resolved.
|
||||
"""
|
||||
|
||||
for option in (
|
||||
name,
|
||||
f"telegram.{name}",
|
||||
f"telegram.ext.{name}",
|
||||
f"telegram.ext.filters.{name}",
|
||||
):
|
||||
try:
|
||||
return eval(option)
|
||||
# NameError will be raised if trying to eval just name and it doesn't work, e.g.
|
||||
# "Name 'ApplicationBuilder' is not defined".
|
||||
# AttributeError will be raised if trying to e.g. eval f"telegram.{name}" when the
|
||||
# class denoted by `name` actually belongs to `telegram.ext`:
|
||||
# "module 'telegram' has no attribute 'ApplicationBuilder'".
|
||||
# If neither option works, this is not a PTB class.
|
||||
except (NameError, AttributeError):
|
||||
continue
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# just try instantiating for debugging purposes
|
||||
AdmonitionInserter()
|
||||
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 inspect
|
||||
|
||||
keyword_args = [
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to {read_timeout}.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: {read_timeout_type}, optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to {write_timeout}.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: :obj:`float` | :obj:`None`, "
|
||||
"optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to "
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: :obj:`float` | "
|
||||
":obj:`None`, optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to "
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: :obj:`float` | :obj:`None`, "
|
||||
"optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: Arbitrary keyword arguments "
|
||||
"to be passed to the Telegram API.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: :obj:`dict`, optional",
|
||||
"",
|
||||
]
|
||||
write_timeout_sub = [":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`", "``20``"]
|
||||
read_timeout_sub = [
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
|
||||
"``2``. :paramref:`timeout` will be added to this value",
|
||||
]
|
||||
read_timeout_type = [":obj:`float` | :obj:`None`", ":obj:`float`"]
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
def is_write_timeout_20(obj: object) -> int:
|
||||
"""inspects the default value of write_timeout parameter of the bot method."""
|
||||
sig = inspect.signature(obj)
|
||||
return 1 if (sig.parameters["write_timeout"].default == 20) else 0
|
||||
|
||||
|
||||
def check_timeout_and_api_kwargs_presence(obj: object) -> int:
|
||||
"""Checks if the method has timeout and api_kwargs keyword only parameters."""
|
||||
sig = inspect.signature(obj)
|
||||
params_to_check = (
|
||||
"read_timeout",
|
||||
"write_timeout",
|
||||
"connect_timeout",
|
||||
"pool_timeout",
|
||||
"api_kwargs",
|
||||
)
|
||||
return all(
|
||||
param in sig.parameters and sig.parameters[param].kind == inspect.Parameter.KEYWORD_ONLY
|
||||
for param in params_to_check
|
||||
)
|
||||
@@ -0,0 +1,77 @@
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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/].
|
||||
"""Functionality in this file is used for getting the [source] links on the classes, methods etc
|
||||
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 sphinx.util import logging
|
||||
|
||||
# get the sphinx(!) logger
|
||||
# Makes sure logs render in red and also plays nicely with e.g. the `nitpicky` option.
|
||||
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 = {}
|
||||
|
||||
|
||||
def _git_branch() -> str:
|
||||
"""Get's the current git sha if available or fall back to `master`"""
|
||||
try:
|
||||
output = subprocess.check_output( # skipcq: BAN-B607
|
||||
["git", "describe", "--tags", "--always"], stderr=subprocess.STDOUT
|
||||
)
|
||||
return output.decode().strip()
|
||||
except Exception as exc:
|
||||
sphinx_logger.exception(
|
||||
"Failed to get a description of the current commit. Falling back to `master`.",
|
||||
exc_info=exc,
|
||||
)
|
||||
return "master"
|
||||
|
||||
|
||||
git_branch = _git_branch()
|
||||
base_url = "https://github.com/python-telegram-bot/python-telegram-bot/blob/"
|
||||
|
||||
|
||||
def linkcode_resolve(_, info):
|
||||
"""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
|
||||
combined = combined.replace("ExtBot.ExtBot", "ExtBot")
|
||||
|
||||
line_info = LINE_NUMBERS.get(combined)
|
||||
|
||||
if not line_info:
|
||||
# Try the __init__
|
||||
line_info = LINE_NUMBERS.get(f"{combined.rsplit('.', 1)[0]}.__init__")
|
||||
if not line_info:
|
||||
# Try the class
|
||||
line_info = LINE_NUMBERS.get(f"{combined.rsplit('.', 1)[0]}")
|
||||
if not line_info:
|
||||
# Try the module
|
||||
line_info = LINE_NUMBERS.get(info["module"])
|
||||
|
||||
if not line_info:
|
||||
return
|
||||
|
||||
file, start_line, end_line = line_info
|
||||
return f"{base_url}{git_branch}/{file}#L{start_line}-L{end_line}"
|
||||
@@ -0,0 +1,209 @@
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 collections.abc
|
||||
import inspect
|
||||
import re
|
||||
import typing
|
||||
from pathlib import Path
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
import telegram
|
||||
import telegram.ext
|
||||
from docs.auxil.admonition_inserter import AdmonitionInserter
|
||||
from docs.auxil.kwargs_insertion import (
|
||||
check_timeout_and_api_kwargs_presence,
|
||||
find_insert_pos_for_kwargs,
|
||||
is_write_timeout_20,
|
||||
keyword_args,
|
||||
read_timeout_sub,
|
||||
read_timeout_type,
|
||||
write_timeout_sub,
|
||||
)
|
||||
from docs.auxil.link_code import LINE_NUMBERS
|
||||
|
||||
ADMONITION_INSERTER = AdmonitionInserter()
|
||||
|
||||
# Some base classes are implementation detail
|
||||
# We want to instead show *their* base class
|
||||
PRIVATE_BASE_CLASSES = {
|
||||
"_ChatUserBaseFilter": "MessageFilter",
|
||||
"_Dice": "MessageFilter",
|
||||
"_BaseThumbedMedium": "TelegramObject",
|
||||
"_BaseMedium": "TelegramObject",
|
||||
"_CredentialsBase": "TelegramObject",
|
||||
}
|
||||
|
||||
|
||||
FILE_ROOT = Path(inspect.getsourcefile(telegram)).parent.parent.resolve()
|
||||
|
||||
|
||||
def autodoc_skip_member(app, what, name, obj, skip, options):
|
||||
"""We use this to not document certain members like filter() or check_update() for filters.
|
||||
See https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#skipping-members"""
|
||||
|
||||
included = {"MessageFilter", "UpdateFilter"} # filter() and check_update() only for these.
|
||||
included_in_obj = any(inc in repr(obj) for inc in included)
|
||||
|
||||
if included_in_obj: # it's difficult to see if check_update is from an inherited-member or not
|
||||
for frame in inspect.stack(): # From https://github.com/sphinx-doc/sphinx/issues/9533
|
||||
if frame.function == "filter_members":
|
||||
docobj = frame.frame.f_locals["self"].object
|
||||
if not any(inc in str(docobj) for inc in included) and name == "check_update":
|
||||
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.
|
||||
|
||||
|
||||
def autodoc_process_docstring(
|
||||
app: Sphinx, what, name: str, obj: object, options, lines: list[str]
|
||||
):
|
||||
"""We do the following things:
|
||||
1) Use this method to automatically insert the Keyword Args and "Shortcuts" admonitions
|
||||
for the Bot methods.
|
||||
|
||||
2) Use this method to automatically insert "Returned in" admonition into classes
|
||||
that are returned from the Bot methods
|
||||
|
||||
3) Use this method to automatically insert "Available in" admonition into classes
|
||||
whose instances are available as attributes of other classes
|
||||
|
||||
4) Use this method to automatically insert "Use in" admonition into classes
|
||||
whose instances can be used as arguments of the Bot methods
|
||||
|
||||
5) Misuse this autodoc hook to get the file names & line numbers because we have access
|
||||
to the actual object here.
|
||||
"""
|
||||
|
||||
# 1) Insert the Keyword Args and "Shortcuts" admonitions for the Bot methods
|
||||
method_name = name.split(".")[-1]
|
||||
if (
|
||||
name.startswith("telegram.Bot.")
|
||||
and what == "method"
|
||||
and method_name.islower()
|
||||
and check_timeout_and_api_kwargs_presence(obj)
|
||||
):
|
||||
insert_index = find_insert_pos_for_kwargs(lines)
|
||||
if not insert_index:
|
||||
raise ValueError(
|
||||
f"Couldn't find the correct position to insert the keyword args for {obj}."
|
||||
)
|
||||
|
||||
long_write_timeout = is_write_timeout_20(obj)
|
||||
get_updates_sub = 1 if (method_name == "get_updates") else 0
|
||||
# The below can be done in 1 line with itertools.chain, but this must be modified in-place
|
||||
for i in range(insert_index, insert_index + len(keyword_args)):
|
||||
lines.insert(
|
||||
i,
|
||||
keyword_args[i - insert_index].format(
|
||||
method=method_name,
|
||||
write_timeout=write_timeout_sub[long_write_timeout],
|
||||
read_timeout=read_timeout_sub[get_updates_sub],
|
||||
read_timeout_type=read_timeout_type[get_updates_sub],
|
||||
),
|
||||
)
|
||||
|
||||
ADMONITION_INSERTER.insert_admonitions(
|
||||
obj=typing.cast(collections.abc.Callable, obj),
|
||||
docstring_lines=lines,
|
||||
)
|
||||
|
||||
# 2-4) Insert "Returned in", "Available in", "Use in" admonitions into classes
|
||||
# (where applicable)
|
||||
if what == "class":
|
||||
ADMONITION_INSERTER.insert_admonitions(
|
||||
obj=typing.cast(type, obj), # since "what" == class, we know it's not just object
|
||||
docstring_lines=lines,
|
||||
)
|
||||
|
||||
# 5) Get the file names & line numbers
|
||||
# We can't properly handle ordinary attributes.
|
||||
# In linkcode_resolve we'll resolve to the `__init__` or module instead
|
||||
if what == "attribute":
|
||||
return
|
||||
|
||||
# Special casing for properties
|
||||
if hasattr(obj, "fget"):
|
||||
obj = obj.fget
|
||||
|
||||
# Special casing for filters
|
||||
if isinstance(obj, telegram.ext.filters.BaseFilter):
|
||||
obj = obj.__class__
|
||||
|
||||
try:
|
||||
source_lines, start_line = inspect.getsourcelines(obj)
|
||||
end_line = start_line + len(source_lines)
|
||||
file = Path(inspect.getsourcefile(obj)).relative_to(FILE_ROOT)
|
||||
LINE_NUMBERS[name] = (file, start_line, end_line)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Since we don't document the `__init__`, we call this manually to have it available for
|
||||
# attributes -- see the note above
|
||||
if what == "class":
|
||||
autodoc_process_docstring(app, "method", f"{name}.__init__", obj.__init__, options, lines)
|
||||
|
||||
|
||||
def autodoc_process_bases(app, name, obj, option, bases: list):
|
||||
"""Here we fine tune how the base class's classes are displayed."""
|
||||
for idx, base in enumerate(bases):
|
||||
# let's use a string representation of the object
|
||||
base = str(base)
|
||||
|
||||
# Special case for abstract context managers which are wrongly resoled for some reason
|
||||
if base.startswith("typing.AbstractAsyncContextManager"):
|
||||
bases[idx] = ":class:`contextlib.AbstractAsyncContextManager`"
|
||||
continue
|
||||
|
||||
# Special case because base classes are in std lib:
|
||||
if "StringEnum" in base == "<enum 'StringEnum'>":
|
||||
bases[idx] = ":class:`enum.Enum`"
|
||||
bases.insert(0, ":class:`str`")
|
||||
continue
|
||||
|
||||
if "IntEnum" in base:
|
||||
bases[idx] = ":class:`enum.IntEnum`"
|
||||
continue
|
||||
|
||||
# Drop generics (at least for now)
|
||||
if base.endswith("]"):
|
||||
base = base.split("[", maxsplit=1)[0]
|
||||
bases[idx] = f":class:`{base}`"
|
||||
|
||||
# Now convert `telegram._message.Message` to `telegram.Message` etc
|
||||
match = re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base)
|
||||
if not match or "_utils" in base:
|
||||
continue
|
||||
|
||||
parts = match.group(0).split(".")
|
||||
|
||||
# Remove private paths
|
||||
for index, part in enumerate(parts):
|
||||
if part.startswith("_"):
|
||||
parts = parts[:index] + parts[-1:]
|
||||
break
|
||||
|
||||
# Replace private base classes with their respective parent
|
||||
parts = [PRIVATE_BASE_CLASSES.get(part, part) for part in parts]
|
||||
|
||||
base = ".".join(parts)
|
||||
|
||||
bases[idx] = f":class:`{base}`"
|
||||
@@ -0,0 +1,92 @@
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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/].
|
||||
from enum import Enum
|
||||
|
||||
from docutils.nodes import Element
|
||||
from sphinx.domains.python import PyXRefRole
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.util import logging
|
||||
|
||||
import telegram
|
||||
|
||||
# get the sphinx(!) logger
|
||||
# Makes sure logs render in red and also plays nicely with e.g. the `nitpicky` option.
|
||||
sphinx_logger = logging.getLogger(__name__)
|
||||
|
||||
CONSTANTS_ROLE = "tg-const"
|
||||
|
||||
|
||||
class TGConstXRefRole(PyXRefRole):
|
||||
"""This is a bit of Sphinx magic. We add a new role type called tg-const that allows us to
|
||||
reference values from the `telegram.constants.module` while using the actual value as title
|
||||
of the link.
|
||||
|
||||
Example:
|
||||
|
||||
:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` renders as `4096` but links to
|
||||
the constant.
|
||||
"""
|
||||
|
||||
def process_link(
|
||||
self,
|
||||
env: BuildEnvironment,
|
||||
refnode: Element,
|
||||
has_explicit_title: bool,
|
||||
title: str,
|
||||
target: str,
|
||||
) -> tuple[str, str]:
|
||||
title, target = super().process_link(env, refnode, has_explicit_title, title, target)
|
||||
try:
|
||||
# We use `eval` to get the value of the expression. Maybe there are better ways to
|
||||
# do this via importlib or so, but it does the job for now
|
||||
value = eval(target)
|
||||
# Maybe we need a better check if the target is actually from tg.constants
|
||||
# for now checking if it's an Enum suffices since those are used nowhere else in PTB
|
||||
if isinstance(value, Enum):
|
||||
# Special casing for file size limits
|
||||
if isinstance(value, telegram.constants.FileSizeLimit):
|
||||
return f"{int(value.value / 1e6)} MB", target
|
||||
return repr(value.value), target
|
||||
# Just for (Bot API) versions number auto add in constants:
|
||||
if isinstance(value, str) and target in (
|
||||
"telegram.constants.BOT_API_VERSION",
|
||||
"telegram.__version__",
|
||||
):
|
||||
return value, target
|
||||
if isinstance(value, tuple) and target in (
|
||||
"telegram.constants.BOT_API_VERSION_INFO",
|
||||
"telegram.__version_info__",
|
||||
):
|
||||
return repr(value), target
|
||||
sphinx_logger.warning(
|
||||
f"%s:%d: WARNING: Did not convert reference %s. :{CONSTANTS_ROLE}: is not supposed"
|
||||
" to be used with this type of target.",
|
||||
refnode.source,
|
||||
refnode.line,
|
||||
refnode.rawsource,
|
||||
)
|
||||
return title, target
|
||||
except Exception as exc:
|
||||
sphinx_logger.exception(
|
||||
"%s:%d: WARNING: Did not convert reference %s due to an exception.",
|
||||
refnode.source,
|
||||
refnode.line,
|
||||
refnode.rawsource,
|
||||
exc_info=exc,
|
||||
)
|
||||
return title, target
|
||||
@@ -1,5 +1,7 @@
|
||||
sphinx==5.0.2
|
||||
sphinx==6.1.3
|
||||
sphinx-pypi-upload
|
||||
furo==2022.6.21
|
||||
furo==2022.12.7
|
||||
git+https://github.com/harshil21/furo-sphinx-search@01efc7be422d7dc02390aab9be68d6f5ce1a5618#egg=furo-sphinx-search
|
||||
sphinx-paramlinks==0.5.4
|
||||
sphinxcontrib-mermaid==0.7.1
|
||||
sphinxcontrib-mermaid==0.7.1
|
||||
sphinx-copybutton==0.5.1
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
:root {
|
||||
--icon--shortcuts: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-signpost' viewBox='0 0 16 16'%3E%3Cpath d='M7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414a1 1 0 0 0-2 0zM12.532 5l1.666 2-1.666 2H2V5h10.532z'/%3E%3C/svg%3E");
|
||||
--icon--returned-in: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-arrow-return-right' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.5 1.5A.5.5 0 0 0 1 2v4.8a2.5 2.5 0 0 0 2.5 2.5h9.793l-3.347 3.346a.5.5 0 0 0 .708.708l4.2-4.2a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 8.3H3.5A1.5 1.5 0 0 1 2 6.8V2a.5.5 0 0 0-.5-.5z'/%3E%3C/svg%3E");
|
||||
--icon--available-in: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-geo-fill' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4 4a4 4 0 1 1 4.5 3.969V13.5a.5.5 0 0 1-1 0V7.97A4 4 0 0 1 4 3.999zm2.493 8.574a.5.5 0 0 1-.411.575c-.712.118-1.28.295-1.655.493a1.319 1.319 0 0 0-.37.265.301.301 0 0 0-.057.09V14l.002.008a.147.147 0 0 0 .016.033.617.617 0 0 0 .145.15c.165.13.435.27.813.395.751.25 1.82.414 3.024.414s2.273-.163 3.024-.414c.378-.126.648-.265.813-.395a.619.619 0 0 0 .146-.15.148.148 0 0 0 .015-.033L12 14v-.004a.301.301 0 0 0-.057-.09 1.318 1.318 0 0 0-.37-.264c-.376-.198-.943-.375-1.655-.493a.5.5 0 1 1 .164-.986c.77.127 1.452.328 1.957.594C12.5 13 13 13.4 13 14c0 .426-.26.752-.544.977-.29.228-.68.413-1.116.558-.878.293-2.059.465-3.34.465-1.281 0-2.462-.172-3.34-.465-.436-.145-.826-.33-1.116-.558C3.26 14.752 3 14.426 3 14c0-.599.5-1 .961-1.243.505-.266 1.187-.467 1.957-.594a.5.5 0 0 1 .575.411z'/%3E%3C/svg%3E");
|
||||
--icon--use-in:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-funnel' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2h-11z'/%3E%3C/svg%3E");
|
||||
}
|
||||
.admonition.shortcuts {
|
||||
border-color: rgb(43, 155, 70);
|
||||
}
|
||||
.admonition.shortcuts > .admonition-title {
|
||||
background-color: rgba(43, 155, 70, 0.1);
|
||||
border-color: rgb(43, 155, 70);
|
||||
}
|
||||
.admonition.shortcuts > .admonition-title::before {
|
||||
background-color: rgb(43, 155, 70);
|
||||
-webkit-mask-image: var(--icon--shortcuts);
|
||||
mask-image: var(--icon--shortcuts);
|
||||
}
|
||||
|
||||
.admonition.returned-in {
|
||||
border-color: rgb(230, 109, 15);
|
||||
}
|
||||
.admonition.returned-in > .admonition-title {
|
||||
background-color: rgba(177, 108, 51, 0.1);
|
||||
border-color: rgb(230, 109, 15);
|
||||
}
|
||||
.admonition.returned-in > .admonition-title::before {
|
||||
background-color: rgb(230, 109, 15);
|
||||
-webkit-mask-image: var(--icon--returned-in);
|
||||
mask-image: var(--icon--returned-in);
|
||||
}
|
||||
|
||||
.admonition.available-in {
|
||||
border-color: rgb(183, 4, 215);
|
||||
}
|
||||
.admonition.available-in > .admonition-title {
|
||||
background-color: rgba(165, 99, 177, 0.1);
|
||||
border-color: rgb(183, 4, 215);
|
||||
}
|
||||
.admonition.available-in > .admonition-title::before {
|
||||
background-color: rgb(183, 4, 215);
|
||||
-webkit-mask-image: var(--icon--available-in);
|
||||
mask-image: var(--icon--available-in);
|
||||
}
|
||||
|
||||
.admonition.use-in {
|
||||
border-color: rgb(203, 147, 1);
|
||||
}
|
||||
.admonition.use-in > .admonition-title {
|
||||
background-color: rgba(176, 144, 60, 0.1);
|
||||
border-color: rgb(203, 147, 1);
|
||||
}
|
||||
.admonition.use-in > .admonition-title::before {
|
||||
background-color: rgb(203, 147, 1);
|
||||
-webkit-mask-image: var(--icon--use-in);
|
||||
mask-image: var(--icon--use-in);
|
||||
}
|
||||
|
||||
.admonition.returned-in > ul:hover, .admonition.available-in > ul:hover, .admonition.use-in > ul:hover, .admonition.shortcuts > ul:hover {
|
||||
cursor: move;
|
||||
}
|
||||
.admonition.returned-in > ul, .admonition.available-in > ul, .admonition.use-in > ul, .admonition.shortcuts > ul {
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.article-container h1 {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
figure > img {
|
||||
height: 300px; /* resize figures so they aren't too big */
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not([data-theme="light"]) figure > img { /* auto and dark is dark mode */
|
||||
filter: invert(92%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
body[data-theme="dark"] figure > img { /* auto and light is light mode */
|
||||
filter: invert(92%);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
.sidebar-sticky .sidebar-brand {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar-sticky .sidebar-brand .sidebar-logo-container {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.sidebar-sticky .sidebar-brand .sidebar-brand-text {
|
||||
align-self: center;
|
||||
}
|
||||
+29
-237
@@ -1,27 +1,19 @@
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Tuple
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
from docutils.nodes import Element
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.domains.python import PyXRefRole
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.util import logging
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../.."))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
# General information about the project.
|
||||
project = "python-telegram-bot"
|
||||
copyright = "2015-2022, Leandro Toledo"
|
||||
copyright = "2015-2023, Leandro Toledo"
|
||||
author = "Leandro Toledo"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
@@ -29,12 +21,12 @@ author = "Leandro Toledo"
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "20.0a2" # telegram.__version__[:3]
|
||||
version = "20.1" # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "20.0a2" # telegram.__version__
|
||||
release = "20.1" # telegram.__version__
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "4.5.0"
|
||||
needs_sphinx = "6.1.3"
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@@ -44,10 +36,16 @@ extensions = [
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.linkcode",
|
||||
"sphinx.ext.extlinks",
|
||||
"sphinx_paramlinks",
|
||||
"sphinx_copybutton",
|
||||
"sphinxcontrib.mermaid",
|
||||
"sphinx_search.extension",
|
||||
]
|
||||
|
||||
# For shorter links to Wiki in docstrings
|
||||
extlinks = {"wiki": ("https://github.com/python-telegram-bot/python-telegram-bot/wiki/%s", "%s")}
|
||||
|
||||
# Use intersphinx to reference the python builtin library docs
|
||||
intersphinx_mapping = {
|
||||
"python": ("https://docs.python.org/3", None),
|
||||
@@ -64,6 +62,9 @@ source_suffix = ".rst"
|
||||
# The master toctree document.
|
||||
master_doc = "index"
|
||||
|
||||
# Global substitutions
|
||||
rst_prolog = (Path.cwd() / "../substitutions/global.rst").read_text(encoding="utf-8")
|
||||
|
||||
# -- Extension settings ------------------------------------------------
|
||||
napoleon_use_admonition_for_examples = True
|
||||
|
||||
@@ -215,8 +216,13 @@ html_static_path = ["_static"]
|
||||
html_css_files = [
|
||||
"style_external_link.css",
|
||||
"style_mermaid_diagrams.css",
|
||||
"style_sidebar_brand.css",
|
||||
"style_general.css",
|
||||
"style_admonitions.css",
|
||||
"style_images.css",
|
||||
]
|
||||
html_permalinks_icon = "¶" # Furo's default permalink icon is `#`` which doesn't look great imo.
|
||||
|
||||
html_permalinks_icon = "¶" # Furo's default permalink icon is `#` which doesn't look great imo.
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = "python-telegram-bot-doc"
|
||||
@@ -257,6 +263,7 @@ latex_logo = "ptb-logo_1024.png"
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [(master_doc, "python-telegram-bot", "python-telegram-bot Documentation", [author], 1)]
|
||||
|
||||
# rtd_sphinx_search_file_type = "un-minified" # Configuration for furo-sphinx-search
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
@@ -277,231 +284,16 @@ texinfo_documents = [
|
||||
|
||||
# -- script stuff --------------------------------------------------------
|
||||
|
||||
# get the sphinx(!) logger
|
||||
# Makes sure logs render in red and also plays nicely with e.g. the `nitpicky` option.
|
||||
sphinx_logger = logging.getLogger(__name__)
|
||||
# Due to Sphinx behaviour, these imports only work when imported here, not at top of module.
|
||||
|
||||
CONSTANTS_ROLE = "tg-const"
|
||||
import telegram # We need this so that the `eval` below works
|
||||
|
||||
|
||||
class TGConstXRefRole(PyXRefRole):
|
||||
"""This is a bit of Sphinx magic. We add a new role type called tg-const that allows us to
|
||||
reference values from the `telegram.constants.module` while using the actual value as title
|
||||
of the link.
|
||||
|
||||
Example:
|
||||
|
||||
:tg-const:`telegram.constants.MessageLimit.TEXT_LENGTH` renders as `4096` but links to the
|
||||
constant.
|
||||
"""
|
||||
|
||||
def process_link(
|
||||
self,
|
||||
env: BuildEnvironment,
|
||||
refnode: Element,
|
||||
has_explicit_title: bool,
|
||||
title: str,
|
||||
target: str,
|
||||
) -> Tuple[str, str]:
|
||||
title, target = super().process_link(env, refnode, has_explicit_title, title, target)
|
||||
try:
|
||||
# We use `eval` to get the value of the expression. Maybe there are better ways to
|
||||
# do this via importlib or so, but it does the job for now
|
||||
value = eval(target)
|
||||
# Maybe we need a better check if the target is actually from tg.constants
|
||||
# for now checking if it's an Enum suffices since those are used nowhere else in PTB
|
||||
if isinstance(value, Enum):
|
||||
# Special casing for file size limits
|
||||
if isinstance(value, telegram.constants.FileSizeLimit):
|
||||
return f"{int(value.value / 1e6)} MB", target
|
||||
return repr(value.value), target
|
||||
# Just for (Bot API) versions number auto add in constants:
|
||||
if isinstance(value, str) and target in (
|
||||
"telegram.constants.BOT_API_VERSION",
|
||||
"telegram.__version__",
|
||||
):
|
||||
return value, target
|
||||
if isinstance(value, tuple) and target in (
|
||||
"telegram.constants.BOT_API_VERSION_INFO",
|
||||
"telegram.__version_info__",
|
||||
):
|
||||
return repr(value), target
|
||||
sphinx_logger.warning(
|
||||
f"%s:%d: WARNING: Did not convert reference %s. :{CONSTANTS_ROLE}: is not supposed"
|
||||
" to be used with this type of target.",
|
||||
refnode.source,
|
||||
refnode.line,
|
||||
refnode.rawsource,
|
||||
)
|
||||
return title, target
|
||||
except Exception as exc:
|
||||
sphinx_logger.exception(
|
||||
f"%s:%d: WARNING: Did not convert reference %s due to an exception.",
|
||||
refnode.source,
|
||||
refnode.line,
|
||||
refnode.rawsource,
|
||||
exc_info=exc,
|
||||
)
|
||||
return title, target
|
||||
|
||||
|
||||
def autodoc_skip_member(app, what, name, obj, skip, options):
|
||||
"""We use this to not document certain members like filter() or check_update() for filters.
|
||||
See https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#skipping-members"""
|
||||
|
||||
included = {"MessageFilter", "UpdateFilter"} # filter() and check_update() only for these.
|
||||
included_in_obj = any(inc in repr(obj) for inc in included)
|
||||
|
||||
if included_in_obj: # it's difficult to see if check_update is from an inherited-member or not
|
||||
for frame in inspect.stack(): # From https://github.com/sphinx-doc/sphinx/issues/9533
|
||||
if frame.function == "filter_members":
|
||||
docobj = frame.frame.f_locals["self"].object
|
||||
if not any(inc in str(docobj) for inc in included) and name == "check_update":
|
||||
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.
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# This part is for getting the [source] links on the classes, methods etc link to the correct
|
||||
# files & lines on github. Can be simplified once https://github.com/sphinx-doc/sphinx/issues/1556
|
||||
# is closed
|
||||
|
||||
line_numbers = {}
|
||||
file_root = Path(inspect.getsourcefile(telegram)).parent.parent.resolve()
|
||||
import telegram.ext # Needed for checking if an object is a BaseFilter
|
||||
|
||||
|
||||
def autodoc_process_docstring(app: Sphinx, what, name: str, obj: object, options, lines):
|
||||
"""We misuse this autodoc hook to get the file names & line numbers because we have access
|
||||
to the actual object here.
|
||||
"""
|
||||
# Ce can't properly handle ordinary attributes.
|
||||
# In linkcode_resolve we'll resolve to the `__init__` or module instead
|
||||
if what == "attribute":
|
||||
return
|
||||
|
||||
# Special casing for properties
|
||||
if hasattr(obj, "fget"):
|
||||
obj = obj.fget
|
||||
|
||||
# Special casing for filters
|
||||
if isinstance(obj, telegram.ext.filters.BaseFilter):
|
||||
obj = obj.__class__
|
||||
|
||||
try:
|
||||
source_lines, start_line = inspect.getsourcelines(obj)
|
||||
end_line = start_line + len(source_lines)
|
||||
file = Path(inspect.getsourcefile(obj)).relative_to(file_root)
|
||||
line_numbers[name] = (file, start_line, end_line)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Since we don't document the `__init__`, we call this manually to have it available for
|
||||
# attributes -- see the note above
|
||||
if what == "class":
|
||||
autodoc_process_docstring(app, "method", f"{name}.__init__", obj.__init__, options, lines)
|
||||
|
||||
|
||||
def _git_branch() -> str:
|
||||
"""Get's the current git sha if available or fall back to `master`"""
|
||||
try:
|
||||
output = subprocess.check_output( # skipcq: BAN-B607
|
||||
["git", "describe", "--tags", "--always"], stderr=subprocess.STDOUT
|
||||
)
|
||||
return output.decode().strip()
|
||||
except Exception as exc:
|
||||
sphinx_logger.exception(
|
||||
f"Failed to get a description of the current commit. Falling back to `master`.",
|
||||
exc_info=exc,
|
||||
)
|
||||
return "master"
|
||||
|
||||
|
||||
git_branch = _git_branch()
|
||||
base_url = "https://github.com/python-telegram-bot/python-telegram-bot/blob/"
|
||||
|
||||
|
||||
def linkcode_resolve(_, info):
|
||||
"""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
|
||||
combined = combined.replace("ExtBot.ExtBot", "ExtBot")
|
||||
|
||||
line_info = line_numbers.get(combined)
|
||||
|
||||
if not line_info:
|
||||
# Try the __init__
|
||||
line_info = line_numbers.get(f"{combined.rsplit('.', 1)[0]}.__init__")
|
||||
if not line_info:
|
||||
# Try the class
|
||||
line_info = line_numbers.get(f"{combined.rsplit('.', 1)[0]}")
|
||||
if not line_info:
|
||||
# Try the module
|
||||
line_info = line_numbers.get(info["module"])
|
||||
|
||||
if not line_info:
|
||||
return
|
||||
|
||||
file, start_line, end_line = line_info
|
||||
return f"{base_url}{git_branch}/{file}#L{start_line}-L{end_line}"
|
||||
|
||||
|
||||
# End of logic for the [source] links
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Some base classes are implementation detail
|
||||
# We want to instead show *their* base class
|
||||
PRIVATE_BASE_CLASSES = {
|
||||
"_ChatUserBaseFilter": "MessageFilter",
|
||||
"_Dice": "MessageFilter",
|
||||
"_BaseThumbedMedium": "TelegramObject",
|
||||
"_BaseMedium": "TelegramObject",
|
||||
"_CredentialsBase": "TelegramObject",
|
||||
}
|
||||
|
||||
|
||||
def autodoc_process_bases(app, name, obj, option, bases: list):
|
||||
"""Here we fine tune how the base class's classes are displayed."""
|
||||
for idx, base in enumerate(bases):
|
||||
# let's use a string representation of the object
|
||||
base = str(base)
|
||||
|
||||
# Special case because base classes are in std lib:
|
||||
if "StringEnum" in base == "<enum 'StringEnum'>":
|
||||
bases[idx] = ":class:`enum.Enum`"
|
||||
bases.insert(0, ":class:`str`")
|
||||
continue
|
||||
|
||||
# Drop generics (at least for now)
|
||||
if base.endswith("]"):
|
||||
base = base.split("[", maxsplit=1)[0]
|
||||
bases[idx] = f":class:`{base}`"
|
||||
|
||||
# Now convert `telegram._message.Message` to `telegram.Message` etc
|
||||
match = re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base)
|
||||
if not match or "_utils" in base:
|
||||
return
|
||||
|
||||
parts = match.group(0).split(".")
|
||||
|
||||
# Remove private paths
|
||||
for index, part in enumerate(parts):
|
||||
if part.startswith("_"):
|
||||
parts = parts[:index] + parts[-1:]
|
||||
break
|
||||
|
||||
# Replace private base classes with their respective parent
|
||||
parts = [PRIVATE_BASE_CLASSES.get(part, part) for part in parts]
|
||||
|
||||
base = ".".join(parts)
|
||||
|
||||
bases[idx] = f":class:`{base}`"
|
||||
# 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 (
|
||||
autodoc_process_bases,
|
||||
autodoc_process_docstring,
|
||||
autodoc_skip_member,
|
||||
)
|
||||
from docs.auxil.tg_const_role import CONSTANTS_ROLE, TGConstXRefRole
|
||||
|
||||
|
||||
def setup(app: Sphinx):
|
||||
|
||||
@@ -40,6 +40,7 @@ up a job to send a message to that user after 30 seconds. The user can
|
||||
also cancel the timer by sending ``/unset``. To learn more about the
|
||||
``JobQueue``, read `this wiki
|
||||
article <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions-%E2%80%93-JobQueue>`__.
|
||||
Note: To use ``JobQueue``, you must install PTB via ``pip install python-telegram-bot[job-queue]``
|
||||
|
||||
:any:`examples.conversationbot`
|
||||
-------------------------------
|
||||
@@ -49,7 +50,7 @@ this library, we introduced the
|
||||
:class:`telegram.ext.ConversationHandler`
|
||||
for that exact purpose. This example uses it to retrieve
|
||||
user-information in a conversation-like style. To get a better
|
||||
understanding, take a look at the :ref:`state diagrem <conversationbot-diagram>`.
|
||||
understanding, take a look at the :ref:`state diagram <conversationbot-diagram>`.
|
||||
|
||||
:any:`examples.conversationbot2`
|
||||
--------------------------------
|
||||
@@ -115,6 +116,7 @@ Don’t forget to enable and configure payments with
|
||||
`@BotFather <https://telegram.me/BotFather>`_. Check out this
|
||||
`guide <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Telegram-Passport>`__
|
||||
on Telegram passports in PTB.
|
||||
Note: To use Telegram Passport, you must install PTB via ``pip install python-telegram-bot[passport]``
|
||||
|
||||
:any:`examples.paymentbot`
|
||||
--------------------------
|
||||
@@ -162,6 +164,7 @@ combination with ``telegram.ext.Application``.
|
||||
|
||||
This example showcases how PTBs “arbitrary callback data” feature can be
|
||||
used.
|
||||
Note: To use arbitrary callback data, you must install PTB via ``pip install python-telegram-bot[callback-data]``
|
||||
|
||||
Pure API
|
||||
--------
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.. tip::
|
||||
When combining ``python-telegram-bot`` with other :mod:`asyncio` based frameworks, using this
|
||||
method is likely not the best choice, as it blocks the event loop until it receives a stop
|
||||
signal as described above.
|
||||
Instead, you can manually call the methods listed below to start and shut down the application
|
||||
and the :attr:`~telegram.ext.Application.updater`.
|
||||
Keeping the event loop running and listening for a stop signal is then up to you.
|
||||
@@ -206,6 +206,8 @@
|
||||
- Used for getting a sticker set
|
||||
* - :meth:`~telegram.Bot.upload_sticker_file`
|
||||
- Used for uploading a sticker file
|
||||
* - :meth:`~telegram.Bot.get_custom_emoji_stickers`
|
||||
- Used for getting custom emoji files based on their IDs
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@@ -254,6 +256,45 @@
|
||||
</details>
|
||||
<br>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>Forum topic management</summary>
|
||||
|
||||
.. list-table::
|
||||
:align: left
|
||||
:widths: 1 4
|
||||
|
||||
* - :meth:`~telegram.Bot.close_forum_topic`
|
||||
- Used for closing a forum topic
|
||||
* - :meth:`~telegram.Bot.close_general_forum_topic`
|
||||
- Used for closing the general forum topic
|
||||
* - :meth:`~telegram.Bot.create_forum_topic`
|
||||
- Used to create a topic
|
||||
* - :meth:`~telegram.Bot.delete_forum_topic`
|
||||
- Used for deleting a forum topic
|
||||
* - :meth:`~telegram.Bot.edit_forum_topic`
|
||||
- Used to edit a topic
|
||||
* - :meth:`~telegram.Bot.edit_general_forum_topic`
|
||||
- Used to edit the general topic
|
||||
* - :meth:`~telegram.Bot.get_forum_topic_icon_stickers`
|
||||
- Used to get custom emojis to use as topic icons
|
||||
* - :meth:`~telegram.Bot.hide_general_forum_topic`
|
||||
- Used to hide the general topic
|
||||
* - :meth:`~telegram.Bot.unhide_general_forum_topic`
|
||||
- Used to unhide the general topic
|
||||
* - :meth:`~telegram.Bot.reopen_forum_topic`
|
||||
- Used to reopen a topic
|
||||
* - :meth:`~telegram.Bot.reopen_general_forum_topic`
|
||||
- Used to reopen the general topic
|
||||
* - :meth:`~telegram.Bot.unpin_all_forum_topic_messages`
|
||||
- Used to unpin all messages in a forum topic
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
@@ -288,6 +329,10 @@
|
||||
:align: left
|
||||
:widths: 1 4
|
||||
|
||||
* - :attr:`~telegram.Bot.base_file_url`
|
||||
- Telegram Bot API file URL
|
||||
* - :attr:`~telegram.Bot.base_url`
|
||||
- Telegram Bot API service URL
|
||||
* - :attr:`~telegram.Bot.bot`
|
||||
- The user instance of the bot as returned by :meth:`~telegram.Bot.get_me`
|
||||
* - :attr:`~telegram.Bot.can_join_groups`
|
||||
@@ -302,12 +347,18 @@
|
||||
- The first name of the bot
|
||||
* - :attr:`~telegram.Bot.last_name`
|
||||
- The last name of the bot
|
||||
* - :attr:`~telegram.Bot.local_mode`
|
||||
- Whether the bot is running in local mode
|
||||
* - :attr:`~telegram.Bot.username`
|
||||
- The username of the bot, without leading ``@``
|
||||
* - :attr:`~telegram.Bot.link`
|
||||
- The t.me link of the bot
|
||||
* - :attr:`~telegram.Bot.private_key`
|
||||
- Deserialized private key for decryption of telegram passport data
|
||||
* - :attr:`~telegram.Bot.supports_inline_queries`
|
||||
- Whether the bot supports inline queries
|
||||
* - :attr:`~telegram.Bot.token`
|
||||
- Bot's unique authentication token
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.. raw:: html
|
||||
|
||||
<center><video height="300px" loop autoplay muted><source src="https://core.telegram.org/file/464001555/10fbd/jvTuV2Ke7WQ.1916669.mp4/a056de323645db409d" type="video/mp4"></video></center>
|
||||
@@ -0,0 +1,10 @@
|
||||
.. tip::
|
||||
When making requests to the Bot API in an asynchronous fashion (e.g. via
|
||||
:attr:`block=False <telegram.ext.BaseHandler.block>`, :meth:`Application.create_task <telegram.ext.Application.create_task>`,
|
||||
:meth:`~telegram.ext.ApplicationBuilder.concurrent_updates` or the :class:`~telegram.ext.JobQueue`), it can happen that more requests
|
||||
are being made in parallel than there are connections in the pool.
|
||||
If the number of requests is much higher than the number of connections, even setting
|
||||
:meth:`~telegram.ext.ApplicationBuilder.pool_timeout` to a larger value may not always be enough to prevent pool
|
||||
timeouts.
|
||||
You should therefore set :meth:`~telegram.ext.ApplicationBuilder.concurrent_updates`, :meth:`~telegram.ext.ApplicationBuilder.connection_pool_size` and
|
||||
:meth:`~telegram.ext.ApplicationBuilder.pool_timeout` to values that make sense for your setup.
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Animation
|
||||
==================
|
||||
Animation
|
||||
=========
|
||||
|
||||
.. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
Available Types
|
||||
---------------
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
telegram.animation
|
||||
telegram.audio
|
||||
telegram.botcommand
|
||||
telegram.botcommandscope
|
||||
telegram.botcommandscopeallchatadministrators
|
||||
telegram.botcommandscopeallgroupchats
|
||||
telegram.botcommandscopeallprivatechats
|
||||
telegram.botcommandscopechat
|
||||
telegram.botcommandscopechatadministrators
|
||||
telegram.botcommandscopechatmember
|
||||
telegram.botcommandscopedefault
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chatadministratorrights
|
||||
telegram.chatinvitelink
|
||||
telegram.chatjoinrequest
|
||||
telegram.chatlocation
|
||||
telegram.chatmember
|
||||
telegram.chatmemberadministrator
|
||||
telegram.chatmemberbanned
|
||||
telegram.chatmemberleft
|
||||
telegram.chatmembermember
|
||||
telegram.chatmemberowner
|
||||
telegram.chatmemberrestricted
|
||||
telegram.chatmemberupdated
|
||||
telegram.chatpermissions
|
||||
telegram.chatphoto
|
||||
telegram.chatshared
|
||||
telegram.contact
|
||||
telegram.dice
|
||||
telegram.document
|
||||
telegram.file
|
||||
telegram.forcereply
|
||||
telegram.forumtopic
|
||||
telegram.forumtopicclosed
|
||||
telegram.forumtopiccreated
|
||||
telegram.forumtopicedited
|
||||
telegram.forumtopicreopened
|
||||
telegram.generalforumtopichidden
|
||||
telegram.generalforumtopicunhidden
|
||||
telegram.inlinekeyboardbutton
|
||||
telegram.inlinekeyboardmarkup
|
||||
telegram.inputfile
|
||||
telegram.inputmedia
|
||||
telegram.inputmediaanimation
|
||||
telegram.inputmediaaudio
|
||||
telegram.inputmediadocument
|
||||
telegram.inputmediaphoto
|
||||
telegram.inputmediavideo
|
||||
telegram.keyboardbutton
|
||||
telegram.keyboardbuttonpolltype
|
||||
telegram.keyboardbuttonrequestchat
|
||||
telegram.keyboardbuttonrequestuser
|
||||
telegram.location
|
||||
telegram.loginurl
|
||||
telegram.menubutton
|
||||
telegram.menubuttoncommands
|
||||
telegram.menubuttondefault
|
||||
telegram.menubuttonwebapp
|
||||
telegram.message
|
||||
telegram.messageautodeletetimerchanged
|
||||
telegram.messageentity
|
||||
telegram.messageid
|
||||
telegram.photosize
|
||||
telegram.poll
|
||||
telegram.pollanswer
|
||||
telegram.polloption
|
||||
telegram.proximityalerttriggered
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replykeyboardremove
|
||||
telegram.sentwebappmessage
|
||||
telegram.telegramobject
|
||||
telegram.update
|
||||
telegram.user
|
||||
telegram.userprofilephotos
|
||||
telegram.usershared
|
||||
telegram.venue
|
||||
telegram.video
|
||||
telegram.videochatended
|
||||
telegram.videochatparticipantsinvited
|
||||
telegram.videochatscheduled
|
||||
telegram.videochatstarted
|
||||
telegram.videonote
|
||||
telegram.voice
|
||||
telegram.webappdata
|
||||
telegram.webappinfo
|
||||
telegram.webhookinfo
|
||||
telegram.writeaccessallowed
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Audio
|
||||
==============
|
||||
Audio
|
||||
=====
|
||||
|
||||
.. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
telegram.Bot
|
||||
============
|
||||
Bot
|
||||
===
|
||||
|
||||
.. autoclass:: telegram.Bot
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:show-inheritance:
|
||||
:special-members: __reduce__, __deepcopy__
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommand
|
||||
===================
|
||||
BotCommand
|
||||
==========
|
||||
|
||||
.. autoclass:: telegram.BotCommand
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScope
|
||||
========================
|
||||
BotCommandScope
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.BotCommandScope
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeAllChatAdministrators
|
||||
=============================================
|
||||
BotCommandScopeAllChatAdministrators
|
||||
====================================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeAllChatAdministrators
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeAllGroupChats
|
||||
=======================================
|
||||
BotCommandScopeAllGroupChats
|
||||
============================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeAllGroupChats
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeAllPrivateChats
|
||||
=======================================
|
||||
BotCommandScopeAllPrivateChats
|
||||
==============================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeAllPrivateChats
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeChat
|
||||
============================
|
||||
BotCommandScopeChat
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeChat
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeChatAdministrators
|
||||
==========================================
|
||||
BotCommandScopeChatAdministrators
|
||||
=================================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeChatAdministrators
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeChatMember
|
||||
==================================
|
||||
BotCommandScopeChatMember
|
||||
=========================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeChatMember
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.BotCommandScopeDefault
|
||||
===============================
|
||||
BotCommandScopeDefault
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.BotCommandScopeDefault
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Callbackgame
|
||||
=====================
|
||||
Callbackgame
|
||||
============
|
||||
|
||||
.. autoclass:: telegram.CallbackGame
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.CallbackQuery
|
||||
======================
|
||||
CallbackQuery
|
||||
=============
|
||||
|
||||
.. autoclass:: telegram.CallbackQuery
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Chat
|
||||
=============
|
||||
Chat
|
||||
====
|
||||
|
||||
.. autoclass:: telegram.Chat
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatAdministratorRights
|
||||
================================
|
||||
ChatAdministratorRights
|
||||
=======================
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatInviteLink
|
||||
=======================
|
||||
ChatInviteLink
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ChatInviteLink
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatJoinRequest
|
||||
========================
|
||||
ChatJoinRequest
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ChatJoinRequest
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatLocation
|
||||
=====================
|
||||
ChatLocation
|
||||
============
|
||||
|
||||
.. autoclass:: telegram.ChatLocation
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMember
|
||||
===================
|
||||
ChatMember
|
||||
==========
|
||||
|
||||
.. autoclass:: telegram.ChatMember
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberAdministrator
|
||||
================================
|
||||
ChatMemberAdministrator
|
||||
=======================
|
||||
|
||||
.. autoclass:: telegram.ChatMemberAdministrator
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberBanned
|
||||
=========================
|
||||
ChatMemberBanned
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.ChatMemberBanned
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberLeft
|
||||
=======================
|
||||
ChatMemberLeft
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ChatMemberLeft
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberMember
|
||||
=========================
|
||||
ChatMemberMember
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.ChatMemberMember
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberOwner
|
||||
========================
|
||||
ChatMemberOwner
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ChatMemberOwner
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberRestricted
|
||||
=============================
|
||||
ChatMemberRestricted
|
||||
====================
|
||||
|
||||
.. autoclass:: telegram.ChatMemberRestricted
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatMemberUpdated
|
||||
==========================
|
||||
ChatMemberUpdated
|
||||
=================
|
||||
|
||||
.. autoclass:: telegram.ChatMemberUpdated
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatPermissions
|
||||
========================
|
||||
ChatPermissions
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ChatPermissions
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChatPhoto
|
||||
==================
|
||||
ChatPhoto
|
||||
=========
|
||||
|
||||
.. autoclass:: telegram.ChatPhoto
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
ChatShared
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.ChatShared
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ChosenInlineResult
|
||||
===========================
|
||||
ChosenInlineResult
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.ChosenInlineResult
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Contact
|
||||
================
|
||||
Contact
|
||||
=======
|
||||
|
||||
.. autoclass:: telegram.Contact
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Credentials
|
||||
====================
|
||||
Credentials
|
||||
===========
|
||||
|
||||
.. autoclass:: telegram.Credentials
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.DataCredentials
|
||||
========================
|
||||
DataCredentials
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.DataCredentials
|
||||
:members:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
telegram.Dice
|
||||
=============
|
||||
Dice
|
||||
====
|
||||
|
||||
.. autoclass:: telegram.Dice
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.Document
|
||||
=================
|
||||
Document
|
||||
========
|
||||
.. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject
|
||||
|
||||
.. autoclass:: telegram.Document
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.EncryptedCredentials
|
||||
=============================
|
||||
EncryptedCredentials
|
||||
====================
|
||||
|
||||
.. autoclass:: telegram.EncryptedCredentials
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.EncryptedPassportElement
|
||||
=================================
|
||||
EncryptedPassportElement
|
||||
========================
|
||||
|
||||
.. autoclass:: telegram.EncryptedPassportElement
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Arbitrary Callback Data
|
||||
-----------------------
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
telegram.ext.callbackdatacache
|
||||
telegram.ext.invalidcallbackdata
|
||||
@@ -0,0 +1,6 @@
|
||||
AIORateLimiter
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ext.AIORateLimiter
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.Application
|
||||
========================
|
||||
Application
|
||||
===========
|
||||
|
||||
.. autoclass:: telegram.ext.Application
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ApplicationBuilder
|
||||
===============================
|
||||
ApplicationBuilder
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.ext.ApplicationBuilder
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ApplicationHandlerStop
|
||||
===================================
|
||||
ApplicationHandlerStop
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.ext.ApplicationHandlerStop
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.BaseHandler
|
||||
========================
|
||||
BaseHandler
|
||||
===========
|
||||
|
||||
.. autoclass:: telegram.ext.BaseHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.BasePersistence
|
||||
============================
|
||||
BasePersistence
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ext.BasePersistence
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
BaseRateLimiter
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ext.BaseRateLimiter
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.CallbackContext
|
||||
============================
|
||||
CallbackContext
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ext.CallbackContext
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.CallbackDataCache
|
||||
==============================
|
||||
CallbackDataCache
|
||||
=================
|
||||
|
||||
.. autoclass:: telegram.ext.CallbackDataCache
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.CallbackQueryHandler
|
||||
=================================
|
||||
CallbackQueryHandler
|
||||
====================
|
||||
|
||||
.. autoclass:: telegram.ext.CallbackQueryHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ChatJoinRequestHandler
|
||||
===================================
|
||||
ChatJoinRequestHandler
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.ext.ChatJoinRequestHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ChatMemberHandler
|
||||
==============================
|
||||
ChatMemberHandler
|
||||
=================
|
||||
|
||||
.. autoclass:: telegram.ext.ChatMemberHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ChosenInlineResultHandler
|
||||
======================================
|
||||
ChosenInlineResultHandler
|
||||
=========================
|
||||
|
||||
.. autoclass:: telegram.ext.ChosenInlineResultHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.CommandHandler
|
||||
===========================
|
||||
CommandHandler
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ext.CommandHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ContextTypes
|
||||
=========================
|
||||
ContextTypes
|
||||
============
|
||||
|
||||
.. autoclass:: telegram.ext.ContextTypes
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.ConversationHandler
|
||||
================================
|
||||
ConversationHandler
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.ext.ConversationHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.Defaults
|
||||
=====================
|
||||
Defaults
|
||||
========
|
||||
|
||||
.. autoclass:: telegram.ext.Defaults
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.DictPersistence
|
||||
============================
|
||||
DictPersistence
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.ext.DictPersistence
|
||||
:members:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
telegram.ext.ExtBot
|
||||
===================
|
||||
ExtBot
|
||||
======
|
||||
|
||||
.. autoclass:: telegram.ext.ExtBot
|
||||
:show-inheritance:
|
||||
|
||||
.. autofunction:: telegram.ext.ExtBot.insert_callback_data
|
||||
:members: insert_callback_data, defaults, rate_limiter, initialize, shutdown, callback_data_cache
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
telegram.ext.filters Module
|
||||
===========================
|
||||
filters Module
|
||||
==============
|
||||
|
||||
.. :bysource: since e.g filters.CHAT is much above filters.Chat() in the docs when it shouldn't.
|
||||
The classes in `filters.py` are sorted alphabetically such that :bysource: still is readable
|
||||
|
||||
.. automodule:: telegram.ext.filters
|
||||
:inherited-members:
|
||||
:inherited-members: BaseFilter, MessageFilter, UpdateFilter
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:member-order: bysource
|
||||
:member-order: bysource
|
||||
@@ -0,0 +1,24 @@
|
||||
Handlers
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
telegram.ext.basehandler
|
||||
telegram.ext.callbackqueryhandler
|
||||
telegram.ext.chatjoinrequesthandler
|
||||
telegram.ext.chatmemberhandler
|
||||
telegram.ext.choseninlineresulthandler
|
||||
telegram.ext.commandhandler
|
||||
telegram.ext.conversationhandler
|
||||
telegram.ext.filters
|
||||
telegram.ext.inlinequeryhandler
|
||||
telegram.ext.messagehandler
|
||||
telegram.ext.pollanswerhandler
|
||||
telegram.ext.pollhandler
|
||||
telegram.ext.precheckoutqueryhandler
|
||||
telegram.ext.prefixhandler
|
||||
telegram.ext.shippingqueryhandler
|
||||
telegram.ext.stringcommandhandler
|
||||
telegram.ext.stringregexhandler
|
||||
telegram.ext.typehandler
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.InlineQueryHandler
|
||||
===============================
|
||||
InlineQueryHandler
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.ext.InlineQueryHandler
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.InvalidCallbackData
|
||||
================================
|
||||
InvalidCallbackData
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.ext.InvalidCallbackData
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.Job
|
||||
=====================
|
||||
Job
|
||||
===
|
||||
|
||||
.. autoclass:: telegram.ext.Job
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.JobQueue
|
||||
=====================
|
||||
JobQueue
|
||||
========
|
||||
|
||||
.. autoclass:: telegram.ext.JobQueue
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.ext.MessageHandler
|
||||
===========================
|
||||
MessageHandler
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ext.MessageHandler
|
||||
:members:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user