mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 15:45:13 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ac52018c2 | |||
| ca7a30963d | |||
| c42a230b96 | |||
| ce9742a602 | |||
| 43279543a3 | |||
| eda2172617 | |||
| 89dfa37dbf | |||
| 3709c2fa93 | |||
| da93fe94ae | |||
| cec34e4bca | |||
| ffe23be992 | |||
| ef1685c436 | |||
| 151123745e | |||
| 0eb11ff3e9 | |||
| dab75fb963 | |||
| 62f89758d7 | |||
| 7a8f4412b2 | |||
| 032a859149 | |||
| 507d6bc0e3 | |||
| bd6a60bb30 | |||
| 3c8f6ed42b | |||
| 6540f288f5 | |||
| 5ab82a9c2b | |||
| 847b97f86e | |||
| efacc3dd1b | |||
| 2ce687c8f1 | |||
| a39a59ee9b | |||
| 06854633ab | |||
| 9a8b208ef7 | |||
| 2f06902518 | |||
| 2bc65560eb | |||
| 79e589b39e | |||
| bd3cdbcdbd | |||
| 9709c03b35 | |||
| 3409f51107 | |||
| 2eae2830f3 | |||
| 28d19c3b9a | |||
| e314e78d06 | |||
| 67a97ae5a7 | |||
| 9248c539d0 | |||
| 6b5e46cc08 | |||
| b3155b2e55 | |||
| ec909e62cf | |||
| 1223e851c3 | |||
| 0b352b043e | |||
| b9d2efdec5 |
@@ -1,7 +1,7 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: ["bug :bug:"]
|
||||
labels: ["📋 triage"]
|
||||
type: '🐛 bug'
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for this project
|
||||
title: "[FEATURE]"
|
||||
labels: ["enhancement"]
|
||||
labels: ["📋 triage"]
|
||||
type: '💡 feature'
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Question
|
||||
description: Get help with errors or general questions
|
||||
title: "[QUESTION]"
|
||||
labels: ["question"]
|
||||
type: '❔ question'
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
version: 1
|
||||
|
||||
labels:
|
||||
- label: "dependencies"
|
||||
- label: "⚙️ dependencies"
|
||||
authors: ["dependabot[bot]", "pre-commit-ci[bot]"]
|
||||
- label: "code quality ✨"
|
||||
- label: "🛠 code-quality"
|
||||
authors: ["pre-commit-ci[bot]"]
|
||||
|
||||
@@ -3,6 +3,9 @@ on:
|
||||
schedule:
|
||||
# First day of month at 05:46 in every 2nd month
|
||||
- cron: '46 5 1 */2 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/docs-linkcheck.yml
|
||||
|
||||
jobs:
|
||||
test-sphinx-build:
|
||||
@@ -10,7 +13,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.10]
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
pull-requests: write # for srvaroa/labeler to add labels in PR
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: srvaroa/labeler@v1.10.1
|
||||
- uses: srvaroa/labeler@v1.12.0
|
||||
# Config file at .github/labeler.yml
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
days-before-stale: 3
|
||||
days-before-close: 2
|
||||
days-before-pr-stale: -1
|
||||
stale-issue-label: 'stale'
|
||||
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.'
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
name: test-type-completeness
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Bibo-Joshi/pyright-type-completeness@1.0.0
|
||||
- uses: Bibo-Joshi/pyright-type-completeness@1.0.1
|
||||
with:
|
||||
package-name: telegram
|
||||
python-version: 3.12
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Check Type Completeness Monthly Run
|
||||
on:
|
||||
schedule:
|
||||
# Run first friday of the month at 03:17 - odd time to spread load on GitHub Actions
|
||||
- cron: '17 3 1-7 * 5'
|
||||
|
||||
jobs:
|
||||
test-type-completeness:
|
||||
name: test-type-completeness
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Bibo-Joshi/pyright-type-completeness@1.0.1
|
||||
id: pyright-type-completeness
|
||||
with:
|
||||
package-name: telegram
|
||||
python-version: 3.12
|
||||
pyright-version: ~=1.1.367
|
||||
- name: Check Output
|
||||
uses: jannekem/run-python-script-action@v1
|
||||
env:
|
||||
TYPE_COMPLETENESS: ${{ steps.pyright-type-completeness.outputs.base-completeness-score }}
|
||||
with:
|
||||
script: |
|
||||
import os
|
||||
completeness = float(os.getenv("TYPE_COMPLETENESS"))
|
||||
|
||||
if completeness >= 1:
|
||||
exit(0)
|
||||
|
||||
text = f"Type Completeness Decreased to {completeness}. ❌"
|
||||
error(text)
|
||||
set_summary(text)
|
||||
exit(1)
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.0-rc.1']
|
||||
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
python -W ignore -m pip install -U pytest-cov
|
||||
python -W ignore -m pip install .
|
||||
python -W ignore -m pip install -r requirements-unit-tests.txt
|
||||
python -W ignore -m pip install pytest-xdist[psutil]
|
||||
python -W ignore -m pip install pytest-xdist
|
||||
|
||||
- name: Test with pytest
|
||||
# We run 4 different suites here
|
||||
@@ -57,21 +57,17 @@ jobs:
|
||||
# - without socks support
|
||||
# - without http2 support
|
||||
TO_TEST="test_no_passport.py or test_datetime.py or test_defaults.py or test_jobqueue.py or test_applicationbuilder.py or test_ratelimiter.py or test_updater.py or test_callbackdatacache.py or test_request.py"
|
||||
pytest -v --cov -k "${TO_TEST}"
|
||||
# Rerun only failed tests (--lf), and don't run any tests if none failed (--lfnf=none)
|
||||
pytest -v --cov --cov-append -k "${TO_TEST}" --lf --lfnf=none --junit-xml=.test_report_no_optionals.xml
|
||||
# No tests were selected, convert returned status code to 0
|
||||
opt_dep_status=$(( $? == 5 ? 0 : $? ))
|
||||
pytest -v --cov -k "${TO_TEST}" --junit-xml=.test_report_no_optionals_junit.xml
|
||||
opt_dep_status=$?
|
||||
|
||||
# Test the rest
|
||||
export TEST_WITH_OPT_DEPS='true'
|
||||
pip install .[all]
|
||||
# `-n auto --dist loadfile` uses pytest-xdist to run each test file on a different CPU
|
||||
# worker. Increasing number of workers has little effect on test duration, but it seems
|
||||
# to increase flakyness, specially on python 3.7 with --dist=loadgroup.
|
||||
pytest -v --cov --cov-append -n auto --dist loadfile
|
||||
pytest -v --cov --cov-append -n auto --dist loadfile --lf --lfnf=none --junit-xml=.test_report_optionals.xml
|
||||
main_status=$(( $? == 5 ? 0 : $? ))
|
||||
# `-n auto --dist worksteal` uses pytest-xdist to run tests on multiple CPU
|
||||
# workers. Increasing number of workers has little effect on test duration, but it seems
|
||||
# to increase flakyness.
|
||||
pytest -v --cov --cov-append -n auto --dist worksteal --junit-xml=.test_report_optionals_junit.xml
|
||||
main_status=$?
|
||||
# exit with non-zero status if any of the two pytest runs failed
|
||||
exit $(( ${opt_dep_status} || ${main_status} ))
|
||||
env:
|
||||
@@ -87,13 +83,19 @@ jobs:
|
||||
if: always() # always run, even if tests fail
|
||||
with:
|
||||
paths: |
|
||||
.test_report_no_optionals.xml
|
||||
.test_report_optionals.xml
|
||||
.test_report_no_optionals_junit.xml
|
||||
.test_report_optionals_junit.xml
|
||||
|
||||
- name: Submit coverage
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
env_vars: OS,PYTHON
|
||||
name: ${{ matrix.os }}-${{ matrix.python-version }}
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
- name: Upload test results to Codecov
|
||||
uses: codecov/test-results-action@v1
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
files: .test_report_no_optionals_junit.xml,.test_report_optionals_junit.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -16,7 +16,7 @@ repos:
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- aiolimiter~=1.1.0
|
||||
- aiolimiter~=1.1,<1.3
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 24.4.2
|
||||
hooks:
|
||||
@@ -29,7 +29,7 @@ repos:
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v3.2.4
|
||||
rev: v3.3.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(?!(tests|docs)).*\.py$
|
||||
@@ -38,7 +38,7 @@ repos:
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- aiolimiter~=1.1.0
|
||||
- aiolimiter~=1.1,<1.3
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.10.1
|
||||
@@ -54,7 +54,7 @@ repos:
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- aiolimiter~=1.1.0
|
||||
- aiolimiter~=1.1,<1.3
|
||||
- . # this basically does `pip install -e .`
|
||||
- id: mypy
|
||||
name: mypy-examples
|
||||
@@ -72,7 +72,7 @@ repos:
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args:
|
||||
- --py38-plus
|
||||
- --py39-plus
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.13.2
|
||||
hooks:
|
||||
|
||||
@@ -23,6 +23,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
|
||||
- `Abdelrahman <https://github.com/aelkheir>`_
|
||||
- `Abshar <https://github.com/abxhr>`_
|
||||
- `Abubakar Alaya <https://github.com/Ecode2>`_
|
||||
- `Alateas <https://github.com/alateas>`_
|
||||
- `Ales Dokshanin <https://github.com/alesdokshanin>`_
|
||||
- `Alexandre <https://github.com/xTudoS>`_
|
||||
@@ -80,6 +81,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `LRezende <https://github.com/lrezende>`_
|
||||
- `Luca Bellanti <https://github.com/Trifase>`_
|
||||
- `Lucas Molinari <https://github.com/lucasmolinari>`_
|
||||
- `Luis Pérez <https://github.com/nemacysts>`_
|
||||
- `macrojames <https://github.com/macrojames>`_
|
||||
- `Matheus Lemos <https://github.com/mlemosf>`_
|
||||
- `Michael Dix <https://github.com/Eisberge>`_
|
||||
@@ -110,11 +112,13 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Rahiel Kasim <https://github.com/rahiel>`_
|
||||
- `Riko Naka <https://github.com/rikonaka>`_
|
||||
- `Rizlas <https://github.com/rizlas>`_
|
||||
- `Snehashish Biswas <https://github.com/Snehashish06>`_
|
||||
- `Sahil Sharma <https://github.com/sahilsharma811>`_
|
||||
- `Sam Mosleh <https://github.com/sam-mosleh>`_
|
||||
- `Sascha <https://github.com/saschalalala>`_
|
||||
- `Shelomentsev D <https://github.com/shelomentsevd>`_
|
||||
- `Shivam Saini <https://github.com/shivamsn97>`_
|
||||
- `Siloé Garcez <https://github.com/roast-lord>`_
|
||||
- `Simon Schürrle <https://github.com/SitiSchu>`_
|
||||
- `sooyhwang <https://github.com/sooyhwang>`_
|
||||
- `syntx <https://github.com/syntx>`_
|
||||
|
||||
+124
@@ -4,6 +4,130 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 21.9
|
||||
============
|
||||
|
||||
*Released 2024-12-07*
|
||||
|
||||
This is the technical changelog for version 21.9. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 8.1 (:pr:`4594` closes :issue:`4592`)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Use ``MessageLimit.DEEP_LINK_LENGTH`` in ``helpers.create_deep_linked_url`` (:pr:`4597` by `nemacysts <https://github.com/nemacysts>`_)
|
||||
- Allow ``Sequence`` Input for ``allowed_updates`` in ``Application`` and ``Updater`` Methods (:pr:`4589` by `nemacysts <https://github.com/nemacysts>`_)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Update ``aiolimiter`` requirement from ~=1.1.0 to >=1.1,<1.3 (:pr:`4595`)
|
||||
- Bump ``pytest`` from 8.3.3 to 8.3.4 (:pr:`4596`)
|
||||
- Bump ``codecov/codecov-action`` from 4 to 5 (:pr:`4585`)
|
||||
- Bump ``pylint`` to v3.3.2 to Improve Python 3.13 Support (:pr:`4590` by `nemacysts <https://github.com/nemacysts>`_)
|
||||
- Bump ``srvaroa/labeler`` from 1.11.1 to 1.12.0 (:pr:`4586`)
|
||||
|
||||
Version 21.8
|
||||
============
|
||||
*Released 2024-12-01*
|
||||
|
||||
This is the technical changelog for version 21.8. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 8.0 (:pr:`4568`, :pr:`4566` closes :issue:`4567`, :pr:`4572`, :pr:`4571`, :pr:`4570`, :pr:`4576`, :pr:`4574`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Documentation Improvements (:pr:`4565` by `Snehashish06 <https://github.com/Snehashish06>`_, :pr:`4573`)
|
||||
|
||||
Version 21.7
|
||||
============
|
||||
*Released 2024-11-04*
|
||||
|
||||
This is the technical changelog for version 21.7. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 7.11 (:pr:`4546` closes :issue:`4543`)
|
||||
- Add ``Message.reply_paid_media`` (:pr:`4551`)
|
||||
- Drop Support for Python 3.8 (:pr:`4398` by `elpekenin <https://github.com/elpekenin>`_)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Allow ``Sequence`` in ``Application.add_handlers`` (:pr:`4531` by `roast-lord <https://github.com/roast-lord>`_ closes :issue:`4530`)
|
||||
- Improve Exception Handling in ``File.download_*`` (:pr:`4542`)
|
||||
- Use Stable Python 3.13 Release in Test Suite (:pr:`4535`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Documentation Improvements (:pr:`4536` by `Ecode2 <https://github.com/Ecode2>`_, :pr:`4556`)
|
||||
- Fix Linkcheck Workflow (:pr:`4545`)
|
||||
- Use ``sphinx-build-compatibility`` to Keep Sphinx Compatibility (:pr:`4492`)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Improve Test Instability Caused by ``Message`` Fixtures (:pr:`4507`)
|
||||
- Stabilize Some Flaky Tests (:pr:`4500`)
|
||||
- Reduce Creation of HTTP Clients in Tests (:pr:`4493`)
|
||||
- Update ``pytest-xdist`` Usage (:pr:`4491`)
|
||||
- Fix Failing Tests by Making Them Independent (:pr:`4494`)
|
||||
- Introduce Codecov's Test Analysis (:pr:`4487`)
|
||||
- Maintenance Work on ``Bot`` Tests (:pr:`4489`)
|
||||
- Introduce ``conftest.py`` for File Related Tests (:pr:`4488`)
|
||||
- Update Issue Templates to Use Issue Types (:pr:`4553`)
|
||||
- Update Automation to Label Changes (:pr:`4552`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Bump ``srvaroa/labeler`` from 1.11.0 to 1.11.1 (:pr:`4549`)
|
||||
- Bump ``sphinx`` from 8.0.2 to 8.1.3 (:pr:`4532`)
|
||||
- Bump ``sphinxcontrib-mermaid`` from 0.9.2 to 1.0.0 (:pr:`4529`)
|
||||
- Bump ``srvaroa/labeler`` from 1.10.1 to 1.11.0 (:pr:`4509`)
|
||||
- Bump ``Bibo-Joshi/pyright-type-completeness`` from 1.0.0 to 1.0.1 (:pr:`4510`)
|
||||
|
||||
Version 21.6
|
||||
============
|
||||
|
||||
*Released 2024-09-19*
|
||||
|
||||
This is the technical changelog for version 21.6. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Full Support for Bot API 7.10 (:pr:`4461` closes :issue:`4459`, :pr:`4460`, :pr:`4463` by `aelkheir <https://github.com/aelkheir>`_, :pr:`4464`)
|
||||
- Add Parameter ``httpx_kwargs`` to ``HTTPXRequest`` (:pr:`4451` closes :issue:`4424`)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Improve Type Completeness (:pr:`4466`)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Update Python 3.13 Test Suite to RC2 (:pr:`4471`)
|
||||
- Enforce the ``offline_bot`` Fixture in ``Test*WithoutRequest`` (:pr:`4465`)
|
||||
- Make Tests for ``telegram.ext`` Independent of Networking (:pr:`4454`)
|
||||
- Rename Testing Base Classes (:pr:`4453`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Bump ``pytest`` from 8.3.2 to 8.3.3 (:pr:`4475`)
|
||||
|
||||
Version 21.5
|
||||
============
|
||||
|
||||
|
||||
+7
-7
@@ -11,7 +11,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.9-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-8.1-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API version
|
||||
|
||||
@@ -70,7 +70,7 @@ Introduction
|
||||
|
||||
This library provides a pure Python, asynchronous interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions **3.8+**.
|
||||
It's compatible with Python versions **3.9+**.
|
||||
|
||||
In addition to the pure API implementation, this library features several convenience methods and shortcuts as well as a number of high-level classes to
|
||||
make the development of bots easy and straightforward. These classes are contained in the
|
||||
@@ -81,7 +81,7 @@ After installing_ the library, be sure to check out the section on `working with
|
||||
Telegram API support
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All types and methods of the Telegram Bot API **7.9** are natively supported by this library.
|
||||
All types and methods of the Telegram Bot API **8.1** are natively supported by this library.
|
||||
In addition, Bot API functionality not yet natively included can still be used as described `in our wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Bot-API-Forward-Compatibility>`_.
|
||||
|
||||
Notable Features
|
||||
@@ -121,7 +121,7 @@ To enable you to verify that a release file that you downloaded was indeed provi
|
||||
|
||||
Starting with v21.4, all releases are signed via `sigstore <https://www.sigstore.dev>`_.
|
||||
The corresponding signature files are uploaded to the `GitHub releases page`_.
|
||||
To verify the signature, please install the `sigstore Python client <https://pypi.org/project/sigstore/>`_ and follow the instructions for `verifying signatures from GitHub Actions <https://github.com/sigstore/sigstore-python#signatures-from-github-actions>`_. As input for the ``--repository`` parameter, please use the value ``python-telegram-bot/python-telegram-bot``.
|
||||
To verify the signature, please install the `sigstore Python client <https://pypi.org/project/sigstore/>`_ and follow the instructions for `verifying signatures from GitHub Actions <https://github.com/sigstore/sigstore-python?tab=readme-ov-file>`_. As input for the ``--repository`` parameter, please use the value ``python-telegram-bot/python-telegram-bot``.
|
||||
|
||||
Earlier releases are signed with a GPG key.
|
||||
The signatures are uploaded to both the `GitHub releases page`_ and the `PyPI project <https://pypi.org/project/python-telegram-bot/>`_ and end with a suffix ``.asc``.
|
||||
@@ -155,7 +155,7 @@ PTB can be installed with optional dependencies:
|
||||
* ``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[http2]"`` installs `httpx[http2] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to use HTTP/2.
|
||||
* ``pip install "python-telegram-bot[rate-limiter]"`` installs `aiolimiter~=1.1.0 <https://aiolimiter.readthedocs.io/en/stable/>`_. Use this, if you want to use ``telegram.ext.AIORateLimiter``.
|
||||
* ``pip install "python-telegram-bot[rate-limiter]"`` installs `aiolimiter~=1.1,<1.3 <https://aiolimiter.readthedocs.io/en/stable/>`_. Use this, if you want to use ``telegram.ext.AIORateLimiter``.
|
||||
* ``pip install "python-telegram-bot[webhooks]"`` installs the `tornado~=6.4 <https://www.tornadoweb.org/en/stable/>`_ library. Use this, if you want to use ``telegram.ext.Updater.start_webhook``/``telegram.ext.Application.run_webhook``.
|
||||
* ``pip install "python-telegram-bot[callback-data]"`` installs the `cachetools>=5.3.3,<5.6.0 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
|
||||
* ``pip install "python-telegram-bot[job-queue]"`` installs the `APScheduler~=3.10.4 <https://apscheduler.readthedocs.io/en/3.x/>`_ library and enforces `pytz>=2018.6 <https://pypi.org/project/pytz/>`_, where ``pytz`` is a dependency of ``APScheduler``. Use this, if you want to use the ``telegram.ext.JobQueue``.
|
||||
@@ -230,6 +230,6 @@ License
|
||||
-------
|
||||
|
||||
You may copy, distribute and modify the software provided that modifications are described and licensed for free under `LGPL-3 <https://www.gnu.org/licenses/lgpl-3.0.html>`_.
|
||||
Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under LGPL-3, but applications that use the library don't have to be.
|
||||
Derivative works (including modifications or anything statically linked to the library) can only be redistributed under LGPL-3, but applications that use the library don't have to be.
|
||||
|
||||
.. _`GitHub releases page`: https://github.com/python-telegram-bot/python-telegram-bot/releases>
|
||||
.. _`GitHub releases page`: https://github.com/python-telegram-bot/python-telegram-bot/releases
|
||||
|
||||
@@ -20,7 +20,8 @@ import inspect
|
||||
import re
|
||||
import typing
|
||||
from collections import defaultdict
|
||||
from typing import Any, Iterator, Union
|
||||
from collections.abc import Iterator
|
||||
from typing import Any, Union
|
||||
|
||||
import telegram
|
||||
import telegram.ext
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import inspect
|
||||
from typing import List
|
||||
|
||||
keyword_args = [
|
||||
"Keyword Arguments:",
|
||||
@@ -85,7 +84,7 @@ get_updates_read_timeout_addition = [
|
||||
]
|
||||
|
||||
|
||||
def find_insert_pos_for_kwargs(lines: List[str]) -> int:
|
||||
def find_insert_pos_for_kwargs(lines: list[str]) -> int:
|
||||
"""Finds the correct position to insert the keyword arguments and returns the index."""
|
||||
for idx, value in reversed(list(enumerate(lines))): # reversed since :returns: is at the end
|
||||
if value.startswith("Returns"):
|
||||
|
||||
@@ -21,7 +21,6 @@ https://github.com/sphinx-doc/sphinx/issues/1556 is closed
|
||||
"""
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Dict, Tuple
|
||||
|
||||
from sphinx.util import logging
|
||||
|
||||
@@ -32,7 +31,7 @@ sphinx_logger = logging.getLogger(__name__)
|
||||
|
||||
# must be a module-level variable so that it can be written to by the `autodoc-process-docstring`
|
||||
# event handler in `sphinx_hooks.py`
|
||||
LINE_NUMBERS: Dict[str, Tuple[Path, int, int]] = {}
|
||||
LINE_NUMBERS: dict[str, tuple[Path, int, int]] = {}
|
||||
|
||||
|
||||
def _git_branch() -> str:
|
||||
|
||||
@@ -187,6 +187,11 @@ def autodoc_process_bases(app, name, obj, option, bases: list) -> None:
|
||||
bases[idx] = ":class:`enum.IntEnum`"
|
||||
continue
|
||||
|
||||
if "FloatEnum" in base:
|
||||
bases[idx] = ":class:`enum.Enum`"
|
||||
bases.insert(0, ":class:`float`")
|
||||
continue
|
||||
|
||||
# Drop generics (at least for now)
|
||||
if base.endswith("]"):
|
||||
base = base.split("[", maxsplit=1)[0]
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
sphinx==8.0.2
|
||||
sphinx==8.1.3
|
||||
furo==2024.8.6
|
||||
furo-sphinx-search @ git+https://github.com/harshil21/furo-sphinx-search@v0.2.0.1
|
||||
sphinx-paramlinks==0.6.0
|
||||
sphinxcontrib-mermaid==0.9.2
|
||||
sphinxcontrib-mermaid==1.0.0
|
||||
sphinx-copybutton==0.5.2
|
||||
sphinx-inline-tabs==2023.4.21
|
||||
sphinx-inline-tabs==2023.4.21
|
||||
# Temporary. See #4387
|
||||
sphinx-build-compatibility @ git+https://github.com/readthedocs/sphinx-build-compatibility.git@58aabc5f207c6c2421f23d3578adc0b14af57047
|
||||
|
||||
+5
-1
@@ -30,7 +30,7 @@ version = telegram.__version__
|
||||
release = telegram.__version__
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "8.0.2"
|
||||
needs_sphinx = "8.1.3"
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@@ -48,6 +48,10 @@ extensions = [
|
||||
"sphinx_search.extension",
|
||||
]
|
||||
|
||||
# Temporary. See #4387
|
||||
if os.environ.get("READTHEDOCS", "") == "True":
|
||||
extensions.append("sphinx_build_compatibility.extension")
|
||||
|
||||
# For shorter links to Wiki in docstrings
|
||||
extlinks = {
|
||||
"wiki": ("https://github.com/python-telegram-bot/python-telegram-bot/wiki/%s", "%s"),
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
- Used for sending documents
|
||||
* - :meth:`~telegram.Bot.send_game`
|
||||
- Used for sending a game
|
||||
* - :meth:`~telegram.Bot.send_gift`
|
||||
- Used for sending a gift
|
||||
* - :meth:`~telegram.Bot.send_invoice`
|
||||
- Used for sending an invoice
|
||||
* - :meth:`~telegram.Bot.send_location`
|
||||
@@ -151,6 +153,8 @@
|
||||
- Used for setting a chat title
|
||||
* - :meth:`~telegram.Bot.set_chat_description`
|
||||
- Used for setting the description of a chat
|
||||
* - :meth:`~telegram.Bot.set_user_emoji_status`
|
||||
- Used for setting the users status emoji
|
||||
* - :meth:`~telegram.Bot.pin_chat_message`
|
||||
- Used for pinning a message
|
||||
* - :meth:`~telegram.Bot.unpin_chat_message`
|
||||
@@ -355,7 +359,7 @@
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>Miscellaneous</summary>
|
||||
<summary>Payments and Stars</summary>
|
||||
|
||||
.. list-table::
|
||||
:align: left
|
||||
@@ -363,18 +367,39 @@
|
||||
|
||||
* - :meth:`~telegram.Bot.create_invoice_link`
|
||||
- Used to generate an HTTP link for an invoice
|
||||
* - :meth:`~telegram.Bot.edit_user_star_subscription`
|
||||
- Used for editing a user's star subscription
|
||||
* - :meth:`~telegram.Bot.get_star_transactions`
|
||||
- Used for obtaining the bot's Telegram Stars transactions
|
||||
* - :meth:`~telegram.Bot.refund_star_payment`
|
||||
- Used for refunding a payment in Telegram Stars
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>Miscellaneous</summary>
|
||||
|
||||
.. list-table::
|
||||
:align: left
|
||||
:widths: 1 4
|
||||
|
||||
* - :meth:`~telegram.Bot.close`
|
||||
- Used for closing server instance when switching to another local server
|
||||
* - :meth:`~telegram.Bot.log_out`
|
||||
- Used for logging out from cloud Bot API server
|
||||
* - :meth:`~telegram.Bot.get_file`
|
||||
- Used for getting basic info about a file
|
||||
* - :meth:`~telegram.Bot.get_available_gifts`
|
||||
- Used for getting information about gifts available for sending
|
||||
* - :meth:`~telegram.Bot.get_me`
|
||||
- Used for getting basic information about the bot
|
||||
* - :meth:`~telegram.Bot.get_star_transactions`
|
||||
- Used for obtaining the bot's Telegram Stars transactions
|
||||
* - :meth:`~telegram.Bot.refund_star_payment`
|
||||
- Used for refunding a payment in Telegram Stars
|
||||
* - :meth:`~telegram.Bot.save_prepared_inline_message`
|
||||
- Used for storing a message to be sent by a user of a Mini App
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
AffiliateInfo
|
||||
=============
|
||||
|
||||
.. autoclass:: telegram.AffiliateInfo
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -29,6 +29,7 @@ Available Types
|
||||
telegram.chat
|
||||
telegram.chatadministratorrights
|
||||
telegram.chatbackground
|
||||
telegram.copytextbutton
|
||||
telegram.backgroundtype
|
||||
telegram.backgroundtypefill
|
||||
telegram.backgroundtypewallpaper
|
||||
@@ -92,7 +93,6 @@ Available Types
|
||||
telegram.inputpaidmediaphoto
|
||||
telegram.inputpaidmediavideo
|
||||
telegram.inputpolloption
|
||||
telegram.inputsticker
|
||||
telegram.keyboardbutton
|
||||
telegram.keyboardbuttonpolltype
|
||||
telegram.keyboardbuttonrequestchat
|
||||
@@ -120,6 +120,7 @@ Available Types
|
||||
telegram.paidmediainfo
|
||||
telegram.paidmediaphoto
|
||||
telegram.paidmediapreview
|
||||
telegram.paidmediapurchased
|
||||
telegram.paidmediavideo
|
||||
telegram.photosize
|
||||
telegram.poll
|
||||
|
||||
@@ -5,5 +5,5 @@ telegram.constants Module
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:no-undoc-members:
|
||||
:inherited-members: Enum, EnumMeta, str, int
|
||||
:inherited-members: Enum, EnumMeta, str, int, float
|
||||
:exclude-members: __format__, __new__, __repr__, __str__
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
CopyTextButton
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.CopyTextButton
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -18,6 +18,7 @@ Handlers
|
||||
telegram.ext.inlinequeryhandler
|
||||
telegram.ext.messagehandler
|
||||
telegram.ext.messagereactionhandler
|
||||
telegram.ext.paidmediapurchasedhandler
|
||||
telegram.ext.pollanswerhandler
|
||||
telegram.ext.pollhandler
|
||||
telegram.ext.precheckoutqueryhandler
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMediaPurchasedHandler
|
||||
=========================
|
||||
|
||||
.. autoclass:: telegram.ext.PaidMediaPurchasedHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
Gift
|
||||
====
|
||||
|
||||
.. autoclass:: telegram.Gift
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
Gifts
|
||||
=====
|
||||
|
||||
.. autoclass:: telegram.Gifts
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -42,3 +42,4 @@ To enable this option, send the ``/setinline`` command to `@BotFather <https://t
|
||||
telegram.inputvenuemessagecontent
|
||||
telegram.inputcontactmessagecontent
|
||||
telegram.inputinvoicemessagecontent
|
||||
telegram.preparedinlinemessage
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMediaPurchased
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.PaidMediaPurchased
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -9,6 +9,7 @@ Your bot can accept payments from Telegram users. Please see the `introduction t
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
telegram.affiliateinfo
|
||||
telegram.invoice
|
||||
telegram.labeledprice
|
||||
telegram.orderinfo
|
||||
@@ -25,7 +26,9 @@ Your bot can accept payments from Telegram users. Please see the `introduction t
|
||||
telegram.startransactions
|
||||
telegram.successfulpayment
|
||||
telegram.transactionpartner
|
||||
telegram.transactionpartneraffiliateprogram
|
||||
telegram.transactionpartnerfragment
|
||||
telegram.transactionpartnerother
|
||||
telegram.transactionpartnertelegramads
|
||||
telegram.transactionpartnertelegramapi
|
||||
telegram.transactionpartneruser
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
PreparedInlineMessage
|
||||
=====================
|
||||
|
||||
.. autoclass:: telegram.PreparedInlineMessage
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -6,6 +6,9 @@ The following methods and objects allow your bot to handle stickers and sticker
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
telegram.gift
|
||||
telegram.gifts
|
||||
telegram.inputsticker
|
||||
telegram.maskposition
|
||||
telegram.sticker
|
||||
telegram.stickerset
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
TransactionPartnerAffiliateProgram
|
||||
===================================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerAffiliateProgram
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -4,4 +4,4 @@ TransactionPartnerFragment
|
||||
.. autoclass:: telegram.TransactionPartnerFragment
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
:inherited-members: TransactionPartner
|
||||
|
||||
@@ -4,4 +4,4 @@ TransactionPartnerOther
|
||||
.. autoclass:: telegram.TransactionPartnerOther
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
:inherited-members: TransactionPartner
|
||||
|
||||
@@ -4,4 +4,4 @@ TransactionPartnerTelegramAds
|
||||
.. autoclass:: telegram.TransactionPartnerTelegramAds
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
:inherited-members: TransactionPartner
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
TransactionPartnerTelegramApi
|
||||
=============================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerTelegramApi
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TransactionPartner
|
||||
@@ -4,4 +4,4 @@ TransactionPartnerUser
|
||||
.. autoclass:: telegram.TransactionPartnerUser
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
:inherited-members: TransactionPartner
|
||||
|
||||
@@ -93,3 +93,7 @@
|
||||
.. |show_cap_above_med| replace:: :obj:`True`, if the caption must be shown above the message media.
|
||||
|
||||
.. |tg_stars| replace:: `Telegram Stars <https://t.me/BotNews/90>`__
|
||||
|
||||
.. |allow_paid_broadcast| replace:: Pass True to allow up to :tg-const:`telegram.constants.FloodLimit.PAID_MESSAGES_PER_SECOND` messages per second, ignoring `broadcasting limits <https://core.telegram.org/bots/faq#how-can-i-message-all-of-my-bot-39s-subscribers-at-once>`__ for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance.
|
||||
|
||||
.. |tz-naive-dtms| replace:: For timezone naive :obj:`datetime.datetime` objects, the default timezone of the bot will be used, which is UTC unless :attr:`telegram.ext.Defaults.tzinfo` is used.
|
||||
@@ -12,7 +12,7 @@ To use arbitrary callback data, you must install PTB via
|
||||
`pip install "python-telegram-bot[callback-data]"`
|
||||
"""
|
||||
import logging
|
||||
from typing import List, Tuple, cast
|
||||
from typing import cast
|
||||
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
@@ -36,7 +36,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends a message with 5 inline buttons attached."""
|
||||
number_list: List[int] = []
|
||||
number_list: list[int] = []
|
||||
await update.message.reply_text("Please choose:", reply_markup=build_keyboard(number_list))
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ async def clear(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
await update.effective_message.reply_text("All clear!")
|
||||
|
||||
|
||||
def build_keyboard(current_list: List[int]) -> InlineKeyboardMarkup:
|
||||
def build_keyboard(current_list: list[int]) -> InlineKeyboardMarkup:
|
||||
"""Helper function to build the next inline keyboard."""
|
||||
return InlineKeyboardMarkup.from_column(
|
||||
[InlineKeyboardButton(str(i), callback_data=(i, current_list)) for i in range(1, 6)]
|
||||
@@ -69,7 +69,7 @@ async def list_button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> Non
|
||||
# Get the data from the callback_data.
|
||||
# If you're using a type checker like MyPy, you'll have to use typing.cast
|
||||
# to make the checker get the expected type of the callback_data
|
||||
number, number_list = cast(Tuple[int, List[int]], query.data)
|
||||
number, number_list = cast(tuple[int, list[int]], query.data)
|
||||
# append the number to the list
|
||||
number_list.append(number)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Optional, Tuple
|
||||
from typing import Optional
|
||||
|
||||
from telegram import Chat, ChatMember, ChatMemberUpdated, Update
|
||||
from telegram.constants import ParseMode
|
||||
@@ -37,7 +37,7 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def extract_status_change(chat_member_update: ChatMemberUpdated) -> Optional[Tuple[bool, bool]]:
|
||||
def extract_status_change(chat_member_update: ChatMemberUpdated) -> Optional[tuple[bool, bool]]:
|
||||
"""Takes a ChatMemberUpdated instance and extracts whether the 'old_chat_member' was a member
|
||||
of the chat and whether the 'new_chat_member' is a member of the chat. Returns None, if
|
||||
the status didn't change.
|
||||
|
||||
@@ -12,7 +12,7 @@ bot.
|
||||
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict, Optional, Set
|
||||
from typing import Optional
|
||||
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.constants import ParseMode
|
||||
@@ -40,7 +40,7 @@ class ChatData:
|
||||
"""Custom class for chat_data. Here we store data per message."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.clicks_per_message: DefaultDict[int, int] = defaultdict(int)
|
||||
self.clicks_per_message: defaultdict[int, int] = defaultdict(int)
|
||||
|
||||
|
||||
# The [ExtBot, dict, ChatData, dict] is for type checkers like mypy
|
||||
@@ -57,7 +57,7 @@ class CustomContext(CallbackContext[ExtBot, dict, ChatData, dict]):
|
||||
self._message_id: Optional[int] = None
|
||||
|
||||
@property
|
||||
def bot_user_ids(self) -> Set[int]:
|
||||
def bot_user_ids(self) -> set[int]:
|
||||
"""Custom shortcut to access a value stored in the bot_data dict"""
|
||||
return self.bot_data.setdefault("user_ids", set())
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
@@ -46,7 +45,7 @@ reply_keyboard = [
|
||||
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
|
||||
|
||||
|
||||
def facts_to_str(user_data: Dict[str, str]) -> str:
|
||||
def facts_to_str(user_data: dict[str, str]) -> str:
|
||||
"""Helper function for formatting the gathered user info."""
|
||||
facts = [f"{key} - {value}" for key, value in user_data.items()]
|
||||
return "\n".join(facts).join(["\n", "\n"])
|
||||
|
||||
@@ -15,7 +15,7 @@ bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Any, Dict, Tuple
|
||||
from typing import Any
|
||||
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
@@ -66,7 +66,7 @@ END = ConversationHandler.END
|
||||
|
||||
|
||||
# Helper
|
||||
def _name_switcher(level: str) -> Tuple[str, str]:
|
||||
def _name_switcher(level: str) -> tuple[str, str]:
|
||||
if level == PARENTS:
|
||||
return "Father", "Mother"
|
||||
return "Brother", "Sister"
|
||||
@@ -122,7 +122,7 @@ async def adding_self(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str
|
||||
async def show_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Pretty print gathered data."""
|
||||
|
||||
def pretty_print(data: Dict[str, Any], level: str) -> str:
|
||||
def pretty_print(data: dict[str, Any], level: str) -> str:
|
||||
people = data.get(level)
|
||||
if not people:
|
||||
return "\nNo information yet."
|
||||
@@ -371,8 +371,8 @@ def main() -> None:
|
||||
entry_points=[CommandHandler("start", start)],
|
||||
states={
|
||||
SHOWING: [CallbackQueryHandler(start, pattern="^" + str(END) + "$")],
|
||||
SELECTING_ACTION: selection_handlers,
|
||||
SELECTING_LEVEL: selection_handlers,
|
||||
SELECTING_ACTION: selection_handlers, # type: ignore[dict-item]
|
||||
SELECTING_LEVEL: selection_handlers, # type: ignore[dict-item]
|
||||
DESCRIBING_SELF: [description_conv],
|
||||
STOPPING: [CommandHandler("start", start)],
|
||||
},
|
||||
|
||||
+39
-40
@@ -2,7 +2,7 @@
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Basic example for a bot that can receive payment from user."""
|
||||
"""Basic example for a bot that can receive payments from users."""
|
||||
|
||||
import logging
|
||||
|
||||
@@ -26,36 +26,36 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Insert the token from your payment provider.
|
||||
# In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
|
||||
PAYMENT_PROVIDER_TOKEN = "PAYMENT_PROVIDER_TOKEN"
|
||||
|
||||
|
||||
async def start_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Displays info on how to use the bot."""
|
||||
"""Provides instructions on how to use the bot."""
|
||||
msg = (
|
||||
"Use /shipping to get an invoice for shipping-payment, or /noshipping for an "
|
||||
"Use /shipping to receive an invoice with shipping included, or /noshipping for an "
|
||||
"invoice without shipping."
|
||||
)
|
||||
|
||||
await update.message.reply_text(msg)
|
||||
|
||||
|
||||
async def start_with_shipping_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends an invoice with shipping-payment."""
|
||||
"""Sends an invoice which triggers a shipping query."""
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
description = "Payment Example using python-telegram-bot"
|
||||
# select a payload just for you to recognize its the donation from your bot
|
||||
description = "Example of a payment process using the python-telegram-bot library."
|
||||
# Unique payload to identify this payment request as being from your bot
|
||||
payload = "Custom-Payload"
|
||||
# In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
|
||||
# Set up the currency.
|
||||
# List of supported currencies: https://core.telegram.org/bots/payments#supported-currencies
|
||||
currency = "USD"
|
||||
# price in dollars
|
||||
# Price in dollars
|
||||
price = 1
|
||||
# price * 100 so as to include 2 decimal points
|
||||
# check https://core.telegram.org/bots/payments#supported-currencies for more details
|
||||
# Convert price to cents from dollars.
|
||||
prices = [LabeledPrice("Test", price * 100)]
|
||||
|
||||
# optionally pass need_name=True, need_phone_number=True,
|
||||
# need_email=True, need_shipping_address=True, is_flexible=True
|
||||
# Optional parameters like need_shipping_address and is_flexible trigger extra user prompts
|
||||
# https://docs.python-telegram-bot.org/en/stable/telegram.bot.html#telegram.Bot.send_invoice
|
||||
await context.bot.send_invoice(
|
||||
chat_id,
|
||||
title,
|
||||
@@ -75,17 +75,16 @@ async def start_with_shipping_callback(update: Update, context: ContextTypes.DEF
|
||||
async def start_without_shipping_callback(
|
||||
update: Update, context: ContextTypes.DEFAULT_TYPE
|
||||
) -> None:
|
||||
"""Sends an invoice without shipping-payment."""
|
||||
"""Sends an invoice without requiring shipping details."""
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
description = "Payment Example using python-telegram-bot"
|
||||
# select a payload just for you to recognize its the donation from your bot
|
||||
description = "Example of a payment process using the python-telegram-bot library."
|
||||
# Unique payload to identify this payment request as being from your bot
|
||||
payload = "Custom-Payload"
|
||||
# In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
|
||||
currency = "USD"
|
||||
# price in dollars
|
||||
# Price in dollars
|
||||
price = 1
|
||||
# price * 100 so as to include 2 decimal points
|
||||
# Convert price to cents from dollars.
|
||||
prices = [LabeledPrice("Test", price * 100)]
|
||||
|
||||
# optionally pass need_name=True, need_phone_number=True,
|
||||
@@ -96,65 +95,65 @@ async def start_without_shipping_callback(
|
||||
|
||||
|
||||
async def shipping_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Answers the ShippingQuery with ShippingOptions"""
|
||||
"""Handles the ShippingQuery with available shipping options."""
|
||||
query = update.shipping_query
|
||||
# check the payload, is this from your bot?
|
||||
# Verify if the payload matches, ensure it's from your bot
|
||||
if query.invoice_payload != "Custom-Payload":
|
||||
# answer False pre_checkout_query
|
||||
# If not, respond with an error
|
||||
await query.answer(ok=False, error_message="Something went wrong...")
|
||||
return
|
||||
|
||||
# First option has a single LabeledPrice
|
||||
# Define available shipping options
|
||||
# First option with a single price entry
|
||||
options = [ShippingOption("1", "Shipping Option A", [LabeledPrice("A", 100)])]
|
||||
# second option has an array of LabeledPrice objects
|
||||
# Second option with multiple price entries
|
||||
price_list = [LabeledPrice("B1", 150), LabeledPrice("B2", 200)]
|
||||
options.append(ShippingOption("2", "Shipping Option B", price_list))
|
||||
await query.answer(ok=True, shipping_options=options)
|
||||
|
||||
|
||||
# after (optional) shipping, it's the pre-checkout
|
||||
# After (optional) shipping, process the pre-checkout step
|
||||
async def precheckout_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Answers the PreQecheckoutQuery"""
|
||||
"""Responds to the PreCheckoutQuery as the final confirmation for checkout."""
|
||||
query = update.pre_checkout_query
|
||||
# check the payload, is this from your bot?
|
||||
# Verify if the payload matches, ensure it's from your bot
|
||||
if query.invoice_payload != "Custom-Payload":
|
||||
# answer False pre_checkout_query
|
||||
# If not, respond with an error
|
||||
await query.answer(ok=False, error_message="Something went wrong...")
|
||||
else:
|
||||
await query.answer(ok=True)
|
||||
|
||||
|
||||
# finally, after contacting the payment provider...
|
||||
# Final callback after successful payment
|
||||
async def successful_payment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Confirms the successful payment."""
|
||||
# do something after successfully receiving payment?
|
||||
await update.message.reply_text("Thank you for your payment!")
|
||||
"""Acknowledges successful payment and thanks the user."""
|
||||
await update.message.reply_text("Thank you for your payment.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Run the bot."""
|
||||
"""Starts the bot and sets up handlers."""
|
||||
# Create the Application and pass it your bot's token.
|
||||
application = Application.builder().token("TOKEN").build()
|
||||
|
||||
# simple start function
|
||||
# Start command to display usage instructions
|
||||
application.add_handler(CommandHandler("start", start_callback))
|
||||
|
||||
# Add command handler to start the payment invoice
|
||||
# Command handlers for starting the payment process
|
||||
application.add_handler(CommandHandler("shipping", start_with_shipping_callback))
|
||||
application.add_handler(CommandHandler("noshipping", start_without_shipping_callback))
|
||||
|
||||
# Optional handler if your product requires shipping
|
||||
# Handler for shipping query (if product requires shipping)
|
||||
application.add_handler(ShippingQueryHandler(shipping_callback))
|
||||
|
||||
# Pre-checkout handler to final check
|
||||
# Pre-checkout handler for verifying payment details.
|
||||
application.add_handler(PreCheckoutQueryHandler(precheckout_callback))
|
||||
|
||||
# Success! Notify your user!
|
||||
# Handler for successful payment. Notify the user that the payment was successful.
|
||||
application.add_handler(
|
||||
MessageHandler(filters.SUCCESSFUL_PAYMENT, successful_payment_callback)
|
||||
)
|
||||
|
||||
# Run the bot until the user presses Ctrl-C
|
||||
# Start polling for updates until interrupted (CTRL+C)
|
||||
application.run_polling(allowed_updates=Update.ALL_TYPES)
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
@@ -47,7 +46,7 @@ reply_keyboard = [
|
||||
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
|
||||
|
||||
|
||||
def facts_to_str(user_data: Dict[str, str]) -> str:
|
||||
def facts_to_str(user_data: dict[str, str]) -> str:
|
||||
"""Helper function for formatting the gathered user info."""
|
||||
facts = [f"{key} - {value}" for key, value in user_data.items()]
|
||||
return "\n".join(facts).join(["\n", "\n"])
|
||||
|
||||
+5
-5
@@ -8,7 +8,7 @@ dynamic = ["version"]
|
||||
name = "python-telegram-bot"
|
||||
description = "We have made you a wrapper you can't refuse"
|
||||
readme = "README.rst"
|
||||
requires-python = ">=3.8"
|
||||
requires-python = ">=3.9"
|
||||
license = "LGPL-3.0-only"
|
||||
license-files = { paths = ["LICENSE", "LICENSE.dual", "LICENSE.lesser"] }
|
||||
authors = [
|
||||
@@ -31,7 +31,6 @@ classifiers = [
|
||||
"Topic :: Internet",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
@@ -87,7 +86,7 @@ passport = [
|
||||
"cffi >= 1.17.0rc1; python_version > '3.12'"
|
||||
]
|
||||
rate-limiter = [
|
||||
"aiolimiter~=1.1.0",
|
||||
"aiolimiter>=1.1,<1.3",
|
||||
]
|
||||
socks = [
|
||||
"httpx[socks]",
|
||||
@@ -150,7 +149,8 @@ enable = ["useless-suppression"]
|
||||
disable = ["duplicate-code", "too-many-arguments", "too-many-public-methods",
|
||||
"too-few-public-methods", "broad-exception-caught", "too-many-instance-attributes",
|
||||
"fixme", "missing-function-docstring", "missing-class-docstring", "too-many-locals",
|
||||
"too-many-lines", "too-many-branches", "too-many-statements", "cyclic-import"
|
||||
"too-many-lines", "too-many-branches", "too-many-statements", "cyclic-import",
|
||||
"too-many-positional-arguments",
|
||||
]
|
||||
|
||||
[tool.pylint.main]
|
||||
@@ -192,7 +192,7 @@ disallow_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_untyped_decorators = true
|
||||
show_error_codes = true
|
||||
python_version = "3.8"
|
||||
python_version = "3.9"
|
||||
|
||||
# For some files, it's easier to just disable strict-optional all together instead of
|
||||
# cluttering the code with `# type: ignore`s or stuff like
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
build
|
||||
|
||||
# For the test suite
|
||||
pytest==8.3.2
|
||||
pytest==8.3.4
|
||||
|
||||
# needed because pytest doesn't come with native support for coroutines as tests
|
||||
pytest-asyncio==0.21.2
|
||||
|
||||
+22
-1
@@ -20,6 +20,7 @@
|
||||
|
||||
__author__ = "devs@python-telegram-bot.org"
|
||||
__all__ = (
|
||||
"AffiliateInfo",
|
||||
"Animation",
|
||||
"Audio",
|
||||
"BackgroundFill",
|
||||
@@ -81,6 +82,7 @@ __all__ = (
|
||||
"ChatShared",
|
||||
"ChosenInlineResult",
|
||||
"Contact",
|
||||
"CopyTextButton",
|
||||
"Credentials",
|
||||
"DataCredentials",
|
||||
"Dice",
|
||||
@@ -100,6 +102,8 @@ __all__ = (
|
||||
"GameHighScore",
|
||||
"GeneralForumTopicHidden",
|
||||
"GeneralForumTopicUnhidden",
|
||||
"Gift",
|
||||
"Gifts",
|
||||
"Giveaway",
|
||||
"GiveawayCompleted",
|
||||
"GiveawayCreated",
|
||||
@@ -180,6 +184,7 @@ __all__ = (
|
||||
"PaidMediaInfo",
|
||||
"PaidMediaPhoto",
|
||||
"PaidMediaPreview",
|
||||
"PaidMediaPurchased",
|
||||
"PaidMediaVideo",
|
||||
"PassportData",
|
||||
"PassportElementError",
|
||||
@@ -199,6 +204,7 @@ __all__ = (
|
||||
"PollAnswer",
|
||||
"PollOption",
|
||||
"PreCheckoutQuery",
|
||||
"PreparedInlineMessage",
|
||||
"ProximityAlertTriggered",
|
||||
"ReactionCount",
|
||||
"ReactionType",
|
||||
@@ -231,9 +237,11 @@ __all__ = (
|
||||
"TelegramObject",
|
||||
"TextQuote",
|
||||
"TransactionPartner",
|
||||
"TransactionPartnerAffiliateProgram",
|
||||
"TransactionPartnerFragment",
|
||||
"TransactionPartnerOther",
|
||||
"TransactionPartnerTelegramAds",
|
||||
"TransactionPartnerTelegramApi",
|
||||
"TransactionPartnerUser",
|
||||
"Update",
|
||||
"User",
|
||||
@@ -329,6 +337,7 @@ from ._chatmember import (
|
||||
from ._chatmemberupdated import ChatMemberUpdated
|
||||
from ._chatpermissions import ChatPermissions
|
||||
from ._choseninlineresult import ChosenInlineResult
|
||||
from ._copytextbutton import CopyTextButton
|
||||
from ._dice import Dice
|
||||
from ._files.animation import Animation
|
||||
from ._files.audio import Audio
|
||||
@@ -369,6 +378,7 @@ from ._forumtopic import (
|
||||
from ._games.callbackgame import CallbackGame
|
||||
from ._games.game import Game
|
||||
from ._games.gamehighscore import GameHighScore
|
||||
from ._gifts import Gift, Gifts
|
||||
from ._giveaway import Giveaway, GiveawayCompleted, GiveawayCreated, GiveawayWinners
|
||||
from ._inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from ._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
@@ -401,6 +411,7 @@ from ._inline.inputlocationmessagecontent import InputLocationMessageContent
|
||||
from ._inline.inputmessagecontent import InputMessageContent
|
||||
from ._inline.inputtextmessagecontent import InputTextMessageContent
|
||||
from ._inline.inputvenuemessagecontent import InputVenueMessageContent
|
||||
from ._inline.preparedinlinemessage import PreparedInlineMessage
|
||||
from ._keyboardbutton import KeyboardButton
|
||||
from ._keyboardbuttonpolltype import KeyboardButtonPollType
|
||||
from ._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUsers
|
||||
@@ -419,7 +430,14 @@ from ._messageorigin import (
|
||||
MessageOriginUser,
|
||||
)
|
||||
from ._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
|
||||
from ._paidmedia import PaidMedia, PaidMediaInfo, PaidMediaPhoto, PaidMediaPreview, PaidMediaVideo
|
||||
from ._paidmedia import (
|
||||
PaidMedia,
|
||||
PaidMediaInfo,
|
||||
PaidMediaPhoto,
|
||||
PaidMediaPreview,
|
||||
PaidMediaPurchased,
|
||||
PaidMediaVideo,
|
||||
)
|
||||
from ._passport.credentials import (
|
||||
Credentials,
|
||||
DataCredentials,
|
||||
@@ -453,6 +471,7 @@ from ._payment.shippingaddress import ShippingAddress
|
||||
from ._payment.shippingoption import ShippingOption
|
||||
from ._payment.shippingquery import ShippingQuery
|
||||
from ._payment.stars import (
|
||||
AffiliateInfo,
|
||||
RevenueWithdrawalState,
|
||||
RevenueWithdrawalStateFailed,
|
||||
RevenueWithdrawalStatePending,
|
||||
@@ -460,9 +479,11 @@ from ._payment.stars import (
|
||||
StarTransaction,
|
||||
StarTransactions,
|
||||
TransactionPartner,
|
||||
TransactionPartnerAffiliateProgram,
|
||||
TransactionPartnerFragment,
|
||||
TransactionPartnerOther,
|
||||
TransactionPartnerTelegramAds,
|
||||
TransactionPartnerTelegramApi,
|
||||
TransactionPartnerUser,
|
||||
)
|
||||
from ._payment.successfulpayment import SuccessfulPayment
|
||||
|
||||
+448
-85
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=redefined-builtin
|
||||
"""This module contains objects representing Telegram bot command scopes."""
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type, Union
|
||||
from typing import TYPE_CHECKING, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -91,7 +91,7 @@ class BotCommandScope(TelegramObject):
|
||||
care of selecting the correct subclass.
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
data (dict[:obj:`str`, ...]): The JSON data.
|
||||
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
|
||||
:obj:`None`, in which case shortcut methods will not be available.
|
||||
|
||||
@@ -107,7 +107,7 @@ class BotCommandScope(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[BotCommandScope]] = {
|
||||
_class_mapping: dict[str, type[BotCommandScope]] = {
|
||||
cls.DEFAULT: BotCommandScopeDefault,
|
||||
cls.ALL_PRIVATE_CHATS: BotCommandScopeAllPrivateChats,
|
||||
cls.ALL_GROUP_CHATS: BotCommandScopeAllGroupChats,
|
||||
|
||||
+11
-10
@@ -19,8 +19,9 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/]
|
||||
"""This module contains the Telegram Business related classes."""
|
||||
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._files.location import Location
|
||||
@@ -145,7 +146,7 @@ class BusinessMessagesDeleted(TelegramObject):
|
||||
business_connection_id (:obj:`str`): Unique identifier of the business connection.
|
||||
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
|
||||
may not have access to the chat or the corresponding user.
|
||||
message_ids (Tuple[:obj:`int`]): A list of identifiers of the deleted messages in the
|
||||
message_ids (tuple[:obj:`int`]): A list of identifiers of the deleted messages in the
|
||||
chat of the business account.
|
||||
"""
|
||||
|
||||
@@ -166,7 +167,7 @@ class BusinessMessagesDeleted(TelegramObject):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.business_connection_id: str = business_connection_id
|
||||
self.chat: Chat = chat
|
||||
self.message_ids: Tuple[int, ...] = parse_sequence_arg(message_ids)
|
||||
self.message_ids: tuple[int, ...] = parse_sequence_arg(message_ids)
|
||||
|
||||
self._id_attrs = (
|
||||
self.business_connection_id,
|
||||
@@ -359,37 +360,37 @@ class BusinessOpeningHoursInterval(TelegramObject):
|
||||
self.opening_minute: int = opening_minute
|
||||
self.closing_minute: int = closing_minute
|
||||
|
||||
self._opening_time: Optional[Tuple[int, int, int]] = None
|
||||
self._closing_time: Optional[Tuple[int, int, int]] = None
|
||||
self._opening_time: Optional[tuple[int, int, int]] = None
|
||||
self._closing_time: Optional[tuple[int, int, int]] = None
|
||||
|
||||
self._id_attrs = (self.opening_minute, self.closing_minute)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def _parse_minute(self, minute: int) -> Tuple[int, int, int]:
|
||||
def _parse_minute(self, minute: int) -> tuple[int, int, int]:
|
||||
return (minute // 1440, minute % 1440 // 60, minute % 1440 % 60)
|
||||
|
||||
@property
|
||||
def opening_time(self) -> Tuple[int, int, int]:
|
||||
def opening_time(self) -> tuple[int, int, int]:
|
||||
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`opening_minute`. It contains
|
||||
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
|
||||
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
|
||||
tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
|
||||
"""
|
||||
if self._opening_time is None:
|
||||
self._opening_time = self._parse_minute(self.opening_minute)
|
||||
return self._opening_time
|
||||
|
||||
@property
|
||||
def closing_time(self) -> Tuple[int, int, int]:
|
||||
def closing_time(self) -> tuple[int, int, int]:
|
||||
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`closing_minute`. It contains
|
||||
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
|
||||
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
|
||||
tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
|
||||
"""
|
||||
if self._closing_time is None:
|
||||
self._closing_time = self._parse_minute(self.closing_minute)
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=redefined-builtin
|
||||
"""This module contains an object that represents a Telegram CallbackQuery"""
|
||||
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple, Union
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.location import Location
|
||||
@@ -676,7 +677,7 @@ class CallbackQuery(TelegramObject):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["GameHighScore", ...]:
|
||||
) -> tuple["GameHighScore", ...]:
|
||||
"""Shortcut for either::
|
||||
|
||||
await update.callback_query.message.get_game_high_score(*args, **kwargs)
|
||||
@@ -695,7 +696,7 @@ class CallbackQuery(TelegramObject):
|
||||
Raises :exc:`TypeError` if :attr:`message` is not accessible.
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.GameHighScore`]
|
||||
tuple[:class:`telegram.GameHighScore`]
|
||||
|
||||
Raises:
|
||||
:exc:`TypeError` if :attr:`message` is not accessible.
|
||||
@@ -833,6 +834,7 @@ class CallbackQuery(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -880,6 +882,7 @@ class CallbackQuery(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
reply_parameters=reply_parameters,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
MAX_ANSWER_TEXT_LENGTH: Final[int] = (
|
||||
|
||||
+97
-13
@@ -18,9 +18,10 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Chat."""
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from html import escape
|
||||
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._chatpermissions import ChatPermissions
|
||||
@@ -43,6 +44,7 @@ if TYPE_CHECKING:
|
||||
ChatMember,
|
||||
Contact,
|
||||
Document,
|
||||
Gift,
|
||||
InlineKeyboardMarkup,
|
||||
InputMediaAudio,
|
||||
InputMediaDocument,
|
||||
@@ -296,7 +298,7 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["ChatMember", ...]:
|
||||
) -> tuple["ChatMember", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.get_chat_administrators(update.effective_chat.id, *args, **kwargs)
|
||||
@@ -305,7 +307,7 @@ class _ChatBase(TelegramObject):
|
||||
:meth:`telegram.Bot.get_chat_administrators`.
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.ChatMember`]: A tuple of administrators in a chat. An Array of
|
||||
tuple[:class:`telegram.ChatMember`]: A tuple of administrators in a chat. An Array of
|
||||
:class:`telegram.ChatMember` objects that contains information about all
|
||||
chat administrators except other bots. If the chat is a group or a supergroup
|
||||
and no administrators were appointed, only the creator will be returned.
|
||||
@@ -1011,6 +1013,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1052,6 +1055,7 @@ class _ChatBase(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def delete_message(
|
||||
@@ -1129,6 +1133,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1140,7 +1145,7 @@ class _ChatBase(TelegramObject):
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
) -> Tuple["Message", ...]:
|
||||
) -> tuple["Message", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_media_group(update.effective_chat.id, *args, **kwargs)
|
||||
@@ -1148,7 +1153,7 @@ class _ChatBase(TelegramObject):
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`.
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.Message`]: On success, a tuple of :class:`~telegram.Message`
|
||||
tuple[:class:`telegram.Message`]: On success, a tuple of :class:`~telegram.Message`
|
||||
instances that were sent is returned.
|
||||
|
||||
"""
|
||||
@@ -1171,6 +1176,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters=reply_parameters,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_chat_action(
|
||||
@@ -1224,6 +1230,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1267,6 +1274,7 @@ class _ChatBase(TelegramObject):
|
||||
has_spoiler=has_spoiler,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
@@ -1283,6 +1291,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1324,6 +1333,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_audio(
|
||||
@@ -1343,6 +1353,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1388,6 +1399,7 @@ class _ChatBase(TelegramObject):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_document(
|
||||
@@ -1405,6 +1417,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1448,6 +1461,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_dice(
|
||||
@@ -1460,6 +1474,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1496,6 +1511,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_game(
|
||||
@@ -1508,6 +1524,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1544,6 +1561,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_invoice(
|
||||
@@ -1575,6 +1593,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1640,6 +1659,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
reply_parameters=reply_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_location(
|
||||
@@ -1657,6 +1677,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1700,6 +1721,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_animation(
|
||||
@@ -1720,6 +1742,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1767,6 +1790,7 @@ class _ChatBase(TelegramObject):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
@@ -1781,6 +1805,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1818,6 +1843,7 @@ class _ChatBase(TelegramObject):
|
||||
emoji=emoji,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_venue(
|
||||
@@ -1837,6 +1863,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1882,6 +1909,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_video(
|
||||
@@ -1903,6 +1931,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1951,6 +1980,7 @@ class _ChatBase(TelegramObject):
|
||||
has_spoiler=has_spoiler,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
@@ -1967,6 +1997,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2008,6 +2039,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_voice(
|
||||
@@ -2024,6 +2056,7 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2066,6 +2099,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_poll(
|
||||
@@ -2091,6 +2125,7 @@ class _ChatBase(TelegramObject):
|
||||
question_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
question_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2128,6 +2163,7 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
explanation=explanation,
|
||||
explanation_parse_mode=explanation_parse_mode,
|
||||
open_period=open_period,
|
||||
@@ -2155,6 +2191,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2196,6 +2233,7 @@ class _ChatBase(TelegramObject):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def copy_message(
|
||||
@@ -2211,6 +2249,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2252,6 +2291,7 @@ class _ChatBase(TelegramObject):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_copies(
|
||||
@@ -2268,7 +2308,7 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["MessageId", ...]:
|
||||
) -> tuple["MessageId", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.copy_messages(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
@@ -2280,7 +2320,7 @@ class _ChatBase(TelegramObject):
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
of the sent messages is returned.
|
||||
|
||||
"""
|
||||
@@ -2313,7 +2353,7 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["MessageId", ...]:
|
||||
) -> tuple["MessageId", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.copy_messages(from_chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
@@ -2325,7 +2365,7 @@ class _ChatBase(TelegramObject):
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
of the sent messages is returned.
|
||||
|
||||
"""
|
||||
@@ -2442,7 +2482,7 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["MessageId", ...]:
|
||||
) -> tuple["MessageId", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.forward_messages(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
@@ -2454,7 +2494,7 @@ class _ChatBase(TelegramObject):
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
of sent messages is returned.
|
||||
|
||||
"""
|
||||
@@ -2485,7 +2525,7 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["MessageId", ...]:
|
||||
) -> tuple["MessageId", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.forward_messages(from_chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
@@ -2497,7 +2537,7 @@ class _ChatBase(TelegramObject):
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
|
||||
of sent messages is returned.
|
||||
|
||||
"""
|
||||
@@ -3350,6 +3390,8 @@ class _ChatBase(TelegramObject):
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
payload: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -3391,6 +3433,48 @@ class _ChatBase(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
payload=payload,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def send_gift(
|
||||
self,
|
||||
gift_id: Union[str, "Gift"],
|
||||
text: Optional[str] = None,
|
||||
text_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
text_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_gift(user_id=update.effective_chat.id, *args, **kwargs )
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_gift`.
|
||||
|
||||
Caution:
|
||||
Can only work, if the chat is a private chat, see :attr:`type`.
|
||||
|
||||
.. versionadded:: 21.8
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().send_gift(
|
||||
user_id=self.id,
|
||||
gift_id=gift_id,
|
||||
text=text,
|
||||
text_parse_mode=text_parse_mode,
|
||||
text_entities=text_entities,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects related to chat backgrounds."""
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.document import Document
|
||||
@@ -87,7 +88,7 @@ class BackgroundFill(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[BackgroundFill]] = {
|
||||
_class_mapping: dict[str, type[BackgroundFill]] = {
|
||||
cls.SOLID: BackgroundFillSolid,
|
||||
cls.GRADIENT: BackgroundFillGradient,
|
||||
cls.FREEFORM_GRADIENT: BackgroundFillFreeformGradient,
|
||||
@@ -212,7 +213,7 @@ class BackgroundFillFreeformGradient(BackgroundFill):
|
||||
super().__init__(type=self.FREEFORM_GRADIENT, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.colors: Tuple[int, ...] = parse_sequence_arg(colors)
|
||||
self.colors: tuple[int, ...] = parse_sequence_arg(colors)
|
||||
|
||||
self._id_attrs = (self.colors,)
|
||||
|
||||
@@ -278,7 +279,7 @@ class BackgroundType(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[BackgroundType]] = {
|
||||
_class_mapping: dict[str, type[BackgroundType]] = {
|
||||
cls.FILL: BackgroundTypeFill,
|
||||
cls.WALLPAPER: BackgroundTypeWallpaper,
|
||||
cls.PATTERN: BackgroundTypePattern,
|
||||
|
||||
+22
-8
@@ -18,8 +18,9 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram ChatBoosts."""
|
||||
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._chat import Chat
|
||||
@@ -119,7 +120,7 @@ class ChatBoostSource(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[ChatBoostSource]] = {
|
||||
_class_mapping: dict[str, type[ChatBoostSource]] = {
|
||||
cls.PREMIUM: ChatBoostSourcePremium,
|
||||
cls.GIFT_CODE: ChatBoostSourceGiftCode,
|
||||
cls.GIVEAWAY: ChatBoostSourceGiveaway,
|
||||
@@ -187,15 +188,22 @@ class ChatBoostSourceGiftCode(ChatBoostSource):
|
||||
|
||||
class ChatBoostSourceGiveaway(ChatBoostSource):
|
||||
"""
|
||||
The boost was obtained by the creation of a Telegram Premium giveaway. This boosts the chat 4
|
||||
times for the duration of the corresponding Telegram Premium subscription.
|
||||
The boost was obtained by the creation of a Telegram Premium giveaway or a Telegram Star.
|
||||
This boosts the chat 4 times for the duration of the corresponding Telegram Premium
|
||||
subscription for Telegram Premium giveaways and :attr:`prize_star_count` / 500 times for
|
||||
one year for Telegram Star giveaways.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Args:
|
||||
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
|
||||
the message could have been deleted already. May be 0 if the message isn't sent yet.
|
||||
user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any.
|
||||
user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any;
|
||||
for Telegram Premium giveaways only.
|
||||
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
|
||||
giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
is_unclaimed (:obj:`bool`, optional): :obj:`True`, if the giveaway was completed, but
|
||||
there was no user to win the prize.
|
||||
|
||||
@@ -205,17 +213,22 @@ class ChatBoostSourceGiveaway(ChatBoostSource):
|
||||
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
|
||||
the message could have been deleted already. May be 0 if the message isn't sent yet.
|
||||
user (:class:`telegram.User`): Optional. User that won the prize in the giveaway if any.
|
||||
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
|
||||
giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
is_unclaimed (:obj:`bool`): Optional. :obj:`True`, if the giveaway was completed, but
|
||||
there was no user to win the prize.
|
||||
"""
|
||||
|
||||
__slots__ = ("giveaway_message_id", "is_unclaimed", "user")
|
||||
__slots__ = ("giveaway_message_id", "is_unclaimed", "prize_star_count", "user")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
giveaway_message_id: int,
|
||||
user: Optional[User] = None,
|
||||
is_unclaimed: Optional[bool] = None,
|
||||
prize_star_count: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -224,6 +237,7 @@ class ChatBoostSourceGiveaway(ChatBoostSource):
|
||||
with self._unfrozen():
|
||||
self.giveaway_message_id: int = giveaway_message_id
|
||||
self.user: Optional[User] = user
|
||||
self.prize_star_count: Optional[int] = prize_star_count
|
||||
self.is_unclaimed: Optional[bool] = is_unclaimed
|
||||
|
||||
|
||||
@@ -418,7 +432,7 @@ class UserChatBoosts(TelegramObject):
|
||||
user.
|
||||
|
||||
Attributes:
|
||||
boosts (Tuple[:class:`telegram.ChatBoost`]): List of boosts added to the chat by the user.
|
||||
boosts (tuple[:class:`telegram.ChatBoost`]): List of boosts added to the chat by the user.
|
||||
"""
|
||||
|
||||
__slots__ = ("boosts",)
|
||||
@@ -431,7 +445,7 @@ class UserChatBoosts(TelegramObject):
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
self.boosts: Tuple[ChatBoost, ...] = parse_sequence_arg(boosts)
|
||||
self.boosts: tuple[ChatBoost, ...] = parse_sequence_arg(boosts)
|
||||
|
||||
self._id_attrs = (self.boosts,)
|
||||
self._freeze()
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatFullInfo."""
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._birthdate import Birthdate
|
||||
from telegram._chat import Chat, _ChatBase
|
||||
@@ -224,7 +225,7 @@ class ChatFullInfo(_ChatBase):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
photo (:class:`telegram.ChatPhoto`): Optional. Chat photo.
|
||||
active_usernames (Tuple[:obj:`str`]): Optional. If set, the list of all `active chat
|
||||
active_usernames (tuple[:obj:`str`]): Optional. If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels.
|
||||
|
||||
@@ -252,7 +253,7 @@ class ChatFullInfo(_ChatBase):
|
||||
of the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
available_reactions (Tuple[:class:`telegram.ReactionType`]): Optional. List of available
|
||||
available_reactions (tuple[:class:`telegram.ReactionType`]): Optional. List of available
|
||||
reactions allowed in the chat. If omitted, then all of
|
||||
:const:`telegram.constants.ReactionEmoji` are allowed.
|
||||
|
||||
@@ -483,14 +484,14 @@ class ChatFullInfo(_ChatBase):
|
||||
self.has_restricted_voice_and_video_messages: Optional[bool] = (
|
||||
has_restricted_voice_and_video_messages
|
||||
)
|
||||
self.active_usernames: Tuple[str, ...] = parse_sequence_arg(active_usernames)
|
||||
self.active_usernames: tuple[str, ...] = parse_sequence_arg(active_usernames)
|
||||
self.emoji_status_custom_emoji_id: Optional[str] = emoji_status_custom_emoji_id
|
||||
self.emoji_status_expiration_date: Optional[datetime] = emoji_status_expiration_date
|
||||
self.has_aggressive_anti_spam_enabled: Optional[bool] = (
|
||||
has_aggressive_anti_spam_enabled
|
||||
)
|
||||
self.has_hidden_members: Optional[bool] = has_hidden_members
|
||||
self.available_reactions: Optional[Tuple[ReactionType, ...]] = parse_sequence_arg(
|
||||
self.available_reactions: Optional[tuple[ReactionType, ...]] = parse_sequence_arg(
|
||||
available_reactions
|
||||
)
|
||||
self.accent_color_id: Optional[int] = accent_color_id
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"""This module contains an object that represents a Telegram ChatMember."""
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -114,7 +114,7 @@ class ChatMember(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[ChatMember]] = {
|
||||
_class_mapping: dict[str, type[ChatMember]] = {
|
||||
cls.OWNER: ChatMemberOwner,
|
||||
cls.ADMINISTRATOR: ChatMemberAdministrator,
|
||||
cls.MEMBER: ChatMemberMember,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatMemberUpdated."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Optional, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._chatinvitelink import ChatInviteLink
|
||||
@@ -162,7 +162,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
def _get_attribute_difference(self, attribute: str) -> Tuple[object, object]:
|
||||
def _get_attribute_difference(self, attribute: str) -> tuple[object, object]:
|
||||
try:
|
||||
old = self.old_chat_member[attribute]
|
||||
except KeyError:
|
||||
@@ -177,9 +177,9 @@ class ChatMemberUpdated(TelegramObject):
|
||||
|
||||
def difference(
|
||||
self,
|
||||
) -> Dict[
|
||||
) -> dict[
|
||||
str,
|
||||
Tuple[
|
||||
tuple[
|
||||
Union[str, bool, datetime.datetime, User], Union[str, bool, datetime.datetime, User]
|
||||
],
|
||||
]:
|
||||
@@ -198,7 +198,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||
.. versionadded:: 13.5
|
||||
|
||||
Returns:
|
||||
Dict[:obj:`str`, Tuple[:class:`object`, :class:`object`]]: A dictionary mapping
|
||||
dict[:obj:`str`, tuple[:class:`object`, :class:`object`]]: A dictionary mapping
|
||||
attribute names to tuples of the form ``(old_value, new_value)``
|
||||
"""
|
||||
# we first get the names of the attributes that have changed
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram CopyTextButton."""
|
||||
from typing import Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class CopyTextButton(TelegramObject):
|
||||
"""
|
||||
This object represents an inline keyboard button that copies specified text to the clipboard.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`text` is equal.
|
||||
|
||||
.. versionadded:: 21.7
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): The text to be copied to the clipboard;
|
||||
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MIN_COPY_TEXT`-
|
||||
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MAX_COPY_TEXT` characters
|
||||
|
||||
Attributes:
|
||||
text (:obj:`str`): The text to be copied to the clipboard;
|
||||
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MIN_COPY_TEXT`-
|
||||
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MAX_COPY_TEXT` characters
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("text",)
|
||||
|
||||
def __init__(self, text: str, *, api_kwargs: Optional[JSONDict] = None):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.text: str = text
|
||||
|
||||
self._id_attrs = (self.text,)
|
||||
|
||||
self._freeze()
|
||||
+3
-3
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Dice."""
|
||||
from typing import Final, List, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -114,8 +114,8 @@ class Dice(TelegramObject):
|
||||
|
||||
.. versionadded:: 13.4
|
||||
"""
|
||||
ALL_EMOJI: Final[List[str]] = list(constants.DiceEmoji)
|
||||
"""List[:obj:`str`]: A list of all available dice emoji."""
|
||||
ALL_EMOJI: Final[list[str]] = list(constants.DiceEmoji)
|
||||
"""list[:obj:`str`]: A list of all available dice emoji."""
|
||||
|
||||
MIN_VALUE: Final[int] = constants.DiceLimit.MIN_VALUE
|
||||
""":const:`telegram.constants.DiceLimit.MIN_VALUE`
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""Common base class for media objects with thumbnails"""
|
||||
from typing import TYPE_CHECKING, Optional, Type, TypeVar
|
||||
from typing import TYPE_CHECKING, Optional, TypeVar
|
||||
|
||||
from telegram._files._basemedium import _BaseMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
@@ -82,7 +82,7 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls: Type[ThumbedMT_co], data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
cls: type[ThumbedMT_co], data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional[ThumbedMT_co]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
+36
-6
@@ -128,9 +128,8 @@ class File(TelegramObject):
|
||||
) -> Path:
|
||||
"""
|
||||
Download this file. By default, the file is saved in the current working directory with
|
||||
:attr:`file_path` as file name. If the file has no filename, the file ID will be used as
|
||||
filename. If :paramref:`custom_path` is supplied as a :obj:`str` or :obj:`pathlib.Path`,
|
||||
it will be saved to that path.
|
||||
:attr:`file_path` as file name. If :paramref:`custom_path` is supplied as a :obj:`str` or
|
||||
:obj:`pathlib.Path`, it will be saved to that path.
|
||||
|
||||
Note:
|
||||
If :paramref:`custom_path` isn't provided and :attr:`file_path` is the path of a
|
||||
@@ -152,6 +151,11 @@ class File(TelegramObject):
|
||||
* This method was previously called ``download``. It was split into
|
||||
:meth:`download_to_drive` and :meth:`download_to_memory`.
|
||||
|
||||
.. versionchanged:: 21.7
|
||||
Raises :exc:`RuntimeError` if :attr:`file_path` is not set. Note that files without
|
||||
a :attr:`file_path` could never be downloaded, as this attribute is mandatory for that
|
||||
operation.
|
||||
|
||||
Args:
|
||||
custom_path (:class:`pathlib.Path` | :obj:`str` , optional): The path where the file
|
||||
will be saved to. If not specified, will be saved in the current working directory
|
||||
@@ -175,7 +179,13 @@ class File(TelegramObject):
|
||||
Returns:
|
||||
:class:`pathlib.Path`: Returns the Path object the file was downloaded to.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If :attr:`file_path` is not set.
|
||||
|
||||
"""
|
||||
if not self.file_path:
|
||||
raise RuntimeError("No `file_path` available for this file. Can not download.")
|
||||
|
||||
local_file = is_local_file(self.file_path)
|
||||
url = None if local_file else self._get_encoded_url()
|
||||
|
||||
@@ -198,10 +208,8 @@ class File(TelegramObject):
|
||||
filename = Path(custom_path)
|
||||
elif local_file:
|
||||
return Path(self.file_path)
|
||||
elif self.file_path:
|
||||
filename = Path(Path(self.file_path).name)
|
||||
else:
|
||||
filename = Path.cwd() / self.file_id
|
||||
filename = Path(Path(self.file_path).name)
|
||||
|
||||
buf = await self.get_bot().request.retrieve(
|
||||
url,
|
||||
@@ -237,6 +245,11 @@ class File(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
.. versionchanged:: 21.7
|
||||
Raises :exc:`RuntimeError` if :attr:`file_path` is not set. Note that files without
|
||||
a :attr:`file_path` could never be downloaded, as this attribute is mandatory for that
|
||||
operation.
|
||||
|
||||
Args:
|
||||
out (:obj:`io.BufferedIOBase`): A file-like object. Must be opened for writing in
|
||||
binary mode.
|
||||
@@ -254,7 +267,13 @@ class File(TelegramObject):
|
||||
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If :attr:`file_path` is not set.
|
||||
"""
|
||||
if not self.file_path:
|
||||
raise RuntimeError("No `file_path` available for this file. Can not download.")
|
||||
|
||||
local_file = is_local_file(self.file_path)
|
||||
url = None if local_file else self._get_encoded_url()
|
||||
path = Path(self.file_path) if local_file else None
|
||||
@@ -283,6 +302,11 @@ class File(TelegramObject):
|
||||
) -> bytearray:
|
||||
"""Download this file and return it as a bytearray.
|
||||
|
||||
.. versionchanged:: 21.7
|
||||
Raises :exc:`RuntimeError` if :attr:`file_path` is not set. Note that files without
|
||||
a :attr:`file_path` could never be downloaded, as this attribute is mandatory for that
|
||||
operation.
|
||||
|
||||
Args:
|
||||
buf (:obj:`bytearray`, optional): Extend the given bytearray with the downloaded data.
|
||||
|
||||
@@ -312,7 +336,13 @@ class File(TelegramObject):
|
||||
:obj:`bytearray`: The same object as :paramref:`buf` if it was specified. Otherwise a
|
||||
newly allocated :obj:`bytearray`.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If :attr:`file_path` is not set.
|
||||
|
||||
"""
|
||||
if not self.file_path:
|
||||
raise RuntimeError("No `file_path` available for this file. Can not download.")
|
||||
|
||||
if buf is None:
|
||||
buf = bytearray()
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ class InputFile:
|
||||
read_file_handle (:obj:`bool`, optional): If :obj:`True` and :paramref:`obj` is a file
|
||||
handle, the data will be read from the file handle on initialization of this object.
|
||||
If :obj:`False`, the file handle will be passed on to the
|
||||
`networking backend <telegram.request.BaseRequest.do_request>`_ which will have to
|
||||
handle the reading. Defaults to :obj:`True`.
|
||||
:attr:`networking backend <telegram.request.BaseRequest.do_request>` which will have
|
||||
to handle the reading. Defaults to :obj:`True`.
|
||||
|
||||
Tip:
|
||||
If you upload extremely large files, you may want to set this to :obj:`False` to
|
||||
@@ -130,7 +130,7 @@ class InputFile:
|
||||
Content may now be a file handle.
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`str`, :obj:`bytes` | :class:`IO`, :obj:`str`]:
|
||||
tuple[:obj:`str`, :obj:`bytes` | :class:`IO`, :obj:`str`]:
|
||||
"""
|
||||
return self.filename, self.input_file_content, self.mimetype
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""Base class for Telegram InputMedia Objects."""
|
||||
from typing import Final, Optional, Sequence, Tuple, Union
|
||||
from collections.abc import Sequence
|
||||
from typing import Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.animation import Animation
|
||||
@@ -74,7 +75,7 @@ class InputMedia(TelegramObject):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -99,7 +100,7 @@ class InputMedia(TelegramObject):
|
||||
self.type: str = enum.get_member(constants.InputMediaType, media_type, media_type)
|
||||
self.media: Union[str, InputFile, Animation, Audio, Document, PhotoSize, Video] = media
|
||||
self.caption: Optional[str] = caption
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
|
||||
self._freeze()
|
||||
@@ -321,7 +322,7 @@ class InputMediaAnimation(InputMedia):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -436,7 +437,7 @@ class InputMediaPhoto(InputMedia):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -546,7 +547,7 @@ class InputMediaVideo(InputMedia):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -676,7 +677,7 @@ class InputMediaAudio(InputMedia):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -779,7 +780,7 @@ class InputMediaDocument(InputMedia):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InputSticker."""
|
||||
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, Union
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from telegram._files.sticker import MaskPosition
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -67,13 +68,13 @@ class InputSticker(TelegramObject):
|
||||
|
||||
Attributes:
|
||||
sticker (:obj:`str` | :class:`telegram.InputFile`): The added sticker.
|
||||
emoji_list (Tuple[:obj:`str`]): Tuple of
|
||||
emoji_list (tuple[:obj:`str`]): Tuple of
|
||||
:tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` -
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the
|
||||
sticker.
|
||||
mask_position (:class:`telegram.MaskPosition`): Optional. Position where the mask should be
|
||||
placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only.
|
||||
keywords (Tuple[:obj:`str`]): Optional. Tuple of
|
||||
keywords (tuple[:obj:`str`]): Optional. Tuple of
|
||||
0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords
|
||||
for the sticker with the total length of up to
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For
|
||||
@@ -110,9 +111,9 @@ class InputSticker(TelegramObject):
|
||||
local_mode=True,
|
||||
attach=True,
|
||||
)
|
||||
self.emoji_list: Tuple[str, ...] = parse_sequence_arg(emoji_list)
|
||||
self.emoji_list: tuple[str, ...] = parse_sequence_arg(emoji_list)
|
||||
self.format: str = format
|
||||
self.mask_position: Optional[MaskPosition] = mask_position
|
||||
self.keywords: Tuple[str, ...] = parse_sequence_arg(keywords)
|
||||
self.keywords: tuple[str, ...] = parse_sequence_arg(keywords)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects that represent stickers."""
|
||||
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
@@ -259,7 +260,7 @@ class StickerSet(TelegramObject):
|
||||
Attributes:
|
||||
name (:obj:`str`): Sticker set name.
|
||||
title (:obj:`str`): Sticker set title.
|
||||
stickers (Tuple[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
stickers (tuple[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
@@ -296,7 +297,7 @@ class StickerSet(TelegramObject):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.name: str = name
|
||||
self.title: str = title
|
||||
self.stickers: Tuple[Sticker, ...] = parse_sequence_arg(stickers)
|
||||
self.stickers: tuple[Sticker, ...] = parse_sequence_arg(stickers)
|
||||
self.sticker_type: str = sticker_type
|
||||
# Optional
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Game."""
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._files.animation import Animation
|
||||
from telegram._files.photosize import PhotoSize
|
||||
@@ -65,7 +66,7 @@ class Game(TelegramObject):
|
||||
Attributes:
|
||||
title (:obj:`str`): Title of the game.
|
||||
description (:obj:`str`): Description of the game.
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game
|
||||
photo (tuple[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game
|
||||
message in chats.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -76,7 +77,7 @@ class Game(TelegramObject):
|
||||
when the bot calls :meth:`telegram.Bot.set_game_score`, or manually edited
|
||||
using :meth:`telegram.Bot.edit_message_text`.
|
||||
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
|
||||
text_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that
|
||||
text_entities (tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that
|
||||
appear in text, such as usernames, URLs, bot commands, etc.
|
||||
This tuple is empty if the message does not contain text entities.
|
||||
|
||||
@@ -112,10 +113,10 @@ class Game(TelegramObject):
|
||||
# Required
|
||||
self.title: str = title
|
||||
self.description: str = description
|
||||
self.photo: Tuple[PhotoSize, ...] = parse_sequence_arg(photo)
|
||||
self.photo: tuple[PhotoSize, ...] = parse_sequence_arg(photo)
|
||||
# Optionals
|
||||
self.text: Optional[str] = text
|
||||
self.text_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
|
||||
self.text_entities: tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
|
||||
self.animation: Optional[Animation] = animation
|
||||
|
||||
self._id_attrs = (self.title, self.description, self.photo)
|
||||
@@ -163,7 +164,7 @@ class Game(TelegramObject):
|
||||
|
||||
return entity_text.decode(TextEncoding.UTF_16_LE)
|
||||
|
||||
def parse_text_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]:
|
||||
def parse_text_entities(self, types: Optional[list[str]] = None) -> dict[MessageEntity, str]:
|
||||
"""
|
||||
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
|
||||
It contains entities from this message filtered by their
|
||||
@@ -176,13 +177,13 @@ class Game(TelegramObject):
|
||||
See :attr:`parse_text_entity` for more info.
|
||||
|
||||
Args:
|
||||
types (List[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
|
||||
types (list[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
|
||||
strings. If the :attr:`~telegram.MessageEntity.type` attribute of an entity is
|
||||
contained in this list, it will be returned. Defaults to
|
||||
:attr:`telegram.MessageEntity.ALL_TYPES`.
|
||||
|
||||
Returns:
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=redefined-builtin
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/]
|
||||
"""This module contains classes related to gifs sent by bots."""
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._files.sticker import Sticker
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class Gift(TelegramObject):
|
||||
"""This object represents a gift that can be sent by the bot.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`id` is equal.
|
||||
|
||||
.. versionadded:: 21.8
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier of the gift
|
||||
sticker (:class:`~telegram.Sticker`): The sticker that represents the gift
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to send the sticker
|
||||
total_count (:obj:`int`, optional): The total number of the gifts of this type that can be
|
||||
sent; for limited gifts only
|
||||
remaining_count (:obj:`int`, optional): The number of remaining gifts of this type that can
|
||||
be sent; for limited gifts only
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier of the gift
|
||||
sticker (:class:`~telegram.Sticker`): The sticker that represents the gift
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to send the sticker
|
||||
total_count (:obj:`int`): Optional. The total number of the gifts of this type that can be
|
||||
sent; for limited gifts only
|
||||
remaining_count (:obj:`int`): Optional. The number of remaining gifts of this type that can
|
||||
be sent; for limited gifts only
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("id", "remaining_count", "star_count", "sticker", "total_count")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: str,
|
||||
sticker: Sticker,
|
||||
star_count: int,
|
||||
total_count: Optional[int] = None,
|
||||
remaining_count: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.id: str = id
|
||||
self.sticker: Sticker = sticker
|
||||
self.star_count: int = star_count
|
||||
self.total_count: Optional[int] = total_count
|
||||
self.remaining_count: Optional[int] = remaining_count
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: Optional["Bot"] = None) -> Optional["Gift"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["sticker"] = Sticker.de_json(data.get("sticker"), bot)
|
||||
return cls(**data)
|
||||
|
||||
|
||||
class Gifts(TelegramObject):
|
||||
"""This object represent a list of gifts.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`gifts` are equal.
|
||||
|
||||
.. versionadded:: 21.8
|
||||
|
||||
Args:
|
||||
gifts (Sequence[:class:`Gift`]): The sequence of gifts
|
||||
|
||||
Attributes:
|
||||
gifts (tuple[:class:`Gift`]): The sequence of gifts
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("gifts",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
gifts: Sequence[Gift],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.gifts: tuple[Gift, ...] = parse_sequence_arg(gifts)
|
||||
|
||||
self._id_attrs = (self.gifts,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: Optional["Bot"] = None) -> Optional["Gifts"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["gifts"] = Gift.de_list(data.get("gifts"), bot)
|
||||
return cls(**data)
|
||||
+62
-13
@@ -18,7 +18,8 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an objects that are related to Telegram giveaways."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -41,7 +42,7 @@ class Giveaway(TelegramObject):
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Args:
|
||||
chats (Tuple[:class:`telegram.Chat`]): The list of chats which the user must join to
|
||||
chats (tuple[:class:`telegram.Chat`]): The list of chats which the user must join to
|
||||
participate in the giveaway.
|
||||
winners_selection_date (:class:`datetime.datetime`): The date when the giveaway winner will
|
||||
be selected. |datetime_localization|
|
||||
@@ -56,8 +57,13 @@ class Giveaway(TelegramObject):
|
||||
country codes indicating the countries from which eligible users for the giveaway must
|
||||
come. If empty, then all users can participate in the giveaway. Users with a phone
|
||||
number that was bought on Fragment can always participate in giveaways.
|
||||
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
|
||||
giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram
|
||||
Premium subscription won from the giveaway will be active for.
|
||||
Premium subscription won from the giveaway will be active for; for Telegram Premium
|
||||
giveaways only.
|
||||
|
||||
Attributes:
|
||||
chats (Sequence[:class:`telegram.Chat`]): The list of chats which the user must join to
|
||||
@@ -71,12 +77,17 @@ class Giveaway(TelegramObject):
|
||||
has_public_winners (:obj:`True`): Optional. :obj:`True`, if the list of giveaway winners
|
||||
will be visible to everyone
|
||||
prize_description (:obj:`str`): Optional. Description of additional giveaway prize
|
||||
country_codes (Tuple[:obj:`str`]): Optional. A tuple of two-letter ISO 3166-1 alpha-2
|
||||
country_codes (tuple[:obj:`str`]): Optional. A tuple of two-letter ISO 3166-1 alpha-2
|
||||
country codes indicating the countries from which eligible users for the giveaway must
|
||||
come. If empty, then all users can participate in the giveaway. Users with a phone
|
||||
number that was bought on Fragment can always participate in giveaways.
|
||||
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
|
||||
giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram
|
||||
Premium subscription won from the giveaway will be active for.
|
||||
Premium subscription won from the giveaway will be active for; for Telegram Premium
|
||||
giveaways only.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
@@ -86,6 +97,7 @@ class Giveaway(TelegramObject):
|
||||
"only_new_members",
|
||||
"premium_subscription_month_count",
|
||||
"prize_description",
|
||||
"prize_star_count",
|
||||
"winner_count",
|
||||
"winners_selection_date",
|
||||
)
|
||||
@@ -100,19 +112,21 @@ class Giveaway(TelegramObject):
|
||||
prize_description: Optional[str] = None,
|
||||
country_codes: Optional[Sequence[str]] = None,
|
||||
premium_subscription_month_count: Optional[int] = None,
|
||||
prize_star_count: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
self.chats: Tuple[Chat, ...] = tuple(chats)
|
||||
self.chats: tuple[Chat, ...] = tuple(chats)
|
||||
self.winners_selection_date: datetime.datetime = winners_selection_date
|
||||
self.winner_count: int = winner_count
|
||||
self.only_new_members: Optional[bool] = only_new_members
|
||||
self.has_public_winners: Optional[bool] = has_public_winners
|
||||
self.prize_description: Optional[str] = prize_description
|
||||
self.country_codes: Tuple[str, ...] = parse_sequence_arg(country_codes)
|
||||
self.country_codes: tuple[str, ...] = parse_sequence_arg(country_codes)
|
||||
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
|
||||
self.prize_star_count: Optional[int] = prize_star_count
|
||||
|
||||
self._id_attrs = (
|
||||
self.chats,
|
||||
@@ -145,13 +159,28 @@ class Giveaway(TelegramObject):
|
||||
|
||||
class GiveawayCreated(TelegramObject):
|
||||
"""This object represents a service message about the creation of a scheduled giveaway.
|
||||
Currently holds no information.
|
||||
|
||||
Args:
|
||||
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be
|
||||
split between giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
|
||||
Attributes:
|
||||
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be
|
||||
split between giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = ("prize_star_count",)
|
||||
|
||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
|
||||
def __init__(
|
||||
self, prize_star_count: Optional[int] = None, *, api_kwargs: Optional[JSONDict] = None
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.prize_star_count: Optional[int] = prize_star_count
|
||||
|
||||
self._freeze()
|
||||
|
||||
@@ -173,6 +202,10 @@ class GiveawayWinners(TelegramObject):
|
||||
winner_count (:obj:`int`): Total number of winners in the giveaway
|
||||
winners (Sequence[:class:`telegram.User`]): List of up to
|
||||
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
|
||||
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
|
||||
giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
additional_chat_count (:obj:`int`, optional): The number of other chats the user had to
|
||||
join in order to be eligible for the giveaway
|
||||
premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram
|
||||
@@ -190,10 +223,14 @@ class GiveawayWinners(TelegramObject):
|
||||
winners_selection_date (:class:`datetime.datetime`): Point in time when winners of the
|
||||
giveaway were selected. |datetime_localization|
|
||||
winner_count (:obj:`int`): Total number of winners in the giveaway
|
||||
winners (Tuple[:class:`telegram.User`]): tuple of up to
|
||||
winners (tuple[:class:`telegram.User`]): tuple of up to
|
||||
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
|
||||
additional_chat_count (:obj:`int`): Optional. The number of other chats the user had to
|
||||
join in order to be eligible for the giveaway
|
||||
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
|
||||
giveaway winners; for Telegram Star giveaways only.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram
|
||||
Premium subscription won from the giveaway will be active for
|
||||
unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes
|
||||
@@ -211,6 +248,7 @@ class GiveawayWinners(TelegramObject):
|
||||
"only_new_members",
|
||||
"premium_subscription_month_count",
|
||||
"prize_description",
|
||||
"prize_star_count",
|
||||
"unclaimed_prize_count",
|
||||
"was_refunded",
|
||||
"winner_count",
|
||||
@@ -231,6 +269,7 @@ class GiveawayWinners(TelegramObject):
|
||||
only_new_members: Optional[bool] = None,
|
||||
was_refunded: Optional[bool] = None,
|
||||
prize_description: Optional[str] = None,
|
||||
prize_star_count: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -240,13 +279,14 @@ class GiveawayWinners(TelegramObject):
|
||||
self.giveaway_message_id: int = giveaway_message_id
|
||||
self.winners_selection_date: datetime.datetime = winners_selection_date
|
||||
self.winner_count: int = winner_count
|
||||
self.winners: Tuple[User, ...] = tuple(winners)
|
||||
self.winners: tuple[User, ...] = tuple(winners)
|
||||
self.additional_chat_count: Optional[int] = additional_chat_count
|
||||
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
|
||||
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count
|
||||
self.only_new_members: Optional[bool] = only_new_members
|
||||
self.was_refunded: Optional[bool] = was_refunded
|
||||
self.prize_description: Optional[str] = prize_description
|
||||
self.prize_star_count: Optional[int] = prize_star_count
|
||||
|
||||
self._id_attrs = (
|
||||
self.chat,
|
||||
@@ -295,21 +335,29 @@ class GiveawayCompleted(TelegramObject):
|
||||
unclaimed_prize_count (:obj:`int`, optional): Number of undistributed prizes
|
||||
giveaway_message (:class:`telegram.Message`, optional): Message with the giveaway that was
|
||||
completed, if it wasn't deleted
|
||||
is_star_giveaway (:obj:`bool`, optional): :obj:`True`, if the giveaway is a Telegram Star
|
||||
giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
Attributes:
|
||||
winner_count (:obj:`int`): Number of winners in the giveaway
|
||||
unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes
|
||||
giveaway_message (:class:`telegram.Message`): Optional. Message with the giveaway that was
|
||||
completed, if it wasn't deleted
|
||||
is_star_giveaway (:obj:`bool`): Optional. :obj:`True`, if the giveaway is a Telegram Star
|
||||
giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
"""
|
||||
|
||||
__slots__ = ("giveaway_message", "unclaimed_prize_count", "winner_count")
|
||||
__slots__ = ("giveaway_message", "is_star_giveaway", "unclaimed_prize_count", "winner_count")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
winner_count: int,
|
||||
unclaimed_prize_count: Optional[int] = None,
|
||||
giveaway_message: Optional["Message"] = None,
|
||||
is_star_giveaway: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -318,6 +366,7 @@ class GiveawayCompleted(TelegramObject):
|
||||
self.winner_count: int = winner_count
|
||||
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count
|
||||
self.giveaway_message: Optional[Message] = giveaway_message
|
||||
self.is_star_giveaway: Optional[bool] = is_star_giveaway
|
||||
|
||||
self._id_attrs = (
|
||||
self.winner_count,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
from typing import TYPE_CHECKING, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._copytextbutton import CopyTextButton
|
||||
from telegram._games.callbackgame import CallbackGame
|
||||
from telegram._loginurl import LoginUrl
|
||||
from telegram._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
|
||||
@@ -123,6 +124,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||
This offers a quick way for the user to open your bot in inline mode in the same chat
|
||||
- good for selecting something from multiple options. Not supported in channels and for
|
||||
messages sent on behalf of a Telegram Business account.
|
||||
copy_text (:class:`telegram.CopyTextButton`, optional): Description of the button that
|
||||
copies the specified text to the clipboard.
|
||||
|
||||
.. versionadded:: 21.7
|
||||
callback_game (:class:`telegram.CallbackGame`, optional): Description of the game that will
|
||||
be launched when the user presses the button
|
||||
|
||||
@@ -192,6 +197,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||
This offers a quick way for the user to open your bot in inline mode in the same chat
|
||||
- good for selecting something from multiple options. Not supported in channels and for
|
||||
messages sent on behalf of a Telegram Business account.
|
||||
copy_text (:class:`telegram.CopyTextButton`): Optional. Description of the button that
|
||||
copies the specified text to the clipboard.
|
||||
|
||||
.. versionadded:: 21.7
|
||||
callback_game (:class:`telegram.CallbackGame`): Optional. Description of the game that will
|
||||
be launched when the user presses the button.
|
||||
|
||||
@@ -224,6 +233,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
__slots__ = (
|
||||
"callback_data",
|
||||
"callback_game",
|
||||
"copy_text",
|
||||
"login_url",
|
||||
"pay",
|
||||
"switch_inline_query",
|
||||
@@ -246,6 +256,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
login_url: Optional[LoginUrl] = None,
|
||||
web_app: Optional[WebAppInfo] = None,
|
||||
switch_inline_query_chosen_chat: Optional[SwitchInlineQueryChosenChat] = None,
|
||||
copy_text: Optional[CopyTextButton] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -265,6 +276,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
self.switch_inline_query_chosen_chat: Optional[SwitchInlineQueryChosenChat] = (
|
||||
switch_inline_query_chosen_chat
|
||||
)
|
||||
self.copy_text: Optional[CopyTextButton] = copy_text
|
||||
self._id_attrs = ()
|
||||
self._set_id_attrs()
|
||||
|
||||
@@ -299,6 +311,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
data["switch_inline_query_chosen_chat"] = SwitchInlineQueryChosenChat.de_json(
|
||||
data.get("switch_inline_query_chosen_chat"), bot
|
||||
)
|
||||
data["copy_text"] = CopyTextButton.de_json(data.get("copy_text"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineKeyboardMarkup."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -57,7 +58,7 @@ class InlineKeyboardMarkup(TelegramObject):
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
inline_keyboard (Tuple[Tuple[:class:`telegram.InlineKeyboardButton`]]): Tuple of
|
||||
inline_keyboard (tuple[tuple[:class:`telegram.InlineKeyboardButton`]]): Tuple of
|
||||
button rows, each represented by a tuple of :class:`~telegram.InlineKeyboardButton`
|
||||
objects.
|
||||
|
||||
@@ -81,7 +82,7 @@ class InlineKeyboardMarkup(TelegramObject):
|
||||
"InlineKeyboardButtons"
|
||||
)
|
||||
# Required
|
||||
self.inline_keyboard: Tuple[Tuple[InlineKeyboardButton, ...], ...] = tuple(
|
||||
self.inline_keyboard: tuple[tuple[InlineKeyboardButton, ...], ...] = tuple(
|
||||
tuple(row) for row in inline_keyboard
|
||||
)
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineQuery."""
|
||||
|
||||
from typing import TYPE_CHECKING, Callable, Final, Optional, Sequence, Union
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Callable, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.location import Location
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultAudio."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -73,7 +74,7 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -124,6 +125,6 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
self.audio_duration: Optional[int] = audio_duration
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedAudio."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -68,7 +69,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -110,6 +111,6 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
# Optionals
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedDocument."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -72,7 +73,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -120,6 +121,6 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedGif."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -74,7 +75,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -124,7 +125,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
self.title: Optional[str] = title
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -74,7 +75,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -124,7 +125,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
self.title: Optional[str] = title
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultPhoto"""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -76,7 +77,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -129,7 +130,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedVideo."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -72,7 +73,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -125,7 +126,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedVoice."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -70,7 +71,7 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -115,6 +116,6 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
# Optionals
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultDocument"""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -86,7 +87,7 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -155,7 +156,7 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
# Optionals
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.description: Optional[str] = description
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultGif."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -102,7 +103,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -166,7 +167,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
self.title: Optional[str] = title
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -104,7 +105,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -168,7 +169,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
self.title: Optional[str] = title
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultPhoto."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -92,7 +93,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -154,7 +155,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultVideo."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -99,7 +100,7 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional.
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional.
|
||||
|captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -171,7 +172,7 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
# Optional
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.video_width: Optional[int] = video_width
|
||||
self.video_height: Optional[int] = video_height
|
||||
self.video_duration: Optional[int] = video_duration
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultVoice."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -72,7 +73,7 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -121,6 +122,6 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
self.voice_duration: Optional[int] = voice_duration
|
||||
self.caption: Optional[str] = caption
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a class that represents a Telegram InputInvoiceMessageContent."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inputmessagecontent import InputMessageContent
|
||||
from telegram._payment.labeledprice import LabeledPrice
|
||||
@@ -122,7 +123,7 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_.
|
||||
Pass ``XTR`` for payments in |tg_stars|.
|
||||
prices (Tuple[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
prices (tuple[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus,
|
||||
etc.). Must contain exactly one item for payments in |tg_stars|.
|
||||
|
||||
@@ -135,7 +136,7 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
`currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it
|
||||
shows the number of digits past the decimal point for each currency (2 for the majority
|
||||
of currencies). Defaults to ``0``. Not supported for payments in |tg_stars|.
|
||||
suggested_tip_amounts (Tuple[:obj:`int`]): Optional. An array of suggested
|
||||
suggested_tip_amounts (tuple[:obj:`int`]): Optional. An array of suggested
|
||||
amounts of tip in the *smallest units* of the currency (integer, **not** float/double).
|
||||
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be
|
||||
positive, passed in a strictly increased order and must not exceed
|
||||
@@ -226,10 +227,10 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
self.payload: str = payload
|
||||
self.provider_token: Optional[str] = provider_token
|
||||
self.currency: str = currency
|
||||
self.prices: Tuple[LabeledPrice, ...] = parse_sequence_arg(prices)
|
||||
self.prices: tuple[LabeledPrice, ...] = parse_sequence_arg(prices)
|
||||
# Optionals
|
||||
self.max_tip_amount: Optional[int] = max_tip_amount
|
||||
self.suggested_tip_amounts: Tuple[int, ...] = parse_sequence_arg(suggested_tip_amounts)
|
||||
self.suggested_tip_amounts: tuple[int, ...] = parse_sequence_arg(suggested_tip_amounts)
|
||||
self.provider_data: Optional[str] = provider_data
|
||||
self.photo_url: Optional[str] = photo_url
|
||||
self.photo_size: Optional[int] = photo_size
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InputTextMessageContent."""
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._inline.inputmessagecontent import InputMessageContent
|
||||
from telegram._messageentity import MessageEntity
|
||||
@@ -75,7 +76,7 @@ class InputTextMessageContent(InputMessageContent):
|
||||
:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -107,7 +108,7 @@ class InputTextMessageContent(InputMessageContent):
|
||||
self.message_text: str = message_text
|
||||
# Optionals
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
self.entities: Tuple[MessageEntity, ...] = parse_sequence_arg(entities)
|
||||
self.entities: tuple[MessageEntity, ...] = parse_sequence_arg(entities)
|
||||
self.link_preview_options: ODVInput[LinkPreviewOptions] = parse_lpo_and_dwpp(
|
||||
disable_web_page_preview, link_preview_options
|
||||
)
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Prepared inline Message."""
|
||||
import datetime as dtm
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class PreparedInlineMessage(TelegramObject):
|
||||
"""Describes an inline message to be sent by a user of a Mini App.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`id` is equal.
|
||||
|
||||
.. versionadded:: 21.8
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier of the prepared message
|
||||
expiration_date (:class:`datetime.datetime`): Expiration date of the prepared message.
|
||||
Expired prepared messages can no longer be used.
|
||||
|datetime_localization|
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier of the prepared message
|
||||
expiration_date (:class:`datetime.datetime`): Expiration date of the prepared message.
|
||||
Expired prepared messages can no longer be used.
|
||||
|datetime_localization|
|
||||
"""
|
||||
|
||||
__slots__ = ("expiration_date", "id")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
expiration_date: dtm.datetime,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.id: str = id
|
||||
self.expiration_date: dtm.datetime = expiration_date
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["PreparedInlineMessage"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
# Get the local timezone from the bot if it has defaults
|
||||
loc_tzinfo = extract_tzinfo_from_defaults(bot)
|
||||
data["expiration_date"] = from_timestamp(data.get("expiration_date"), tzinfo=loc_tzinfo)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects related to Telegram menu buttons."""
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -76,7 +76,7 @@ class MenuButton(TelegramObject):
|
||||
care of selecting the correct subclass.
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
data (dict[:obj:`str`, ...]): The JSON data.
|
||||
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
|
||||
:obj:`None`, in which case shortcut methods will not be available.
|
||||
|
||||
@@ -95,7 +95,7 @@ class MenuButton(TelegramObject):
|
||||
if not data and cls is MenuButton:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[MenuButton]] = {
|
||||
_class_mapping: dict[str, type[MenuButton]] = {
|
||||
cls.COMMANDS: MenuButtonCommands,
|
||||
cls.WEB_APP: MenuButtonWebApp,
|
||||
cls.DEFAULT: MenuButtonDefault,
|
||||
|
||||
+153
-30
@@ -21,8 +21,9 @@
|
||||
|
||||
import datetime
|
||||
import re
|
||||
from collections.abc import Sequence
|
||||
from html import escape
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple, TypedDict, Union
|
||||
from typing import TYPE_CHECKING, Optional, TypedDict, Union
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._chatbackground import ChatBackground
|
||||
@@ -104,6 +105,7 @@ if TYPE_CHECKING:
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
InputPaidMedia,
|
||||
InputPollOption,
|
||||
LabeledPrice,
|
||||
MessageId,
|
||||
@@ -279,7 +281,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
and notice that some positional arguments changed position as a result.
|
||||
|
||||
Args:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat. In specific instances
|
||||
(e.g., message containing a video sent to a big chat), the server might automatically
|
||||
schedule a message instead of sending it immediately. In such cases, this field will be
|
||||
``0`` and the relevant message will be unusable until it is actually sent.
|
||||
from_user (:class:`telegram.User`, optional): Sender of the message; may be empty for
|
||||
messages sent to channels. For backward compatibility, if the message was sent on
|
||||
behalf of a chat, the field contains a fake sender user in non-channel chats.
|
||||
@@ -589,7 +594,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Attributes:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat. In specific instances
|
||||
(e.g., message containing a video sent to a big chat), the server might automatically
|
||||
schedule a message instead of sending it immediately. In such cases, this field will be
|
||||
``0`` and the relevant message will be unusable until it is actually sent.
|
||||
from_user (:class:`telegram.User`): Optional. Sender of the message; may be empty for
|
||||
messages sent to channels. For backward compatibility, if the message was sent on
|
||||
behalf of a chat, the field contains a fake sender user in non-channel chats.
|
||||
@@ -629,7 +637,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message belongs to.
|
||||
text (:obj:`str`): Optional. For text messages, the actual UTF-8 text of the message,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
|
||||
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For text messages, special
|
||||
entities (tuple[:class:`telegram.MessageEntity`]): Optional. For text messages, special
|
||||
entities like usernames, URLs, bot commands, etc. that appear in the text. See
|
||||
:attr:`parse_entity` and :attr:`parse_entities` methods for how to use properly.
|
||||
This list is empty if the message does not contain entities.
|
||||
@@ -648,7 +656,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
..versionadded:: 21.3
|
||||
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For messages with a
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. For messages with a
|
||||
Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the
|
||||
caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities`
|
||||
methods for how to use properly. This list is empty if the message does not contain
|
||||
@@ -675,7 +683,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
game (:class:`telegram.Game`): Optional. Message is a game, information about the game.
|
||||
:ref:`More about games >> <games-tree>`.
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available
|
||||
photo (tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available
|
||||
sizes of the photo. This list is empty if the message does not contain a photo.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
@@ -703,7 +711,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
about the video message.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
new_chat_members (Tuple[:class:`telegram.User`]): Optional. New members that were added
|
||||
new_chat_members (tuple[:class:`telegram.User`]): Optional. New members that were added
|
||||
to the group or supergroup and information about them (the bot itself may be one of
|
||||
these members). This list is empty if the message does not contain new chat members.
|
||||
|
||||
@@ -722,7 +730,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
left_chat_member (:class:`telegram.User`): Optional. A member was removed from the group,
|
||||
information about them (this member may be the bot itself).
|
||||
new_chat_title (:obj:`str`): Optional. A chat title was changed to this value.
|
||||
new_chat_photo (Tuple[:class:`telegram.PhotoSize`]): A chat photo was changed to
|
||||
new_chat_photo (tuple[:class:`telegram.PhotoSize`]): A chat photo was changed to
|
||||
this value. This list is empty if the message does not contain a new chat photo.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -1118,12 +1126,12 @@ class Message(MaybeInaccessibleMessage):
|
||||
self.edit_date: Optional[datetime.datetime] = edit_date
|
||||
self.has_protected_content: Optional[bool] = has_protected_content
|
||||
self.text: Optional[str] = text
|
||||
self.entities: Tuple[MessageEntity, ...] = parse_sequence_arg(entities)
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.entities: tuple[MessageEntity, ...] = parse_sequence_arg(entities)
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.audio: Optional[Audio] = audio
|
||||
self.game: Optional[Game] = game
|
||||
self.document: Optional[Document] = document
|
||||
self.photo: Tuple[PhotoSize, ...] = parse_sequence_arg(photo)
|
||||
self.photo: tuple[PhotoSize, ...] = parse_sequence_arg(photo)
|
||||
self.sticker: Optional[Sticker] = sticker
|
||||
self.video: Optional[Video] = video
|
||||
self.voice: Optional[Voice] = voice
|
||||
@@ -1132,10 +1140,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
self.contact: Optional[Contact] = contact
|
||||
self.location: Optional[Location] = location
|
||||
self.venue: Optional[Venue] = venue
|
||||
self.new_chat_members: Tuple[User, ...] = parse_sequence_arg(new_chat_members)
|
||||
self.new_chat_members: tuple[User, ...] = parse_sequence_arg(new_chat_members)
|
||||
self.left_chat_member: Optional[User] = left_chat_member
|
||||
self.new_chat_title: Optional[str] = new_chat_title
|
||||
self.new_chat_photo: Tuple[PhotoSize, ...] = parse_sequence_arg(new_chat_photo)
|
||||
self.new_chat_photo: tuple[PhotoSize, ...] = parse_sequence_arg(new_chat_photo)
|
||||
self.delete_chat_photo: Optional[bool] = bool(delete_chat_photo)
|
||||
self.group_chat_created: Optional[bool] = bool(group_chat_created)
|
||||
self.supergroup_chat_created: Optional[bool] = bool(supergroup_chat_created)
|
||||
@@ -1406,7 +1414,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
* :class:`telegram.Invoice`
|
||||
* :class:`telegram.Location`
|
||||
* :class:`telegram.PassportData`
|
||||
* List[:class:`telegram.PhotoSize`]
|
||||
* list[:class:`telegram.PhotoSize`]
|
||||
* :class:`telegram.PaidMediaInfo`
|
||||
* :class:`telegram.Poll`
|
||||
* :class:`telegram.Sticker`
|
||||
@@ -1478,7 +1486,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
def compute_quote_position_and_entities(
|
||||
self, quote: str, index: Optional[int] = None
|
||||
) -> Tuple[int, Optional[Tuple[MessageEntity, ...]]]:
|
||||
) -> tuple[int, Optional[tuple[MessageEntity, ...]]]:
|
||||
"""
|
||||
Use this function to compute position and entities of a quote in the message text or
|
||||
caption. Useful for filling the parameters
|
||||
@@ -1504,7 +1512,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message. If not specified, the first occurrence is used.
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`int`, :obj:`None` | Tuple[:class:`~telegram.MessageEntity`, ...]]: On
|
||||
tuple[:obj:`int`, :obj:`None` | tuple[:class:`~telegram.MessageEntity`, ...]]: On
|
||||
success, a tuple containing information about quote position and entities is returned.
|
||||
|
||||
Raises:
|
||||
@@ -1647,7 +1655,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
quote: Optional[bool],
|
||||
reply_to_message_id: Optional[int],
|
||||
reply_parameters: Optional["ReplyParameters"],
|
||||
) -> Tuple[Union[str, int], ReplyParameters]:
|
||||
) -> tuple[Union[str, int], ReplyParameters]:
|
||||
if quote and do_quote:
|
||||
raise ValueError("The arguments `quote` and `do_quote` are mutually exclusive")
|
||||
|
||||
@@ -1714,6 +1722,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1779,6 +1788,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_markdown(
|
||||
@@ -1792,6 +1802,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1863,6 +1874,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_markdown_v2(
|
||||
@@ -1876,6 +1888,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1943,6 +1956,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_html(
|
||||
@@ -1956,6 +1970,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2023,6 +2038,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_media_group(
|
||||
@@ -2035,6 +2051,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2048,7 +2065,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
) -> Tuple["Message", ...]:
|
||||
) -> tuple["Message", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_media_group(
|
||||
@@ -2075,7 +2092,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
.. versionadded:: 20.8
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.Message`]: An array of the sent Messages.
|
||||
tuple[:class:`telegram.Message`]: An array of the sent Messages.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
@@ -2102,6 +2119,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_photo(
|
||||
@@ -2117,6 +2135,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
has_spoiler: Optional[bool] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2184,6 +2203,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
has_spoiler=has_spoiler,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
@@ -2203,6 +2223,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2272,6 +2293,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_document(
|
||||
@@ -2288,6 +2310,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2355,6 +2378,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_animation(
|
||||
@@ -2374,6 +2398,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2445,6 +2470,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
@@ -2458,6 +2484,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
emoji: Optional[str] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2519,6 +2546,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
emoji=emoji,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_video(
|
||||
@@ -2539,6 +2567,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2611,6 +2640,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
@@ -2626,6 +2656,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2691,6 +2722,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_voice(
|
||||
@@ -2706,6 +2738,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2772,6 +2805,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_location(
|
||||
@@ -2788,6 +2822,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2855,6 +2890,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_venue(
|
||||
@@ -2873,6 +2909,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2942,6 +2979,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_contact(
|
||||
@@ -2956,6 +2994,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3021,6 +3060,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_poll(
|
||||
@@ -3045,6 +3085,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
question_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
question_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3118,6 +3159,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
question_parse_mode=question_parse_mode,
|
||||
question_entities=question_entities,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_dice(
|
||||
@@ -3129,6 +3171,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3189,6 +3232,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_chat_action(
|
||||
@@ -3244,6 +3288,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3306,6 +3351,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_invoice(
|
||||
@@ -3337,6 +3383,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3427,6 +3474,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
message_effect_id=message_effect_id,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def forward(
|
||||
@@ -3491,6 +3539,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3536,6 +3585,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_copy(
|
||||
@@ -3551,6 +3601,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3615,6 +3666,78 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def reply_paid_media(
|
||||
self,
|
||||
star_count: int,
|
||||
media: Sequence["InputPaidMedia"],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
payload: Optional[str] = None,
|
||||
allow_paid_broadcast: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> "Message":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_paid_media(
|
||||
chat_id=message.chat.id,
|
||||
business_connection_id=message.business_connection_id,
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_paid_media`.
|
||||
|
||||
.. versionadded:: 21.7
|
||||
|
||||
Keyword Args:
|
||||
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
|
||||
Mutually exclusive with :paramref:`quote`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, the sent message is returned.
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, None, reply_to_message_id, reply_parameters
|
||||
)
|
||||
return await self.get_bot().send_paid_media(
|
||||
chat_id=chat_id,
|
||||
caption=caption,
|
||||
star_count=star_count,
|
||||
media=media,
|
||||
payload=payload,
|
||||
business_connection_id=self.business_connection_id,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
reply_markup=reply_markup,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
)
|
||||
|
||||
async def edit_text(
|
||||
@@ -3989,7 +4112,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Tuple["GameHighScore", ...]:
|
||||
) -> tuple["GameHighScore", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.get_game_high_scores(
|
||||
@@ -4005,7 +4128,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.GameHighScore`]
|
||||
tuple[:class:`telegram.GameHighScore`]
|
||||
"""
|
||||
return await self.get_bot().get_game_high_scores(
|
||||
chat_id=self.chat_id,
|
||||
@@ -4431,7 +4554,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
return parse_message_entity(self.caption, entity)
|
||||
|
||||
def parse_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]:
|
||||
def parse_entities(self, types: Optional[list[str]] = None) -> dict[MessageEntity, str]:
|
||||
"""
|
||||
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
|
||||
It contains entities from this message filtered by their
|
||||
@@ -4444,21 +4567,21 @@ class Message(MaybeInaccessibleMessage):
|
||||
See :attr:`parse_entity` for more info.
|
||||
|
||||
Args:
|
||||
types (List[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
|
||||
types (list[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
|
||||
strings. If the ``type`` attribute of an entity is contained in this list, it will
|
||||
be returned. Defaults to a list of all types. All types can be found as constants
|
||||
in :class:`telegram.MessageEntity`.
|
||||
|
||||
Returns:
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
return parse_message_entities(self.text, self.entities, types=types)
|
||||
|
||||
def parse_caption_entities(
|
||||
self, types: Optional[List[str]] = None
|
||||
) -> Dict[MessageEntity, str]:
|
||||
self, types: Optional[list[str]] = None
|
||||
) -> dict[MessageEntity, str]:
|
||||
"""
|
||||
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
|
||||
It contains entities from this message's caption filtered by their
|
||||
@@ -4471,13 +4594,13 @@ class Message(MaybeInaccessibleMessage):
|
||||
codepoints. See :attr:`parse_entity` for more info.
|
||||
|
||||
Args:
|
||||
types (List[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
|
||||
types (list[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
|
||||
strings. If the ``type`` attribute of an entity is contained in this list, it will
|
||||
be returned. Defaults to a list of all types. All types can be found as constants
|
||||
in :class:`telegram.MessageEntity`.
|
||||
|
||||
Returns:
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
@@ -4487,7 +4610,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
def _parse_html(
|
||||
cls,
|
||||
message_text: Optional[str],
|
||||
entities: Dict[MessageEntity, str],
|
||||
entities: dict[MessageEntity, str],
|
||||
urled: bool = False,
|
||||
offset: int = 0,
|
||||
) -> Optional[str]:
|
||||
@@ -4676,7 +4799,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
def _parse_markdown(
|
||||
cls,
|
||||
message_text: Optional[str],
|
||||
entities: Dict[MessageEntity, str],
|
||||
entities: dict[MessageEntity, str],
|
||||
urled: bool = False,
|
||||
version: MarkdownVersion = 1,
|
||||
offset: int = 0,
|
||||
|
||||
+21
-18
@@ -20,7 +20,8 @@
|
||||
|
||||
import copy
|
||||
import itertools
|
||||
from typing import TYPE_CHECKING, Dict, Final, List, Optional, Sequence, Tuple, Union
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -44,10 +45,11 @@ class MessageEntity(TelegramObject):
|
||||
considered equal, if their :attr:`type`, :attr:`offset` and :attr:`length` are equal.
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the entity. Can be :attr:`MENTION` (@username),
|
||||
:attr:`HASHTAG` (#hashtag), :attr:`CASHTAG` ($USD), :attr:`BOT_COMMAND`
|
||||
(/start@jobs_bot), :attr:`URL` (https://telegram.org),
|
||||
:attr:`EMAIL` (do-not-reply@telegram.org), :attr:`PHONE_NUMBER` (+1-212-555-0123),
|
||||
type (:obj:`str`): Type of the entity. Can be :attr:`MENTION` (``@username``),
|
||||
:attr:`HASHTAG` (``#hashtag`` or ``#hashtag@chatusername``), :attr:`CASHTAG` (``$USD``
|
||||
or ``USD@chatusername``), :attr:`BOT_COMMAND` (``/start@jobs_bot``), :attr:`URL`
|
||||
(``https://telegram.org``), :attr:`EMAIL` (``do-not-reply@telegram.org``),
|
||||
:attr:`PHONE_NUMBER` (``+1-212-555-0123``),
|
||||
:attr:`BOLD` (**bold text**), :attr:`ITALIC` (*italic text*), :attr:`UNDERLINE`
|
||||
(underlined text), :attr:`STRIKETHROUGH`, :attr:`SPOILER` (spoiler message),
|
||||
:attr:`BLOCKQUOTE` (block quotation), :attr:`CODE` (monowidth string), :attr:`PRE`
|
||||
@@ -73,10 +75,11 @@ class MessageEntity(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the entity. Can be :attr:`MENTION` (@username),
|
||||
:attr:`HASHTAG` (#hashtag), :attr:`CASHTAG` ($USD), :attr:`BOT_COMMAND`
|
||||
(/start@jobs_bot), :attr:`URL` (https://telegram.org),
|
||||
:attr:`EMAIL` (do-not-reply@telegram.org), :attr:`PHONE_NUMBER` (+1-212-555-0123),
|
||||
type (:obj:`str`): Type of the entity. Can be :attr:`MENTION` (``@username``),
|
||||
:attr:`HASHTAG` (``#hashtag`` or ``#hashtag@chatusername``), :attr:`CASHTAG` (``$USD``
|
||||
or ``USD@chatusername``), :attr:`BOT_COMMAND` (``/start@jobs_bot``), :attr:`URL`
|
||||
(``https://telegram.org``), :attr:`EMAIL` (``do-not-reply@telegram.org``),
|
||||
:attr:`PHONE_NUMBER` (``+1-212-555-0123``),
|
||||
:attr:`BOLD` (**bold text**), :attr:`ITALIC` (*italic text*), :attr:`UNDERLINE`
|
||||
(underlined text), :attr:`STRIKETHROUGH`, :attr:`SPOILER` (spoiler message),
|
||||
:attr:`BLOCKQUOTE` (block quotation), :attr:`CODE` (monowidth string), :attr:`PRE`
|
||||
@@ -200,7 +203,7 @@ class MessageEntity(TelegramObject):
|
||||
accumulated_length = 0
|
||||
# calculate the length of each slice text[:position] in utf-16 accordingly,
|
||||
# store the position translations
|
||||
position_translation: Dict[int, int] = {}
|
||||
position_translation: dict[int, int] = {}
|
||||
for i, position in enumerate(positions):
|
||||
last_position = positions[i - 1] if i > 0 else 0
|
||||
text_slice = text[last_position:position]
|
||||
@@ -286,8 +289,8 @@ class MessageEntity(TelegramObject):
|
||||
@classmethod
|
||||
def concatenate(
|
||||
cls,
|
||||
*args: Union[Tuple[str, _SEM], Tuple[str, _SEM, bool]],
|
||||
) -> Tuple[str, _SEM]:
|
||||
*args: Union[tuple[str, _SEM], tuple[str, _SEM, bool]],
|
||||
) -> tuple[str, _SEM]:
|
||||
"""Utility functionality for concatenating two text along with their formatting entities.
|
||||
|
||||
Tip:
|
||||
@@ -332,8 +335,8 @@ class MessageEntity(TelegramObject):
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Args:
|
||||
*args (Tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]] | \
|
||||
Tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`], :obj:`bool`]):
|
||||
*args (tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]] | \
|
||||
tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`], :obj:`bool`]):
|
||||
Arbitrary number of tuples containing the text and its entities to concatenate.
|
||||
If the last element of the tuple is a :obj:`bool`, it is used to determine whether
|
||||
to adjust the entities to UTF-16 via
|
||||
@@ -341,11 +344,11 @@ class MessageEntity(TelegramObject):
|
||||
default.
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]]: The concatenated text
|
||||
tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]]: The concatenated text
|
||||
and its entities
|
||||
"""
|
||||
output_text = ""
|
||||
output_entities: List[MessageEntity] = []
|
||||
output_entities: list[MessageEntity] = []
|
||||
for arg in args:
|
||||
text, entities = arg[0], arg[1]
|
||||
|
||||
@@ -357,8 +360,8 @@ class MessageEntity(TelegramObject):
|
||||
|
||||
return output_text, output_entities
|
||||
|
||||
ALL_TYPES: Final[List[str]] = list(constants.MessageEntityType)
|
||||
"""List[:obj:`str`]: A list of all available message entity types."""
|
||||
ALL_TYPES: Final[list[str]] = list(constants.MessageEntityType)
|
||||
"""list[:obj:`str`]: A list of all available message entity types."""
|
||||
BLOCKQUOTE: Final[str] = constants.MessageEntityType.BLOCKQUOTE
|
||||
""":const:`telegram.constants.MessageEntityType.BLOCKQUOTE`
|
||||
|
||||
|
||||
@@ -31,10 +31,16 @@ class MessageId(TelegramObject):
|
||||
considered equal, if their :attr:`message_id` is equal.
|
||||
|
||||
Args:
|
||||
message_id (:obj:`int`): Unique message identifier.
|
||||
message_id (:obj:`int`): Unique message identifier. In specific instances
|
||||
(e.g., message containing a video sent to a big chat), the server might automatically
|
||||
schedule a message instead of sending it immediately. In such cases, this field will be
|
||||
``0`` and the relevant message will be unusable until it is actually sent.
|
||||
|
||||
Attributes:
|
||||
message_id (:obj:`int`): Unique message identifier.
|
||||
message_id (:obj:`int`): Unique message identifier. In specific instances
|
||||
(e.g., message containing a video sent to a big chat), the server might automatically
|
||||
schedule a message instead of sending it immediately. In such cases, this field will be
|
||||
``0`` and the relevant message will be unusable until it is actually sent.
|
||||
"""
|
||||
|
||||
__slots__ = ("message_id",)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram MessageOigin."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._chat import Chat
|
||||
@@ -105,7 +105,7 @@ class MessageOrigin(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[MessageOrigin]] = {
|
||||
_class_mapping: dict[str, type[MessageOrigin]] = {
|
||||
cls.USER: MessageOriginUser,
|
||||
cls.HIDDEN_USER: MessageOriginHiddenUser,
|
||||
cls.CHAT: MessageOriginChat,
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram MessageReaction Update."""
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._reaction import ReactionCount, ReactionType
|
||||
@@ -54,7 +55,7 @@ class MessageReactionCountUpdated(TelegramObject):
|
||||
message_id (:obj:`int`): Unique message identifier inside the chat.
|
||||
date (:class:`datetime.datetime`): Date of the change in Unix time
|
||||
|datetime_localization|
|
||||
reactions (Tuple[:class:`telegram.ReactionCount`]): List of reactions that are present on
|
||||
reactions (tuple[:class:`telegram.ReactionCount`]): List of reactions that are present on
|
||||
the message
|
||||
"""
|
||||
|
||||
@@ -79,7 +80,7 @@ class MessageReactionCountUpdated(TelegramObject):
|
||||
self.chat: Chat = chat
|
||||
self.message_id: int = message_id
|
||||
self.date: datetime = date
|
||||
self.reactions: Tuple[ReactionCount, ...] = parse_sequence_arg(reactions)
|
||||
self.reactions: tuple[ReactionCount, ...] = parse_sequence_arg(reactions)
|
||||
|
||||
self._id_attrs = (self.chat, self.message_id, self.date, self.reactions)
|
||||
self._freeze()
|
||||
@@ -132,9 +133,9 @@ class MessageReactionUpdated(TelegramObject):
|
||||
message_id (:obj:`int`): Unique message identifier inside the chat.
|
||||
date (:class:`datetime.datetime`): Date of the change in Unix time.
|
||||
|datetime_localization|
|
||||
old_reaction (Tuple[:class:`telegram.ReactionType`]): Previous list of reaction types
|
||||
old_reaction (tuple[:class:`telegram.ReactionType`]): Previous list of reaction types
|
||||
that were set by the user.
|
||||
new_reaction (Tuple[:class:`telegram.ReactionType`]): New list of reaction types that
|
||||
new_reaction (tuple[:class:`telegram.ReactionType`]): New list of reaction types that
|
||||
were set by the user.
|
||||
user (:class:`telegram.User`): Optional. The user that changed the reaction, if the user
|
||||
isn't anonymous.
|
||||
@@ -169,8 +170,8 @@ class MessageReactionUpdated(TelegramObject):
|
||||
self.chat: Chat = chat
|
||||
self.message_id: int = message_id
|
||||
self.date: datetime = date
|
||||
self.old_reaction: Tuple[ReactionType, ...] = parse_sequence_arg(old_reaction)
|
||||
self.new_reaction: Tuple[ReactionType, ...] = parse_sequence_arg(new_reaction)
|
||||
self.old_reaction: tuple[ReactionType, ...] = parse_sequence_arg(old_reaction)
|
||||
self.new_reaction: tuple[ReactionType, ...] = parse_sequence_arg(new_reaction)
|
||||
|
||||
# Optional
|
||||
self.user: Optional[User] = user
|
||||
|
||||
+58
-7
@@ -18,12 +18,14 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects that represent paid media in Telegram."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._files.video import Video
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
@@ -80,7 +82,7 @@ class PaidMedia(TelegramObject):
|
||||
care of selecting the correct subclass.
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
data (dict[:obj:`str`, ...]): The JSON data.
|
||||
bot (:class:`telegram.Bot`, optional): The bot associated with this object.
|
||||
|
||||
Returns:
|
||||
@@ -95,7 +97,7 @@ class PaidMedia(TelegramObject):
|
||||
if not data and cls is PaidMedia:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[PaidMedia]] = {
|
||||
_class_mapping: dict[str, type[PaidMedia]] = {
|
||||
cls.PREVIEW: PaidMediaPreview,
|
||||
cls.PHOTO: PaidMediaPhoto,
|
||||
cls.VIDEO: PaidMediaVideo,
|
||||
@@ -164,7 +166,7 @@ class PaidMediaPhoto(PaidMedia):
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the paid media, always :tg-const:`telegram.PaidMedia.PHOTO`.
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): The photo.
|
||||
photo (tuple[:class:`telegram.PhotoSize`]): The photo.
|
||||
"""
|
||||
|
||||
__slots__ = ("photo",)
|
||||
@@ -178,7 +180,7 @@ class PaidMediaPhoto(PaidMedia):
|
||||
super().__init__(type=PaidMedia.PHOTO, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.photo: Tuple[PhotoSize, ...] = parse_sequence_arg(photo)
|
||||
self.photo: tuple[PhotoSize, ...] = parse_sequence_arg(photo)
|
||||
|
||||
self._id_attrs = (self.type, self.photo)
|
||||
|
||||
@@ -258,7 +260,7 @@ class PaidMediaInfo(TelegramObject):
|
||||
Attributes:
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access to
|
||||
the media.
|
||||
paid_media (Tuple[:class:`telegram.PaidMedia`]): Information about the paid media.
|
||||
paid_media (tuple[:class:`telegram.PaidMedia`]): Information about the paid media.
|
||||
"""
|
||||
|
||||
__slots__ = ("paid_media", "star_count")
|
||||
@@ -272,7 +274,7 @@ class PaidMediaInfo(TelegramObject):
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.star_count: int = star_count
|
||||
self.paid_media: Tuple[PaidMedia, ...] = parse_sequence_arg(paid_media)
|
||||
self.paid_media: tuple[PaidMedia, ...] = parse_sequence_arg(paid_media)
|
||||
|
||||
self._id_attrs = (self.star_count, self.paid_media)
|
||||
self._freeze()
|
||||
@@ -288,3 +290,52 @@ class PaidMediaInfo(TelegramObject):
|
||||
|
||||
data["paid_media"] = PaidMedia.de_list(data.get("paid_media"), bot=bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class PaidMediaPurchased(TelegramObject):
|
||||
"""This object contains information about a paid media purchase.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`from_user` and :attr:`paid_media_payload` are equal.
|
||||
|
||||
Note:
|
||||
In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead.
|
||||
|
||||
.. versionadded:: 21.6
|
||||
|
||||
Args:
|
||||
from_user (:class:`telegram.User`): User who purchased the media.
|
||||
paid_media_payload (:obj:`str`): Bot-specified paid media payload.
|
||||
|
||||
Attributes:
|
||||
from_user (:class:`telegram.User`): User who purchased the media.
|
||||
paid_media_payload (:obj:`str`): Bot-specified paid media payload.
|
||||
"""
|
||||
|
||||
__slots__ = ("from_user", "paid_media_payload")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
from_user: "User",
|
||||
paid_media_payload: str,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.from_user: User = from_user
|
||||
self.paid_media_payload: str = paid_media_payload
|
||||
|
||||
self._id_attrs = (self.from_user, self.paid_media_payload)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["PaidMediaPurchased"]:
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["from_user"] = User.de_json(data=data.pop("from"), bot=bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
# pylint: disable=missing-module-docstring, redefined-builtin
|
||||
import json
|
||||
from base64 import b64decode
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, no_type_check
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional, no_type_check
|
||||
|
||||
try:
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
@@ -390,11 +391,11 @@ class SecureValue(TelegramObject):
|
||||
selfie (:class:`telegram.FileCredentials`, optional): Credentials for encrypted selfie
|
||||
of the user with a document. Can be available for "passport", "driver_license",
|
||||
"identity_card" and "internal_passport".
|
||||
translation (List[:class:`telegram.FileCredentials`], optional): Credentials for an
|
||||
translation (list[:class:`telegram.FileCredentials`], optional): Credentials for an
|
||||
encrypted translation of the document. Available for "passport", "driver_license",
|
||||
"identity_card", "internal_passport", "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration" and "temporary_registration".
|
||||
files (List[:class:`telegram.FileCredentials`], optional): Credentials for encrypted
|
||||
files (list[:class:`telegram.FileCredentials`], optional): Credentials for encrypted
|
||||
files. Available for "utility_bill", "bank_statement", "rental_agreement",
|
||||
"passport_registration" and "temporary_registration" types.
|
||||
|
||||
@@ -410,7 +411,7 @@ class SecureValue(TelegramObject):
|
||||
selfie (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted selfie
|
||||
of the user with a document. Can be available for "passport", "driver_license",
|
||||
"identity_card" and "internal_passport".
|
||||
translation (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for an
|
||||
translation (tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for an
|
||||
encrypted translation of the document. Available for "passport", "driver_license",
|
||||
"identity_card", "internal_passport", "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration" and "temporary_registration".
|
||||
@@ -418,7 +419,7 @@ class SecureValue(TelegramObject):
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
files (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted
|
||||
files (tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted
|
||||
files. Available for "utility_bill", "bank_statement", "rental_agreement",
|
||||
"passport_registration" and "temporary_registration" types.
|
||||
|
||||
@@ -447,8 +448,8 @@ class SecureValue(TelegramObject):
|
||||
self.front_side: Optional[FileCredentials] = front_side
|
||||
self.reverse_side: Optional[FileCredentials] = reverse_side
|
||||
self.selfie: Optional[FileCredentials] = selfie
|
||||
self.files: Tuple[FileCredentials, ...] = parse_sequence_arg(files)
|
||||
self.translation: Tuple[FileCredentials, ...] = parse_sequence_arg(translation)
|
||||
self.files: tuple[FileCredentials, ...] = parse_sequence_arg(files)
|
||||
self.translation: tuple[FileCredentials, ...] = parse_sequence_arg(translation)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user