From 995321698024630d432a8b24c3d28d0ff8d0e21e Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Sun, 5 Feb 2023 18:09:55 +0100 Subject: [PATCH] Documentation Improvements (#3464, #3483, #3484, #3497, #3512, #3501, #3515, #3523, #3498, #3529) Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com> Co-authored-by: Shivam Saini <51438830+shivamsn97@users.noreply.github.com> Co-authored-by: Aditya Yadav Co-authored-by: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Co-authored-by: Crsi <47722349+CrsiX@users.noreply.github.com> Co-authored-by: poolitzer Co-authored-by: Aditya --- .github/CONTRIBUTING.rst | 2 +- .github/workflows/docs.yml | 2 + .pre-commit-config.yaml | 2 +- AUTHORS.rst | 1 + docs/Makefile | 2 + docs/auxil/admonition_inserter.py | 599 ++++++++++++++++++ docs/auxil/kwargs_insertion.py | 79 +++ docs/auxil/link_code.py | 77 +++ docs/auxil/sphinx_hooks.py | 209 ++++++ docs/auxil/tg_const_role.py | 92 +++ docs/requirements-docs.txt | 7 +- docs/source/_static/style_admonitions.css | 65 ++ docs/source/_static/style_general.css | 3 + docs/source/_static/style_sidebar_brand.css | 11 + docs/source/conf.py | 347 +--------- docs/source/telegram.animation.rst | 4 +- docs/source/telegram.audio.rst | 4 +- docs/source/telegram.bot.rst | 4 +- docs/source/telegram.botcommand.rst | 4 +- docs/source/telegram.botcommandscope.rst | 4 +- ...m.botcommandscopeallchatadministrators.rst | 4 +- .../telegram.botcommandscopeallgroupchats.rst | 4 +- ...elegram.botcommandscopeallprivatechats.rst | 4 +- docs/source/telegram.botcommandscopechat.rst | 4 +- ...gram.botcommandscopechatadministrators.rst | 4 +- .../telegram.botcommandscopechatmember.rst | 4 +- .../telegram.botcommandscopedefault.rst | 4 +- docs/source/telegram.callbackgame.rst | 4 +- docs/source/telegram.callbackquery.rst | 4 +- docs/source/telegram.chat.rst | 4 +- .../telegram.chatadministratorrights.rst | 4 +- docs/source/telegram.chatinvitelink.rst | 4 +- docs/source/telegram.chatjoinrequest.rst | 4 +- docs/source/telegram.chatlocation.rst | 4 +- docs/source/telegram.chatmember.rst | 4 +- .../telegram.chatmemberadministrator.rst | 4 +- docs/source/telegram.chatmemberbanned.rst | 4 +- docs/source/telegram.chatmemberleft.rst | 4 +- docs/source/telegram.chatmembermember.rst | 4 +- docs/source/telegram.chatmemberowner.rst | 4 +- docs/source/telegram.chatmemberrestricted.rst | 4 +- docs/source/telegram.chatmemberupdated.rst | 4 +- docs/source/telegram.chatpermissions.rst | 4 +- docs/source/telegram.chatphoto.rst | 4 +- docs/source/telegram.choseninlineresult.rst | 4 +- docs/source/telegram.contact.rst | 4 +- docs/source/telegram.credentials.rst | 4 +- docs/source/telegram.datacredentials.rst | 4 +- docs/source/telegram.dice.rst | 4 +- docs/source/telegram.document.rst | 4 +- docs/source/telegram.encryptedcredentials.rst | 4 +- .../telegram.encryptedpassportelement.rst | 4 +- docs/source/telegram.ext.aioratelimiter.rst | 4 +- docs/source/telegram.ext.application.rst | 4 +- .../telegram.ext.applicationbuilder.rst | 4 +- .../telegram.ext.applicationhandlerstop.rst | 4 +- docs/source/telegram.ext.basehandler.rst | 4 +- docs/source/telegram.ext.basepersistence.rst | 4 +- docs/source/telegram.ext.baseratelimiter.rst | 4 +- docs/source/telegram.ext.callbackcontext.rst | 4 +- .../source/telegram.ext.callbackdatacache.rst | 4 +- .../telegram.ext.callbackqueryhandler.rst | 4 +- .../telegram.ext.chatjoinrequesthandler.rst | 4 +- .../source/telegram.ext.chatmemberhandler.rst | 4 +- ...telegram.ext.choseninlineresulthandler.rst | 4 +- docs/source/telegram.ext.commandhandler.rst | 4 +- docs/source/telegram.ext.contexttypes.rst | 4 +- .../telegram.ext.conversationhandler.rst | 4 +- docs/source/telegram.ext.defaults.rst | 4 +- docs/source/telegram.ext.dictpersistence.rst | 4 +- docs/source/telegram.ext.extbot.rst | 4 +- docs/source/telegram.ext.filters.rst | 4 +- .../telegram.ext.inlinequeryhandler.rst | 4 +- .../telegram.ext.invalidcallbackdata.rst | 4 +- docs/source/telegram.ext.job.rst | 4 +- docs/source/telegram.ext.jobqueue.rst | 4 +- docs/source/telegram.ext.messagehandler.rst | 4 +- docs/source/telegram.ext.persistenceinput.rst | 4 +- .../source/telegram.ext.picklepersistence.rst | 4 +- .../source/telegram.ext.pollanswerhandler.rst | 4 +- docs/source/telegram.ext.pollhandler.rst | 4 +- .../telegram.ext.precheckoutqueryhandler.rst | 4 +- docs/source/telegram.ext.prefixhandler.rst | 4 +- .../telegram.ext.shippingqueryhandler.rst | 4 +- .../telegram.ext.stringcommandhandler.rst | 4 +- .../telegram.ext.stringregexhandler.rst | 4 +- docs/source/telegram.ext.typehandler.rst | 4 +- docs/source/telegram.ext.updater.rst | 4 +- docs/source/telegram.file.rst | 4 +- docs/source/telegram.filecredentials.rst | 4 +- docs/source/telegram.forcereply.rst | 4 +- docs/source/telegram.forumtopic.rst | 4 +- docs/source/telegram.forumtopicclosed.rst | 4 +- docs/source/telegram.forumtopiccreated.rst | 4 +- docs/source/telegram.forumtopicedited.rst | 4 +- docs/source/telegram.forumtopicreopened.rst | 4 +- docs/source/telegram.game.rst | 4 +- docs/source/telegram.gamehighscore.rst | 4 +- .../telegram.generalforumtopichidden.rst | 4 +- .../telegram.generalforumtopicunhidden.rst | 4 +- docs/source/telegram.iddocumentdata.rst | 4 +- docs/source/telegram.inlinekeyboardbutton.rst | 4 +- docs/source/telegram.inlinekeyboardmarkup.rst | 4 +- docs/source/telegram.inlinequery.rst | 4 +- docs/source/telegram.inlinequeryresult.rst | 4 +- .../telegram.inlinequeryresultarticle.rst | 4 +- .../telegram.inlinequeryresultaudio.rst | 4 +- .../telegram.inlinequeryresultcachedaudio.rst | 4 +- ...legram.inlinequeryresultcacheddocument.rst | 4 +- .../telegram.inlinequeryresultcachedgif.rst | 4 +- ...legram.inlinequeryresultcachedmpeg4gif.rst | 4 +- .../telegram.inlinequeryresultcachedphoto.rst | 4 +- ...elegram.inlinequeryresultcachedsticker.rst | 4 +- .../telegram.inlinequeryresultcachedvideo.rst | 4 +- .../telegram.inlinequeryresultcachedvoice.rst | 4 +- .../telegram.inlinequeryresultcontact.rst | 4 +- .../telegram.inlinequeryresultdocument.rst | 4 +- .../source/telegram.inlinequeryresultgame.rst | 4 +- docs/source/telegram.inlinequeryresultgif.rst | 4 +- .../telegram.inlinequeryresultlocation.rst | 4 +- .../telegram.inlinequeryresultmpeg4gif.rst | 4 +- .../telegram.inlinequeryresultphoto.rst | 4 +- .../telegram.inlinequeryresultvenue.rst | 4 +- .../telegram.inlinequeryresultvideo.rst | 4 +- .../telegram.inlinequeryresultvoice.rst | 4 +- .../telegram.inputcontactmessagecontent.rst | 4 +- docs/source/telegram.inputfile.rst | 4 +- .../telegram.inputinvoicemessagecontent.rst | 4 +- .../telegram.inputlocationmessagecontent.rst | 4 +- docs/source/telegram.inputmedia.rst | 4 +- docs/source/telegram.inputmediaanimation.rst | 4 +- docs/source/telegram.inputmediaaudio.rst | 4 +- docs/source/telegram.inputmediadocument.rst | 4 +- docs/source/telegram.inputmediaphoto.rst | 4 +- docs/source/telegram.inputmediavideo.rst | 4 +- docs/source/telegram.inputmessagecontent.rst | 4 +- .../telegram.inputtextmessagecontent.rst | 4 +- .../telegram.inputvenuemessagecontent.rst | 4 +- docs/source/telegram.invoice.rst | 4 +- docs/source/telegram.keyboardbutton.rst | 4 +- .../telegram.keyboardbuttonpolltype.rst | 4 +- docs/source/telegram.labeledprice.rst | 4 +- docs/source/telegram.location.rst | 4 +- docs/source/telegram.loginurl.rst | 4 +- docs/source/telegram.maskposition.rst | 4 +- docs/source/telegram.menubutton.rst | 4 +- docs/source/telegram.menubuttoncommands.rst | 4 +- docs/source/telegram.menubuttondefault.rst | 4 +- docs/source/telegram.menubuttonwebapp.rst | 4 +- docs/source/telegram.message.rst | 4 +- ...telegram.messageautodeletetimerchanged.rst | 4 +- docs/source/telegram.messageentity.rst | 4 +- docs/source/telegram.messageid.rst | 4 +- docs/source/telegram.orderinfo.rst | 4 +- docs/source/telegram.passportdata.rst | 4 +- docs/source/telegram.passportelementerror.rst | 4 +- ...telegram.passportelementerrordatafield.rst | 4 +- .../telegram.passportelementerrorfile.rst | 4 +- .../telegram.passportelementerrorfiles.rst | 4 +- ...telegram.passportelementerrorfrontside.rst | 4 +- ...legram.passportelementerrorreverseside.rst | 4 +- .../telegram.passportelementerrorselfie.rst | 4 +- ...am.passportelementerrortranslationfile.rst | 4 +- ...m.passportelementerrortranslationfiles.rst | 4 +- ...legram.passportelementerrorunspecified.rst | 4 +- docs/source/telegram.passportfile.rst | 4 +- docs/source/telegram.personaldetails.rst | 4 +- docs/source/telegram.photosize.rst | 4 +- docs/source/telegram.poll.rst | 4 +- docs/source/telegram.pollanswer.rst | 4 +- docs/source/telegram.polloption.rst | 4 +- docs/source/telegram.precheckoutquery.rst | 4 +- .../telegram.proximityalerttriggered.rst | 4 +- docs/source/telegram.replykeyboardmarkup.rst | 4 +- docs/source/telegram.replykeyboardremove.rst | 4 +- docs/source/telegram.request.baserequest.rst | 4 +- docs/source/telegram.request.httpxrequest.rst | 4 +- docs/source/telegram.request.requestdata.rst | 4 +- docs/source/telegram.residentialaddress.rst | 4 +- docs/source/telegram.securedata.rst | 4 +- docs/source/telegram.securevalue.rst | 4 +- docs/source/telegram.sentwebappmessage.rst | 4 +- docs/source/telegram.shippingaddress.rst | 4 +- docs/source/telegram.shippingoption.rst | 4 +- docs/source/telegram.shippingquery.rst | 4 +- docs/source/telegram.sticker.rst | 4 +- docs/source/telegram.stickerset.rst | 4 +- docs/source/telegram.successfulpayment.rst | 4 +- docs/source/telegram.telegramobject.rst | 4 +- docs/source/telegram.update.rst | 4 +- docs/source/telegram.user.rst | 4 +- docs/source/telegram.userprofilephotos.rst | 4 +- docs/source/telegram.venue.rst | 4 +- docs/source/telegram.video.rst | 4 +- docs/source/telegram.videochatended.rst | 4 +- .../telegram.videochatparticipantsinvited.rst | 4 +- docs/source/telegram.videochatscheduled.rst | 5 +- docs/source/telegram.videochatstarted.rst | 4 +- docs/source/telegram.videonote.rst | 4 +- docs/source/telegram.voice.rst | 4 +- docs/source/telegram.webappdata.rst | 4 +- docs/source/telegram.webappinfo.rst | 4 +- docs/source/telegram.webhookinfo.rst | 4 +- docs/source/telegram.writeaccessallowed.rst | 4 +- telegram/_bot.py | 257 ++------ telegram/_callbackquery.py | 2 +- telegram/_chatadministratorrights.py | 9 +- telegram/_chatmember.py | 8 +- telegram/_chatmemberupdated.py | 2 +- telegram/_choseninlineresult.py | 2 +- telegram/_files/file.py | 12 +- telegram/_files/venue.py | 2 +- telegram/_inline/inlinequery.py | 2 +- telegram/_keyboardbutton.py | 16 +- telegram/_message.py | 14 +- telegram/_passport/credentials.py | 4 +- telegram/_payment/precheckoutquery.py | 2 +- telegram/_payment/shippingquery.py | 2 +- telegram/_poll.py | 4 +- telegram/ext/_aioratelimiter.py | 2 +- telegram/ext/_application.py | 17 +- telegram/ext/_applicationbuilder.py | 9 +- telegram/ext/_basepersistence.py | 10 +- telegram/ext/_callbackcontext.py | 2 +- telegram/ext/_callbackdatacache.py | 5 +- telegram/ext/_conversationhandler.py | 4 +- telegram/ext/_dictpersistence.py | 10 +- telegram/ext/_jobqueue.py | 11 +- telegram/ext/_picklepersistence.py | 10 +- telegram/ext/_updater.py | 3 +- tests/docs/README.md | 7 + tests/docs/admonition_inserter.py | 232 +++++++ 232 files changed, 1905 insertions(+), 1010 deletions(-) create mode 100644 docs/auxil/admonition_inserter.py create mode 100644 docs/auxil/kwargs_insertion.py create mode 100644 docs/auxil/link_code.py create mode 100644 docs/auxil/sphinx_hooks.py create mode 100644 docs/auxil/tg_const_role.py create mode 100644 docs/source/_static/style_admonitions.css create mode 100644 docs/source/_static/style_general.css create mode 100644 docs/source/_static/style_sidebar_brand.css create mode 100644 tests/docs/README.md create mode 100644 tests/docs/admonition_inserter.py diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 6b813ead8..6e5e2190b 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -185,7 +185,7 @@ doc strings don't have a separate documentation site they generate, instead, the User facing documentation ------------------------- -We use `sphinx`_ to generate static HTML docs. To build them, first make sure you have the required dependencies: +We use `sphinx`_ to generate static HTML docs. To build them, first make sure you're running Python 3.9 or above and have the required dependencies: .. code-block:: bash diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9cdb9e86a..64bdbe636 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -30,6 +30,8 @@ jobs: run: | python -W ignore -m pip install --upgrade pip python -W ignore -m pip install -r requirements-all.txt + - name: Test autogeneration of admonitions + run: pytest -v --tb=short tests/docs/admonition_inserter.py - name: Build docs run: sphinx-build docs/source docs/build/html -W --keep-going -j auto - name: Upload docs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0d3ade148..b13703376 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -68,7 +68,7 @@ repos: rev: v3.3.1 hooks: - id: pyupgrade - files: ^(telegram|examples|tests)/.*\.py$ + files: ^(telegram|examples|tests|docs)/.*\.py$ args: - --py37-plus - repo: https://github.com/pycqa/isort diff --git a/AUTHORS.rst b/AUTHORS.rst index 7f38b601c..1f806057b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -102,6 +102,7 @@ The following wonderful people contributed directly or indirectly to this projec - `Sahil Sharma `_ - `Sascha `_ - `Shelomentsev D `_ +- `Shivam Saini `_ - `Simon Schürrle `_ - `sooyhwang `_ - `syntx `_ diff --git a/docs/Makefile b/docs/Makefile index 42da80011..97bac83fc 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -56,6 +56,8 @@ html: @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." +rebuild: clean html + dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo diff --git a/docs/auxil/admonition_inserter.py b/docs/auxil/admonition_inserter.py new file mode 100644 index 000000000..31634277a --- /dev/null +++ b/docs/auxil/admonition_inserter.py @@ -0,0 +1,599 @@ +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2023 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +import collections.abc +import inspect +import re +import typing +from collections import defaultdict +from typing import Any, Iterator, Union + +import telegram +import telegram.ext + + +def _iter_own_public_methods(cls: type) -> Iterator[tuple[str, type]]: + """Iterates over methods of a class that are not protected/private, + not camelCase and not inherited from the parent class. + + Returns pairs of method names and methods. + + This function is defined outside the class because it is used to create class constants. + """ + return ( + m + for m in inspect.getmembers(cls, predicate=inspect.isfunction) # not .ismethod + if not m[0].startswith("_") + and m[0].islower() # to avoid camelCase methods + and m[0] in cls.__dict__ # method is not inherited from parent class + ) + + +class AdmonitionInserter: + """Class for inserting admonitions into docs of Telegram classes.""" + + CLASS_ADMONITION_TYPES = ("use_in", "available_in", "returned_in") + METHOD_ADMONITION_TYPES = ("shortcuts",) + ALL_ADMONITION_TYPES = CLASS_ADMONITION_TYPES + METHOD_ADMONITION_TYPES + + FORWARD_REF_PATTERN = re.compile(r"^ForwardRef\('(?P\w+)'\)$") + """ A pattern to find a class name in a ForwardRef typing annotation. + Class name (in a named group) is surrounded by parentheses and single quotes. + Note that since we're analyzing argument by argument, the pattern can be strict, with + start and end markers. + """ + + FORWARD_REF_SKIP_PATTERN = re.compile(r"^ForwardRef\('DefaultValue\[\w+]'\)$") + """A pattern that will be used to skip known ForwardRef's that need not be resolved + to a Telegram class, e.g.: + ForwardRef('DefaultValue[None]') + ForwardRef('DefaultValue[DVValueType]') + """ + + METHOD_NAMES_FOR_BOT_AND_APPBUILDER: dict[type, str] = { + cls: tuple(m[0] for m in _iter_own_public_methods(cls)) # m[0] means we take only names + for cls in (telegram.Bot, telegram.ext.ApplicationBuilder) + } + """A dictionary mapping Bot and ApplicationBuilder classes to their relevant methods that will + be mentioned in 'Returned in' and 'Use in' admonitions in other classes' docstrings. + Methods must be public, not aliases, not inherited from TelegramObject. + """ + + def __init__(self): + self.admonitions: dict[str, dict[Union[type, collections.abc.Callable], str]] = { + # dynamically determine which method to use to create a sub-dictionary + admonition_type: getattr(self, f"_create_{admonition_type}")() + for admonition_type in self.ALL_ADMONITION_TYPES + } + """Dictionary with admonitions. Contains sub-dictionaries, one per admonition type. + Each sub-dictionary matches bot methods (for "Shortcuts") or telegram classes (for other + admonition types) to texts of admonitions, e.g.: + ``` + { + "use_in": {: + <"Use in" admonition for ChatInviteLink>, ...}, + "available_in": {: + <"Available in" admonition">, ...}, + "returned_in": {...} + } + ``` + """ + + def insert_admonitions( + self, + obj: Union[type, collections.abc.Callable], + docstring_lines: list[str], + ): + """Inserts admonitions into docstring lines for a given class or method. + + **Modifies lines in place**. + """ + # A better way would be to copy the lines and return them, but that will not work with + # docs.auxil.sphinx_hooks.autodoc_process_docstring() + + for admonition_type in self.ALL_ADMONITION_TYPES: + + # If there is no admonition of the given type for the given class or method, + # continue to the next admonition type, maybe the class/method is listed there. + if obj not in self.admonitions[admonition_type]: + continue + + insert_idx = self._find_insert_pos_for_admonition(docstring_lines) + admonition_lines = self.admonitions[admonition_type][obj].splitlines() + + for idx in range(insert_idx, insert_idx + len(admonition_lines)): + docstring_lines.insert(idx, admonition_lines[idx - insert_idx]) + + def _create_available_in(self) -> dict[type, str]: + """Creates a dictionary with 'Available in' admonitions for classes that are available + in attributes of other classes. + """ + + # Generate a mapping of classes to ReST links to attributes in other classes that + # correspond to instances of a given class + # i.e. {telegram._files.sticker.Sticker: {":attr:`telegram.Message.sticker`", ...}} + attrs_for_class = defaultdict(set) + + # The following regex is supposed to capture a class name in a line like this: + # media (:obj:`str` | :class:`telegram.InputFile`): Audio file to send. + # + # Note that even if such typing description spans over multiple lines but each line ends + # with a backslash (otherwise Sphinx will throw an error) + # (e.g. EncryptedPassportElement.data), then Sphinx will combine these lines into a single + # line automatically, and it will contain no backslash (only some extra many whitespaces + # from the indentation). + + attr_docstr_pattern = re.compile( + r"^\s*(?P[a-z_]+)" # Any number of spaces, named group for attribute + r"\s?\(" # Optional whitespace, opening parenthesis + r".*" # Any number of characters (that could denote a built-in type) + r":class:`.+`" # Marker of a classref, class name in backticks + r".*\):" # Any number of characters, closing parenthesis, colon. + # The ^ colon above along with parenthesis is important because it makes sure that + # the class is mentioned in the attribute description, not in free text. + r".*$", # Any number of characters, end of string (end of line) + re.VERBOSE, + ) + + # for properties: there is no attr name in docstring. Just check if there's a class name. + prop_docstring_pattern = re.compile(r":class:`.+`.*:") + + # pattern for iterating over potentially many class names in docstring for one attribute. + # Tilde is optional (sometimes it is in the docstring, sometimes not). + single_class_name_pattern = re.compile(r":class:`~?(?P[\w.]*)`") + + classes_to_inspect = inspect.getmembers(telegram, inspect.isclass) + inspect.getmembers( + telegram.ext, inspect.isclass + ) + + for class_name, inspected_class in classes_to_inspect: + # We need to make "" into + # "telegram.StickerSet" because that's the way the classes are mentioned in + # docstrings. + name_of_inspected_class_in_docstr = self._generate_class_name_for_link(inspected_class) + + # Parsing part of the docstring with attributes (parsing of properties follows later) + docstring_lines = inspect.getdoc(inspected_class).splitlines() + lines_with_attrs = [] + for idx, line in enumerate(docstring_lines): + if line.strip() == "Attributes:": + lines_with_attrs = docstring_lines[idx + 1 :] + break + + for line in lines_with_attrs: + line_match = attr_docstr_pattern.match(line) + if not line_match: + continue + + target_attr = line_match.group("attr_name") + # a typing description of one attribute can contain multiple classes + for match in single_class_name_pattern.finditer(line): + name_of_class_in_attr = match.group("class_name") + + # Writing to dictionary: matching the class found in the docstring + # and its subclasses to the attribute of the class being inspected. + # The class in the attribute docstring (or its subclass) is the key, + # ReST link to attribute of the class currently being inspected is the value. + try: + self._resolve_arg_and_add_link( + arg=name_of_class_in_attr, + dict_of_methods_for_class=attrs_for_class, + link=f":attr:`{name_of_inspected_class_in_docstr}.{target_attr}`", + ) + except NotImplementedError as e: + raise NotImplementedError( + f"Error generating Sphinx 'Available in' admonition " + f"(admonition_inserter.py). Class {name_of_class_in_attr} present in " + f"attribute {target_attr} of class {name_of_inspected_class_in_docstr}" + f" could not be resolved. {str(e)}" + ) + + # Properties need to be parsed separately because they act like attributes but not + # listed as attributes. + properties = inspect.getmembers(inspected_class, lambda o: isinstance(o, property)) + for prop_name, _ in properties: + # Make sure this property is really defined in the class being inspected. + # A property can be inherited from a parent class, then a link to it will not work. + if prop_name not in inspected_class.__dict__: + continue + + # 1. Can't use typing.get_type_hints because double-quoted type hints + # (like "Application") will throw a NameError + # 2. Can't use inspect.signature because return annotations of properties can be + # hard to parse (like "(self) -> BD"). + # 3. fget is used to access the actual function under the property wrapper + docstring = inspect.getdoc(getattr(inspected_class, prop_name).fget) + if docstring is None: + continue + + first_line = docstring.splitlines()[0] + if not prop_docstring_pattern.match(first_line): + continue + + for match in single_class_name_pattern.finditer(first_line): + name_of_class_in_prop = match.group("class_name") + + # Writing to dictionary: matching the class found in the docstring and its + # subclasses to the property of the class being inspected. + # The class in the property docstring (or its subclass) is the key, + # ReST link to property of the class currently being inspected is the value. + try: + self._resolve_arg_and_add_link( + arg=name_of_class_in_prop, + dict_of_methods_for_class=attrs_for_class, + link=f":attr:`{name_of_inspected_class_in_docstr}.{prop_name}`", + ) + except NotImplementedError as e: + raise NotImplementedError( + f"Error generating Sphinx 'Available in' admonition " + f"(admonition_inserter.py). Class {name_of_class_in_prop} present in " + f"property {prop_name} of class {name_of_inspected_class_in_docstr}" + f" could not be resolved. {str(e)}" + ) + + return self._generate_admonitions(attrs_for_class, admonition_type="available_in") + + def _create_returned_in(self) -> dict[type, str]: + """Creates a dictionary with 'Returned in' admonitions for classes that are returned + in Bot's and ApplicationBuilder's methods. + """ + + # Generate a mapping of classes to ReST links to Bot methods which return it, + # i.e. {: {:meth:`telegram.Bot.send_message`, ...}} + methods_for_class = defaultdict(set) + + for cls, method_names in self.METHOD_NAMES_FOR_BOT_AND_APPBUILDER.items(): + for method_name in method_names: + + sig = inspect.signature(getattr(cls, method_name)) + ret_annot = sig.return_annotation + + method_link = self._generate_link_to_method(method_name, cls) + + try: + self._resolve_arg_and_add_link( + arg=ret_annot, + dict_of_methods_for_class=methods_for_class, + link=method_link, + ) + except NotImplementedError as e: + raise NotImplementedError( + f"Error generating Sphinx 'Returned in' admonition " + f"(admonition_inserter.py). {cls}, method {method_name}. " + f"Couldn't resolve type hint in return annotation {ret_annot}. {str(e)}" + ) + + return self._generate_admonitions(methods_for_class, admonition_type="returned_in") + + def _create_shortcuts(self) -> dict[collections.abc.Callable, str]: + """Creates a dictionary with 'Shortcuts' admonitions for Bot methods that + have shortcuts in other classes. + """ + + # pattern for looking for calls to Bot methods only + bot_method_pattern = re.compile( + r"""\s* # any number of whitespaces + (?<=return\sawait\sself\.get_bot\(\)\.) # lookbehind + \w+ # the method name we are looking for, letters/underscores + (?=\() # lookahead: opening bracket before the args of the method start + """, + re.VERBOSE, + ) + + # Generate a mapping of methods of classes to links to Bot methods which they are shortcuts + # for, i.e. {: {:meth:`telegram.User.send_voice`, ...} + shortcuts_for_bot_method = defaultdict(set) + + # inspect methods of all telegram classes for return statements that indicate + # that this given method is a shortcut for a Bot method + for class_name, cls in inspect.getmembers(telegram, predicate=inspect.isclass): + + # no need to inspect Bot's own methods, as Bot can't have shortcuts in Bot + if cls is telegram.Bot: + continue + + for method_name, method in _iter_own_public_methods(cls): + + # .getsourcelines() returns a tuple. Item [1] is an int + for line in inspect.getsourcelines(method)[0]: + + if not (bot_method_match := bot_method_pattern.search(line)): + continue + + bot_method = getattr(telegram.Bot, bot_method_match.group()) + + link_to_shortcut_method = self._generate_link_to_method(method_name, cls) + + shortcuts_for_bot_method[bot_method].add(link_to_shortcut_method) + + return self._generate_admonitions(shortcuts_for_bot_method, admonition_type="shortcuts") + + def _create_use_in(self) -> dict[type, str]: + """Creates a dictionary with 'Use in' admonitions for classes whose instances are + accepted as arguments for Bot's and ApplicationBuilder's methods. + """ + + # Generate a mapping of classes to links to Bot methods which accept them as arguments, + # i.e. {: + # {:meth:`telegram.Bot.answer_inline_query`, ...}} + methods_for_class = defaultdict(set) + + for cls, method_names in self.METHOD_NAMES_FOR_BOT_AND_APPBUILDER.items(): + for method_name in method_names: + method_link = self._generate_link_to_method(method_name, cls) + + sig = inspect.signature(getattr(cls, method_name)) + parameters = sig.parameters + + for param in parameters.values(): + try: + self._resolve_arg_and_add_link( + arg=param.annotation, + dict_of_methods_for_class=methods_for_class, + link=method_link, + ) + except NotImplementedError as e: + raise NotImplementedError( + f"Error generating Sphinx 'Use in' admonition " + f"(admonition_inserter.py). {cls}, method {method_name}, parameter " + f"{param}: Couldn't resolve type hint {param.annotation}. {str(e)}" + ) + + return self._generate_admonitions(methods_for_class, admonition_type="use_in") + + @staticmethod + def _find_insert_pos_for_admonition(lines: list[str]) -> int: + """Finds the correct position to insert the class admonition and returns the index. + + The admonition will be insert above "See also", "Examples:", version added/changed notes + and args, whatever comes first. + + If no key phrases are found, the admonition will be inserted at the very end. + """ + for idx, value in list(enumerate(lines)): + if ( + value.startswith(".. seealso:") + # The docstring contains heading "Examples:", but Sphinx will have it converted + # to ".. admonition: Examples": + or value.startswith(".. admonition:: Examples") + or value.startswith(".. version") + # The space after ":param" is important because docstring can contain ":paramref:" + # in its plain text in the beginning of a line (e.g. ExtBot): + or value.startswith(":param ") + # some classes (like "Credentials") have no params, so insert before attrs: + or value.startswith(".. attribute::") + ): + return idx + return len(lines) - 1 + + def _generate_admonitions( + self, + attrs_or_methods_for_class: dict[type, set[str]], + admonition_type: str, + ) -> dict[type, str]: + """Generates admonitions of a given type. + Takes a dictionary of classes matched to ReST links to methods or attributes, e.g.: + + ``` + {: + [":meth: `telegram.Bot.get_sticker_set`", ...]}. + ``` + + Returns a dictionary of classes matched to full admonitions, e.g. + for `admonition_type` "returned_in" (note that title and CSS class are generated + automatically): + + ``` + {: + ".. admonition:: Returned in: + :class: returned-in + + :meth: `telegram.Bot.get_sticker_set`"}. + ``` + """ + + if admonition_type not in self.ALL_ADMONITION_TYPES: + raise TypeError(f"Admonition type {admonition_type} not supported.") + + admonition_for_class = {} + + for cls, attrs in attrs_or_methods_for_class.items(): + + if cls is telegram.ext.ApplicationBuilder: + # ApplicationBuilder is only used in and returned from its own methods, + # so its page needs no admonitions. + continue + + attrs = sorted(attrs) + + # e.g. for admonition type "use_in" the title will be "Use in" and CSS class "use-in". + admonition = f""" + +.. admonition:: {admonition_type.title().replace("_", " ")} + :class: {admonition_type.replace("_", "-")} + """ + if len(attrs) > 1: + for target_attr in attrs: + admonition += "\n * " + target_attr + else: + admonition += f"\n {attrs[0]}" + + admonition += "\n " # otherwise an unexpected unindent warning will be issued + admonition_for_class[cls] = admonition + + return admonition_for_class + + @staticmethod + def _generate_class_name_for_link(cls: type) -> str: + """Generates class name that can be used in a ReST link.""" + + # Check for potential presence of ".ext.", we will need to keep it. + ext = ".ext" if ".ext." in str(cls) else "" + return f"telegram{ext}.{cls.__name__}" + + def _generate_link_to_method(self, method_name: str, cls: type) -> str: + """Generates a ReST link to a method of a telegram class.""" + + return f":meth:`{self._generate_class_name_for_link(cls)}.{method_name}`" + + @staticmethod + def _iter_subclasses(cls: type) -> Iterator: + return ( + # exclude private classes + c + for c in cls.__subclasses__() + if not str(c).split(".")[-1].startswith("_") + ) + + def _resolve_arg_and_add_link( + self, + arg: Any, + dict_of_methods_for_class: defaultdict, + link: str, + ) -> None: + """A helper method. Tries to resolve the arg into a valid class. In case of success, + adds the link (to a method, attribute, or property) for that class' and its subclasses' + sets of links in the dictionary of admonitions. + + **Modifies dictionary in place.** + """ + for cls in self._resolve_arg(arg): + + # When trying to resolve an argument from args or return annotation, + # the method _resolve_arg returns None if nothing could be resolved. + # Also, if class was resolved correctly, "telegram" will definitely be in its str(). + if cls is None or "telegram" not in str(cls): + continue + + dict_of_methods_for_class[cls].add(link) + + for subclass in self._iter_subclasses(cls): + dict_of_methods_for_class[subclass].add(link) + + def _resolve_arg(self, arg: Any) -> Iterator[Union[type, None]]: + """Analyzes an argument of a method and recursively yields classes that the argument + or its sub-arguments (in cases like Union[...]) belong to, if they can be resolved to + telegram or telegram.ext classes. + + Raises `NotImplementedError`. + """ + + origin = typing.get_origin(arg) + + if ( + origin in (collections.abc.Callable, typing.IO) + or arg is None + # no other check available (by type or origin) for these: + or str(type(arg)) in ("", "") + ): + pass + + # RECURSIVE CALLS + # for cases like Union[Sequence.... + elif origin in ( + Union, + collections.abc.Coroutine, + collections.abc.Sequence, + ): + for sub_arg in typing.get_args(arg): + yield from self._resolve_arg(sub_arg) + + elif isinstance(arg, typing.TypeVar): + # gets access to the "bound=..." parameter + yield from self._resolve_arg(arg.__bound__) + # END RECURSIVE CALLS + + elif isinstance(arg, typing.ForwardRef): + m = self.FORWARD_REF_PATTERN.match(str(arg)) + # We're sure it's a ForwardRef, so, unless it belongs to known exceptions, + # the class must be resolved. + # If it isn't resolved, we'll have the program throw an exception to be sure. + try: + cls = self._resolve_class(m.group("class_name")) + except AttributeError: + # skip known ForwardRef's that need not be resolved to a Telegram class + if self.FORWARD_REF_SKIP_PATTERN.match(str(arg)): + pass + else: + raise NotImplementedError(f"Could not process ForwardRef: {arg}") + else: + yield cls + + # For custom generics like telegram.ext._application.Application[~BT, ~CCT, ~UD...]. + # This must come before the check for isinstance(type) because GenericAlias can also be + # recognized as type if it belongs to . + elif str(type(arg)) in ("", ""): + if "telegram" in str(arg): + # get_origin() of telegram.ext._application.Application[~BT, ~CCT, ~UD...] + # will produce + yield origin + + elif isinstance(arg, type): + if "telegram" in str(arg): + yield arg + + # For some reason "InlineQueryResult", "InputMedia" & some others are currently not + # recognized as ForwardRefs and are identified as plain strings. + elif isinstance(arg, str): + + # args like "ApplicationBuilder[BT, CCT, UD, CD, BD, JQ]" can be recognized as strings. + # Remove whatever is in the square brackets because it doesn't need to be parsed. + arg = re.sub(r"\[.+]", "", arg) + + cls = self._resolve_class(arg) + # Here we don't want an exception to be thrown since we're not sure it's ForwardRef + if cls is not None: + yield cls + + else: + raise NotImplementedError( + f"Cannot process argument {arg} of type {type(arg)} (origin {origin})" + ) + + @staticmethod + def _resolve_class(name: str) -> Union[type, None]: + """The keys in the admonitions dictionary are not strings like "telegram.StickerSet" + but classes like . + + This method attempts to resolve a PTB class from a name that does or does not + contain the word 'telegram', e.g. + from "telegram.StickerSet" or "StickerSet". + + Returns a class on success, :obj:`None` if nothing could be resolved. + """ + + for option in ( + name, + f"telegram.{name}", + f"telegram.ext.{name}", + f"telegram.ext.filters.{name}", + ): + try: + return eval(option) + # NameError will be raised if trying to eval just name and it doesn't work, e.g. + # "Name 'ApplicationBuilder' is not defined". + # AttributeError will be raised if trying to e.g. eval f"telegram.{name}" when the + # class denoted by `name` actually belongs to `telegram.ext`: + # "module 'telegram' has no attribute 'ApplicationBuilder'". + # If neither option works, this is not a PTB class. + except (NameError, AttributeError): + continue + + +if __name__ == "__main__": + # just try instantiating for debugging purposes + AdmonitionInserter() diff --git a/docs/auxil/kwargs_insertion.py b/docs/auxil/kwargs_insertion.py new file mode 100644 index 000000000..4cedfa6b5 --- /dev/null +++ b/docs/auxil/kwargs_insertion.py @@ -0,0 +1,79 @@ +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2023 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +import inspect + +keyword_args = [ + ":keyword _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: Value to pass to " + ":paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to {read_timeout}.", + ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: {read_timeout_type}, optional", + ":keyword _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: Value to pass to " + ":paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to {write_timeout}.", + ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: :obj:`float` | :obj:`None`, " + "optional", + ":keyword _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: Value to pass to " + ":paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to " + ":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.", + ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: :obj:`float` | " + ":obj:`None`, optional", + ":keyword _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: Value to pass to " + ":paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to " + ":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.", + ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: :obj:`float` | :obj:`None`, " + "optional", + ":keyword _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: Arbitrary keyword arguments " + "to be passed to the Telegram API.", + ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: :obj:`dict`, optional", + "", +] +write_timeout_sub = [":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`", "``20``"] +read_timeout_sub = [ + ":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.", + "``2``. :paramref:`timeout` will be added to this value", +] +read_timeout_type = [":obj:`float` | :obj:`None`", ":obj:`float`"] + + +def find_insert_pos_for_kwargs(lines: list[str]) -> int: + """Finds the correct position to insert the keyword arguments and returns the index.""" + for idx, value in reversed(list(enumerate(lines))): # reversed since :returns: is at the end + if value.startswith(":returns:"): + return idx + else: + return False + + +def is_write_timeout_20(obj: object) -> int: + """inspects the default value of write_timeout parameter of the bot method.""" + sig = inspect.signature(obj) + return 1 if (sig.parameters["write_timeout"].default == 20) else 0 + + +def check_timeout_and_api_kwargs_presence(obj: object) -> int: + """Checks if the method has timeout and api_kwargs keyword only parameters.""" + sig = inspect.signature(obj) + params_to_check = ( + "read_timeout", + "write_timeout", + "connect_timeout", + "pool_timeout", + "api_kwargs", + ) + return all( + param in sig.parameters and sig.parameters[param].kind == inspect.Parameter.KEYWORD_ONLY + for param in params_to_check + ) diff --git a/docs/auxil/link_code.py b/docs/auxil/link_code.py new file mode 100644 index 000000000..dc32f6394 --- /dev/null +++ b/docs/auxil/link_code.py @@ -0,0 +1,77 @@ +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2023 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +"""Functionality in this file is used for getting the [source] links on the classes, methods etc +to link to the correct files & lines on github. Can be simplified once +https://github.com/sphinx-doc/sphinx/issues/1556 is closed +""" +import subprocess + +from sphinx.util import logging + +# get the sphinx(!) logger +# Makes sure logs render in red and also plays nicely with e.g. the `nitpicky` option. +sphinx_logger = logging.getLogger(__name__) + + +# must be a module-level variable so that it can be written to by the `autodoc-process-docstring` +# event handler in `sphinx_hooks.py` +LINE_NUMBERS = {} + + +def _git_branch() -> str: + """Get's the current git sha if available or fall back to `master`""" + try: + output = subprocess.check_output( # skipcq: BAN-B607 + ["git", "describe", "--tags", "--always"], stderr=subprocess.STDOUT + ) + return output.decode().strip() + except Exception as exc: + sphinx_logger.exception( + "Failed to get a description of the current commit. Falling back to `master`.", + exc_info=exc, + ) + return "master" + + +git_branch = _git_branch() +base_url = "https://github.com/python-telegram-bot/python-telegram-bot/blob/" + + +def linkcode_resolve(_, info): + """See www.sphinx-doc.org/en/master/usage/extensions/linkcode.html""" + combined = ".".join((info["module"], info["fullname"])) + # special casing for ExtBot which is due to the special structure of extbot.rst + combined = combined.replace("ExtBot.ExtBot", "ExtBot") + + line_info = LINE_NUMBERS.get(combined) + + if not line_info: + # Try the __init__ + line_info = LINE_NUMBERS.get(f"{combined.rsplit('.', 1)[0]}.__init__") + if not line_info: + # Try the class + line_info = LINE_NUMBERS.get(f"{combined.rsplit('.', 1)[0]}") + if not line_info: + # Try the module + line_info = LINE_NUMBERS.get(info["module"]) + + if not line_info: + return + + file, start_line, end_line = line_info + return f"{base_url}{git_branch}/{file}#L{start_line}-L{end_line}" diff --git a/docs/auxil/sphinx_hooks.py b/docs/auxil/sphinx_hooks.py new file mode 100644 index 000000000..dfe325ccb --- /dev/null +++ b/docs/auxil/sphinx_hooks.py @@ -0,0 +1,209 @@ +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2023 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +import collections.abc +import inspect +import re +import typing +from pathlib import Path + +from sphinx.application import Sphinx + +import telegram +import telegram.ext +from docs.auxil.admonition_inserter import AdmonitionInserter +from docs.auxil.kwargs_insertion import ( + check_timeout_and_api_kwargs_presence, + find_insert_pos_for_kwargs, + is_write_timeout_20, + keyword_args, + read_timeout_sub, + read_timeout_type, + write_timeout_sub, +) +from docs.auxil.link_code import LINE_NUMBERS + +ADMONITION_INSERTER = AdmonitionInserter() + +# Some base classes are implementation detail +# We want to instead show *their* base class +PRIVATE_BASE_CLASSES = { + "_ChatUserBaseFilter": "MessageFilter", + "_Dice": "MessageFilter", + "_BaseThumbedMedium": "TelegramObject", + "_BaseMedium": "TelegramObject", + "_CredentialsBase": "TelegramObject", +} + + +FILE_ROOT = Path(inspect.getsourcefile(telegram)).parent.parent.resolve() + + +def autodoc_skip_member(app, what, name, obj, skip, options): + """We use this to not document certain members like filter() or check_update() for filters. + See https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#skipping-members""" + + included = {"MessageFilter", "UpdateFilter"} # filter() and check_update() only for these. + included_in_obj = any(inc in repr(obj) for inc in included) + + if included_in_obj: # it's difficult to see if check_update is from an inherited-member or not + for frame in inspect.stack(): # From https://github.com/sphinx-doc/sphinx/issues/9533 + if frame.function == "filter_members": + docobj = frame.frame.f_locals["self"].object + if not any(inc in str(docobj) for inc in included) and name == "check_update": + return True + break + + if name == "filter" and obj.__module__ == "telegram.ext.filters": + if not included_in_obj: + return True # return True to exclude from docs. + + +def autodoc_process_docstring( + app: Sphinx, what, name: str, obj: object, options, lines: list[str] +): + """We do the following things: + 1) Use this method to automatically insert the Keyword Args and "Shortcuts" admonitions + for the Bot methods. + + 2) Use this method to automatically insert "Returned in" admonition into classes + that are returned from the Bot methods + + 3) Use this method to automatically insert "Available in" admonition into classes + whose instances are available as attributes of other classes + + 4) Use this method to automatically insert "Use in" admonition into classes + whose instances can be used as arguments of the Bot methods + + 5) Misuse this autodoc hook to get the file names & line numbers because we have access + to the actual object here. + """ + + # 1) Insert the Keyword Args and "Shortcuts" admonitions for the Bot methods + method_name = name.split(".")[-1] + if ( + name.startswith("telegram.Bot.") + and what == "method" + and method_name.islower() + and check_timeout_and_api_kwargs_presence(obj) + ): + insert_index = find_insert_pos_for_kwargs(lines) + if not insert_index: + raise ValueError( + f"Couldn't find the correct position to insert the keyword args for {obj}." + ) + + long_write_timeout = is_write_timeout_20(obj) + get_updates_sub = 1 if (method_name == "get_updates") else 0 + # The below can be done in 1 line with itertools.chain, but this must be modified in-place + for i in range(insert_index, insert_index + len(keyword_args)): + lines.insert( + i, + keyword_args[i - insert_index].format( + method=method_name, + write_timeout=write_timeout_sub[long_write_timeout], + read_timeout=read_timeout_sub[get_updates_sub], + read_timeout_type=read_timeout_type[get_updates_sub], + ), + ) + + ADMONITION_INSERTER.insert_admonitions( + obj=typing.cast(collections.abc.Callable, obj), + docstring_lines=lines, + ) + + # 2-4) Insert "Returned in", "Available in", "Use in" admonitions into classes + # (where applicable) + if what == "class": + ADMONITION_INSERTER.insert_admonitions( + obj=typing.cast(type, obj), # since "what" == class, we know it's not just object + docstring_lines=lines, + ) + + # 5) Get the file names & line numbers + # We can't properly handle ordinary attributes. + # In linkcode_resolve we'll resolve to the `__init__` or module instead + if what == "attribute": + return + + # Special casing for properties + if hasattr(obj, "fget"): + obj = obj.fget + + # Special casing for filters + if isinstance(obj, telegram.ext.filters.BaseFilter): + obj = obj.__class__ + + try: + source_lines, start_line = inspect.getsourcelines(obj) + end_line = start_line + len(source_lines) + file = Path(inspect.getsourcefile(obj)).relative_to(FILE_ROOT) + LINE_NUMBERS[name] = (file, start_line, end_line) + except Exception: + pass + + # Since we don't document the `__init__`, we call this manually to have it available for + # attributes -- see the note above + if what == "class": + autodoc_process_docstring(app, "method", f"{name}.__init__", obj.__init__, options, lines) + + +def autodoc_process_bases(app, name, obj, option, bases: list): + """Here we fine tune how the base class's classes are displayed.""" + for idx, base in enumerate(bases): + # let's use a string representation of the object + base = str(base) + + # Special case for abstract context managers which are wrongly resoled for some reason + if base.startswith("typing.AbstractAsyncContextManager"): + bases[idx] = ":class:`contextlib.AbstractAsyncContextManager`" + continue + + # Special case because base classes are in std lib: + if "StringEnum" in base == "": + bases[idx] = ":class:`enum.Enum`" + bases.insert(0, ":class:`str`") + continue + + if "IntEnum" in base: + bases[idx] = ":class:`enum.IntEnum`" + continue + + # Drop generics (at least for now) + if base.endswith("]"): + base = base.split("[", maxsplit=1)[0] + bases[idx] = f":class:`{base}`" + + # Now convert `telegram._message.Message` to `telegram.Message` etc + match = re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base) + if not match or "_utils" in base: + continue + + parts = match.group(0).split(".") + + # Remove private paths + for index, part in enumerate(parts): + if part.startswith("_"): + parts = parts[:index] + parts[-1:] + break + + # Replace private base classes with their respective parent + parts = [PRIVATE_BASE_CLASSES.get(part, part) for part in parts] + + base = ".".join(parts) + + bases[idx] = f":class:`{base}`" diff --git a/docs/auxil/tg_const_role.py b/docs/auxil/tg_const_role.py new file mode 100644 index 000000000..e2962b218 --- /dev/null +++ b/docs/auxil/tg_const_role.py @@ -0,0 +1,92 @@ +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2023 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +from enum import Enum + +from docutils.nodes import Element +from sphinx.domains.python import PyXRefRole +from sphinx.environment import BuildEnvironment +from sphinx.util import logging + +import telegram + +# get the sphinx(!) logger +# Makes sure logs render in red and also plays nicely with e.g. the `nitpicky` option. +sphinx_logger = logging.getLogger(__name__) + +CONSTANTS_ROLE = "tg-const" + + +class TGConstXRefRole(PyXRefRole): + """This is a bit of Sphinx magic. We add a new role type called tg-const that allows us to + reference values from the `telegram.constants.module` while using the actual value as title + of the link. + + Example: + + :tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` renders as `4096` but links to + the constant. + """ + + def process_link( + self, + env: BuildEnvironment, + refnode: Element, + has_explicit_title: bool, + title: str, + target: str, + ) -> tuple[str, str]: + title, target = super().process_link(env, refnode, has_explicit_title, title, target) + try: + # We use `eval` to get the value of the expression. Maybe there are better ways to + # do this via importlib or so, but it does the job for now + value = eval(target) + # Maybe we need a better check if the target is actually from tg.constants + # for now checking if it's an Enum suffices since those are used nowhere else in PTB + if isinstance(value, Enum): + # Special casing for file size limits + if isinstance(value, telegram.constants.FileSizeLimit): + return f"{int(value.value / 1e6)} MB", target + return repr(value.value), target + # Just for (Bot API) versions number auto add in constants: + if isinstance(value, str) and target in ( + "telegram.constants.BOT_API_VERSION", + "telegram.__version__", + ): + return value, target + if isinstance(value, tuple) and target in ( + "telegram.constants.BOT_API_VERSION_INFO", + "telegram.__version_info__", + ): + return repr(value), target + sphinx_logger.warning( + f"%s:%d: WARNING: Did not convert reference %s. :{CONSTANTS_ROLE}: is not supposed" + " to be used with this type of target.", + refnode.source, + refnode.line, + refnode.rawsource, + ) + return title, target + except Exception as exc: + sphinx_logger.exception( + "%s:%d: WARNING: Did not convert reference %s due to an exception.", + refnode.source, + refnode.line, + refnode.rawsource, + exc_info=exc, + ) + return title, target diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 2f8cd8248..01318e788 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,6 +1,7 @@ -sphinx==5.3.0 +sphinx==6.1.3 sphinx-pypi-upload furo==2022.12.7 -git+https://github.com/harshil21/furo-sphinx-search@be5cfa221a01f6e259bb2bb1f76d6ede7ffc1f11#egg=furo-sphinx-search +git+https://github.com/harshil21/furo-sphinx-search@01efc7be422d7dc02390aab9be68d6f5ce1a5618#egg=furo-sphinx-search sphinx-paramlinks==0.5.4 -sphinxcontrib-mermaid==0.7.1 \ No newline at end of file +sphinxcontrib-mermaid==0.7.1 +sphinx-copybutton==0.5.1 diff --git a/docs/source/_static/style_admonitions.css b/docs/source/_static/style_admonitions.css new file mode 100644 index 000000000..89c0d4b9e --- /dev/null +++ b/docs/source/_static/style_admonitions.css @@ -0,0 +1,65 @@ +:root { + --icon--shortcuts: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-signpost' viewBox='0 0 16 16'%3E%3Cpath d='M7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414a1 1 0 0 0-2 0zM12.532 5l1.666 2-1.666 2H2V5h10.532z'/%3E%3C/svg%3E"); + --icon--returned-in: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-arrow-return-right' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.5 1.5A.5.5 0 0 0 1 2v4.8a2.5 2.5 0 0 0 2.5 2.5h9.793l-3.347 3.346a.5.5 0 0 0 .708.708l4.2-4.2a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 8.3H3.5A1.5 1.5 0 0 1 2 6.8V2a.5.5 0 0 0-.5-.5z'/%3E%3C/svg%3E"); + --icon--available-in: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-geo-fill' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4 4a4 4 0 1 1 4.5 3.969V13.5a.5.5 0 0 1-1 0V7.97A4 4 0 0 1 4 3.999zm2.493 8.574a.5.5 0 0 1-.411.575c-.712.118-1.28.295-1.655.493a1.319 1.319 0 0 0-.37.265.301.301 0 0 0-.057.09V14l.002.008a.147.147 0 0 0 .016.033.617.617 0 0 0 .145.15c.165.13.435.27.813.395.751.25 1.82.414 3.024.414s2.273-.163 3.024-.414c.378-.126.648-.265.813-.395a.619.619 0 0 0 .146-.15.148.148 0 0 0 .015-.033L12 14v-.004a.301.301 0 0 0-.057-.09 1.318 1.318 0 0 0-.37-.264c-.376-.198-.943-.375-1.655-.493a.5.5 0 1 1 .164-.986c.77.127 1.452.328 1.957.594C12.5 13 13 13.4 13 14c0 .426-.26.752-.544.977-.29.228-.68.413-1.116.558-.878.293-2.059.465-3.34.465-1.281 0-2.462-.172-3.34-.465-.436-.145-.826-.33-1.116-.558C3.26 14.752 3 14.426 3 14c0-.599.5-1 .961-1.243.505-.266 1.187-.467 1.957-.594a.5.5 0 0 1 .575.411z'/%3E%3C/svg%3E"); + --icon--use-in:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-funnel' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2h-11z'/%3E%3C/svg%3E"); +} +.admonition.shortcuts { + border-color: rgb(43, 155, 70); +} +.admonition.shortcuts > .admonition-title { + background-color: rgba(43, 155, 70, 0.1); + border-color: rgb(43, 155, 70); +} +.admonition.shortcuts > .admonition-title::before { + background-color: rgb(43, 155, 70); + -webkit-mask-image: var(--icon--shortcuts); + mask-image: var(--icon--shortcuts); +} + +.admonition.returned-in { + border-color: rgb(230, 109, 15); +} +.admonition.returned-in > .admonition-title { + background-color: rgba(177, 108, 51, 0.1); + border-color: rgb(230, 109, 15); +} +.admonition.returned-in > .admonition-title::before { + background-color: rgb(230, 109, 15); + -webkit-mask-image: var(--icon--returned-in); + mask-image: var(--icon--returned-in); +} + +.admonition.available-in { + border-color: rgb(183, 4, 215); +} +.admonition.available-in > .admonition-title { + background-color: rgba(165, 99, 177, 0.1); + border-color: rgb(183, 4, 215); +} +.admonition.available-in > .admonition-title::before { + background-color: rgb(183, 4, 215); + -webkit-mask-image: var(--icon--available-in); + mask-image: var(--icon--available-in); +} + +.admonition.use-in { + border-color: rgb(203, 147, 1); +} +.admonition.use-in > .admonition-title { + background-color: rgba(176, 144, 60, 0.1); + border-color: rgb(203, 147, 1); +} +.admonition.use-in > .admonition-title::before { + background-color: rgb(203, 147, 1); + -webkit-mask-image: var(--icon--use-in); + mask-image: var(--icon--use-in); +} + +.admonition.returned-in > ul:hover, .admonition.available-in > ul:hover, .admonition.use-in > ul:hover, .admonition.shortcuts > ul:hover { + cursor: move; +} +.admonition.returned-in > ul, .admonition.available-in > ul, .admonition.use-in > ul, .admonition.shortcuts > ul { + max-height: 200px; + overflow-y: scroll; +} diff --git a/docs/source/_static/style_general.css b/docs/source/_static/style_general.css new file mode 100644 index 000000000..295b79918 --- /dev/null +++ b/docs/source/_static/style_general.css @@ -0,0 +1,3 @@ +.article-container h1 { + overflow-wrap: anywhere; +} \ No newline at end of file diff --git a/docs/source/_static/style_sidebar_brand.css b/docs/source/_static/style_sidebar_brand.css new file mode 100644 index 000000000..7e198989d --- /dev/null +++ b/docs/source/_static/style_sidebar_brand.css @@ -0,0 +1,11 @@ +.sidebar-sticky .sidebar-brand { + flex-direction: row; +} + +.sidebar-sticky .sidebar-brand .sidebar-logo-container { + align-self: center; +} + +.sidebar-sticky .sidebar-brand .sidebar-brand-text { + align-self: center; +} \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 995900bb8..40fce9335 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,20 +1,12 @@ -import inspect import os import re -import subprocess import sys -from enum import Enum from pathlib import Path -from typing import List, Tuple # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -from docutils.nodes import Element from sphinx.application import Sphinx -from sphinx.domains.python import PyXRefRole -from sphinx.environment import BuildEnvironment -from sphinx.util import logging sys.path.insert(0, os.path.abspath("../..")) @@ -34,7 +26,7 @@ version = "20.0" # telegram.__version__[:3] release = "20.0" # telegram.__version__ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = "5.1.1" +needs_sphinx = "6.1.3" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -46,6 +38,7 @@ extensions = [ "sphinx.ext.linkcode", "sphinx.ext.extlinks", "sphinx_paramlinks", + "sphinx_copybutton", "sphinxcontrib.mermaid", "sphinx_search.extension", ] @@ -220,7 +213,13 @@ html_favicon = "ptb-logo_1024.ico" # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] -html_css_files = ["style_external_link.css", "style_mermaid_diagrams.css"] +html_css_files = [ + "style_external_link.css", + "style_mermaid_diagrams.css", + "style_sidebar_brand.css", + "style_general.css", + "style_admonitions.css", +] html_permalinks_icon = "¶" # Furo's default permalink icon is `#` which doesn't look great imo. @@ -284,326 +283,16 @@ texinfo_documents = [ # -- script stuff -------------------------------------------------------- -# get the sphinx(!) logger -# Makes sure logs render in red and also plays nicely with e.g. the `nitpicky` option. -sphinx_logger = logging.getLogger(__name__) +# Due to Sphinx behaviour, these imports only work when imported here, not at top of module. -CONSTANTS_ROLE = "tg-const" -import telegram # We need this so that the `eval` below works - - -class TGConstXRefRole(PyXRefRole): - """This is a bit of Sphinx magic. We add a new role type called tg-const that allows us to - reference values from the `telegram.constants.module` while using the actual value as title - of the link. - - Example: - - :tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` renders as `4096` but links to the - constant. - """ - - def process_link( - self, - env: BuildEnvironment, - refnode: Element, - has_explicit_title: bool, - title: str, - target: str, - ) -> Tuple[str, str]: - title, target = super().process_link(env, refnode, has_explicit_title, title, target) - try: - # We use `eval` to get the value of the expression. Maybe there are better ways to - # do this via importlib or so, but it does the job for now - value = eval(target) - # Maybe we need a better check if the target is actually from tg.constants - # for now checking if it's an Enum suffices since those are used nowhere else in PTB - if isinstance(value, Enum): - # Special casing for file size limits - if isinstance(value, telegram.constants.FileSizeLimit): - return f"{int(value.value / 1e6)} MB", target - return repr(value.value), target - # Just for (Bot API) versions number auto add in constants: - if isinstance(value, str) and target in ( - "telegram.constants.BOT_API_VERSION", - "telegram.__version__", - ): - return value, target - if isinstance(value, tuple) and target in ( - "telegram.constants.BOT_API_VERSION_INFO", - "telegram.__version_info__", - ): - return repr(value), target - sphinx_logger.warning( - f"%s:%d: WARNING: Did not convert reference %s. :{CONSTANTS_ROLE}: is not supposed" - " to be used with this type of target.", - refnode.source, - refnode.line, - refnode.rawsource, - ) - return title, target - except Exception as exc: - sphinx_logger.exception( - "%s:%d: WARNING: Did not convert reference %s due to an exception.", - refnode.source, - refnode.line, - refnode.rawsource, - exc_info=exc, - ) - return title, target - - -def autodoc_skip_member(app, what, name, obj, skip, options): - """We use this to not document certain members like filter() or check_update() for filters. - See https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#skipping-members""" - - included = {"MessageFilter", "UpdateFilter"} # filter() and check_update() only for these. - included_in_obj = any(inc in repr(obj) for inc in included) - - if included_in_obj: # it's difficult to see if check_update is from an inherited-member or not - for frame in inspect.stack(): # From https://github.com/sphinx-doc/sphinx/issues/9533 - if frame.function == "filter_members": - docobj = frame.frame.f_locals["self"].object - if not any(inc in str(docobj) for inc in included) and name == "check_update": - return True - break - - if name == "filter" and obj.__module__ == "telegram.ext.filters": - if not included_in_obj: - return True # return True to exclude from docs. - - -# ------------------------------------------------------------------------------------------------ -# This part is for getting the [source] links on the classes, methods etc link to the correct -# files & lines on github. Can be simplified once https://github.com/sphinx-doc/sphinx/issues/1556 -# is closed - -line_numbers = {} -file_root = Path(inspect.getsourcefile(telegram)).parent.parent.resolve() -import telegram.ext # Needed for checking if an object is a BaseFilter - -keyword_args = [ - ":keyword _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: Value to pass to :paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to {read_timeout}.", - ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: {read_timeout_type}, optional", - ":keyword _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: Value to pass to :paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to {write_timeout}.", - ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: :obj:`float` | :obj:`None`, optional", - ":keyword _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: Value to pass to :paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.", - ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: :obj:`float` | :obj:`None`, optional", - ":keyword _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: Value to pass to :paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.", - ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: :obj:`float` | :obj:`None`, optional", - ":keyword _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: Arbitrary keyword arguments to be passed to the Telegram API.", - ":kwtype _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: :obj:`dict`, optional", - "", -] - -write_timeout_sub = [":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`", "``20``"] -read_timeout_sub = [ - ":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.", - "``2``. :paramref:`timeout` will be added to this value", -] -read_timeout_type = [":obj:`float` | :obj:`None`", ":obj:`float`"] - - -def find_insert_pos(lines: List[str]) -> int: - """Finds the correct position to insert the keyword arguments and returns the index.""" - for idx, value in reversed(list(enumerate(lines))): # reversed since :returns: is at the end - if value.startswith(":returns:"): - return idx - else: - return False - - -def is_write_timeout_20(obj: object) -> int: - """inspects the default value of write_timeout parameter of the bot method.""" - sig = inspect.signature(obj) - return 1 if (sig.parameters["write_timeout"].default == 20) else 0 - - -def check_timeout_and_api_kwargs_presence(obj: object) -> int: - """Checks if the method has timeout and api_kwargs keyword only parameters.""" - sig = inspect.signature(obj) - params_to_check = ( - "read_timeout", - "write_timeout", - "connect_timeout", - "pool_timeout", - "api_kwargs", - ) - return all( - param in sig.parameters and sig.parameters[param].kind == inspect.Parameter.KEYWORD_ONLY - for param in params_to_check - ) - - -def autodoc_process_docstring( - app: Sphinx, what, name: str, obj: object, options, lines: List[str] -): - """We do two things: - 1) Use this method to automatically insert the Keyword Args for the Bot methods. - - 2) Misuse this autodoc hook to get the file names & line numbers because we have access - to the actual object here. - """ - # 1) Insert the Keyword Args for the Bot methods - method_name = name.split(".")[-1] - if ( - name.startswith("telegram.Bot.") - and what == "method" - and method_name.islower() - and check_timeout_and_api_kwargs_presence(obj) - ): - insert_index = find_insert_pos(lines) - if not insert_index: - raise ValueError( - f"Couldn't find the correct position to insert the keyword args for {obj}." - ) - - long_write_timeout = is_write_timeout_20(obj) - get_updates_sub = 1 if (method_name == "get_updates") else 0 - # The below can be done in 1 line with itertools.chain, but this must be modified in-place - for i in range(insert_index, insert_index + len(keyword_args)): - lines.insert( - i, - keyword_args[i - insert_index].format( - method=method_name, - write_timeout=write_timeout_sub[long_write_timeout], - read_timeout=read_timeout_sub[get_updates_sub], - read_timeout_type=read_timeout_type[get_updates_sub], - ), - ) - - # 2) Get the file names & line numbers - # We can't properly handle ordinary attributes. - # In linkcode_resolve we'll resolve to the `__init__` or module instead - if what == "attribute": - return - - # Special casing for properties - if hasattr(obj, "fget"): - obj = obj.fget - - # Special casing for filters - if isinstance(obj, telegram.ext.filters.BaseFilter): - obj = obj.__class__ - - try: - source_lines, start_line = inspect.getsourcelines(obj) - end_line = start_line + len(source_lines) - file = Path(inspect.getsourcefile(obj)).relative_to(file_root) - line_numbers[name] = (file, start_line, end_line) - except Exception: - pass - - # Since we don't document the `__init__`, we call this manually to have it available for - # attributes -- see the note above - if what == "class": - autodoc_process_docstring(app, "method", f"{name}.__init__", obj.__init__, options, lines) - - -def _git_branch() -> str: - """Get's the current git sha if available or fall back to `master`""" - try: - output = subprocess.check_output( # skipcq: BAN-B607 - ["git", "describe", "--tags", "--always"], stderr=subprocess.STDOUT - ) - return output.decode().strip() - except Exception as exc: - sphinx_logger.exception( - "Failed to get a description of the current commit. Falling back to `master`.", - exc_info=exc, - ) - return "master" - - -git_branch = _git_branch() -base_url = "https://github.com/python-telegram-bot/python-telegram-bot/blob/" - - -def linkcode_resolve(_, info): - """See www.sphinx-doc.org/en/master/usage/extensions/linkcode.html""" - combined = ".".join((info["module"], info["fullname"])) - # special casing for ExtBot which is due to the special structure of extbot.rst - combined = combined.replace("ExtBot.ExtBot", "ExtBot") - - line_info = line_numbers.get(combined) - - if not line_info: - # Try the __init__ - line_info = line_numbers.get(f"{combined.rsplit('.', 1)[0]}.__init__") - if not line_info: - # Try the class - line_info = line_numbers.get(f"{combined.rsplit('.', 1)[0]}") - if not line_info: - # Try the module - line_info = line_numbers.get(info["module"]) - - if not line_info: - return - - file, start_line, end_line = line_info - return f"{base_url}{git_branch}/{file}#L{start_line}-L{end_line}" - - -# End of logic for the [source] links -# ------------------------------------------------------------------------------------------------ - - -# Some base classes are implementation detail -# We want to instead show *their* base class -PRIVATE_BASE_CLASSES = { - "_ChatUserBaseFilter": "MessageFilter", - "_Dice": "MessageFilter", - "_BaseThumbedMedium": "TelegramObject", - "_BaseMedium": "TelegramObject", - "_CredentialsBase": "TelegramObject", -} - - -def autodoc_process_bases(app, name, obj, option, bases: list): - """Here we fine tune how the base class's classes are displayed.""" - for idx, base in enumerate(bases): - # let's use a string representation of the object - base = str(base) - - # Special case for abstract context managers which are wrongly resoled for some reason - if base.startswith("typing.AbstractAsyncContextManager"): - bases[idx] = ":class:`contextlib.AbstractAsyncContextManager`" - continue - - # Special case because base classes are in std lib: - if "StringEnum" in base == "": - bases[idx] = ":class:`enum.Enum`" - bases.insert(0, ":class:`str`") - continue - - if "IntEnum" in base: - bases[idx] = ":class:`enum.IntEnum`" - continue - - # Drop generics (at least for now) - if base.endswith("]"): - base = base.split("[", maxsplit=1)[0] - bases[idx] = f":class:`{base}`" - - # Now convert `telegram._message.Message` to `telegram.Message` etc - match = re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base) - if not match or "_utils" in base: - continue - - parts = match.group(0).split(".") - - # Remove private paths - for index, part in enumerate(parts): - if part.startswith("_"): - parts = parts[:index] + parts[-1:] - break - - # Replace private base classes with their respective parent - parts = [PRIVATE_BASE_CLASSES.get(part, part) for part in parts] - - base = ".".join(parts) - - bases[idx] = f":class:`{base}`" +# Not used but must be imported for the linkcode extension to find it +from docs.auxil.link_code import linkcode_resolve +from docs.auxil.sphinx_hooks import ( + autodoc_process_bases, + autodoc_process_docstring, + autodoc_skip_member, +) +from docs.auxil.tg_const_role import CONSTANTS_ROLE, TGConstXRefRole def setup(app: Sphinx): diff --git a/docs/source/telegram.animation.rst b/docs/source/telegram.animation.rst index 05776f0fc..94b5f8187 100644 --- a/docs/source/telegram.animation.rst +++ b/docs/source/telegram.animation.rst @@ -1,5 +1,5 @@ -telegram.Animation -================== +Animation +========= .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject diff --git a/docs/source/telegram.audio.rst b/docs/source/telegram.audio.rst index ae4928eca..9e501f701 100644 --- a/docs/source/telegram.audio.rst +++ b/docs/source/telegram.audio.rst @@ -1,5 +1,5 @@ -telegram.Audio -============== +Audio +===== .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject diff --git a/docs/source/telegram.bot.rst b/docs/source/telegram.bot.rst index 5f78d3778..a12f5706f 100644 --- a/docs/source/telegram.bot.rst +++ b/docs/source/telegram.bot.rst @@ -1,5 +1,5 @@ -telegram.Bot -============ +Bot +=== .. autoclass:: telegram.Bot :members: diff --git a/docs/source/telegram.botcommand.rst b/docs/source/telegram.botcommand.rst index 9ceb402c5..a8e710f03 100644 --- a/docs/source/telegram.botcommand.rst +++ b/docs/source/telegram.botcommand.rst @@ -1,5 +1,5 @@ -telegram.BotCommand -=================== +BotCommand +========== .. autoclass:: telegram.BotCommand :members: diff --git a/docs/source/telegram.botcommandscope.rst b/docs/source/telegram.botcommandscope.rst index 0cbbca97d..9aae87231 100644 --- a/docs/source/telegram.botcommandscope.rst +++ b/docs/source/telegram.botcommandscope.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScope -======================== +BotCommandScope +=============== .. autoclass:: telegram.BotCommandScope :members: diff --git a/docs/source/telegram.botcommandscopeallchatadministrators.rst b/docs/source/telegram.botcommandscopeallchatadministrators.rst index e77bb0987..f33c44a9d 100644 --- a/docs/source/telegram.botcommandscopeallchatadministrators.rst +++ b/docs/source/telegram.botcommandscopeallchatadministrators.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeAllChatAdministrators -============================================= +BotCommandScopeAllChatAdministrators +==================================== .. autoclass:: telegram.BotCommandScopeAllChatAdministrators :members: diff --git a/docs/source/telegram.botcommandscopeallgroupchats.rst b/docs/source/telegram.botcommandscopeallgroupchats.rst index c00d78380..91833b205 100644 --- a/docs/source/telegram.botcommandscopeallgroupchats.rst +++ b/docs/source/telegram.botcommandscopeallgroupchats.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeAllGroupChats -======================================= +BotCommandScopeAllGroupChats +============================ .. autoclass:: telegram.BotCommandScopeAllGroupChats :members: diff --git a/docs/source/telegram.botcommandscopeallprivatechats.rst b/docs/source/telegram.botcommandscopeallprivatechats.rst index c63bf9039..c0c5cef5c 100644 --- a/docs/source/telegram.botcommandscopeallprivatechats.rst +++ b/docs/source/telegram.botcommandscopeallprivatechats.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeAllPrivateChats -======================================= +BotCommandScopeAllPrivateChats +============================== .. autoclass:: telegram.BotCommandScopeAllPrivateChats :members: diff --git a/docs/source/telegram.botcommandscopechat.rst b/docs/source/telegram.botcommandscopechat.rst index cd54df932..9efac3f9d 100644 --- a/docs/source/telegram.botcommandscopechat.rst +++ b/docs/source/telegram.botcommandscopechat.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeChat -============================ +BotCommandScopeChat +=================== .. autoclass:: telegram.BotCommandScopeChat :members: diff --git a/docs/source/telegram.botcommandscopechatadministrators.rst b/docs/source/telegram.botcommandscopechatadministrators.rst index 7e4734293..e02b6ebdd 100644 --- a/docs/source/telegram.botcommandscopechatadministrators.rst +++ b/docs/source/telegram.botcommandscopechatadministrators.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeChatAdministrators -========================================== +BotCommandScopeChatAdministrators +================================= .. autoclass:: telegram.BotCommandScopeChatAdministrators :members: diff --git a/docs/source/telegram.botcommandscopechatmember.rst b/docs/source/telegram.botcommandscopechatmember.rst index c86175c80..65c7f63b0 100644 --- a/docs/source/telegram.botcommandscopechatmember.rst +++ b/docs/source/telegram.botcommandscopechatmember.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeChatMember -================================== +BotCommandScopeChatMember +========================= .. autoclass:: telegram.BotCommandScopeChatMember :members: diff --git a/docs/source/telegram.botcommandscopedefault.rst b/docs/source/telegram.botcommandscopedefault.rst index cbf90cfe3..89124ef04 100644 --- a/docs/source/telegram.botcommandscopedefault.rst +++ b/docs/source/telegram.botcommandscopedefault.rst @@ -1,5 +1,5 @@ -telegram.BotCommandScopeDefault -=============================== +BotCommandScopeDefault +====================== .. autoclass:: telegram.BotCommandScopeDefault :members: diff --git a/docs/source/telegram.callbackgame.rst b/docs/source/telegram.callbackgame.rst index 6fa11ded8..c8b47a0a9 100644 --- a/docs/source/telegram.callbackgame.rst +++ b/docs/source/telegram.callbackgame.rst @@ -1,5 +1,5 @@ -telegram.Callbackgame -===================== +Callbackgame +============ .. autoclass:: telegram.CallbackGame :members: diff --git a/docs/source/telegram.callbackquery.rst b/docs/source/telegram.callbackquery.rst index 297189aaf..02db37a8a 100644 --- a/docs/source/telegram.callbackquery.rst +++ b/docs/source/telegram.callbackquery.rst @@ -1,5 +1,5 @@ -telegram.CallbackQuery -====================== +CallbackQuery +============= .. autoclass:: telegram.CallbackQuery :members: diff --git a/docs/source/telegram.chat.rst b/docs/source/telegram.chat.rst index cd04bb87b..3ef967247 100644 --- a/docs/source/telegram.chat.rst +++ b/docs/source/telegram.chat.rst @@ -1,5 +1,5 @@ -telegram.Chat -============= +Chat +==== .. autoclass:: telegram.Chat :members: diff --git a/docs/source/telegram.chatadministratorrights.rst b/docs/source/telegram.chatadministratorrights.rst index 068c0fc43..a9aee459b 100644 --- a/docs/source/telegram.chatadministratorrights.rst +++ b/docs/source/telegram.chatadministratorrights.rst @@ -1,5 +1,5 @@ -telegram.ChatAdministratorRights -================================ +ChatAdministratorRights +======================= .. versionadded:: 20.0 diff --git a/docs/source/telegram.chatinvitelink.rst b/docs/source/telegram.chatinvitelink.rst index ca24e5340..3314af1ec 100644 --- a/docs/source/telegram.chatinvitelink.rst +++ b/docs/source/telegram.chatinvitelink.rst @@ -1,5 +1,5 @@ -telegram.ChatInviteLink -======================= +ChatInviteLink +============== .. autoclass:: telegram.ChatInviteLink :members: diff --git a/docs/source/telegram.chatjoinrequest.rst b/docs/source/telegram.chatjoinrequest.rst index e1450cc10..8c4f5cb27 100644 --- a/docs/source/telegram.chatjoinrequest.rst +++ b/docs/source/telegram.chatjoinrequest.rst @@ -1,5 +1,5 @@ -telegram.ChatJoinRequest -======================== +ChatJoinRequest +=============== .. autoclass:: telegram.ChatJoinRequest :members: diff --git a/docs/source/telegram.chatlocation.rst b/docs/source/telegram.chatlocation.rst index 8994d138e..12b5e2127 100644 --- a/docs/source/telegram.chatlocation.rst +++ b/docs/source/telegram.chatlocation.rst @@ -1,5 +1,5 @@ -telegram.ChatLocation -===================== +ChatLocation +============ .. autoclass:: telegram.ChatLocation :members: diff --git a/docs/source/telegram.chatmember.rst b/docs/source/telegram.chatmember.rst index 7bba9e448..771b3636d 100644 --- a/docs/source/telegram.chatmember.rst +++ b/docs/source/telegram.chatmember.rst @@ -1,5 +1,5 @@ -telegram.ChatMember -=================== +ChatMember +========== .. autoclass:: telegram.ChatMember :members: diff --git a/docs/source/telegram.chatmemberadministrator.rst b/docs/source/telegram.chatmemberadministrator.rst index 62a56f183..b9b385328 100644 --- a/docs/source/telegram.chatmemberadministrator.rst +++ b/docs/source/telegram.chatmemberadministrator.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberAdministrator -================================ +ChatMemberAdministrator +======================= .. autoclass:: telegram.ChatMemberAdministrator :members: diff --git a/docs/source/telegram.chatmemberbanned.rst b/docs/source/telegram.chatmemberbanned.rst index 15f5ff2db..f3d3fb7b6 100644 --- a/docs/source/telegram.chatmemberbanned.rst +++ b/docs/source/telegram.chatmemberbanned.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberBanned -========================= +ChatMemberBanned +================ .. autoclass:: telegram.ChatMemberBanned :members: diff --git a/docs/source/telegram.chatmemberleft.rst b/docs/source/telegram.chatmemberleft.rst index 6a0ca2b15..c692f73df 100644 --- a/docs/source/telegram.chatmemberleft.rst +++ b/docs/source/telegram.chatmemberleft.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberLeft -======================= +ChatMemberLeft +============== .. autoclass:: telegram.ChatMemberLeft :members: diff --git a/docs/source/telegram.chatmembermember.rst b/docs/source/telegram.chatmembermember.rst index 55ca6fe99..6a4723803 100644 --- a/docs/source/telegram.chatmembermember.rst +++ b/docs/source/telegram.chatmembermember.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberMember -========================= +ChatMemberMember +================ .. autoclass:: telegram.ChatMemberMember :members: diff --git a/docs/source/telegram.chatmemberowner.rst b/docs/source/telegram.chatmemberowner.rst index 03f162a7f..6f5217a3c 100644 --- a/docs/source/telegram.chatmemberowner.rst +++ b/docs/source/telegram.chatmemberowner.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberOwner -======================== +ChatMemberOwner +=============== .. autoclass:: telegram.ChatMemberOwner :members: diff --git a/docs/source/telegram.chatmemberrestricted.rst b/docs/source/telegram.chatmemberrestricted.rst index 957414ed3..97b5d3ec2 100644 --- a/docs/source/telegram.chatmemberrestricted.rst +++ b/docs/source/telegram.chatmemberrestricted.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberRestricted -============================= +ChatMemberRestricted +==================== .. autoclass:: telegram.ChatMemberRestricted :members: diff --git a/docs/source/telegram.chatmemberupdated.rst b/docs/source/telegram.chatmemberupdated.rst index d6feecc44..3c4dcf0a8 100644 --- a/docs/source/telegram.chatmemberupdated.rst +++ b/docs/source/telegram.chatmemberupdated.rst @@ -1,5 +1,5 @@ -telegram.ChatMemberUpdated -========================== +ChatMemberUpdated +================= .. autoclass:: telegram.ChatMemberUpdated :members: diff --git a/docs/source/telegram.chatpermissions.rst b/docs/source/telegram.chatpermissions.rst index 7cefdbc23..d14479bb2 100644 --- a/docs/source/telegram.chatpermissions.rst +++ b/docs/source/telegram.chatpermissions.rst @@ -1,5 +1,5 @@ -telegram.ChatPermissions -======================== +ChatPermissions +=============== .. autoclass:: telegram.ChatPermissions :members: diff --git a/docs/source/telegram.chatphoto.rst b/docs/source/telegram.chatphoto.rst index 4ab6ae0a2..b5f337e9b 100644 --- a/docs/source/telegram.chatphoto.rst +++ b/docs/source/telegram.chatphoto.rst @@ -1,5 +1,5 @@ -telegram.ChatPhoto -================== +ChatPhoto +========= .. autoclass:: telegram.ChatPhoto :members: diff --git a/docs/source/telegram.choseninlineresult.rst b/docs/source/telegram.choseninlineresult.rst index d60547d4b..e357c1e07 100644 --- a/docs/source/telegram.choseninlineresult.rst +++ b/docs/source/telegram.choseninlineresult.rst @@ -1,5 +1,5 @@ -telegram.ChosenInlineResult -=========================== +ChosenInlineResult +================== .. autoclass:: telegram.ChosenInlineResult :members: diff --git a/docs/source/telegram.contact.rst b/docs/source/telegram.contact.rst index f38079be9..682b43458 100644 --- a/docs/source/telegram.contact.rst +++ b/docs/source/telegram.contact.rst @@ -1,5 +1,5 @@ -telegram.Contact -================ +Contact +======= .. autoclass:: telegram.Contact :members: diff --git a/docs/source/telegram.credentials.rst b/docs/source/telegram.credentials.rst index 6a3fe39e1..0b6cc68d2 100644 --- a/docs/source/telegram.credentials.rst +++ b/docs/source/telegram.credentials.rst @@ -1,5 +1,5 @@ -telegram.Credentials -==================== +Credentials +=========== .. autoclass:: telegram.Credentials :members: diff --git a/docs/source/telegram.datacredentials.rst b/docs/source/telegram.datacredentials.rst index b0916762e..f6bc8643f 100644 --- a/docs/source/telegram.datacredentials.rst +++ b/docs/source/telegram.datacredentials.rst @@ -1,5 +1,5 @@ -telegram.DataCredentials -======================== +DataCredentials +=============== .. autoclass:: telegram.DataCredentials :members: diff --git a/docs/source/telegram.dice.rst b/docs/source/telegram.dice.rst index d7f7a6467..827935d67 100644 --- a/docs/source/telegram.dice.rst +++ b/docs/source/telegram.dice.rst @@ -1,5 +1,5 @@ -telegram.Dice -============= +Dice +==== .. autoclass:: telegram.Dice :members: diff --git a/docs/source/telegram.document.rst b/docs/source/telegram.document.rst index 83db9ffa0..e59a84ba6 100644 --- a/docs/source/telegram.document.rst +++ b/docs/source/telegram.document.rst @@ -1,5 +1,5 @@ -telegram.Document -================= +Document +======== .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject .. autoclass:: telegram.Document diff --git a/docs/source/telegram.encryptedcredentials.rst b/docs/source/telegram.encryptedcredentials.rst index d42851436..7c7a61c83 100644 --- a/docs/source/telegram.encryptedcredentials.rst +++ b/docs/source/telegram.encryptedcredentials.rst @@ -1,5 +1,5 @@ -telegram.EncryptedCredentials -============================= +EncryptedCredentials +==================== .. autoclass:: telegram.EncryptedCredentials :members: diff --git a/docs/source/telegram.encryptedpassportelement.rst b/docs/source/telegram.encryptedpassportelement.rst index f22963601..0204af1ee 100644 --- a/docs/source/telegram.encryptedpassportelement.rst +++ b/docs/source/telegram.encryptedpassportelement.rst @@ -1,5 +1,5 @@ -telegram.EncryptedPassportElement -================================= +EncryptedPassportElement +======================== .. autoclass:: telegram.EncryptedPassportElement :members: diff --git a/docs/source/telegram.ext.aioratelimiter.rst b/docs/source/telegram.ext.aioratelimiter.rst index b43c0350e..de329f077 100644 --- a/docs/source/telegram.ext.aioratelimiter.rst +++ b/docs/source/telegram.ext.aioratelimiter.rst @@ -1,5 +1,5 @@ -telegram.ext.AIORateLimiter -============================ +AIORateLimiter +============== .. autoclass:: telegram.ext.AIORateLimiter :members: diff --git a/docs/source/telegram.ext.application.rst b/docs/source/telegram.ext.application.rst index 722340ea8..4b1a3f259 100644 --- a/docs/source/telegram.ext.application.rst +++ b/docs/source/telegram.ext.application.rst @@ -1,5 +1,5 @@ -telegram.ext.Application -======================== +Application +=========== .. autoclass:: telegram.ext.Application :members: diff --git a/docs/source/telegram.ext.applicationbuilder.rst b/docs/source/telegram.ext.applicationbuilder.rst index a5e7d6126..ec0a6574c 100644 --- a/docs/source/telegram.ext.applicationbuilder.rst +++ b/docs/source/telegram.ext.applicationbuilder.rst @@ -1,5 +1,5 @@ -telegram.ext.ApplicationBuilder -=============================== +ApplicationBuilder +================== .. autoclass:: telegram.ext.ApplicationBuilder :members: diff --git a/docs/source/telegram.ext.applicationhandlerstop.rst b/docs/source/telegram.ext.applicationhandlerstop.rst index fe2feb9d2..db536aee1 100644 --- a/docs/source/telegram.ext.applicationhandlerstop.rst +++ b/docs/source/telegram.ext.applicationhandlerstop.rst @@ -1,5 +1,5 @@ -telegram.ext.ApplicationHandlerStop -=================================== +ApplicationHandlerStop +====================== .. autoclass:: telegram.ext.ApplicationHandlerStop :members: diff --git a/docs/source/telegram.ext.basehandler.rst b/docs/source/telegram.ext.basehandler.rst index cb4061cf5..9dfd607ce 100644 --- a/docs/source/telegram.ext.basehandler.rst +++ b/docs/source/telegram.ext.basehandler.rst @@ -1,5 +1,5 @@ -telegram.ext.BaseHandler -======================== +BaseHandler +=========== .. autoclass:: telegram.ext.BaseHandler :members: diff --git a/docs/source/telegram.ext.basepersistence.rst b/docs/source/telegram.ext.basepersistence.rst index 013c052d8..c45fcf65b 100644 --- a/docs/source/telegram.ext.basepersistence.rst +++ b/docs/source/telegram.ext.basepersistence.rst @@ -1,5 +1,5 @@ -telegram.ext.BasePersistence -============================ +BasePersistence +=============== .. autoclass:: telegram.ext.BasePersistence :members: diff --git a/docs/source/telegram.ext.baseratelimiter.rst b/docs/source/telegram.ext.baseratelimiter.rst index c4820549a..1d41db92b 100644 --- a/docs/source/telegram.ext.baseratelimiter.rst +++ b/docs/source/telegram.ext.baseratelimiter.rst @@ -1,5 +1,5 @@ -telegram.ext.BaseRateLimiter -============================ +BaseRateLimiter +=============== .. autoclass:: telegram.ext.BaseRateLimiter :members: diff --git a/docs/source/telegram.ext.callbackcontext.rst b/docs/source/telegram.ext.callbackcontext.rst index 364879318..f88241d0d 100644 --- a/docs/source/telegram.ext.callbackcontext.rst +++ b/docs/source/telegram.ext.callbackcontext.rst @@ -1,5 +1,5 @@ -telegram.ext.CallbackContext -============================ +CallbackContext +=============== .. autoclass:: telegram.ext.CallbackContext :members: diff --git a/docs/source/telegram.ext.callbackdatacache.rst b/docs/source/telegram.ext.callbackdatacache.rst index 96dbedd9f..0ad16d096 100644 --- a/docs/source/telegram.ext.callbackdatacache.rst +++ b/docs/source/telegram.ext.callbackdatacache.rst @@ -1,5 +1,5 @@ -telegram.ext.CallbackDataCache -============================== +CallbackDataCache +================= .. autoclass:: telegram.ext.CallbackDataCache :members: diff --git a/docs/source/telegram.ext.callbackqueryhandler.rst b/docs/source/telegram.ext.callbackqueryhandler.rst index 4e876e413..1414993bb 100644 --- a/docs/source/telegram.ext.callbackqueryhandler.rst +++ b/docs/source/telegram.ext.callbackqueryhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.CallbackQueryHandler -================================= +CallbackQueryHandler +==================== .. autoclass:: telegram.ext.CallbackQueryHandler :members: diff --git a/docs/source/telegram.ext.chatjoinrequesthandler.rst b/docs/source/telegram.ext.chatjoinrequesthandler.rst index e36596b4a..7f860a8fc 100644 --- a/docs/source/telegram.ext.chatjoinrequesthandler.rst +++ b/docs/source/telegram.ext.chatjoinrequesthandler.rst @@ -1,5 +1,5 @@ -telegram.ext.ChatJoinRequestHandler -=================================== +ChatJoinRequestHandler +====================== .. autoclass:: telegram.ext.ChatJoinRequestHandler :members: diff --git a/docs/source/telegram.ext.chatmemberhandler.rst b/docs/source/telegram.ext.chatmemberhandler.rst index 59675b954..e2662c308 100644 --- a/docs/source/telegram.ext.chatmemberhandler.rst +++ b/docs/source/telegram.ext.chatmemberhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.ChatMemberHandler -============================== +ChatMemberHandler +================= .. autoclass:: telegram.ext.ChatMemberHandler :members: diff --git a/docs/source/telegram.ext.choseninlineresulthandler.rst b/docs/source/telegram.ext.choseninlineresulthandler.rst index e415c2d7e..19a0d975c 100644 --- a/docs/source/telegram.ext.choseninlineresulthandler.rst +++ b/docs/source/telegram.ext.choseninlineresulthandler.rst @@ -1,5 +1,5 @@ -telegram.ext.ChosenInlineResultHandler -====================================== +ChosenInlineResultHandler +========================= .. autoclass:: telegram.ext.ChosenInlineResultHandler :members: diff --git a/docs/source/telegram.ext.commandhandler.rst b/docs/source/telegram.ext.commandhandler.rst index a892d3ca8..91d7be065 100644 --- a/docs/source/telegram.ext.commandhandler.rst +++ b/docs/source/telegram.ext.commandhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.CommandHandler -=========================== +CommandHandler +============== .. autoclass:: telegram.ext.CommandHandler :members: diff --git a/docs/source/telegram.ext.contexttypes.rst b/docs/source/telegram.ext.contexttypes.rst index 28f3e31a7..ef15bf713 100644 --- a/docs/source/telegram.ext.contexttypes.rst +++ b/docs/source/telegram.ext.contexttypes.rst @@ -1,5 +1,5 @@ -telegram.ext.ContextTypes -========================= +ContextTypes +============ .. autoclass:: telegram.ext.ContextTypes :members: diff --git a/docs/source/telegram.ext.conversationhandler.rst b/docs/source/telegram.ext.conversationhandler.rst index aa4bac815..3ec96f1fd 100644 --- a/docs/source/telegram.ext.conversationhandler.rst +++ b/docs/source/telegram.ext.conversationhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.ConversationHandler -================================ +ConversationHandler +=================== .. autoclass:: telegram.ext.ConversationHandler :members: diff --git a/docs/source/telegram.ext.defaults.rst b/docs/source/telegram.ext.defaults.rst index d08a6ed5c..365494614 100644 --- a/docs/source/telegram.ext.defaults.rst +++ b/docs/source/telegram.ext.defaults.rst @@ -1,5 +1,5 @@ -telegram.ext.Defaults -===================== +Defaults +======== .. autoclass:: telegram.ext.Defaults :members: diff --git a/docs/source/telegram.ext.dictpersistence.rst b/docs/source/telegram.ext.dictpersistence.rst index 08b78de37..d9f3ab56a 100644 --- a/docs/source/telegram.ext.dictpersistence.rst +++ b/docs/source/telegram.ext.dictpersistence.rst @@ -1,5 +1,5 @@ -telegram.ext.DictPersistence -============================ +DictPersistence +=============== .. autoclass:: telegram.ext.DictPersistence :members: diff --git a/docs/source/telegram.ext.extbot.rst b/docs/source/telegram.ext.extbot.rst index ae441ec05..d61a36b07 100644 --- a/docs/source/telegram.ext.extbot.rst +++ b/docs/source/telegram.ext.extbot.rst @@ -1,5 +1,5 @@ -telegram.ext.ExtBot -=================== +ExtBot +====== .. autoclass:: telegram.ext.ExtBot :show-inheritance: diff --git a/docs/source/telegram.ext.filters.rst b/docs/source/telegram.ext.filters.rst index d32a0015d..24306dca3 100644 --- a/docs/source/telegram.ext.filters.rst +++ b/docs/source/telegram.ext.filters.rst @@ -1,5 +1,5 @@ -telegram.ext.filters Module -=========================== +filters Module +============== .. :bysource: since e.g filters.CHAT is much above filters.Chat() in the docs when it shouldn't. The classes in `filters.py` are sorted alphabetically such that :bysource: still is readable diff --git a/docs/source/telegram.ext.inlinequeryhandler.rst b/docs/source/telegram.ext.inlinequeryhandler.rst index 5b249c9fa..26469d997 100644 --- a/docs/source/telegram.ext.inlinequeryhandler.rst +++ b/docs/source/telegram.ext.inlinequeryhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.InlineQueryHandler -=============================== +InlineQueryHandler +================== .. autoclass:: telegram.ext.InlineQueryHandler :members: diff --git a/docs/source/telegram.ext.invalidcallbackdata.rst b/docs/source/telegram.ext.invalidcallbackdata.rst index b19bed91c..7bfc7e451 100644 --- a/docs/source/telegram.ext.invalidcallbackdata.rst +++ b/docs/source/telegram.ext.invalidcallbackdata.rst @@ -1,5 +1,5 @@ -telegram.ext.InvalidCallbackData -================================ +InvalidCallbackData +=================== .. autoclass:: telegram.ext.InvalidCallbackData :members: diff --git a/docs/source/telegram.ext.job.rst b/docs/source/telegram.ext.job.rst index c150bc37c..469f8875f 100644 --- a/docs/source/telegram.ext.job.rst +++ b/docs/source/telegram.ext.job.rst @@ -1,5 +1,5 @@ -telegram.ext.Job -===================== +Job +=== .. autoclass:: telegram.ext.Job :members: diff --git a/docs/source/telegram.ext.jobqueue.rst b/docs/source/telegram.ext.jobqueue.rst index 080d64226..75658e30d 100644 --- a/docs/source/telegram.ext.jobqueue.rst +++ b/docs/source/telegram.ext.jobqueue.rst @@ -1,5 +1,5 @@ -telegram.ext.JobQueue -===================== +JobQueue +======== .. autoclass:: telegram.ext.JobQueue :members: diff --git a/docs/source/telegram.ext.messagehandler.rst b/docs/source/telegram.ext.messagehandler.rst index 2d1ca39bf..2292eb445 100644 --- a/docs/source/telegram.ext.messagehandler.rst +++ b/docs/source/telegram.ext.messagehandler.rst @@ -1,5 +1,5 @@ -telegram.ext.MessageHandler -=========================== +MessageHandler +============== .. autoclass:: telegram.ext.MessageHandler :members: diff --git a/docs/source/telegram.ext.persistenceinput.rst b/docs/source/telegram.ext.persistenceinput.rst index b2d491979..4a1bc2822 100644 --- a/docs/source/telegram.ext.persistenceinput.rst +++ b/docs/source/telegram.ext.persistenceinput.rst @@ -1,5 +1,5 @@ -telegram.ext.PersistenceInput -============================= +PersistenceInput +================ .. autoclass:: telegram.ext.PersistenceInput :show-inheritance: diff --git a/docs/source/telegram.ext.picklepersistence.rst b/docs/source/telegram.ext.picklepersistence.rst index f8691b181..ffd65a203 100644 --- a/docs/source/telegram.ext.picklepersistence.rst +++ b/docs/source/telegram.ext.picklepersistence.rst @@ -1,5 +1,5 @@ -telegram.ext.PicklePersistence -============================== +PicklePersistence +================= .. autoclass:: telegram.ext.PicklePersistence :members: diff --git a/docs/source/telegram.ext.pollanswerhandler.rst b/docs/source/telegram.ext.pollanswerhandler.rst index 5113f135e..3f215e520 100644 --- a/docs/source/telegram.ext.pollanswerhandler.rst +++ b/docs/source/telegram.ext.pollanswerhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.PollAnswerHandler -============================== +PollAnswerHandler +================= .. autoclass:: telegram.ext.PollAnswerHandler :members: diff --git a/docs/source/telegram.ext.pollhandler.rst b/docs/source/telegram.ext.pollhandler.rst index da30d879f..2f6c19f26 100644 --- a/docs/source/telegram.ext.pollhandler.rst +++ b/docs/source/telegram.ext.pollhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.PollHandler -======================== +PollHandler +=========== .. autoclass:: telegram.ext.PollHandler :members: diff --git a/docs/source/telegram.ext.precheckoutqueryhandler.rst b/docs/source/telegram.ext.precheckoutqueryhandler.rst index 28fe9d49a..482cba07b 100644 --- a/docs/source/telegram.ext.precheckoutqueryhandler.rst +++ b/docs/source/telegram.ext.precheckoutqueryhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.PreCheckoutQueryHandler -==================================== +PreCheckoutQueryHandler +======================= .. autoclass:: telegram.ext.PreCheckoutQueryHandler :members: diff --git a/docs/source/telegram.ext.prefixhandler.rst b/docs/source/telegram.ext.prefixhandler.rst index 18fb2be14..ad7683852 100644 --- a/docs/source/telegram.ext.prefixhandler.rst +++ b/docs/source/telegram.ext.prefixhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.PrefixHandler -=========================== +PrefixHandler +============= .. autoclass:: telegram.ext.PrefixHandler :members: diff --git a/docs/source/telegram.ext.shippingqueryhandler.rst b/docs/source/telegram.ext.shippingqueryhandler.rst index 7da2992b9..f368630fd 100644 --- a/docs/source/telegram.ext.shippingqueryhandler.rst +++ b/docs/source/telegram.ext.shippingqueryhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.ShippingQueryHandler -================================= +ShippingQueryHandler +==================== .. autoclass:: telegram.ext.ShippingQueryHandler :members: diff --git a/docs/source/telegram.ext.stringcommandhandler.rst b/docs/source/telegram.ext.stringcommandhandler.rst index 57ed1710e..c716753ef 100644 --- a/docs/source/telegram.ext.stringcommandhandler.rst +++ b/docs/source/telegram.ext.stringcommandhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.StringCommandHandler -================================= +StringCommandHandler +==================== .. autoclass:: telegram.ext.StringCommandHandler :members: diff --git a/docs/source/telegram.ext.stringregexhandler.rst b/docs/source/telegram.ext.stringregexhandler.rst index 621d9b732..d8d8ef025 100644 --- a/docs/source/telegram.ext.stringregexhandler.rst +++ b/docs/source/telegram.ext.stringregexhandler.rst @@ -1,5 +1,5 @@ -telegram.ext.StringRegexHandler -=============================== +StringRegexHandler +================== .. autoclass:: telegram.ext.StringRegexHandler :members: diff --git a/docs/source/telegram.ext.typehandler.rst b/docs/source/telegram.ext.typehandler.rst index 05ebd4ee3..a85dd0f19 100644 --- a/docs/source/telegram.ext.typehandler.rst +++ b/docs/source/telegram.ext.typehandler.rst @@ -1,5 +1,5 @@ -telegram.ext.TypeHandler -======================== +TypeHandler +=========== .. autoclass:: telegram.ext.TypeHandler :members: diff --git a/docs/source/telegram.ext.updater.rst b/docs/source/telegram.ext.updater.rst index 2a52132d7..642ddd202 100644 --- a/docs/source/telegram.ext.updater.rst +++ b/docs/source/telegram.ext.updater.rst @@ -1,5 +1,5 @@ -telegram.ext.Updater -==================== +Updater +======= .. autoclass:: telegram.ext.Updater :members: diff --git a/docs/source/telegram.file.rst b/docs/source/telegram.file.rst index f04d547ab..479474678 100644 --- a/docs/source/telegram.file.rst +++ b/docs/source/telegram.file.rst @@ -1,5 +1,5 @@ -telegram.File -============= +File +==== .. autoclass:: telegram.File :members: diff --git a/docs/source/telegram.filecredentials.rst b/docs/source/telegram.filecredentials.rst index 600661e50..b82338ce7 100644 --- a/docs/source/telegram.filecredentials.rst +++ b/docs/source/telegram.filecredentials.rst @@ -1,5 +1,5 @@ -telegram.FileCredentials -======================== +FileCredentials +=============== .. autoclass:: telegram.FileCredentials :members: diff --git a/docs/source/telegram.forcereply.rst b/docs/source/telegram.forcereply.rst index 75bfc166a..8418d56f1 100644 --- a/docs/source/telegram.forcereply.rst +++ b/docs/source/telegram.forcereply.rst @@ -1,5 +1,5 @@ -telegram.ForceReply -=================== +ForceReply +========== .. autoclass:: telegram.ForceReply :members: diff --git a/docs/source/telegram.forumtopic.rst b/docs/source/telegram.forumtopic.rst index a2dd6389c..ba2ceb3a4 100644 --- a/docs/source/telegram.forumtopic.rst +++ b/docs/source/telegram.forumtopic.rst @@ -1,5 +1,5 @@ -telegram.ForumTopic -=================== +ForumTopic +========== .. autoclass:: telegram.ForumTopic :members: diff --git a/docs/source/telegram.forumtopicclosed.rst b/docs/source/telegram.forumtopicclosed.rst index 198a67372..1954cc4e0 100644 --- a/docs/source/telegram.forumtopicclosed.rst +++ b/docs/source/telegram.forumtopicclosed.rst @@ -1,5 +1,5 @@ -telegram.ForumTopicClosed -========================= +ForumTopicClosed +================ .. autoclass:: telegram.ForumTopicClosed :members: diff --git a/docs/source/telegram.forumtopiccreated.rst b/docs/source/telegram.forumtopiccreated.rst index f1da6f81d..828aacee8 100644 --- a/docs/source/telegram.forumtopiccreated.rst +++ b/docs/source/telegram.forumtopiccreated.rst @@ -1,5 +1,5 @@ -telegram.ForumTopicCreated -========================== +ForumTopicCreated +================= .. autoclass:: telegram.ForumTopicCreated :members: diff --git a/docs/source/telegram.forumtopicedited.rst b/docs/source/telegram.forumtopicedited.rst index 77dfb3491..1b0a09a48 100644 --- a/docs/source/telegram.forumtopicedited.rst +++ b/docs/source/telegram.forumtopicedited.rst @@ -1,5 +1,5 @@ -telegram.ForumTopicEdited -========================= +ForumTopicEdited +================ .. autoclass:: telegram.ForumTopicEdited :members: diff --git a/docs/source/telegram.forumtopicreopened.rst b/docs/source/telegram.forumtopicreopened.rst index b81c395d2..d1e021865 100644 --- a/docs/source/telegram.forumtopicreopened.rst +++ b/docs/source/telegram.forumtopicreopened.rst @@ -1,5 +1,5 @@ -telegram.ForumTopicReopened -=========================== +ForumTopicReopened +================== .. autoclass:: telegram.ForumTopicReopened :members: diff --git a/docs/source/telegram.game.rst b/docs/source/telegram.game.rst index ada1140d5..53f55489f 100644 --- a/docs/source/telegram.game.rst +++ b/docs/source/telegram.game.rst @@ -1,5 +1,5 @@ -telegram.Game -============= +Game +==== .. autoclass:: telegram.Game :members: diff --git a/docs/source/telegram.gamehighscore.rst b/docs/source/telegram.gamehighscore.rst index c69c7fe1d..784e4dd3a 100644 --- a/docs/source/telegram.gamehighscore.rst +++ b/docs/source/telegram.gamehighscore.rst @@ -1,5 +1,5 @@ -telegram.GameHighScore -====================== +GameHighScore +============= .. autoclass:: telegram.GameHighScore :members: diff --git a/docs/source/telegram.generalforumtopichidden.rst b/docs/source/telegram.generalforumtopichidden.rst index d3843ab6c..5d70e782f 100644 --- a/docs/source/telegram.generalforumtopichidden.rst +++ b/docs/source/telegram.generalforumtopichidden.rst @@ -1,5 +1,5 @@ -telegram.GeneralForumTopicHidden -================================ +GeneralForumTopicHidden +======================= .. autoclass:: telegram.GeneralForumTopicHidden :members: diff --git a/docs/source/telegram.generalforumtopicunhidden.rst b/docs/source/telegram.generalforumtopicunhidden.rst index 924ddc742..ee82c770b 100644 --- a/docs/source/telegram.generalforumtopicunhidden.rst +++ b/docs/source/telegram.generalforumtopicunhidden.rst @@ -1,5 +1,5 @@ -telegram.GeneralForumTopicUnhidden -================================== +GeneralForumTopicUnhidden +========================= .. autoclass:: telegram.GeneralForumTopicUnhidden :members: diff --git a/docs/source/telegram.iddocumentdata.rst b/docs/source/telegram.iddocumentdata.rst index 1333f7ed4..999d23bcc 100644 --- a/docs/source/telegram.iddocumentdata.rst +++ b/docs/source/telegram.iddocumentdata.rst @@ -1,5 +1,5 @@ -telegram.IdDocumentData -======================= +IdDocumentData +============== .. autoclass:: telegram.IdDocumentData :members: diff --git a/docs/source/telegram.inlinekeyboardbutton.rst b/docs/source/telegram.inlinekeyboardbutton.rst index 9a118a75c..ff61d6fb4 100644 --- a/docs/source/telegram.inlinekeyboardbutton.rst +++ b/docs/source/telegram.inlinekeyboardbutton.rst @@ -1,5 +1,5 @@ -telegram.InlineKeyboardButton -============================= +InlineKeyboardButton +==================== .. autoclass:: telegram.InlineKeyboardButton :members: diff --git a/docs/source/telegram.inlinekeyboardmarkup.rst b/docs/source/telegram.inlinekeyboardmarkup.rst index 63aba4630..99a44cc9e 100644 --- a/docs/source/telegram.inlinekeyboardmarkup.rst +++ b/docs/source/telegram.inlinekeyboardmarkup.rst @@ -1,5 +1,5 @@ -telegram.InlineKeyboardMarkup -============================= +InlineKeyboardMarkup +==================== .. autoclass:: telegram.InlineKeyboardMarkup :members: diff --git a/docs/source/telegram.inlinequery.rst b/docs/source/telegram.inlinequery.rst index ce17a816d..eb806aa38 100644 --- a/docs/source/telegram.inlinequery.rst +++ b/docs/source/telegram.inlinequery.rst @@ -1,5 +1,5 @@ -telegram.InlineQuery -==================== +InlineQuery +=========== .. autoclass:: telegram.InlineQuery :members: diff --git a/docs/source/telegram.inlinequeryresult.rst b/docs/source/telegram.inlinequeryresult.rst index 97e9a97ff..eda58f1c2 100644 --- a/docs/source/telegram.inlinequeryresult.rst +++ b/docs/source/telegram.inlinequeryresult.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResult -========================== +InlineQueryResult +================= .. autoclass:: telegram.InlineQueryResult :members: diff --git a/docs/source/telegram.inlinequeryresultarticle.rst b/docs/source/telegram.inlinequeryresultarticle.rst index c8756fdc7..1600c0590 100644 --- a/docs/source/telegram.inlinequeryresultarticle.rst +++ b/docs/source/telegram.inlinequeryresultarticle.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultArticle -================================= +InlineQueryResultArticle +======================== .. autoclass:: telegram.InlineQueryResultArticle :members: diff --git a/docs/source/telegram.inlinequeryresultaudio.rst b/docs/source/telegram.inlinequeryresultaudio.rst index 83bb5d452..a78399b00 100644 --- a/docs/source/telegram.inlinequeryresultaudio.rst +++ b/docs/source/telegram.inlinequeryresultaudio.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultAudio -=============================== +InlineQueryResultAudio +====================== .. autoclass:: telegram.InlineQueryResultAudio :members: diff --git a/docs/source/telegram.inlinequeryresultcachedaudio.rst b/docs/source/telegram.inlinequeryresultcachedaudio.rst index f7e992916..860b7a4ed 100644 --- a/docs/source/telegram.inlinequeryresultcachedaudio.rst +++ b/docs/source/telegram.inlinequeryresultcachedaudio.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedAudio -===================================== +InlineQueryResultCachedAudio +============================ .. autoclass:: telegram.InlineQueryResultCachedAudio :members: diff --git a/docs/source/telegram.inlinequeryresultcacheddocument.rst b/docs/source/telegram.inlinequeryresultcacheddocument.rst index 18db7ba7a..6768b7521 100644 --- a/docs/source/telegram.inlinequeryresultcacheddocument.rst +++ b/docs/source/telegram.inlinequeryresultcacheddocument.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedDocument -======================================== +InlineQueryResultCachedDocument +=============================== .. autoclass:: telegram.InlineQueryResultCachedDocument :members: diff --git a/docs/source/telegram.inlinequeryresultcachedgif.rst b/docs/source/telegram.inlinequeryresultcachedgif.rst index 9faaf071a..c0b2f6277 100644 --- a/docs/source/telegram.inlinequeryresultcachedgif.rst +++ b/docs/source/telegram.inlinequeryresultcachedgif.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedGif -=================================== +InlineQueryResultCachedGif +========================== .. autoclass:: telegram.InlineQueryResultCachedGif :members: diff --git a/docs/source/telegram.inlinequeryresultcachedmpeg4gif.rst b/docs/source/telegram.inlinequeryresultcachedmpeg4gif.rst index 1c6406ab5..780fca432 100644 --- a/docs/source/telegram.inlinequeryresultcachedmpeg4gif.rst +++ b/docs/source/telegram.inlinequeryresultcachedmpeg4gif.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedMpeg4Gif -======================================== +InlineQueryResultCachedMpeg4Gif +=============================== .. autoclass:: telegram.InlineQueryResultCachedMpeg4Gif :members: diff --git a/docs/source/telegram.inlinequeryresultcachedphoto.rst b/docs/source/telegram.inlinequeryresultcachedphoto.rst index 9887210f3..8a5b1bc4b 100644 --- a/docs/source/telegram.inlinequeryresultcachedphoto.rst +++ b/docs/source/telegram.inlinequeryresultcachedphoto.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedPhoto -===================================== +InlineQueryResultCachedPhoto +============================ .. autoclass:: telegram.InlineQueryResultCachedPhoto :members: diff --git a/docs/source/telegram.inlinequeryresultcachedsticker.rst b/docs/source/telegram.inlinequeryresultcachedsticker.rst index 4b989ddba..eb204cb88 100644 --- a/docs/source/telegram.inlinequeryresultcachedsticker.rst +++ b/docs/source/telegram.inlinequeryresultcachedsticker.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedSticker -======================================= +InlineQueryResultCachedSticker +============================== .. autoclass:: telegram.InlineQueryResultCachedSticker :members: diff --git a/docs/source/telegram.inlinequeryresultcachedvideo.rst b/docs/source/telegram.inlinequeryresultcachedvideo.rst index 49efa7e89..121d5b95b 100644 --- a/docs/source/telegram.inlinequeryresultcachedvideo.rst +++ b/docs/source/telegram.inlinequeryresultcachedvideo.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedVideo -===================================== +InlineQueryResultCachedVideo +============================ .. autoclass:: telegram.InlineQueryResultCachedVideo :members: diff --git a/docs/source/telegram.inlinequeryresultcachedvoice.rst b/docs/source/telegram.inlinequeryresultcachedvoice.rst index 88a5377c8..dbe132af1 100644 --- a/docs/source/telegram.inlinequeryresultcachedvoice.rst +++ b/docs/source/telegram.inlinequeryresultcachedvoice.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultCachedVoice -===================================== +InlineQueryResultCachedVoice +============================ .. autoclass:: telegram.InlineQueryResultCachedVoice :members: diff --git a/docs/source/telegram.inlinequeryresultcontact.rst b/docs/source/telegram.inlinequeryresultcontact.rst index 017ccfbca..3fee7ac4e 100644 --- a/docs/source/telegram.inlinequeryresultcontact.rst +++ b/docs/source/telegram.inlinequeryresultcontact.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultContact -================================= +InlineQueryResultContact +======================== .. autoclass:: telegram.InlineQueryResultContact :members: diff --git a/docs/source/telegram.inlinequeryresultdocument.rst b/docs/source/telegram.inlinequeryresultdocument.rst index ec8542260..914fc0c0d 100644 --- a/docs/source/telegram.inlinequeryresultdocument.rst +++ b/docs/source/telegram.inlinequeryresultdocument.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultDocument -================================== +InlineQueryResultDocument +========================= .. autoclass:: telegram.InlineQueryResultDocument :members: diff --git a/docs/source/telegram.inlinequeryresultgame.rst b/docs/source/telegram.inlinequeryresultgame.rst index 7c6172d80..8c3189c81 100644 --- a/docs/source/telegram.inlinequeryresultgame.rst +++ b/docs/source/telegram.inlinequeryresultgame.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultGame -============================== +InlineQueryResultGame +===================== .. autoclass:: telegram.InlineQueryResultGame :members: diff --git a/docs/source/telegram.inlinequeryresultgif.rst b/docs/source/telegram.inlinequeryresultgif.rst index a9c60f143..c19a9f790 100644 --- a/docs/source/telegram.inlinequeryresultgif.rst +++ b/docs/source/telegram.inlinequeryresultgif.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultGif -============================= +InlineQueryResultGif +==================== .. autoclass:: telegram.InlineQueryResultGif :members: diff --git a/docs/source/telegram.inlinequeryresultlocation.rst b/docs/source/telegram.inlinequeryresultlocation.rst index 37980636d..053bb74f0 100644 --- a/docs/source/telegram.inlinequeryresultlocation.rst +++ b/docs/source/telegram.inlinequeryresultlocation.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultLocation -================================== +InlineQueryResultLocation +========================= .. autoclass:: telegram.InlineQueryResultLocation :members: diff --git a/docs/source/telegram.inlinequeryresultmpeg4gif.rst b/docs/source/telegram.inlinequeryresultmpeg4gif.rst index ad7e12d47..6e6d68bf7 100644 --- a/docs/source/telegram.inlinequeryresultmpeg4gif.rst +++ b/docs/source/telegram.inlinequeryresultmpeg4gif.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultMpeg4Gif -================================== +InlineQueryResultMpeg4Gif +========================= .. autoclass:: telegram.InlineQueryResultMpeg4Gif :members: diff --git a/docs/source/telegram.inlinequeryresultphoto.rst b/docs/source/telegram.inlinequeryresultphoto.rst index 40a9f63c3..b7f4671ca 100644 --- a/docs/source/telegram.inlinequeryresultphoto.rst +++ b/docs/source/telegram.inlinequeryresultphoto.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultPhoto -=============================== +InlineQueryResultPhoto +====================== .. autoclass:: telegram.InlineQueryResultPhoto :members: diff --git a/docs/source/telegram.inlinequeryresultvenue.rst b/docs/source/telegram.inlinequeryresultvenue.rst index 4378ed478..0c5f19b03 100644 --- a/docs/source/telegram.inlinequeryresultvenue.rst +++ b/docs/source/telegram.inlinequeryresultvenue.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultVenue -=============================== +InlineQueryResultVenue +====================== .. autoclass:: telegram.InlineQueryResultVenue :members: diff --git a/docs/source/telegram.inlinequeryresultvideo.rst b/docs/source/telegram.inlinequeryresultvideo.rst index 3cb445fd0..3df6d559a 100644 --- a/docs/source/telegram.inlinequeryresultvideo.rst +++ b/docs/source/telegram.inlinequeryresultvideo.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultVideo -=============================== +InlineQueryResultVideo +====================== .. autoclass:: telegram.InlineQueryResultVideo :members: diff --git a/docs/source/telegram.inlinequeryresultvoice.rst b/docs/source/telegram.inlinequeryresultvoice.rst index e3efd0717..8194b3ad6 100644 --- a/docs/source/telegram.inlinequeryresultvoice.rst +++ b/docs/source/telegram.inlinequeryresultvoice.rst @@ -1,5 +1,5 @@ -telegram.InlineQueryResultVoice -=============================== +InlineQueryResultVoice +====================== .. autoclass:: telegram.InlineQueryResultVoice :members: diff --git a/docs/source/telegram.inputcontactmessagecontent.rst b/docs/source/telegram.inputcontactmessagecontent.rst index 3a98e7e98..5deb70724 100644 --- a/docs/source/telegram.inputcontactmessagecontent.rst +++ b/docs/source/telegram.inputcontactmessagecontent.rst @@ -1,5 +1,5 @@ -telegram.InputContactMessageContent -=================================== +InputContactMessageContent +========================== .. autoclass:: telegram.InputContactMessageContent :members: diff --git a/docs/source/telegram.inputfile.rst b/docs/source/telegram.inputfile.rst index cd55a869c..717f9235a 100644 --- a/docs/source/telegram.inputfile.rst +++ b/docs/source/telegram.inputfile.rst @@ -1,5 +1,5 @@ -telegram.InputFile -================== +InputFile +========= .. autoclass:: telegram.InputFile :members: diff --git a/docs/source/telegram.inputinvoicemessagecontent.rst b/docs/source/telegram.inputinvoicemessagecontent.rst index f19f8c6da..0354229e7 100644 --- a/docs/source/telegram.inputinvoicemessagecontent.rst +++ b/docs/source/telegram.inputinvoicemessagecontent.rst @@ -1,5 +1,5 @@ -telegram.InputInvoiceMessageContent -=================================== +InputInvoiceMessageContent +========================== .. autoclass:: telegram.InputInvoiceMessageContent :members: diff --git a/docs/source/telegram.inputlocationmessagecontent.rst b/docs/source/telegram.inputlocationmessagecontent.rst index b5bc314e2..51359967c 100644 --- a/docs/source/telegram.inputlocationmessagecontent.rst +++ b/docs/source/telegram.inputlocationmessagecontent.rst @@ -1,5 +1,5 @@ -telegram.InputLocationMessageContent -==================================== +InputLocationMessageContent +=========================== .. autoclass:: telegram.InputLocationMessageContent :members: diff --git a/docs/source/telegram.inputmedia.rst b/docs/source/telegram.inputmedia.rst index 26b9d76eb..4f58bbb0e 100644 --- a/docs/source/telegram.inputmedia.rst +++ b/docs/source/telegram.inputmedia.rst @@ -1,5 +1,5 @@ -telegram.InputMedia -=================== +InputMedia +========== .. autoclass:: telegram.InputMedia :members: diff --git a/docs/source/telegram.inputmediaanimation.rst b/docs/source/telegram.inputmediaanimation.rst index b94711b06..4324182d7 100644 --- a/docs/source/telegram.inputmediaanimation.rst +++ b/docs/source/telegram.inputmediaanimation.rst @@ -1,5 +1,5 @@ -telegram.InputMediaAnimation -============================ +InputMediaAnimation +=================== .. autoclass:: telegram.InputMediaAnimation :members: diff --git a/docs/source/telegram.inputmediaaudio.rst b/docs/source/telegram.inputmediaaudio.rst index 5a7a977fc..f91484ed3 100644 --- a/docs/source/telegram.inputmediaaudio.rst +++ b/docs/source/telegram.inputmediaaudio.rst @@ -1,5 +1,5 @@ -telegram.InputMediaAudio -======================== +InputMediaAudio +=============== .. autoclass:: telegram.InputMediaAudio :members: diff --git a/docs/source/telegram.inputmediadocument.rst b/docs/source/telegram.inputmediadocument.rst index 746b15f9a..e6681a73b 100644 --- a/docs/source/telegram.inputmediadocument.rst +++ b/docs/source/telegram.inputmediadocument.rst @@ -1,5 +1,5 @@ -telegram.InputMediaDocument -=========================== +InputMediaDocument +================== .. autoclass:: telegram.InputMediaDocument :members: diff --git a/docs/source/telegram.inputmediaphoto.rst b/docs/source/telegram.inputmediaphoto.rst index 07bfe307f..ad7091fe7 100644 --- a/docs/source/telegram.inputmediaphoto.rst +++ b/docs/source/telegram.inputmediaphoto.rst @@ -1,5 +1,5 @@ -telegram.InputMediaPhoto -======================== +InputMediaPhoto +=============== .. autoclass:: telegram.InputMediaPhoto :members: diff --git a/docs/source/telegram.inputmediavideo.rst b/docs/source/telegram.inputmediavideo.rst index af28e4667..751261c48 100644 --- a/docs/source/telegram.inputmediavideo.rst +++ b/docs/source/telegram.inputmediavideo.rst @@ -1,5 +1,5 @@ -telegram.InputMediaVideo -======================== +InputMediaVideo +=============== .. autoclass:: telegram.InputMediaVideo :members: diff --git a/docs/source/telegram.inputmessagecontent.rst b/docs/source/telegram.inputmessagecontent.rst index 374510996..a7b50b5b4 100644 --- a/docs/source/telegram.inputmessagecontent.rst +++ b/docs/source/telegram.inputmessagecontent.rst @@ -1,5 +1,5 @@ -telegram.InputMessageContent -============================ +InputMessageContent +=================== .. autoclass:: telegram.InputMessageContent :members: diff --git a/docs/source/telegram.inputtextmessagecontent.rst b/docs/source/telegram.inputtextmessagecontent.rst index 88d7972f4..652a6bef1 100644 --- a/docs/source/telegram.inputtextmessagecontent.rst +++ b/docs/source/telegram.inputtextmessagecontent.rst @@ -1,5 +1,5 @@ -telegram.InputTextMessageContent -================================ +InputTextMessageContent +======================= .. autoclass:: telegram.InputTextMessageContent :members: diff --git a/docs/source/telegram.inputvenuemessagecontent.rst b/docs/source/telegram.inputvenuemessagecontent.rst index 009a39920..678be16e6 100644 --- a/docs/source/telegram.inputvenuemessagecontent.rst +++ b/docs/source/telegram.inputvenuemessagecontent.rst @@ -1,5 +1,5 @@ -telegram.InputVenueMessageContent -================================= +InputVenueMessageContent +======================== .. autoclass:: telegram.InputVenueMessageContent :members: diff --git a/docs/source/telegram.invoice.rst b/docs/source/telegram.invoice.rst index f38c4e6c7..0033452af 100644 --- a/docs/source/telegram.invoice.rst +++ b/docs/source/telegram.invoice.rst @@ -1,5 +1,5 @@ -telegram.Invoice -================ +Invoice +======= .. autoclass:: telegram.Invoice :members: diff --git a/docs/source/telegram.keyboardbutton.rst b/docs/source/telegram.keyboardbutton.rst index cec3de5d7..ccc5ebb7c 100644 --- a/docs/source/telegram.keyboardbutton.rst +++ b/docs/source/telegram.keyboardbutton.rst @@ -1,5 +1,5 @@ -telegram.KeyboardButton -======================= +KeyboardButton +============== .. autoclass:: telegram.KeyboardButton :members: diff --git a/docs/source/telegram.keyboardbuttonpolltype.rst b/docs/source/telegram.keyboardbuttonpolltype.rst index fa4315abd..44d0d13e4 100644 --- a/docs/source/telegram.keyboardbuttonpolltype.rst +++ b/docs/source/telegram.keyboardbuttonpolltype.rst @@ -1,5 +1,5 @@ -telegram.KeyboardButtonPollType -=============================== +KeyboardButtonPollType +====================== .. autoclass:: telegram.KeyboardButtonPollType :members: diff --git a/docs/source/telegram.labeledprice.rst b/docs/source/telegram.labeledprice.rst index 7c9d5668a..18ec28c0d 100644 --- a/docs/source/telegram.labeledprice.rst +++ b/docs/source/telegram.labeledprice.rst @@ -1,5 +1,5 @@ -telegram.LabeledPrice -===================== +LabeledPrice +============ .. autoclass:: telegram.LabeledPrice :members: diff --git a/docs/source/telegram.location.rst b/docs/source/telegram.location.rst index 7d3a62c21..5240b3247 100644 --- a/docs/source/telegram.location.rst +++ b/docs/source/telegram.location.rst @@ -1,5 +1,5 @@ -telegram.Location -================= +Location +======== .. autoclass:: telegram.Location :members: diff --git a/docs/source/telegram.loginurl.rst b/docs/source/telegram.loginurl.rst index 3f8324d95..382b44de5 100644 --- a/docs/source/telegram.loginurl.rst +++ b/docs/source/telegram.loginurl.rst @@ -1,5 +1,5 @@ -telegram.LoginUrl -================= +LoginUrl +======== .. autoclass:: telegram.LoginUrl :members: diff --git a/docs/source/telegram.maskposition.rst b/docs/source/telegram.maskposition.rst index d38bb3445..469693dbe 100644 --- a/docs/source/telegram.maskposition.rst +++ b/docs/source/telegram.maskposition.rst @@ -1,5 +1,5 @@ -telegram.MaskPosition -===================== +MaskPosition +============ .. autoclass:: telegram.MaskPosition :members: diff --git a/docs/source/telegram.menubutton.rst b/docs/source/telegram.menubutton.rst index 26774e3d5..63a0935b0 100644 --- a/docs/source/telegram.menubutton.rst +++ b/docs/source/telegram.menubutton.rst @@ -1,5 +1,5 @@ -telegram.MenuButton -=================== +MenuButton +========== .. autoclass:: telegram.MenuButton :members: diff --git a/docs/source/telegram.menubuttoncommands.rst b/docs/source/telegram.menubuttoncommands.rst index 4e0833629..bc44e738f 100644 --- a/docs/source/telegram.menubuttoncommands.rst +++ b/docs/source/telegram.menubuttoncommands.rst @@ -1,5 +1,5 @@ -telegram.MenuButtonCommands -=========================== +MenuButtonCommands +================== .. autoclass:: telegram.MenuButtonCommands :members: diff --git a/docs/source/telegram.menubuttondefault.rst b/docs/source/telegram.menubuttondefault.rst index 1db0dd93f..31924b088 100644 --- a/docs/source/telegram.menubuttondefault.rst +++ b/docs/source/telegram.menubuttondefault.rst @@ -1,5 +1,5 @@ -telegram.MenuButtonDefault -========================== +MenuButtonDefault +================= .. autoclass:: telegram.MenuButtonDefault :members: diff --git a/docs/source/telegram.menubuttonwebapp.rst b/docs/source/telegram.menubuttonwebapp.rst index 3b8d761c4..6eba96a23 100644 --- a/docs/source/telegram.menubuttonwebapp.rst +++ b/docs/source/telegram.menubuttonwebapp.rst @@ -1,5 +1,5 @@ -telegram.MenuButtonWebApp -========================= +MenuButtonWebApp +================ .. autoclass:: telegram.MenuButtonWebApp :members: diff --git a/docs/source/telegram.message.rst b/docs/source/telegram.message.rst index 97259744c..83eea6314 100644 --- a/docs/source/telegram.message.rst +++ b/docs/source/telegram.message.rst @@ -1,5 +1,5 @@ -telegram.Message -================ +Message +======= .. autoclass:: telegram.Message :members: diff --git a/docs/source/telegram.messageautodeletetimerchanged.rst b/docs/source/telegram.messageautodeletetimerchanged.rst index ae1fd5472..69658f3c6 100644 --- a/docs/source/telegram.messageautodeletetimerchanged.rst +++ b/docs/source/telegram.messageautodeletetimerchanged.rst @@ -1,5 +1,5 @@ -telegram.MessageAutoDeleteTimerChanged -====================================== +MessageAutoDeleteTimerChanged +============================= .. autoclass:: telegram.MessageAutoDeleteTimerChanged :members: diff --git a/docs/source/telegram.messageentity.rst b/docs/source/telegram.messageentity.rst index 9e3fce97b..1d669f0e7 100644 --- a/docs/source/telegram.messageentity.rst +++ b/docs/source/telegram.messageentity.rst @@ -1,5 +1,5 @@ -telegram.MessageEntity -====================== +MessageEntity +============= .. autoclass:: telegram.MessageEntity :members: diff --git a/docs/source/telegram.messageid.rst b/docs/source/telegram.messageid.rst index 9df1de2a1..a4a7b8b16 100644 --- a/docs/source/telegram.messageid.rst +++ b/docs/source/telegram.messageid.rst @@ -1,5 +1,5 @@ -telegram.MessageId -================== +MessageId +========= .. autoclass:: telegram.MessageId :members: diff --git a/docs/source/telegram.orderinfo.rst b/docs/source/telegram.orderinfo.rst index 28741db79..4826a584f 100644 --- a/docs/source/telegram.orderinfo.rst +++ b/docs/source/telegram.orderinfo.rst @@ -1,5 +1,5 @@ -telegram.OrderInfo -================== +OrderInfo +========= .. autoclass:: telegram.OrderInfo :members: diff --git a/docs/source/telegram.passportdata.rst b/docs/source/telegram.passportdata.rst index 43a33b560..8fad1edb2 100644 --- a/docs/source/telegram.passportdata.rst +++ b/docs/source/telegram.passportdata.rst @@ -1,5 +1,5 @@ -telegram.PassportData -===================== +PassportData +============ .. autoclass:: telegram.PassportData :members: diff --git a/docs/source/telegram.passportelementerror.rst b/docs/source/telegram.passportelementerror.rst index 00ef430d7..f2a5ccbd6 100644 --- a/docs/source/telegram.passportelementerror.rst +++ b/docs/source/telegram.passportelementerror.rst @@ -1,5 +1,5 @@ -telegram.PassportElementError -============================= +PassportElementError +==================== .. autoclass:: telegram.PassportElementError :members: diff --git a/docs/source/telegram.passportelementerrordatafield.rst b/docs/source/telegram.passportelementerrordatafield.rst index ac304f7b5..a697f70fe 100644 --- a/docs/source/telegram.passportelementerrordatafield.rst +++ b/docs/source/telegram.passportelementerrordatafield.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorDataField -====================================== +PassportElementErrorDataField +============================= .. autoclass:: telegram.PassportElementErrorDataField :members: diff --git a/docs/source/telegram.passportelementerrorfile.rst b/docs/source/telegram.passportelementerrorfile.rst index 339d7a786..281175332 100644 --- a/docs/source/telegram.passportelementerrorfile.rst +++ b/docs/source/telegram.passportelementerrorfile.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorFile -================================= +PassportElementErrorFile +======================== .. autoclass:: telegram.PassportElementErrorFile :members: diff --git a/docs/source/telegram.passportelementerrorfiles.rst b/docs/source/telegram.passportelementerrorfiles.rst index f9643d969..b537e3347 100644 --- a/docs/source/telegram.passportelementerrorfiles.rst +++ b/docs/source/telegram.passportelementerrorfiles.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorFiles -================================== +PassportElementErrorFiles +========================= .. autoclass:: telegram.PassportElementErrorFiles :members: diff --git a/docs/source/telegram.passportelementerrorfrontside.rst b/docs/source/telegram.passportelementerrorfrontside.rst index a92635a27..0b3126f85 100644 --- a/docs/source/telegram.passportelementerrorfrontside.rst +++ b/docs/source/telegram.passportelementerrorfrontside.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorFrontSide -====================================== +PassportElementErrorFrontSide +============================= .. autoclass:: telegram.PassportElementErrorFrontSide :members: diff --git a/docs/source/telegram.passportelementerrorreverseside.rst b/docs/source/telegram.passportelementerrorreverseside.rst index 380a10664..401bced18 100644 --- a/docs/source/telegram.passportelementerrorreverseside.rst +++ b/docs/source/telegram.passportelementerrorreverseside.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorReverseSide -======================================== +PassportElementErrorReverseSide +=============================== .. autoclass:: telegram.PassportElementErrorReverseSide :members: diff --git a/docs/source/telegram.passportelementerrorselfie.rst b/docs/source/telegram.passportelementerrorselfie.rst index e79c2d8e3..ce5b2f2bd 100644 --- a/docs/source/telegram.passportelementerrorselfie.rst +++ b/docs/source/telegram.passportelementerrorselfie.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorSelfie -======================================== +PassportElementErrorSelfie +========================== .. autoclass:: telegram.PassportElementErrorSelfie :members: diff --git a/docs/source/telegram.passportelementerrortranslationfile.rst b/docs/source/telegram.passportelementerrortranslationfile.rst index f195552cc..4aa055b75 100644 --- a/docs/source/telegram.passportelementerrortranslationfile.rst +++ b/docs/source/telegram.passportelementerrortranslationfile.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorTranslationFile -============================================ +PassportElementErrorTranslationFile +=================================== .. autoclass:: telegram.PassportElementErrorTranslationFile :members: diff --git a/docs/source/telegram.passportelementerrortranslationfiles.rst b/docs/source/telegram.passportelementerrortranslationfiles.rst index 0a01244bb..36c4e223e 100644 --- a/docs/source/telegram.passportelementerrortranslationfiles.rst +++ b/docs/source/telegram.passportelementerrortranslationfiles.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorTranslationFiles -============================================= +PassportElementErrorTranslationFiles +==================================== .. autoclass:: telegram.PassportElementErrorTranslationFiles :members: diff --git a/docs/source/telegram.passportelementerrorunspecified.rst b/docs/source/telegram.passportelementerrorunspecified.rst index aa5ce87ac..be3987822 100644 --- a/docs/source/telegram.passportelementerrorunspecified.rst +++ b/docs/source/telegram.passportelementerrorunspecified.rst @@ -1,5 +1,5 @@ -telegram.PassportElementErrorUnspecified -======================================== +PassportElementErrorUnspecified +=============================== .. autoclass:: telegram.PassportElementErrorUnspecified :members: diff --git a/docs/source/telegram.passportfile.rst b/docs/source/telegram.passportfile.rst index a2af1c5f6..643ba3df8 100644 --- a/docs/source/telegram.passportfile.rst +++ b/docs/source/telegram.passportfile.rst @@ -1,5 +1,5 @@ -telegram.PassportFile -===================== +PassportFile +============ .. autoclass:: telegram.PassportFile :members: diff --git a/docs/source/telegram.personaldetails.rst b/docs/source/telegram.personaldetails.rst index 145769f23..dfe4408c1 100644 --- a/docs/source/telegram.personaldetails.rst +++ b/docs/source/telegram.personaldetails.rst @@ -1,5 +1,5 @@ -telegram.PersonalDetails -======================== +PersonalDetails +=============== .. autoclass:: telegram.PersonalDetails :members: diff --git a/docs/source/telegram.photosize.rst b/docs/source/telegram.photosize.rst index 978daa364..d36e6e27f 100644 --- a/docs/source/telegram.photosize.rst +++ b/docs/source/telegram.photosize.rst @@ -1,5 +1,5 @@ -telegram.PhotoSize -================== +PhotoSize +========= .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject .. autoclass:: telegram.PhotoSize diff --git a/docs/source/telegram.poll.rst b/docs/source/telegram.poll.rst index cd369a027..705215d9d 100644 --- a/docs/source/telegram.poll.rst +++ b/docs/source/telegram.poll.rst @@ -1,5 +1,5 @@ -telegram.Poll -============= +Poll +==== .. autoclass:: telegram.Poll :members: diff --git a/docs/source/telegram.pollanswer.rst b/docs/source/telegram.pollanswer.rst index b74899ebf..211d8abf7 100644 --- a/docs/source/telegram.pollanswer.rst +++ b/docs/source/telegram.pollanswer.rst @@ -1,5 +1,5 @@ -telegram.PollAnswer -=================== +PollAnswer +========== .. autoclass:: telegram.PollAnswer :members: diff --git a/docs/source/telegram.polloption.rst b/docs/source/telegram.polloption.rst index 53a6cd69e..264f00f52 100644 --- a/docs/source/telegram.polloption.rst +++ b/docs/source/telegram.polloption.rst @@ -1,5 +1,5 @@ -telegram.PollOption -=================== +PollOption +========== .. autoclass:: telegram.PollOption :members: diff --git a/docs/source/telegram.precheckoutquery.rst b/docs/source/telegram.precheckoutquery.rst index 1b3893981..4d2ed627a 100644 --- a/docs/source/telegram.precheckoutquery.rst +++ b/docs/source/telegram.precheckoutquery.rst @@ -1,5 +1,5 @@ -telegram.PreCheckoutQuery -========================= +PreCheckoutQuery +================ .. autoclass:: telegram.PreCheckoutQuery :members: diff --git a/docs/source/telegram.proximityalerttriggered.rst b/docs/source/telegram.proximityalerttriggered.rst index ab01987ab..7e80117c5 100644 --- a/docs/source/telegram.proximityalerttriggered.rst +++ b/docs/source/telegram.proximityalerttriggered.rst @@ -1,5 +1,5 @@ -telegram.ProximityAlertTriggered -================================ +ProximityAlertTriggered +======================= .. autoclass:: telegram.ProximityAlertTriggered :members: diff --git a/docs/source/telegram.replykeyboardmarkup.rst b/docs/source/telegram.replykeyboardmarkup.rst index 8f55975ea..395124b3c 100644 --- a/docs/source/telegram.replykeyboardmarkup.rst +++ b/docs/source/telegram.replykeyboardmarkup.rst @@ -1,5 +1,5 @@ -telegram.ReplyKeyboardMarkup -============================ +ReplyKeyboardMarkup +=================== .. autoclass:: telegram.ReplyKeyboardMarkup :members: diff --git a/docs/source/telegram.replykeyboardremove.rst b/docs/source/telegram.replykeyboardremove.rst index 0f318d2ca..e1e4bb30d 100644 --- a/docs/source/telegram.replykeyboardremove.rst +++ b/docs/source/telegram.replykeyboardremove.rst @@ -1,5 +1,5 @@ -telegram.ReplyKeyboardRemove -============================ +ReplyKeyboardRemove +=================== .. autoclass:: telegram.ReplyKeyboardRemove :members: diff --git a/docs/source/telegram.request.baserequest.rst b/docs/source/telegram.request.baserequest.rst index 9280772e2..f3510e5f1 100644 --- a/docs/source/telegram.request.baserequest.rst +++ b/docs/source/telegram.request.baserequest.rst @@ -1,5 +1,5 @@ -telegram.request.BaseRequest -============================ +BaseRequest +=========== .. autoclass:: telegram.request.BaseRequest :members: diff --git a/docs/source/telegram.request.httpxrequest.rst b/docs/source/telegram.request.httpxrequest.rst index 8d33a943a..9c1441821 100644 --- a/docs/source/telegram.request.httpxrequest.rst +++ b/docs/source/telegram.request.httpxrequest.rst @@ -1,5 +1,5 @@ -telegram.request.HTTPXRequest -============================= +HTTPXRequest +============ .. autoclass:: telegram.request.HTTPXRequest :members: diff --git a/docs/source/telegram.request.requestdata.rst b/docs/source/telegram.request.requestdata.rst index e5d4e76a7..189a19291 100644 --- a/docs/source/telegram.request.requestdata.rst +++ b/docs/source/telegram.request.requestdata.rst @@ -1,5 +1,5 @@ -telegram.request.RequestData -============================ +RequestData +=========== .. autoclass:: telegram.request.RequestData :members: diff --git a/docs/source/telegram.residentialaddress.rst b/docs/source/telegram.residentialaddress.rst index 95be56963..00fea5756 100644 --- a/docs/source/telegram.residentialaddress.rst +++ b/docs/source/telegram.residentialaddress.rst @@ -1,5 +1,5 @@ -telegram.ResidentialAddress -=========================== +ResidentialAddress +================== .. autoclass:: telegram.ResidentialAddress :members: diff --git a/docs/source/telegram.securedata.rst b/docs/source/telegram.securedata.rst index ec24c8c4c..9396fdfec 100644 --- a/docs/source/telegram.securedata.rst +++ b/docs/source/telegram.securedata.rst @@ -1,5 +1,5 @@ -telegram.SecureData -=================== +SecureData +========== .. autoclass:: telegram.SecureData :members: diff --git a/docs/source/telegram.securevalue.rst b/docs/source/telegram.securevalue.rst index ba756a2cc..105bd8580 100644 --- a/docs/source/telegram.securevalue.rst +++ b/docs/source/telegram.securevalue.rst @@ -1,5 +1,5 @@ -telegram.SecureValue -==================== +SecureValue +=========== .. autoclass:: telegram.SecureValue :members: diff --git a/docs/source/telegram.sentwebappmessage.rst b/docs/source/telegram.sentwebappmessage.rst index ae7e7025e..1fd1dd0ab 100644 --- a/docs/source/telegram.sentwebappmessage.rst +++ b/docs/source/telegram.sentwebappmessage.rst @@ -1,5 +1,5 @@ -telegram.SentWebAppMessage -=============================== +SentWebAppMessage +================= .. autoclass:: telegram.SentWebAppMessage :members: diff --git a/docs/source/telegram.shippingaddress.rst b/docs/source/telegram.shippingaddress.rst index 6b89c4f86..7704e957f 100644 --- a/docs/source/telegram.shippingaddress.rst +++ b/docs/source/telegram.shippingaddress.rst @@ -1,5 +1,5 @@ -telegram.ShippingAddress -======================== +ShippingAddress +=============== .. autoclass:: telegram.ShippingAddress :members: diff --git a/docs/source/telegram.shippingoption.rst b/docs/source/telegram.shippingoption.rst index f0af54f85..45359c776 100644 --- a/docs/source/telegram.shippingoption.rst +++ b/docs/source/telegram.shippingoption.rst @@ -1,5 +1,5 @@ -telegram.ShippingOption -======================= +ShippingOption +============== .. autoclass:: telegram.ShippingOption :members: diff --git a/docs/source/telegram.shippingquery.rst b/docs/source/telegram.shippingquery.rst index 5e3c6fd13..400809e26 100644 --- a/docs/source/telegram.shippingquery.rst +++ b/docs/source/telegram.shippingquery.rst @@ -1,5 +1,5 @@ -telegram.ShippingQuery -====================== +ShippingQuery +============= .. autoclass:: telegram.ShippingQuery :members: diff --git a/docs/source/telegram.sticker.rst b/docs/source/telegram.sticker.rst index 24dc77d57..65b4a0f23 100644 --- a/docs/source/telegram.sticker.rst +++ b/docs/source/telegram.sticker.rst @@ -1,5 +1,5 @@ -telegram.Sticker -================ +Sticker +======= .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject diff --git a/docs/source/telegram.stickerset.rst b/docs/source/telegram.stickerset.rst index 3705c2ef8..83ec00e16 100644 --- a/docs/source/telegram.stickerset.rst +++ b/docs/source/telegram.stickerset.rst @@ -1,5 +1,5 @@ -telegram.StickerSet -=================== +StickerSet +========== .. autoclass:: telegram.StickerSet :members: diff --git a/docs/source/telegram.successfulpayment.rst b/docs/source/telegram.successfulpayment.rst index 43228b505..19b1e6db5 100644 --- a/docs/source/telegram.successfulpayment.rst +++ b/docs/source/telegram.successfulpayment.rst @@ -1,5 +1,5 @@ -telegram.SuccessfulPayment -========================== +SuccessfulPayment +================= .. autoclass:: telegram.SuccessfulPayment :members: diff --git a/docs/source/telegram.telegramobject.rst b/docs/source/telegram.telegramobject.rst index ca05cdd81..65fb7a9cc 100644 --- a/docs/source/telegram.telegramobject.rst +++ b/docs/source/telegram.telegramobject.rst @@ -1,5 +1,5 @@ -telegram.TelegramObject -======================= +TelegramObject +============== .. autoclass:: telegram.TelegramObject :members: diff --git a/docs/source/telegram.update.rst b/docs/source/telegram.update.rst index e03ef4bd3..0c3c3f0f2 100644 --- a/docs/source/telegram.update.rst +++ b/docs/source/telegram.update.rst @@ -1,5 +1,5 @@ -telegram.Update -=============== +Update +====== .. autoclass:: telegram.Update :members: diff --git a/docs/source/telegram.user.rst b/docs/source/telegram.user.rst index e6d05c27a..1e138240a 100644 --- a/docs/source/telegram.user.rst +++ b/docs/source/telegram.user.rst @@ -1,5 +1,5 @@ -telegram.User -============= +User +==== .. autoclass:: telegram.User :members: diff --git a/docs/source/telegram.userprofilephotos.rst b/docs/source/telegram.userprofilephotos.rst index 8ca19882e..d9edd69a0 100644 --- a/docs/source/telegram.userprofilephotos.rst +++ b/docs/source/telegram.userprofilephotos.rst @@ -1,5 +1,5 @@ -telegram.UserProfilePhotos -========================== +UserProfilePhotos +================= .. autoclass:: telegram.UserProfilePhotos :members: diff --git a/docs/source/telegram.venue.rst b/docs/source/telegram.venue.rst index 0cba4d0d1..f54e598a0 100644 --- a/docs/source/telegram.venue.rst +++ b/docs/source/telegram.venue.rst @@ -1,5 +1,5 @@ -telegram.Venue -============== +Venue +===== .. autoclass:: telegram.Venue :members: diff --git a/docs/source/telegram.video.rst b/docs/source/telegram.video.rst index 18c607c4b..34c81eb24 100644 --- a/docs/source/telegram.video.rst +++ b/docs/source/telegram.video.rst @@ -1,5 +1,5 @@ -telegram.Video -============== +Video +===== .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject diff --git a/docs/source/telegram.videochatended.rst b/docs/source/telegram.videochatended.rst index 8e167e444..02ba5742b 100644 --- a/docs/source/telegram.videochatended.rst +++ b/docs/source/telegram.videochatended.rst @@ -1,5 +1,5 @@ -telegram.VideoChatEnded -======================= +VideoChatEnded +============== .. autoclass:: telegram.VideoChatEnded :members: diff --git a/docs/source/telegram.videochatparticipantsinvited.rst b/docs/source/telegram.videochatparticipantsinvited.rst index b0e85ac65..84f301430 100644 --- a/docs/source/telegram.videochatparticipantsinvited.rst +++ b/docs/source/telegram.videochatparticipantsinvited.rst @@ -1,5 +1,5 @@ -telegram.VideoChatParticipantsInvited -===================================== +VideoChatParticipantsInvited +============================ .. autoclass:: telegram.VideoChatParticipantsInvited :members: diff --git a/docs/source/telegram.videochatscheduled.rst b/docs/source/telegram.videochatscheduled.rst index 96897780b..0e69b8994 100644 --- a/docs/source/telegram.videochatscheduled.rst +++ b/docs/source/telegram.videochatscheduled.rst @@ -1,7 +1,6 @@ -telegram.VideoChatScheduled -=========================== +VideoChatScheduled +================== .. autoclass:: telegram.VideoChatScheduled :members: :show-inheritance: - diff --git a/docs/source/telegram.videochatstarted.rst b/docs/source/telegram.videochatstarted.rst index d96772542..005dde65e 100644 --- a/docs/source/telegram.videochatstarted.rst +++ b/docs/source/telegram.videochatstarted.rst @@ -1,5 +1,5 @@ -telegram.VideoChatStarted -========================= +VideoChatStarted +================ .. autoclass:: telegram.VideoChatStarted :members: diff --git a/docs/source/telegram.videonote.rst b/docs/source/telegram.videonote.rst index 937a76d2c..5217acb04 100644 --- a/docs/source/telegram.videonote.rst +++ b/docs/source/telegram.videonote.rst @@ -1,5 +1,5 @@ -telegram.VideoNote -================== +VideoNote +========= .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject diff --git a/docs/source/telegram.voice.rst b/docs/source/telegram.voice.rst index 479a143aa..b3667b6ed 100644 --- a/docs/source/telegram.voice.rst +++ b/docs/source/telegram.voice.rst @@ -1,5 +1,5 @@ -telegram.Voice -============== +Voice +===== .. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject diff --git a/docs/source/telegram.webappdata.rst b/docs/source/telegram.webappdata.rst index 10e97b34c..003414419 100644 --- a/docs/source/telegram.webappdata.rst +++ b/docs/source/telegram.webappdata.rst @@ -1,5 +1,5 @@ -telegram.WebAppData -=========================== +WebAppData +========== .. autoclass:: telegram.WebAppData :members: diff --git a/docs/source/telegram.webappinfo.rst b/docs/source/telegram.webappinfo.rst index 43a450245..85423c2c5 100644 --- a/docs/source/telegram.webappinfo.rst +++ b/docs/source/telegram.webappinfo.rst @@ -1,5 +1,5 @@ -telegram.WebAppInfo -========================= +WebAppInfo +========== .. autoclass:: telegram.WebAppInfo :members: diff --git a/docs/source/telegram.webhookinfo.rst b/docs/source/telegram.webhookinfo.rst index 233b76637..b58027ec0 100644 --- a/docs/source/telegram.webhookinfo.rst +++ b/docs/source/telegram.webhookinfo.rst @@ -1,5 +1,5 @@ -telegram.WebhookInfo -==================== +WebhookInfo +=========== .. autoclass:: telegram.WebhookInfo :members: diff --git a/docs/source/telegram.writeaccessallowed.rst b/docs/source/telegram.writeaccessallowed.rst index 9487a24b2..81ffffa16 100644 --- a/docs/source/telegram.writeaccessallowed.rst +++ b/docs/source/telegram.writeaccessallowed.rst @@ -1,5 +1,5 @@ -telegram.WriteAccessAllowed -=========================== +WriteAccessAllowed +================== .. autoclass:: telegram.WriteAccessAllowed :members: diff --git a/telegram/_bot.py b/telegram/_bot.py index 9400dd175..2facd77e0 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -132,7 +132,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): await bot.initialize() # code finally: - await request_object.shutdown() + await bot.shutdown() Note: * Most bot methods have the argument ``api_kwargs`` which allows passing arbitrary keywords @@ -147,10 +147,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Examples: :any:`Raw API Bot ` - .. seealso:: :attr:`telegram.ext.Application.bot`, - :attr:`telegram.ext.CallbackContext.bot`, - :attr:`telegram.ext.Updater.bot`, - :wiki:`Your First Bot `, + .. seealso:: :wiki:`Your First Bot `, :wiki:`Builder Pattern ` .. versionadded:: 13.2 @@ -723,10 +720,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> Message: """Use this method to send text messages. - .. seealso:: :meth:`telegram.Chat.send_message`, :meth:`telegram.User.send_message`, - :meth:`telegram.Message.reply_text`, :meth:`telegram.Message.reply_html`, - :meth:`telegram.Message.reply_markdown`, :meth:`telegram.Message.reply_markdown_v2` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| text (:obj:`str`): Text of the message to be sent. Max @@ -810,8 +803,14 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): - If the bot has :attr:`~telegram.ChatMemberAdministrator.can_delete_messages` permission in a supergroup or a channel, it can delete any message there. - .. seealso:: :meth:`telegram.Message.delete`, - :meth:`telegram.CallbackQuery.delete_message` + .. + The method CallbackQuery.delete_message() will not be found when automatically + generating "Shortcuts" admonitions for Bot methods because it has no calls + to Bot methods in its return statement(s). So it is manually included in "See also". + + .. seealso:: + :meth:`telegram.CallbackQuery.delete_message` (calls :meth:`delete_message` + indirectly, via :meth:`telegram.Message.delete`) Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -863,9 +862,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): As a workaround, it is still possible to use :meth:`copy_message`. However, this behaviour is undocumented and might be changed by Telegram. - .. seealso:: :meth:`telegram.Message.forward`, :meth:`telegram.Chat.forward_to`, - :meth:`telegram.Chat.forward_from` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| from_chat_id (:obj:`int` | :obj:`str`): Unique identifier for the chat where the @@ -930,9 +926,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> Message: """Use this method to send photos. - .. seealso:: :meth:`telegram.Message.reply_photo`, :meth:`telegram.Chat.send_photo`, - :meth:`telegram.User.send_photo`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1054,9 +1048,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): For sending voice messages, use the :meth:`send_voice` method instead. - .. seealso:: :meth:`telegram.Message.reply_audio`, :meth:`telegram.Chat.send_audio`, - :meth:`telegram.User.send_audio`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1180,9 +1172,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): :tg-const:`telegram.constants.FileSizeLimit.FILESIZE_UPLOAD` in size, this limit may be changed in the future. - .. seealso:: :meth:`telegram.Message.reply_document`, :meth:`telegram.Chat.send_document`, - :meth:`telegram.User.send_document`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1294,9 +1284,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): """ Use this method to send static ``.WEBP``, animated ``.TGS``, or video ``.WEBM`` stickers. - .. seealso:: :meth:`telegram.Message.reply_sticker`, :meth:`telegram.Chat.send_sticker`, - :meth:`telegram.User.send_sticker`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1391,9 +1379,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): easily generate thumbnails. However, this behaviour is undocumented and might be changed by Telegram. - .. seealso:: :meth:`telegram.Message.reply_video`, :meth:`telegram.Chat.send_video`, - :meth:`telegram.User.send_video`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1525,10 +1511,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): easily generate thumbnails. However, this behaviour is undocumented and might be changed by Telegram. - .. seealso:: :meth:`telegram.Message.reply_video_note`, - :meth:`telegram.Chat.send_video_note`, - :meth:`telegram.User.send_video_note`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1649,10 +1632,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): generate thumbnails. However, this behaviour is undocumented and might be changed by Telegram. - .. seealso:: :meth:`telegram.Message.reply_animation`, - :meth:`telegram.Chat.send_animation`, - :meth:`telegram.User.send_animation`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1785,9 +1765,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): :tg-const:`telegram.constants.FileSizeLimit.FILESIZE_DOWNLOAD` voice notes will be sent as files. - .. seealso:: :meth:`telegram.Message.reply_voice`, :meth:`telegram.Chat.send_voice`, - :meth:`telegram.User.send_voice`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -1891,18 +1869,15 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): """Use this method to send a group of photos, videos, documents or audios as an album. Documents and audio files can be only grouped in an album with messages of the same type. - .. versionchanged:: 20.0 - Returns a tuple instead of a list. - Note: If you supply a :paramref:`caption` (along with either :paramref:`parse_mode` or :paramref:`caption_entities`), then items in :paramref:`media` must have no captions, and vice versa. - .. seealso:: :meth:`telegram.Message.reply_media_group`, - :meth:`telegram.Chat.send_media_group`, - :meth:`telegram.User.send_media_group`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` + + .. versionchanged:: 20.0 + Returns a tuple instead of a list. Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -2028,9 +2003,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): You can either supply a :paramref:`latitude` and :paramref:`longitude` or a :paramref:`location`. - .. seealso:: :meth:`telegram.Message.reply_location`, :meth:`telegram.Chat.send_location`, - :meth:`telegram.User.send_location` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| latitude (:obj:`float`, optional): Latitude of location. @@ -2144,9 +2116,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): You can either supply a :paramref:`latitude` and :paramref:`longitude` or a :paramref:`location`. - .. seealso:: :meth:`telegram.Message.edit_live_location`, - :meth:`telegram.CallbackQuery.edit_message_live_location` - Args: chat_id (:obj:`int` | :obj:`str`, optional): Required if :paramref:`inline_message_id` is not specified. |chat_id_channel| @@ -2231,9 +2200,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): """Use this method to stop updating a live location message sent by the bot or via the bot (for inline bots) before :paramref:`~telegram.Location.live_period` expires. - .. seealso:: :meth:`telegram.Message.stop_live_location`, - :meth:`telegram.CallbackQuery.stop_message_live_location` - Args: chat_id (:obj:`int` | :obj:`str`, optional): Required if :paramref:`inline_message_id` is not specified. |chat_id_channel| @@ -2301,9 +2267,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): * Foursquare details and Google Place details are mutually exclusive. However, this behaviour is undocumented and might be changed by Telegram. - .. seealso:: :meth:`telegram.Message.reply_venue`, :meth:`telegram.Chat.send_venue`, - :meth:`telegram.User.send_venue` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| latitude (:obj:`float`, optional): Latitude of venue. @@ -2423,9 +2386,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): :paramref:`first_name` with optionally :paramref:`last_name` and optionally :paramref:`vcard`. - .. seealso:: :meth:`telegram.Message.reply_contact`, :meth:`telegram.Chat.send_contact`, - :meth:`telegram.User.send_contact` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| phone_number (:obj:`str`, optional): Contact's phone number. @@ -2520,9 +2480,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> Message: """Use this method to send a game. - .. seealso:: :meth:`telegram.Message.reply_game`, :meth:`telegram.Chat.send_game`, - :meth:`telegram.User.send_game` - Args: chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat. game_short_name (:obj:`str`): Short name of the game, serves as the unique identifier @@ -2585,9 +2542,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Telegram clients clear its typing status). Telegram only recommends using this method when a response from the bot will take a noticeable amount of time to arrive. - .. seealso:: :meth:`telegram.Message.reply_chat_action`, :meth:`telegram.Chat.send_action`, - :meth:`telegram.User.send_chat_action` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| action(:obj:`str`): Type of action to broadcast. Choose one, depending on what the user @@ -2746,7 +2700,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, - passes a start parameter that instructs the bot to return an oauth link. Once done, the + passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities. @@ -2756,8 +2710,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): :paramref:`telegram.InlineQuery.answer.auto_pagination` set to :obj:`True`, which will take care of passing the correct value. - .. seealso:: :meth:`telegram.InlineQuery.answer`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: inline_query_id (:obj:`str`): Unique identifier for the answered query. @@ -2842,8 +2795,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> UserProfilePhotos: """Use this method to get a list of profile pictures for a user. - .. seealso:: :meth:`telegram.User.get_profile_photos` - Args: user_id (:obj:`int`): Unique identifier of the target user. offset (:obj:`int`, optional): Sequential number of the first photo to be returned. @@ -2900,13 +2851,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): You should save the file's MIME type and name (if available) when the File object is received. - .. seealso:: :meth:`telegram.Animation.get_file`, :meth:`telegram.Audio.get_file`, - :meth:`telegram.ChatPhoto.get_big_file`, :meth:`telegram.ChatPhoto.get_small_file`, - :meth:`telegram.Document.get_file`, :meth:`telegram.PassportFile.get_file`, - :meth:`telegram.PhotoSize.get_file`, :meth:`telegram.Sticker.get_file`, - :meth:`telegram.Video.get_file`, :meth:`telegram.VideoNote.get_file`, - :meth:`telegram.Voice.get_file`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: file_id (:obj:`str` | :class:`telegram.Animation` | :class:`telegram.Audio` | \ @@ -2967,8 +2912,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): using invite links, etc., unless unbanned first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - .. seealso:: :meth:`telegram.Chat.ban_member` - .. versionadded:: 13.7 Args: @@ -3033,8 +2976,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): their channels**. The bot must be an administrator in the supergroup or channel for this to work and must have the appropriate administrator rights. - .. seealso:: :meth:`telegram.Chat.ban_chat`, :meth:`telegram.Chat.ban_sender_chat` - .. versionadded:: 13.9 Args: @@ -3084,8 +3025,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): join it. So if the user is a member of the chat they will also be *removed* from the chat. If you don't want this, use the parameter :paramref:`only_if_banned`. - .. seealso:: :meth:`telegram.Chat.unban_member` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| user_id (:obj:`int`): Unique identifier of the target user. @@ -3128,8 +3067,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): The bot must be an administrator for this to work and must have the appropriate administrator rights. - .. seealso:: :meth:`telegram.Chat.unban_chat` - .. versionadded:: 13.9 Args: @@ -3181,8 +3118,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): and accept the terms. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter. - .. seealso:: :meth:`telegram.CallbackQuery.answer` - Args: callback_query_id (:obj:`str`): Unique identifier for the query to be answered. text (:obj:`str`, optional): Text of the notification. If not specified, nothing will @@ -3251,8 +3186,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Note: |editreplymarkup|. - .. seealso:: :meth:`telegram.Message.edit_text`, - :meth:`telegram.CallbackQuery.edit_message_text`, :attr:`telegram.Game.text` + .. seealso:: :attr:`telegram.Game.text` Args: chat_id (:obj:`int` | :obj:`str`, optional): Required if :paramref:`inline_message_id` @@ -3329,9 +3263,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Note: |editreplymarkup| - .. seealso:: :meth:`telegram.Message.edit_caption`, - :meth:`telegram.CallbackQuery.edit_message_caption` - Args: chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not specified. |chat_id_channel| @@ -3404,9 +3335,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Note: |editreplymarkup| - .. seealso:: :meth:`telegram.Message.edit_media`, - :meth:`telegram.CallbackQuery.edit_message_media`, - :wiki:`Working with Files and Media ` + .. seealso:: :wiki:`Working with Files and Media ` Args: media (:class:`telegram.InputMedia`): An object for a new media content @@ -3466,9 +3395,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Note: |editreplymarkup| - .. seealso:: :meth:`telegram.Message.edit_reply_markup`, - :meth:`telegram.CallbackQuery.edit_message_reply_markup` - Args: chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not specified. |chat_id_channel| @@ -3520,9 +3446,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> Tuple[Update, ...]: """Use this method to receive incoming updates using long polling. - .. versionchanged:: 20.0 - Returns a tuple instead of a list. - Note: 1. This method will not work if an outgoing webhook is set up. 2. In order to avoid getting duplicate updates, recalculate offset after each @@ -3532,6 +3455,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): .. seealso:: :meth:`telegram.ext.Application.run_polling`, :meth:`telegram.ext.Updater.start_polling` + .. versionchanged:: 20.0 + Returns a tuple instead of a list. + Args: offset (:obj:`int`, optional): Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received @@ -3672,7 +3598,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): :tg-const:`telegram.constants.WebhookLimit.MAX_CONNECTIONS_LIMIT`. Defaults to ``40``. Use lower values to limit the load on your bot's server, and higher values to increase your bot's throughput. - allowed_updates (Sequence[:obj:`str`], optional): A sequence the types of + allowed_updates (Sequence[:obj:`str`], optional): A sequence of the types of updates you want your bot to receive. For example, specify ["message", "edited_channel_post", "callback_query"] to only receive updates of these types. See :class:`telegram.Update` for a complete list of available update types. @@ -3779,8 +3705,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> bool: """Use this method for your bot to leave a group, supergroup or channel. - .. seealso:: :meth:`telegram.Chat.leave` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -3858,8 +3782,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): """ Use this method to get a list of administrators in a chat. - .. seealso:: :meth:`telegram.Chat.get_administrators` - .. versionchanged:: 20.0 Returns a tuple instead of a list. @@ -3901,8 +3823,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): ) -> int: """Use this method to get the number of members in a chat. - .. seealso:: :meth:`telegram.Chat.get_member_count` - .. versionadded:: 13.7 Args: @@ -3939,10 +3859,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): pool_timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None, ) -> ChatMember: - """Use this method to get information about a member of a chat. The method is guaranteed - to work only if the bot is an administrator in the chat. - - .. seealso:: :meth:`telegram.Chat.get_member` + """Use this method to get information about a member of a chat. The method is only + guaranteed to work for other users if the bot is an administrator in the chat. Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -4087,7 +4005,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): """ Use this method to set the score of the specified user in a game message. - .. seealso:: :meth:`telegram.CallbackQuery.set_game_score`, :attr:`telegram.Game.text` + .. seealso:: :attr:`telegram.Game.text` Args: user_id (:obj:`int`): User identifier. @@ -4150,16 +4068,13 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. - .. versionchanged:: 20.0 - Returns a tuple instead of a list. - Note: This method will currently return scores for the target user, plus two of their closest neighbors on each side. Will also return the top three users if the user and his neighbors are not among them. Please note that this behavior is subject to change. - .. seealso:: :meth:`telegram.CallbackQuery.get_game_high_scores`, - :meth:`telegram.Message.get_game_high_scores` + .. versionchanged:: 20.0 + Returns a tuple instead of a list. Args: user_id (:obj:`int`): Target user id. @@ -4241,9 +4156,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): order of the arguments had to be changed. Use keyword arguments to make sure that the arguments are passed correctly. - .. seealso:: :meth:`telegram.Message.reply_invoice`, :meth:`telegram.Chat.send_invoice`, - :meth:`telegram.User.send_invoice` - .. versionchanged:: 13.5 As of Bot API 5.2, the parameter :paramref:`start_parameter` is optional. @@ -4401,8 +4313,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): :class:`telegram.Update` with a :attr:`telegram.Update.shipping_query` field to the bot. Use this method to reply to shipping queries. - .. seealso:: :meth:`telegram.ShippingQuery.answer` - Args: shipping_query_id (:obj:`str`): Unique identifier for the query to be answered. ok (:obj:`bool`): Specify :obj:`True` if delivery to the specified address is possible @@ -4467,8 +4377,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. - .. seealso:: :meth:`telegram.PreCheckoutQuery.answer` - Args: pre_checkout_query_id (:obj:`str`): Unique identifier for the query to be answered. ok (:obj:`bool`): Specify :obj:`True` if everything is alright @@ -4571,8 +4479,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): the supergroup for this to work and must have the appropriate admin rights. Pass :obj:`True` for all boolean parameters to lift restrictions from a user. - .. seealso:: :meth:`telegram.ChatPermissions.all_permissions`, - :meth:`telegram.Chat.restrict_member` + .. seealso:: :meth:`telegram.ChatPermissions.all_permissions` Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_group| @@ -4641,8 +4548,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): an administrator in the chat for this to work and must have the appropriate admin rights. Pass :obj:`False` for all boolean parameters to demote a user. - .. seealso:: :meth:`telegram.Chat.promote_member` - .. versionchanged:: 20.0 The argument ``can_manage_voice_chats`` was renamed to :paramref:`can_manage_video_chats` in accordance to Bot API 6.0. @@ -4679,9 +4584,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): can_pin_messages (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can pin messages, supergroups only. can_promote_members (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can - add new administrators with a subset of his own privileges or demote administrators - that he has promoted, directly or indirectly (promoted by administrators that were - appointed by him). + add new administrators with a subset of their own privileges or demote + administrators that they have promoted, directly or indirectly + (promoted by administrators that were appointed by the user). can_manage_topics (:obj:`bool`, optional): Pass :obj:`True`, if the user is allowed to create, rename, close, and reopen forum topics; supergroups only. @@ -4740,8 +4645,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): administrator in the group or a supergroup for this to work and must have the :attr:`telegram.ChatMemberAdministrator.can_restrict_members` admin rights. - .. seealso:: :meth:`telegram.Chat.set_permissions` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_group| permissions (:class:`telegram.ChatPermissions`): New default chat permissions. @@ -4782,8 +4685,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Use this method to set a custom title for administrators promoted by the bot in a supergroup. The bot must be an administrator for this to work. - .. seealso:: :meth:`telegram.Chat.set_administrator_custom_title` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_group| user_id (:obj:`int`): Unique identifier of the target administrator. @@ -4835,8 +4736,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): by calling the :meth:`get_chat` method. If your bot needs to generate a new primary invite link replacing its previous one, use :meth:`export_chat_invite_link` again. - .. seealso:: :meth:`telegram.Chat.export_invite_link` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -4879,8 +4778,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): administrator in the chat for this to work and must have the appropriate admin rights. The link can be revoked using the method :meth:`revoke_chat_invite_link`. - .. seealso:: :meth:`telegram.Chat.create_invite_link` - .. versionadded:: 13.4 Args: @@ -4957,8 +4854,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): parameters to the default values. However, since not documented, this behaviour may change unbeknown to PTB. - .. seealso:: :meth:`telegram.Chat.edit_invite_link` - .. versionadded:: 13.4 Args: @@ -5032,8 +4927,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): revoked, a new link is automatically generated. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - .. seealso:: :meth:`telegram.Chat.revoke_invite_link` - .. versionadded:: 13.4 Args: @@ -5082,9 +4975,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): The bot must be an administrator in the chat for this to work and must have the :attr:`telegram.ChatPermissions.can_invite_users` administrator right. - .. seealso:: :meth:`telegram.Chat.approve_join_request`, - :meth:`telegram.ChatJoinRequest.approve`, :meth:`telegram.User.approve_join_request` - .. versionadded:: 13.8 Args: @@ -5128,9 +5018,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): The bot must be an administrator in the chat for this to work and must have the :attr:`telegram.ChatPermissions.can_invite_users` administrator right. - .. seealso:: :meth:`telegram.Chat.decline_join_request`, - :meth:`telegram.ChatJoinRequest.decline`, :meth:`telegram.User.decline_join_request` - .. versionadded:: 13.8 Args: @@ -5174,8 +5061,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - .. seealso:: :meth:`telegram.Chat.set_photo` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| photo (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path`): New chat photo. @@ -5223,8 +5108,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): must be an administrator in the chat for this to work and must have the appropriate admin rights. - .. seealso:: :meth:`telegram.Chat.delete_photo` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -5264,8 +5147,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - .. seealso:: :meth:`telegram.Chat.set_title` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| title (:obj:`str`): New chat title, @@ -5308,8 +5189,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): must be an administrator in the chat for this to work and must have the appropriate admin rights. - .. seealso:: :meth:`telegram.Chat.set_description` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| description (:obj:`str`, optional): New chat description, @@ -5356,9 +5235,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): right in a supergroup or :attr:`~telegram.ChatMemberAdministrator.can_edit_messages` admin right in a channel. - .. seealso:: :meth:`telegram.Chat.pin_message`, :meth:`telegram.Message.pin`, - :meth:`telegram.User.pin_message` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| message_id (:obj:`int`): Identifier of a message to pin. @@ -5408,9 +5284,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): right in a supergroup or :attr:`~telegram.ChatMemberAdministrator.can_edit_messages` admin right in a channel. - .. seealso:: :meth:`telegram.Chat.unpin_message`, :meth:`telegram.Message.unpin`, - :meth:`telegram.User.unpin_message` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| message_id (:obj:`int`, optional): Identifier of a message to unpin. If not specified, @@ -5453,9 +5326,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]): admin right in a supergroup or :attr:`~telegram.ChatMemberAdministrator.can_edit_messages` admin right in a channel. - .. seealso:: :meth:`telegram.Chat.unpin_all_messages`, - :meth:`telegram.User.unpin_all_messages` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| @@ -6037,9 +5907,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. """ Use this method to send a native poll. - .. seealso:: :meth:`telegram.Message.reply_poll`, :meth:`telegram.Chat.send_poll`, - :meth:`telegram.User.send_poll` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`- @@ -6158,8 +6025,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. """ Use this method to stop a poll which was sent by the bot. - .. seealso:: :meth:`telegram.Message.stop_poll` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| message_id (:obj:`int`): Identifier of the original message with the poll. @@ -6211,9 +6076,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. """ Use this method to send an animated emoji that will display a random value. - .. seealso:: :meth:`telegram.Message.reply_dice`, :meth:`telegram.Chat.send_dice`, - :meth:`telegram.User.send_dice` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| disable_notification (:obj:`bool`, optional): |disable_notification| @@ -6618,10 +6480,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. be copied. The method is analogous to the method :meth:`forward_message`, but the copied message doesn't have a link to the original message. - .. seealso:: :meth:`telegram.Message.copy`, :meth:`telegram.Chat.send_copy`, - :meth:`telegram.Chat.copy_message`, :meth:`telegram.User.send_copy`, - :meth:`telegram.User.copy_message` - Args: chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| from_chat_id (:obj:`int` | :obj:`str`): Unique identifier for the chat where the @@ -6700,8 +6558,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. """Use this method to change the bot's menu button in a private chat, or the default menu button. - .. seealso:: :meth:`get_chat_menu_button`, :meth:`telegram.Chat.set_menu_button`, - :meth:`telegram.Chat.get_menu_button`, :meth:`telegram.User.set_menu_button`, + .. seealso:: :meth:`get_chat_menu_button`, :meth:`telegram.Chat.get_menu_button` :meth:`telegram.User.get_menu_button` .. versionadded:: 20.0 @@ -6742,8 +6599,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. """Use this method to get the current value of the bot's menu button in a private chat, or the default menu button. - .. seealso:: :meth:`set_chat_menu_button`, :meth:`telegram.Chat.get_menu_button`, - :meth:`telegram.Chat.set_menu_button`, :meth:`telegram.User.get_menu_button`, + .. seealso:: :meth:`set_chat_menu_button`, :meth:`telegram.Chat.set_menu_button`, :meth:`telegram.User.set_menu_button` .. versionadded:: 20.0 @@ -6909,7 +6765,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. api_kwargs: JSONDict = None, ) -> Tuple[Sticker, ...]: """Use this method to get custom emoji stickers, which can be used as a forum topic - icon by any user. Requires no parameters. + icon by any user. Requires no parameters. .. versionadded:: 20.0 @@ -6949,8 +6805,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. an administrator in the chat for this to work and must have :paramref:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights. - .. seealso:: :meth:`telegram.Chat.create_forum_topic`, - .. versionadded:: 20.0 Args: @@ -7012,9 +6866,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. :paramref:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights, unless it is the creator of the topic. - .. seealso:: :meth:`telegram.Message.edit_forum_topic`, - :meth:`telegram.Chat.edit_forum_topic`, - .. versionadded:: 20.0 Args: @@ -7070,9 +6921,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. :paramref:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights, unless it is the creator of the topic. - .. seealso:: :meth:`telegram.Message.close_forum_topic`, - :meth:`telegram.Chat.close_forum_topic`, - .. versionadded:: 20.0 Args: @@ -7118,9 +6966,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. :paramref:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights, unless it is the creator of the topic. - .. seealso:: :meth:`telegram.Message.reopen_forum_topic`, - :meth:`telegram.Chat.reopen_forum_topic`, - .. versionadded:: 20.0 Args: @@ -7165,9 +7010,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. chat. The bot must be an administrator in the chat for this to work and must have :paramref:`~telegram.ChatAdministratorRights.can_delete_messages` administrator rights. - .. seealso:: :meth:`telegram.Message.delete_forum_topic`, - :meth:`telegram.Chat.delete_forum_topic`, - .. versionadded:: 20.0 Args: @@ -7213,9 +7055,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. :paramref:`~telegram.ChatAdministratorRights.can_pin_messages` administrator rights in the supergroup. - .. seealso:: :meth:`telegram.Message.unpin_all_forum_topic_messages`, - :meth:`telegram.Chat.unpin_all_forum_topic_messages`, - .. versionadded:: 20.0 Args: @@ -7260,8 +7099,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. must be an administrator in the chat for this to work and must have :attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights. - .. seealso:: :meth:`telegram.Chat.edit_general_forum_topic` - .. versionadded:: 20.0 Args: @@ -7305,8 +7142,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. be an administrator in the chat for this to work and must have :attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights. - .. seealso:: :meth:`telegram.Chat.close_general_forum_topic` - .. versionadded:: 20.0 Args: @@ -7348,8 +7183,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. :attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights. The topic will be automatically unhidden if it was hidden. - .. seealso:: :meth:`telegram.Chat.reopen_general_forum_topic` - .. versionadded:: 20.0 Args: @@ -7391,8 +7224,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. :attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights. The topic will be automatically closed if it was open. - .. seealso:: :meth:`telegram.Chat.hide_general_forum_topic` - .. versionadded:: 20.0 Args: @@ -7433,8 +7264,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified. be an administrator in the chat for this to work and must have :attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights. - .. seealso:: :meth:`telegram.Chat.unhide_general_forum_topic` - .. versionadded:: 20.0 Args: diff --git a/telegram/_callbackquery.py b/telegram/_callbackquery.py index e640743a8..02bd7dfa2 100644 --- a/telegram/_callbackquery.py +++ b/telegram/_callbackquery.py @@ -51,7 +51,7 @@ class CallbackQuery(TelegramObject): considered equal, if their :attr:`id` is equal. Note: - * In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + * In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. * Exactly one of the fields :attr:`data` or :attr:`game_short_name` will be present. * After the user presses an inline button, Telegram clients will display a progress bar until you call :attr:`answer`. It is, therefore, necessary to react diff --git a/telegram/_chatadministratorrights.py b/telegram/_chatadministratorrights.py index c551a6d0b..0a86c5d38 100644 --- a/telegram/_chatadministratorrights.py +++ b/telegram/_chatadministratorrights.py @@ -37,9 +37,6 @@ class ChatAdministratorRights(TelegramObject): :attr:`can_manage_topics` is considered as well when comparing objects of this type in terms of equality. - .. seealso: :meth:`Bot.set_my_default_administrator_rights`, - :meth:`Bot.get_my_default_administrator_rights` - .. versionadded:: 20.0 Args: @@ -55,9 +52,9 @@ class ChatAdministratorRights(TelegramObject): can_restrict_members (:obj:`bool`): :obj:`True`, if the administrator can restrict, ban or unban chat members. can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new - administrators with a subset of their own privileges or demote administrators that he - has promoted, directly or indirectly (promoted by administrators that were appointed by - the user.) + administrators with a subset of their own privileges or demote administrators + that they have promoted, directly or indirectly (promoted by administrators that + were appointed by the user). can_change_info (:obj:`bool`): :obj:`True`, if the user is allowed to change the chat title ,photo and other settings. can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to diff --git a/telegram/_chatmember.py b/telegram/_chatmember.py index d9c7d1124..8974a9d5c 100644 --- a/telegram/_chatmember.py +++ b/telegram/_chatmember.py @@ -241,10 +241,10 @@ class ChatMemberAdministrator(ChatMember): .. versionadded:: 20.0 can_restrict_members (:obj:`bool`): :obj:`True`, if the administrator can restrict, ban or unban chat members. - can_promote_members (:obj:`bool`): :obj:`True`, if the administrator - can add new administrators with a subset of his own privileges or demote - administrators that he has promoted, directly or indirectly (promoted by - administrators that were appointed by the user). + can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new + administrators with a subset of their own privileges or demote administrators + that they have promoted, directly or indirectly (promoted by administrators that + were appointed by the user). can_change_info (:obj:`bool`): :obj:`True`, if the user can change the chat title, photo and other settings. can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite diff --git a/telegram/_chatmemberupdated.py b/telegram/_chatmemberupdated.py index 659a09f42..78f6c18cb 100644 --- a/telegram/_chatmemberupdated.py +++ b/telegram/_chatmemberupdated.py @@ -42,7 +42,7 @@ class ChatMemberUpdated(TelegramObject): .. versionadded:: 13.4 Note: - In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. Examples: :any:`Chat Member Bot ` diff --git a/telegram/_choseninlineresult.py b/telegram/_choseninlineresult.py index c9c9b01e8..94a91ba13 100644 --- a/telegram/_choseninlineresult.py +++ b/telegram/_choseninlineresult.py @@ -39,7 +39,7 @@ class ChosenInlineResult(TelegramObject): considered equal, if their :attr:`result_id` is equal. Note: - * In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + * In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. * It is necessary to enable inline feedback via `@Botfather `_ in order to receive these objects in updates. diff --git a/telegram/_files/file.py b/telegram/_files/file.py index 23145b8af..7cd86f1bc 100644 --- a/telegram/_files/file.py +++ b/telegram/_files/file.py @@ -127,10 +127,10 @@ class File(TelegramObject): pool_timeout: ODVInput[float] = DEFAULT_NONE, ) -> Path: """ - Download this file. By default, the file is saved in the current working directory with its - original filename as reported by Telegram. 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. + 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. Note: If :paramref:`custom_path` isn't provided and :attr:`file_path` is the path of a @@ -154,7 +154,9 @@ class File(TelegramObject): 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. + will be saved to. If not specified, will be saved in the current working directory + with :attr:`file_path` as file name or the :attr:`file_id` if :attr:`file_path` + is not set. Keyword Args: read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to diff --git a/telegram/_files/venue.py b/telegram/_files/venue.py index 5811d7a73..f737c9141 100644 --- a/telegram/_files/venue.py +++ b/telegram/_files/venue.py @@ -35,7 +35,7 @@ class Venue(TelegramObject): considered equal, if their :attr:`location` and :attr:`title` are equal. Note: - Foursquare details and Google Pace details are mutually exclusive. However, this + Foursquare details and Google Place details are mutually exclusive. However, this behaviour is undocumented and might be changed by Telegram. Args: diff --git a/telegram/_inline/inlinequery.py b/telegram/_inline/inlinequery.py index 12fb2b400..4e8d3764d 100644 --- a/telegram/_inline/inlinequery.py +++ b/telegram/_inline/inlinequery.py @@ -41,7 +41,7 @@ class InlineQuery(TelegramObject): considered equal, if their :attr:`id` is equal. Note: - In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. .. versionchanged:: 20.0 The following are now keyword-only arguments in Bot methods: diff --git a/telegram/_keyboardbutton.py b/telegram/_keyboardbutton.py index 6fbdfc8aa..f8447f90f 100644 --- a/telegram/_keyboardbutton.py +++ b/telegram/_keyboardbutton.py @@ -58,10 +58,10 @@ class KeyboardButton(TelegramObject): sent as a contact when the button is pressed. Available in private chats only. request_location (:obj:`bool`, optional): If :obj:`True`, the user's current location will be sent when the button is pressed. Available in private chats only. - request_poll (:class:`KeyboardButtonPollType`, optional): If specified, the user will be - asked to create a poll and send it to the bot when the button is pressed. Available in - private chats only. - web_app (:class:`WebAppInfo`, optional): If specified, the described `Web App + request_poll (:class:`~telegram.KeyboardButtonPollType`, optional): If specified, the user + will be asked to create a poll and send it to the bot when the button is pressed. + Available in private chats only. + web_app (:class:`~telegram.WebAppInfo`, optional): If specified, the described `Web App `_ will be launched when the button is pressed. The Web App will be able to send a :attr:`Message.web_app_data` service message. Available in private chats only. @@ -74,10 +74,10 @@ class KeyboardButton(TelegramObject): sent as a contact when the button is pressed. Available in private chats only. request_location (:obj:`bool`): Optional. If :obj:`True`, the user's current location will be sent when the button is pressed. Available in private chats only. - request_poll (:class:`KeyboardButtonPollType`): Optional. If specified, the user will be - asked to create a poll and send it to the bot when the button is pressed. Available in - private chats only. - web_app (:class:`WebAppInfo`): Optional. If specified, the described `Web App + request_poll (:class:`~telegram.KeyboardButtonPollType`): Optional. If specified, + the user will be asked to create a poll and send it to the bot when the button is + pressed. Available in private chats only. + web_app (:class:`~telegram.WebAppInfo`): Optional. If specified, the described `Web App `_ will be launched when the button is pressed. The Web App will be able to send a :attr:`Message.web_app_data` service message. Available in private chats only. diff --git a/telegram/_message.py b/telegram/_message.py index 9c4b78ee8..62f84d013 100644 --- a/telegram/_message.py +++ b/telegram/_message.py @@ -92,7 +92,7 @@ class Message(TelegramObject): considered equal, if their :attr:`message_id` and :attr:`chat` are equal. Note: - In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. .. versionchanged:: 20.0 @@ -3552,8 +3552,8 @@ class Message(TelegramObject): Note: * :tg-const:`telegram.constants.ParseMode.MARKDOWN` is a legacy mode, retained by - Telegram for backward compatibility. You should use - :meth:`text_markdown_v2` instead. + Telegram for backward compatibility. You should use + :meth:`text_markdown_v2` instead. * |custom_emoji_formatting_note| @@ -3596,8 +3596,8 @@ class Message(TelegramObject): Note: * :tg-const:`telegram.constants.ParseMode.MARKDOWN` is a legacy mode, retained by - Telegram for backward compatibility. You should use :meth:`text_markdown_v2_urled` - instead. + Telegram for backward compatibility. You should use :meth:`text_markdown_v2_urled` + instead. * |custom_emoji_formatting_note| @@ -3686,8 +3686,8 @@ class Message(TelegramObject): Note: * :tg-const:`telegram.constants.ParseMode.MARKDOWN` is a legacy mode, retained by - Telegram for backward compatibility. You should use - :meth:`caption_markdown_v2_urled` instead. + Telegram for backward compatibility. You should use + :meth:`caption_markdown_v2_urled` instead. * |custom_emoji_formatting_note| diff --git a/telegram/_passport/credentials.py b/telegram/_passport/credentials.py index df64d9ece..5a53d4b68 100644 --- a/telegram/_passport/credentials.py +++ b/telegram/_passport/credentials.py @@ -114,14 +114,14 @@ class EncryptedCredentials(TelegramObject): :obj:`telegram.PassportData.decrypted_credentials`. Args: - data (:class:`telegram.Credentials` or :obj:`str`): Decrypted data with unique user's + data (:class:`telegram.Credentials` | :obj:`str`): Decrypted data with unique user's nonce, data hashes and secrets used for EncryptedPassportElement decryption and authentication or base64 encrypted data. hash (:obj:`str`): Base64-encoded data hash for data authentication. secret (:obj:`str`): Decrypted or encrypted secret used for decryption. Attributes: - data (:class:`telegram.Credentials` or :obj:`str`): Decrypted data with unique user's + data (:class:`telegram.Credentials` | :obj:`str`): Decrypted data with unique user's nonce, data hashes and secrets used for EncryptedPassportElement decryption and authentication or base64 encrypted data. hash (:obj:`str`): Base64-encoded data hash for data authentication. diff --git a/telegram/_payment/precheckoutquery.py b/telegram/_payment/precheckoutquery.py index e5965d988..011038bf2 100644 --- a/telegram/_payment/precheckoutquery.py +++ b/telegram/_payment/precheckoutquery.py @@ -37,7 +37,7 @@ class PreCheckoutQuery(TelegramObject): considered equal, if their :attr:`id` is equal. Note: - In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. Args: id (:obj:`str`): Unique query identifier. diff --git a/telegram/_payment/shippingquery.py b/telegram/_payment/shippingquery.py index 7e13f84a5..fbc970295 100644 --- a/telegram/_payment/shippingquery.py +++ b/telegram/_payment/shippingquery.py @@ -38,7 +38,7 @@ class ShippingQuery(TelegramObject): considered equal, if their :attr:`id` is equal. Note: - In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead. + In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. Args: id (:obj:`str`): Unique query identifier. diff --git a/telegram/_poll.py b/telegram/_poll.py index f983e6acc..2b1b8a787 100644 --- a/telegram/_poll.py +++ b/telegram/_poll.py @@ -146,7 +146,7 @@ class Poll(TelegramObject): id (:obj:`str`): Unique poll identifier. question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`- :tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters. - options (Sequence[:class:`PollOption`]): List of poll options. + options (Sequence[:class:`~telegram.PollOption`]): List of poll options. .. versionchanged:: 20.0 |sequenceclassargs| @@ -178,7 +178,7 @@ class Poll(TelegramObject): id (:obj:`str`): Unique poll identifier. question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`- :tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters. - options (Tuple[:class:`PollOption`]): List of poll options. + options (Tuple[:class:`~telegram.PollOption`]): List of poll options. .. versionchanged:: 20.0 |tupleclassattrs| diff --git a/telegram/ext/_aioratelimiter.py b/telegram/ext/_aioratelimiter.py index 64251ef1a..691ab3825 100644 --- a/telegram/ext/_aioratelimiter.py +++ b/telegram/ext/_aioratelimiter.py @@ -105,7 +105,7 @@ class AIORateLimiter(BaseRateLimiter[int]): to groups and channels per :paramref:`group_time_period`. When set to 0, no rate limiting will be applied. Defaults to 20. group_time_period (:obj:`float`): The time period (in seconds) during which the - :paramref:`group_time_period` is enforced. When set to 0, no rate limiting will be + :paramref:`group_max_rate` is enforced. When set to 0, no rate limiting will be applied. Defaults to 60. max_retries (:obj:`int`): The maximum number of retries to be made in case of a :exc:`~telegram.error.RetryAfter` exception. diff --git a/telegram/ext/_application.py b/telegram/ext/_application.py index 6b73aea94..7d987e545 100644 --- a/telegram/ext/_application.py +++ b/telegram/ext/_application.py @@ -518,7 +518,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica async def start(self) -> None: """Starts - * a background task that fetches updates from :attr:`update_queue` and processes them. + * a background task that fetches updates from :attr:`update_queue` and processes them via + :meth:`process_update`. * :attr:`job_queue`, if set. * a background task that calls :meth:`update_persistence` in regular intervals, if :attr:`persistence` is set. @@ -1060,7 +1061,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica async def process_update(self, update: object) -> None: """Processes a single update and marks the update to be updated by the persistence later. - Exceptions raised by handler callbacks will be processed by :meth:`process_update`. + Exceptions raised by handler callbacks will be processed by :meth:`process_error`. .. seealso:: :wiki:`Concurrency` @@ -1287,17 +1288,17 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica def migrate_chat_data( self, message: "Message" = None, old_chat_id: int = None, new_chat_id: int = None ) -> None: - """Moves the contents of :attr:`chat_data` at key old_chat_id to the key new_chat_id. - Also marks the entries to be updated accordingly in the next run of - :meth:`update_persistence`. + """Moves the contents of :attr:`chat_data` at key :paramref:`old_chat_id` to the key + :paramref:`new_chat_id`. Also marks the entries to be updated accordingly in the next run + of :meth:`update_persistence`. Warning: - * Any data stored in :attr:`chat_data` at key ``new_chat_id`` will be overridden - * The key `old_chat_id` of :attr:`chat_data` will be deleted + * Any data stored in :attr:`chat_data` at key :paramref:`new_chat_id` will be + overridden + * The key :paramref:`old_chat_id` of :attr:`chat_data` will be deleted * This does not update the :attr:`~telegram.ext.Job.chat_id` attribute of any scheduled :class:`telegram.ext.Job`. - Warning: When using :attr:`concurrent_updates` or the :attr:`job_queue`, :meth:`process_update` or :meth:`telegram.ext.Job.run` may re-create the old entry due to the asynchronous nature of these features. Please make sure that your program can diff --git a/telegram/ext/_applicationbuilder.py b/telegram/ext/_applicationbuilder.py index e3ecf1c45..b146b0abc 100644 --- a/telegram/ext/_applicationbuilder.py +++ b/telegram/ext/_applicationbuilder.py @@ -546,7 +546,7 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]): def pool_timeout(self: BuilderType, pool_timeout: Optional[float]) -> BuilderType: """Sets the connection pool's connection freeing timeout for the :paramref:`~telegram.request.HTTPXRequest.pool_timeout` parameter of - :attr:`telegram.Bot.request`. Defaults to :obj:`None`. + :attr:`telegram.Bot.request`. Defaults to ``1.0``. .. include:: inclusions/pool_size_tip.rst @@ -689,7 +689,7 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]): ) -> BuilderType: """Sets the connection pool's connection freeing timeout for the :paramref:`~telegram.request.HTTPXRequest.pool_timeout` parameter which is used for the - :meth:`telegram.Bot.get_updates` request. Defaults to :obj:`None`. + :meth:`telegram.Bot.get_updates` request. Defaults to ``1.0``. Args: get_updates_pool_timeout (:obj:`float`): See @@ -812,8 +812,8 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]): def local_mode(self: BuilderType, local_mode: bool) -> BuilderType: """Specifies the value for :paramref:`~telegram.Bot.local_mode` for the - :attr:`telegram.ext.Application.bot`. - If not called, will default to :obj:`False`. + :attr:`telegram.ext.Application.bot`. + If not called, will default to :obj:`False`. .. seealso:: :wiki:`Local Bot API Server ` @@ -870,6 +870,7 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]): def concurrent_updates(self: BuilderType, concurrent_updates: Union[bool, int]) -> BuilderType: """Specifies if and how many updates may be processed concurrently instead of one by one. + If not called, updates will be processed one by one. Warning: Processing updates concurrently is not recommended when stateful handlers like diff --git a/telegram/ext/_basepersistence.py b/telegram/ext/_basepersistence.py index fac198d3d..7e1ea6f18 100644 --- a/telegram/ext/_basepersistence.py +++ b/telegram/ext/_basepersistence.py @@ -121,9 +121,9 @@ class BasePersistence(Generic[UD, CD, BD], ABC): handled by the specific implementation - see above note. Args: - store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be - saved by this persistence instance. By default, all available kinds of data will be - saved. + store_data (:class:`~telegram.ext.PersistenceInput`, optional): Specifies which kinds of + data will be saved by this persistence instance. By default, all available kinds of + data will be saved. update_interval (:obj:`int` | :obj:`float`, optional): The :class:`~telegram.ext.Application` will update the persistence in regular intervals. This parameter specifies the time (in seconds) to @@ -132,8 +132,8 @@ class BasePersistence(Generic[UD, CD, BD], ABC): .. versionadded:: 20.0 Attributes: - store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this - persistence instance. + store_data (:class:`~telegram.ext.PersistenceInput`): Specifies which kinds of data will + be saved by this persistence instance. bot (:class:`telegram.Bot`): The bot associated with the persistence. """ diff --git a/telegram/ext/_callbackcontext.py b/telegram/ext/_callbackcontext.py index 682196f3a..b4834000f 100644 --- a/telegram/ext/_callbackcontext.py +++ b/telegram/ext/_callbackcontext.py @@ -389,7 +389,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]): def job_queue(self) -> Optional["JobQueue[CCT]"]: """ :class:`telegram.ext.JobQueue`: The :class:`JobQueue` used by the - :class:`telegram.ext.Application`. + :class:`telegram.ext.Application`. .. seealso:: :wiki:`Job Queue ` """ diff --git a/telegram/ext/_callbackdatacache.py b/telegram/ext/_callbackdatacache.py index 5fc854324..5089048f8 100644 --- a/telegram/ext/_callbackdatacache.py +++ b/telegram/ext/_callbackdatacache.py @@ -41,7 +41,7 @@ if TYPE_CHECKING: class InvalidCallbackData(TelegramError): """ - Raised when the received callback data has been tempered with or deleted from cache. + Raised when the received callback data has been tampered with or deleted from cache. Examples: :any:`Arbitrary Callback Data Bot ` @@ -115,8 +115,7 @@ class CallbackDataCache: Examples: :any:`Arbitrary Callback Data Bot ` - .. seealso:: :attr:`telegram.ext.ExtBot.callback_data_cache`, - :wiki:`Architecture Overview `, + .. seealso:: :wiki:`Architecture Overview `, :wiki:`Arbitrary callback_data ` .. versionadded:: 13.6 diff --git a/telegram/ext/_conversationhandler.py b/telegram/ext/_conversationhandler.py index 1ce3a0831..04948b0c5 100644 --- a/telegram/ext/_conversationhandler.py +++ b/telegram/ext/_conversationhandler.py @@ -125,8 +125,8 @@ class ConversationHandler(BaseHandler[Update, CCT]): Warning: :class:`ConversationHandler` heavily relies on incoming updates being processed one by one. - When using this handler, :attr:`telegram.ext.Application.concurrent_updates` should be - :obj:`False`. + When using this handler, :attr:`telegram.ext.ApplicationBuilder.concurrent_updates` should + be set to :obj:`False`. Note: :class:`ConversationHandler` will only accept updates that are (subclass-)instances of diff --git a/telegram/ext/_dictpersistence.py b/telegram/ext/_dictpersistence.py index 04dcec698..1111d7865 100644 --- a/telegram/ext/_dictpersistence.py +++ b/telegram/ext/_dictpersistence.py @@ -49,9 +49,9 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any, The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`. Args: - store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be - saved by this persistence instance. By default, all available kinds of data will be - saved. + store_data (:class:`~telegram.ext.PersistenceInput`, optional): Specifies which kinds of + data will be saved by this persistence instance. By default, all available kinds of + data will be saved. user_data_json (:obj:`str`, optional): JSON string that will be used to reconstruct user_data on creating this persistence. Default is ``""``. chat_data_json (:obj:`str`, optional): JSON string that will be used to reconstruct @@ -71,8 +71,8 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any, .. versionadded:: 20.0 Attributes: - store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this - persistence instance. + store_data (:class:`~telegram.ext.PersistenceInput`): Specifies which kinds of data will + be saved by this persistence instance. """ __slots__ = ( diff --git a/telegram/ext/_jobqueue.py b/telegram/ext/_jobqueue.py index 3940a3c5b..4a84e716e 100644 --- a/telegram/ext/_jobqueue.py +++ b/telegram/ext/_jobqueue.py @@ -60,9 +60,7 @@ class JobQueue(Generic[CCT]): Examples: :any:`Timer Bot ` - .. seealso:: :attr:`telegram.ext.Application.job_queue`, - :attr:`telegram.ext.CallbackContext.job_queue`, - :wiki:`Architecture Overview `, + .. seealso:: :wiki:`Architecture Overview `, :wiki:`Job Queue ` .. versionchanged:: 20.0 @@ -670,8 +668,9 @@ class Job(Generic[CCT]): async def callback(context: CallbackContext) - data (:obj:`object`, optional): Additional data needed for the callback function. Can be - accessed through :attr:`Job.data` in the callback. Defaults to :obj:`None`. + data (:obj:`object`, optional): Additional data needed for the :paramref:`callback` + function. Can be accessed through :attr:`Job.data` in the callback. Defaults to + :obj:`None`. name (:obj:`str`, optional): The name of the new job. Defaults to :external:obj:`callback.__name__ `. chat_id (:obj:`int`, optional): Chat id of the chat that this job is associated with. @@ -683,7 +682,7 @@ class Job(Generic[CCT]): Attributes: callback (:term:`coroutine function`): The callback function that should be executed by the new job. - data (:obj:`object`): Optional. Additional data needed for the callback function. + data (:obj:`object`): Optional. Additional data needed for the :attr:`callback` function. name (:obj:`str`): Optional. The name of the new job. chat_id (:obj:`int`): Optional. Chat id of the chat that this job is associated with. diff --git a/telegram/ext/_picklepersistence.py b/telegram/ext/_picklepersistence.py index 0b3632253..691e84970 100644 --- a/telegram/ext/_picklepersistence.py +++ b/telegram/ext/_picklepersistence.py @@ -147,9 +147,9 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): Args: filepath (:obj:`str` | :obj:`pathlib.Path`): The filepath for storing the pickle files. When :attr:`single_file` is :obj:`False` this will be used as a prefix. - store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be - saved by this persistence instance. By default, all available kinds of data will be - saved. + store_data (:class:`~telegram.ext.PersistenceInput`, optional): Specifies which kinds of + data will be saved by this persistence instance. By default, all available kinds of + data will be saved. single_file (:obj:`bool`, optional): When :obj:`False` will store 5 separate files of `filename_user_data`, `filename_bot_data`, `filename_chat_data`, `filename_callback_data` and `filename_conversations`. Default is :obj:`True`. @@ -172,8 +172,8 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): Attributes: filepath (:obj:`str` | :obj:`pathlib.Path`): The filepath for storing the pickle files. When :attr:`single_file` is :obj:`False` this will be used as a prefix. - store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this - persistence instance. + store_data (:class:`~telegram.ext.PersistenceInput`): Specifies which kinds of data will + be saved by this persistence instance. single_file (:obj:`bool`): Optional. When :obj:`False` will store 5 separate files of `filename_user_data`, `filename_bot_data`, `filename_chat_data`, `filename_callback_data` and `filename_conversations`. Default is :obj:`True`. diff --git a/telegram/ext/_updater.py b/telegram/ext/_updater.py index 50ea3c59d..e4207cef6 100644 --- a/telegram/ext/_updater.py +++ b/telegram/ext/_updater.py @@ -410,10 +410,9 @@ class Updater(AsyncContextManager["Updater"]): :meth:`start_webhook` now *always* calls :meth:`telegram.Bot.set_webhook`, so pass ``webhook_url`` instead of calling ``updater.bot.set_webhook(webhook_url)`` manually. .. versionchanged:: 20.0 + * Removed the ``clean`` argument in favor of :paramref:`drop_pending_updates` and removed the deprecated argument ``force_event_loop``. - * To use this method, PTB must be installed via - ``pip install python-telegram-bot[webhooks]``. Args: listen (:obj:`str`, optional): IP-Address to listen on. Defaults to diff --git a/tests/docs/README.md b/tests/docs/README.md new file mode 100644 index 000000000..0ea5eb3ad --- /dev/null +++ b/tests/docs/README.md @@ -0,0 +1,7 @@ +# Documentation tests + +This directory contains tests that cover our scripting logic for automatically generating +additional elements for the documentation pages. + +These tests are not meant to be run with the general test suite, so the modules do not have any +`test_` prefix in their names. By default, `pytest` ignores files that have no such prefix. diff --git a/tests/docs/admonition_inserter.py b/tests/docs/admonition_inserter.py new file mode 100644 index 000000000..38e368724 --- /dev/null +++ b/tests/docs/admonition_inserter.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2023 +# Leandro Toledo de Souza +# +# 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 is intentionally named without "test_" prefix. +# These tests are supposed to be run on GitHub when building docs. +# The tests require Python 3.9+ (just like AdmonitionInserter being tested), +# so they cannot be included in the main suite while older versions of Python are supported. + +import collections.abc + +import pytest + +import telegram.ext +from docs.auxil.admonition_inserter import AdmonitionInserter + + +@pytest.fixture(scope="session") +def admonition_inserter(): + return AdmonitionInserter() + + +class TestAdmonitionInserter: + """This is a minimal-effort test to ensure that the `AdmonitionInserter` + used for automatically inserting references in the docs works as expected. + + It does not aim to cover all links in the documentation, but rather checks that several special + cases (which where discovered during the implementation of `AdmonitionInserter`) are handled + correctly. + """ + + def test_admonitions_dict(self, admonition_inserter): + # there are keys for every type of admonition + assert len(admonition_inserter.admonitions) == len( + admonition_inserter.ALL_ADMONITION_TYPES + ) + + # for each type of admonitions, there is at least one entry + # ({class/method: admonition text}) + for admonition_type in admonition_inserter.ALL_ADMONITION_TYPES: + assert admonition_type in admonition_inserter.admonitions + assert len(admonition_inserter.admonitions[admonition_type].keys()) > 0 + + # checking class admonitions + for admonition_type in admonition_inserter.CLASS_ADMONITION_TYPES: + # keys are telegram classes + for cls in admonition_inserter.admonitions[admonition_type]: + # Test classes crop up in AppBuilder, they can't come from code being tested. + if "tests.conftest" in str(cls): + continue + + assert isinstance(cls, type) + assert str(cls).startswith(" + ), + ( + "shortcuts", + telegram.Bot.edit_message_caption, + # this method in CallbackQuery contains two return statements, + # one of which is with Bot + ":meth:`telegram.CallbackQuery.edit_message_caption`", + ), + ( + "use_in", + telegram.InlineQueryResult, + ":meth:`telegram.Bot.answer_web_app_query`", # ForwardRef + ), + ( + "use_in", + telegram.InputMediaPhoto, + ":meth:`telegram.Bot.send_media_group`", # Sequence[Union[...]] + ), + ( + "use_in", + telegram.MaskPosition, + ":meth:`telegram.Bot.add_sticker_to_set`", # optional + ), + ( + "use_in", + telegram.Sticker, + ":meth:`telegram.Bot.get_file`", # .file_id with lots of piped types + ), + ( + "use_in", + telegram.ext.BasePersistence, + ":meth:`telegram.ext.ApplicationBuilder.persistence`", + ), + ("use_in", telegram.ext.Defaults, ":meth:`telegram.ext.ApplicationBuilder.defaults`"), + ( + "use_in", + telegram.ext.JobQueue, + ":meth:`telegram.ext.ApplicationBuilder.job_queue`", # TypeVar + ), + ( + "use_in", + telegram.ext.PicklePersistence, # subclass + ":meth:`telegram.ext.ApplicationBuilder.persistence`", + ), + ), + ) + def test_check_presence(self, admonition_inserter, admonition_type, cls, link): + """Checks if a given link is present in the admonition of a given type for a given + class. + """ + admonitions = admonition_inserter.admonitions + + assert cls in admonitions[admonition_type] + + # exactly one of the lines in the admonition for this class must consist of the link + # (this is a stricter check than just checking if the entire admonition contains the link) + lines_with_link = [ + line + for line in admonitions[admonition_type][cls].splitlines() + # remove whitespaces and occasional bullet list marker + if line.strip().removeprefix("* ") == link + ] + assert lines_with_link, ( + f"Class {cls}, does not have link {link} in a {admonition_type} admonition:\n" + f"{admonitions[admonition_type][cls]}" + ) + assert len(lines_with_link) == 1, ( + f"Class {cls}, must contain only one link {link} in a {admonition_type} admonition:\n" + f"{admonitions[admonition_type][cls]}" + ) + + @pytest.mark.parametrize( + "admonition_type, cls, link", + ( + ( + "returned_in", + telegram.ext.CallbackContext, + # -> Application[BT, CCT, UD, CD, BD, JQ]. + # In this case classes inside square brackets must not be parsed + ":meth:`telegram.ext.ApplicationBuilder.build`", + ), + ), + ) + def test_check_absence(self, admonition_inserter, admonition_type, cls, link): + """Checks if a given link is **absent** in the admonition of a given type for a given + class. + + If a given class has no admonition of this type at all, the test will also pass. + """ + admonitions = admonition_inserter.admonitions + + assert not ( + cls in admonitions[admonition_type] + and [ + line + for line in admonitions[admonition_type][cls].splitlines() + # remove whitespaces and occasional bullet list marker + if line.strip().removeprefix("* ") == link + ] + ), ( + f"Class {cls} is not supposed to have link {link} in a {admonition_type} admonition:\n" + f"{admonitions[admonition_type][cls]}" + )