Update pre-commit Settings (#2415)

Co-authored-by: Harshil <ilovebhagwan@gmail.com>
This commit is contained in:
Bibo-Joshi 2021-03-13 16:21:03 +01:00 committed by GitHub
parent aba17cb997
commit 3a9a0ab96d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 213 additions and 237 deletions

View file

@ -109,12 +109,6 @@ Here's how to make a one-off code change.
- Before making a commit ensure that all automated tests still pass:
.. code-block::
$ make test
If you don't have ``make``, do:
.. code-block::
$ pytest -v
@ -127,18 +121,18 @@ Here's how to make a one-off code change.
prior to running the tests.
- To actually make the commit (this will trigger tests for yapf, lint and pep8 automatically):
- If you want run style & type checks before committing run
.. code-block::
$ pre-commit run -a
- To actually make the commit (this will trigger tests style & type checks automatically):
.. code-block:: bash
$ git add your-file-changed.py
- yapf may change code formatting, make sure to re-add them to your commit.
.. code-block:: bash
$ git commit -a -m "your-commit-message-here"
- Finally, push it to your GitHub fork, run:
.. code-block:: bash
@ -196,7 +190,7 @@ Style commandments
Assert comparison order
#######################
- assert statements should compare in **actual** == **expected** order.
Assert statements should compare in **actual** == **expected** order.
For example (assuming ``test_call`` is the thing being tested):
.. code-block:: python

View file

@ -0,0 +1,17 @@
name: Warning maintainers
on:
pull_request:
paths:
- requirements.txt
- requirements-dev.txt
- .pre-commit-config.yaml
jobs:
job:
runs-on: ubuntu-latest
name: about pre-commit and dependency change
steps:
- name: running the check
uses: Poolitzer/notifier-action@master
with:
notify-message: Hey! Looks like you edited the (dev) requirements or the pre-commit hooks. I'm just a friendly reminder to keep the pre-commit hook versions in sync with the dev requirements and the additional dependencies for the hooks in sync with the requirements :)
repo-token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,6 +1,6 @@
# Make sure that
# * the revs specified here match requirements-dev.txt
# * the makefile checks the same files as pre-commit
# * the additional_dependencies here match requirements.txt
repos:
- repo: https://github.com/psf/black
rev: 20.8b1
@ -14,21 +14,43 @@ repos:
hooks:
- id: flake8
- repo: https://github.com/PyCQA/pylint
rev: pylint-2.6.0
rev: pylint-2.7.2
hooks:
- id: pylint
files: ^(telegram|examples)/.*\.py$
args:
- --rcfile=setup.cfg
- --rcfile=setup.cfg
additional_dependencies:
- certifi
- tornado>=5.1
- APScheduler==3.6.3
- . # this basically does `pip install -e .`
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.800
rev: v0.812
hooks:
- id: mypy
files: ^(telegram|examples)/.*\.py$
name: mypy-ptb
files: ^telegram/.*\.py$
additional_dependencies:
- certifi
- tornado>=5.1
- APScheduler==3.6.3
- . # this basically does `pip install -e .`
- id: mypy
name: mypy-examples
files: ^examples/.*\.py$
args:
- --no-strict-optional
- --follow-imports=silent
additional_dependencies:
- certifi
- tornado>=5.1
- APScheduler==3.6.3
- . # this basically does `pip install -e .`
- repo: https://github.com/asottile/pyupgrade
rev: v2.10.0
hooks:
- id: pyupgrade
files: ^(telegram|examples|tests)/.*\.py$
args:
- --py36-plus
- --py36-plus

View file

@ -1,53 +0,0 @@
.DEFAULT_GOAL := help
.PHONY: clean pep8 black lint test install
PYLINT := pylint
PYTEST := pytest
PEP8 := flake8
BLACK := black
MYPY := mypy
PIP := pip
clean:
rm -fr build
rm -fr dist
find . -name '*.pyc' -exec rm -f {} \;
find . -name '*.pyo' -exec rm -f {} \;
find . -name '*~' -exec rm -f {} \;
find . -regex "./telegram[0-9]*.\(jpg\|mp3\|mp4\|ogg\|png\|webp\)" -exec rm {} \;
pep8:
$(PEP8) telegram tests examples
black:
$(BLACK) .
lint:
$(PYLINT) --rcfile=setup.cfg telegram examples
mypy:
$(MYPY) -p telegram
$(MYPY) examples
test:
$(PYTEST) -v
install:
$(PIP) install -r requirements.txt -r requirements-dev.txt
help:
@echo "Available targets:"
@echo "- clean Clean up the source directory"
@echo "- pep8 Check style with flake8"
@echo "- lint Check style with pylint"
@echo "- black Check style with black"
@echo "- mypy Check type hinting with mypy"
@echo "- test Run tests using pytest"
@echo
@echo "Available variables:"
@echo "- PYLINT default: $(PYLINT)"
@echo "- PYTEST default: $(PYTEST)"
@echo "- PEP8 default: $(PEP8)"
@echo "- BLACK default: $(BLACK)"
@echo "- MYPY default: $(MYPY)"
@echo "- PIP default: $(PIP)"

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -37,7 +36,7 @@ logger = logging.getLogger(__name__)
GENDER, PHOTO, LOCATION, BIO = range(4)
def start(update: Update, context: CallbackContext) -> int:
def start(update: Update, _: CallbackContext) -> int:
reply_keyboard = [['Boy', 'Girl', 'Other']]
update.message.reply_text(
@ -50,7 +49,7 @@ def start(update: Update, context: CallbackContext) -> int:
return GENDER
def gender(update: Update, context: CallbackContext) -> int:
def gender(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
logger.info("Gender of %s: %s", user.first_name, update.message.text)
update.message.reply_text(
@ -62,52 +61,52 @@ def gender(update: Update, context: CallbackContext) -> int:
return PHOTO
def photo(update: Update, context: CallbackContext) -> int:
def photo(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
photo_file = update.message.photo[-1].get_file()
photo_file.download('user_photo.jpg')
logger.info("Photo of %s: %s", user.first_name, 'user_photo.jpg')
update.message.reply_text(
'Gorgeous! Now, send me your location please, ' 'or send /skip if you don\'t want to.'
'Gorgeous! Now, send me your location please, or send /skip if you don\'t want to.'
)
return LOCATION
def skip_photo(update: Update, context: CallbackContext) -> int:
def skip_photo(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
logger.info("User %s did not send a photo.", user.first_name)
update.message.reply_text(
'I bet you look great! Now, send me your location please, ' 'or send /skip.'
'I bet you look great! Now, send me your location please, or send /skip.'
)
return LOCATION
def location(update: Update, context: CallbackContext) -> int:
def location(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
user_location = update.message.location
logger.info(
"Location of %s: %f / %f", user.first_name, user_location.latitude, user_location.longitude
)
update.message.reply_text(
'Maybe I can visit you sometime! ' 'At last, tell me something about yourself.'
'Maybe I can visit you sometime! At last, tell me something about yourself.'
)
return BIO
def skip_location(update: Update, context: CallbackContext) -> int:
def skip_location(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
logger.info("User %s did not send a location.", user.first_name)
update.message.reply_text(
'You seem a bit paranoid! ' 'At last, tell me something about yourself.'
'You seem a bit paranoid! At last, tell me something about yourself.'
)
return BIO
def bio(update: Update, context: CallbackContext) -> int:
def bio(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
logger.info("Bio of %s: %s", user.first_name, update.message.text)
update.message.reply_text('Thank you! I hope we can talk again some day.')
@ -115,7 +114,7 @@ def bio(update: Update, context: CallbackContext) -> int:
return ConversationHandler.END
def cancel(update: Update, context: CallbackContext) -> int:
def cancel(update: Update, _: CallbackContext) -> int:
user = update.message.from_user
logger.info("User %s canceled the conversation.", user.first_name)
update.message.reply_text(

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -54,7 +53,7 @@ def facts_to_str(user_data: Dict[str, str]) -> str:
return "\n".join(facts).join(['\n', '\n'])
def start(update: Update, context: CallbackContext) -> int:
def start(update: Update, _: CallbackContext) -> int:
update.message.reply_text(
"Hi! My name is Doctor Botter. I will hold a more complex conversation with you. "
"Why don't you tell me something about yourself?",
@ -72,9 +71,9 @@ def regular_choice(update: Update, context: CallbackContext) -> int:
return TYPING_REPLY
def custom_choice(update: Update, context: CallbackContext) -> int:
def custom_choice(update: Update, _: CallbackContext) -> int:
update.message.reply_text(
'Alright, please send me the category first, ' 'for example "Most impressive skill"'
'Alright, please send me the category first, for example "Most impressive skill"'
)
return TYPING_CHOICE

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""Bot that explains Telegram's "Deep Linking Parameters" functionality.
@ -79,7 +78,7 @@ def deep_linked_level_2(update: Update, context: CallbackContext) -> None:
update.message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True)
def deep_linked_level_3(update: Update, context: CallbackContext) -> None:
def deep_linked_level_3(update: Update, _: CallbackContext) -> None:
"""Reached through the USING_ENTITIES payload"""
update.message.reply_text(
"It is also possible to make deep-linking using InlineKeyboardButtons.",
@ -104,7 +103,7 @@ def deep_linked_level_4(update: Update, context: CallbackContext) -> None:
)
def main():
def main() -> None:
"""Start the bot."""
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -31,22 +30,22 @@ logger = logging.getLogger(__name__)
# Define a few command handlers. These usually take the two arguments update and
# context. Error handlers also receive the raised TelegramError object in error.
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
update.message.reply_text('Hi!')
def help_command(update: Update, context: CallbackContext) -> None:
def help_command(update: Update, _: CallbackContext) -> None:
"""Send a message when the command /help is issued."""
update.message.reply_text('Help!')
def echo(update: Update, context: CallbackContext) -> None:
def echo(update: Update, _: CallbackContext) -> None:
"""Echo the user message."""
update.message.reply_text(update.message.text)
def main():
def main() -> None:
"""Start the bot."""
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -28,7 +27,7 @@ BOT_TOKEN = "TOKEN"
DEVELOPER_CHAT_ID = 123456789
def error_handler(update: Update, context: CallbackContext) -> None:
def error_handler(update: object, context: CallbackContext) -> None:
"""Log the error and send a telegram message to notify the developer."""
# Log the error before we do anything else, so we can see it even if something breaks.
logger.error(msg="Exception while handling an update:", exc_info=context.error)
@ -40,9 +39,10 @@ def error_handler(update: Update, context: CallbackContext) -> None:
# Build the message with some markup and additional information about what happened.
# You might need to add some logic to deal with messages longer than the 4096 character limit.
update_str = update.to_dict() if isinstance(update, Update) else str(update)
message = (
f'An exception was raised while handling an update\n'
f'<pre>update = {html.escape(json.dumps(update.to_dict(), indent=2, ensure_ascii=False))}'
f'<pre>update = {html.escape(json.dumps(update_str, indent=2, ensure_ascii=False))}'
'</pre>\n\n'
f'<pre>context.chat_data = {html.escape(str(context.chat_data))}</pre>\n\n'
f'<pre>context.user_data = {html.escape(str(context.user_data))}</pre>\n\n'
@ -53,19 +53,19 @@ def error_handler(update: Update, context: CallbackContext) -> None:
context.bot.send_message(chat_id=DEVELOPER_CHAT_ID, text=message, parse_mode=ParseMode.HTML)
def bad_command(update: Update, context: CallbackContext) -> None:
def bad_command(_: Update, context: CallbackContext) -> None:
"""Raise an error to trigger the error handler."""
context.bot.wrong_method_name()
context.bot.wrong_method_name() # type: ignore[attr-defined]
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> None:
update.effective_message.reply_html(
'Use /bad_command to cause an error.\n'
f'Your chat id is <code>{update.effective_chat.id}</code>.'
)
def main():
def main() -> None:
# Create the Updater and pass it your bot's token.
updater = Updater(BOT_TOKEN)

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -30,32 +29,34 @@ logger = logging.getLogger(__name__)
# Define a few command handlers. These usually take the two arguments update and
# context. Error handlers also receive the raised TelegramError object in error.
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
update.message.reply_text('Hi!')
def help_command(update: Update, context: CallbackContext) -> None:
def help_command(update: Update, _: CallbackContext) -> None:
"""Send a message when the command /help is issued."""
update.message.reply_text('Help!')
def inlinequery(update: Update, context: CallbackContext) -> None:
def inlinequery(update: Update, _: CallbackContext) -> None:
"""Handle the inline query."""
query = update.inline_query.query
results = [
InlineQueryResultArticle(
id=uuid4(), title="Caps", input_message_content=InputTextMessageContent(query.upper())
id=str(uuid4()),
title="Caps",
input_message_content=InputTextMessageContent(query.upper()),
),
InlineQueryResultArticle(
id=uuid4(),
id=str(uuid4()),
title="Bold",
input_message_content=InputTextMessageContent(
f"*{escape_markdown(query)}*", parse_mode=ParseMode.MARKDOWN
),
),
InlineQueryResultArticle(
id=uuid4(),
id=str(uuid4()),
title="Italic",
input_message_content=InputTextMessageContent(
f"_{escape_markdown(query)}_", parse_mode=ParseMode.MARKDOWN

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -17,7 +16,7 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> None:
keyboard = [
[
InlineKeyboardButton("Option 1", callback_data='1'),
@ -31,7 +30,7 @@ def start(update: Update, context: CallbackContext) -> None:
update.message.reply_text('Please choose:', reply_markup=reply_markup)
def button(update: Update, context: CallbackContext) -> None:
def button(update: Update, _: CallbackContext) -> None:
query = update.callback_query
# CallbackQueries need to be answered, even if no notification to the user is needed
@ -41,11 +40,11 @@ def button(update: Update, context: CallbackContext) -> None:
query.edit_message_text(text=f"Selected option: {query.data}")
def help_command(update: Update, context: CallbackContext) -> None:
def help_command(update: Update, _: CallbackContext) -> None:
update.message.reply_text("Use /start to test this bot.")
def main():
def main() -> None:
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""Simple inline keyboard bot with multiple CallbackQueryHandlers.
@ -38,7 +37,7 @@ FIRST, SECOND = range(2)
ONE, TWO, THREE, FOUR = range(4)
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> int:
"""Send message on `/start`."""
# Get user that sent /start and log his name
user = update.message.from_user
@ -60,7 +59,7 @@ def start(update: Update, context: CallbackContext) -> None:
return FIRST
def start_over(update: Update, context: CallbackContext) -> None:
def start_over(update: Update, _: CallbackContext) -> int:
"""Prompt same text & keyboard as `start` does but not as new message"""
# Get CallbackQuery from Update
query = update.callback_query
@ -81,7 +80,7 @@ def start_over(update: Update, context: CallbackContext) -> None:
return FIRST
def one(update: Update, context: CallbackContext) -> None:
def one(update: Update, _: CallbackContext) -> int:
"""Show new choice of buttons"""
query = update.callback_query
query.answer()
@ -98,7 +97,7 @@ def one(update: Update, context: CallbackContext) -> None:
return FIRST
def two(update: Update, context: CallbackContext) -> None:
def two(update: Update, _: CallbackContext) -> int:
"""Show new choice of buttons"""
query = update.callback_query
query.answer()
@ -115,7 +114,7 @@ def two(update: Update, context: CallbackContext) -> None:
return FIRST
def three(update: Update, context: CallbackContext) -> None:
def three(update: Update, _: CallbackContext) -> int:
"""Show new choice of buttons"""
query = update.callback_query
query.answer()
@ -133,7 +132,7 @@ def three(update: Update, context: CallbackContext) -> None:
return SECOND
def four(update: Update, context: CallbackContext) -> None:
def four(update: Update, _: CallbackContext) -> int:
"""Show new choice of buttons"""
query = update.callback_query
query.answer()
@ -150,7 +149,7 @@ def four(update: Update, context: CallbackContext) -> None:
return FIRST
def end(update: Update, context: CallbackContext) -> None:
def end(update: Update, _: CallbackContext) -> int:
"""Returns `ConversationHandler.END`, which tells the
ConversationHandler that the conversation is over"""
query = update.callback_query
@ -159,7 +158,7 @@ def end(update: Update, context: CallbackContext) -> None:
return ConversationHandler.END
def main():
def main() -> None:
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -16,6 +15,7 @@ bot.
"""
import logging
from typing import Tuple, Dict, Any
from telegram import InlineKeyboardMarkup, InlineKeyboardButton, Update
from telegram.ext import (
@ -64,14 +64,14 @@ END = ConversationHandler.END
# Helper
def _name_switcher(level):
def _name_switcher(level: str) -> Tuple[str, str]:
if level == PARENTS:
return 'Father', 'Mother'
return 'Brother', 'Sister'
# Top level conversation callbacks
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, context: CallbackContext) -> str:
"""Select an action: Adding parent/child or show data."""
text = (
'You may add a familiy member, yourself show the gathered data or end the '
@ -103,7 +103,7 @@ def start(update: Update, context: CallbackContext) -> None:
return SELECTING_ACTION
def adding_self(update: Update, context: CallbackContext) -> None:
def adding_self(update: Update, context: CallbackContext) -> str:
"""Add information about youself."""
context.user_data[CURRENT_LEVEL] = SELF
text = 'Okay, please tell me about yourself.'
@ -116,10 +116,10 @@ def adding_self(update: Update, context: CallbackContext) -> None:
return DESCRIBING_SELF
def show_data(update: Update, context: CallbackContext) -> None:
def show_data(update: Update, context: CallbackContext) -> str:
"""Pretty print gathered data."""
def prettyprint(user_data, level):
def prettyprint(user_data: Dict[str, Any], level: str) -> str:
people = user_data.get(level)
if not people:
return '\nNo information yet.'
@ -151,14 +151,14 @@ def show_data(update: Update, context: CallbackContext) -> None:
return SHOWING
def stop(update: Update, context: CallbackContext) -> None:
def stop(update: Update, _: CallbackContext) -> int:
"""End Conversation by command."""
update.message.reply_text('Okay, bye.')
return END
def end(update: Update, context: CallbackContext) -> None:
def end(update: Update, _: CallbackContext) -> int:
"""End conversation from InlineKeyboardButton."""
update.callback_query.answer()
@ -169,7 +169,7 @@ def end(update: Update, context: CallbackContext) -> None:
# Second level conversation callbacks
def select_level(update: Update, context: CallbackContext) -> None:
def select_level(update: Update, _: CallbackContext) -> str:
"""Choose to add a parent or a child."""
text = 'You may add a parent or a child. Also you can show the gathered data or go back.'
buttons = [
@ -190,7 +190,7 @@ def select_level(update: Update, context: CallbackContext) -> None:
return SELECTING_LEVEL
def select_gender(update: Update, context: CallbackContext) -> None:
def select_gender(update: Update, context: CallbackContext) -> str:
"""Choose to add mother or father."""
level = update.callback_query.data
context.user_data[CURRENT_LEVEL] = level
@ -217,7 +217,7 @@ def select_gender(update: Update, context: CallbackContext) -> None:
return SELECTING_GENDER
def end_second_level(update: Update, context: CallbackContext) -> None:
def end_second_level(update: Update, context: CallbackContext) -> int:
"""Return to top level conversation."""
context.user_data[START_OVER] = True
start(update, context)
@ -226,7 +226,7 @@ def end_second_level(update: Update, context: CallbackContext) -> None:
# Third level callbacks
def select_feature(update: Update, context: CallbackContext) -> None:
def select_feature(update: Update, context: CallbackContext) -> str:
"""Select a feature to update for the person."""
buttons = [
[
@ -253,7 +253,7 @@ def select_feature(update: Update, context: CallbackContext) -> None:
return SELECTING_FEATURE
def ask_for_input(update: Update, context: CallbackContext) -> None:
def ask_for_input(update: Update, context: CallbackContext) -> str:
"""Prompt user to input data for selected feature."""
context.user_data[CURRENT_FEATURE] = update.callback_query.data
text = 'Okay, tell me.'
@ -264,7 +264,7 @@ def ask_for_input(update: Update, context: CallbackContext) -> None:
return TYPING
def save_input(update: Update, context: CallbackContext) -> None:
def save_input(update: Update, context: CallbackContext) -> str:
"""Save input for feature and return to feature selection."""
user_data = context.user_data
user_data[FEATURES][user_data[CURRENT_FEATURE]] = update.message.text
@ -274,7 +274,7 @@ def save_input(update: Update, context: CallbackContext) -> None:
return select_feature(update, context)
def end_describing(update: Update, context: CallbackContext) -> None:
def end_describing(update: Update, context: CallbackContext) -> int:
"""End gathering of features and return to parent conversation."""
user_data = context.user_data
level = user_data[CURRENT_LEVEL]
@ -292,14 +292,14 @@ def end_describing(update: Update, context: CallbackContext) -> None:
return END
def stop_nested(update: Update, context: CallbackContext) -> None:
def stop_nested(update: Update, _: CallbackContext) -> str:
"""Completely end conversation from within nested conversation."""
update.message.reply_text('Okay, bye.')
return STOPPING
def main():
def main() -> None:
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -24,7 +23,7 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
def msg(update: Update, context: CallbackContext) -> None:
def msg(update: Update, _: CallbackContext) -> None:
# If we received any passport data
passport_data = update.message.passport_data
if passport_data:
@ -65,19 +64,19 @@ def msg(update: Update, context: CallbackContext) -> None:
actual_file.download()
if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'):
if data.front_side:
file = data.front_side.get_file()
print(data.type, file)
file.download()
front_file = data.front_side.get_file()
print(data.type, front_file)
front_file.download()
if data.type in ('driver_license' and 'identity_card'):
if data.reverse_side:
file = data.reverse_side.get_file()
print(data.type, file)
file.download()
reverse_file = data.reverse_side.get_file()
print(data.type, reverse_file)
reverse_file.download()
if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'):
if data.selfie:
file = data.selfie.get_file()
print(data.type, file)
file.download()
selfie_file = data.selfie.get_file()
print(data.type, selfie_file)
selfie_file.download()
if data.type in (
'passport',
'driver_license',
@ -96,7 +95,7 @@ def msg(update: Update, context: CallbackContext) -> None:
actual_file.download()
def main():
def main() -> None:
"""Start the bot."""
# Create the Updater and pass it your token and private key
updater = Updater("TOKEN", private_key=open('private.key', 'rb').read())

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -28,7 +27,7 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
def start_callback(update: Update, context: CallbackContext) -> None:
def start_callback(update: Update, _: CallbackContext) -> None:
msg = "Use /shipping to get an invoice for shipping-payment, "
msg += "or /noshipping for an invoice without shipping."
update.message.reply_text(msg)
@ -91,7 +90,7 @@ def start_without_shipping_callback(update: Update, context: CallbackContext) ->
)
def shipping_callback(update: Update, context: CallbackContext) -> None:
def shipping_callback(update: Update, _: CallbackContext) -> None:
query = update.shipping_query
# check the payload, is this from your bot?
if query.invoice_payload != 'Custom-Payload':
@ -109,7 +108,7 @@ def shipping_callback(update: Update, context: CallbackContext) -> None:
# after (optional) shipping, it's the pre-checkout
def precheckout_callback(update: Update, context: CallbackContext) -> None:
def precheckout_callback(update: Update, _: CallbackContext) -> None:
query = update.pre_checkout_query
# check the payload, is this from your bot?
if query.invoice_payload != 'Custom-Payload':
@ -120,12 +119,12 @@ def precheckout_callback(update: Update, context: CallbackContext) -> None:
# finally, after contacting the payment provider...
def successful_payment_callback(update: Update, context: CallbackContext) -> None:
def successful_payment_callback(update: Update, _: CallbackContext) -> None:
# do something after successfully receiving payment?
update.message.reply_text("Thank you for your payment!")
def main():
def main() -> None:
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116, C0103
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -16,6 +15,7 @@ bot.
"""
import logging
from typing import Dict
from telegram import ReplyKeyboardMarkup, Update
from telegram.ext import (
@ -46,7 +46,7 @@ reply_keyboard = [
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
def facts_to_str(user_data):
def facts_to_str(user_data: Dict[str, str]) -> str:
facts = list()
for key, value in user_data.items():
@ -55,7 +55,7 @@ def facts_to_str(user_data):
return "\n".join(facts).join(['\n', '\n'])
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, context: CallbackContext) -> int:
reply_text = "Hi! My name is Doctor Botter."
if context.user_data:
reply_text += (
@ -72,7 +72,7 @@ def start(update: Update, context: CallbackContext) -> None:
return CHOOSING
def regular_choice(update: Update, context: CallbackContext) -> None:
def regular_choice(update: Update, context: CallbackContext) -> int:
text = update.message.text.lower()
context.user_data['choice'] = text
if context.user_data.get(text):
@ -86,7 +86,7 @@ def regular_choice(update: Update, context: CallbackContext) -> None:
return TYPING_REPLY
def custom_choice(update: Update, context: CallbackContext) -> None:
def custom_choice(update: Update, _: CallbackContext) -> int:
update.message.reply_text(
'Alright, please send me the category first, ' 'for example "Most impressive skill"'
)
@ -94,7 +94,7 @@ def custom_choice(update: Update, context: CallbackContext) -> None:
return TYPING_CHOICE
def received_information(update: Update, context: CallbackContext) -> None:
def received_information(update: Update, context: CallbackContext) -> int:
text = update.message.text
category = context.user_data['choice']
context.user_data[category] = text.lower()
@ -117,7 +117,7 @@ def show_data(update: Update, context: CallbackContext) -> None:
)
def done(update: Update, context: CallbackContext) -> None:
def done(update: Update, context: CallbackContext) -> int:
if 'choice' in context.user_data:
del context.user_data['choice']
@ -127,13 +127,13 @@ def done(update: Update, context: CallbackContext) -> None:
return ConversationHandler.END
def main():
def main() -> None:
# Create the Updater and pass it your bot's token.
pp = PicklePersistence(filename='conversationbot')
updater = Updater("TOKEN", persistence=pp)
persistence = PicklePersistence(filename='conversationbot')
updater = Updater("TOKEN", persistence=persistence)
# Get the dispatcher to register handlers
dp = updater.dispatcher
dispatcher = updater.dispatcher
# Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
conv_handler = ConversationHandler(
@ -162,10 +162,10 @@ def main():
persistent=True,
)
dp.add_handler(conv_handler)
dispatcher.add_handler(conv_handler)
show_data_handler = CommandHandler('show_data', show_data)
dp.add_handler(show_data_handler)
dispatcher.add_handler(show_data_handler)
# Start the Bot
updater.start_polling()

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -35,7 +34,7 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> None:
"""Inform user about what this bot can do"""
update.message.reply_text(
'Please select /poll to get a Poll, /quiz to get a Quiz or /preview'
@ -121,7 +120,7 @@ def receive_quiz_answer(update: Update, context: CallbackContext) -> None:
context.bot.stop_poll(quiz_data["chat_id"], quiz_data["message_id"])
def preview(update: Update, context: CallbackContext) -> None:
def preview(update: Update, _: CallbackContext) -> None:
"""Ask user to create a poll and display a preview of it"""
# using this without a type lets the user chooses what he wants (quiz or poll)
button = [[KeyboardButton("Press me!", request_poll=KeyboardButtonPollType())]]
@ -132,7 +131,7 @@ def preview(update: Update, context: CallbackContext) -> None:
)
def receive_poll(update: Update, context: CallbackContext) -> None:
def receive_poll(update: Update, _: CallbackContext) -> None:
"""On receiving polls, reply to it by a closed poll copying the received poll"""
actual_poll = update.effective_message.poll
# Only need to set the question and options, since all other parameters don't matter for
@ -146,7 +145,7 @@ def receive_poll(update: Update, context: CallbackContext) -> None:
)
def help_handler(update: Update, context: CallbackContext) -> None:
def help_handler(update: Update, _: CallbackContext) -> None:
"""Display a help message"""
update.message.reply_text("Use /quiz, /poll or /preview to test this bot.")

View file

@ -39,7 +39,7 @@ def main() -> NoReturn:
sleep(1)
except Unauthorized:
# The user has removed or blocked the bot.
UPDATE_ID += 1 # type: ignore[operator]
UPDATE_ID += 1
def echo(bot: telegram.Bot) -> None:

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0613, C0116
# type: ignore[union-attr]
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
@ -34,17 +33,17 @@ logger = logging.getLogger(__name__)
# Define a few command handlers. These usually take the two arguments update and
# context. Error handlers also receive the raised TelegramError object in error.
def start(update: Update, context: CallbackContext) -> None:
def start(update: Update, _: CallbackContext) -> None:
update.message.reply_text('Hi! Use /set <seconds> to set a timer')
def alarm(context):
def alarm(context: CallbackContext) -> None:
"""Send the alarm message."""
job = context.job
context.bot.send_message(job.context, text='Beep!')
def remove_job_if_exists(name, context):
def remove_job_if_exists(name: str, context: CallbackContext) -> bool:
"""Remove job with given name. Returns whether job was removed."""
current_jobs = context.job_queue.get_jobs_by_name(name)
if not current_jobs:
@ -84,7 +83,7 @@ def unset(update: Update, context: CallbackContext) -> None:
update.message.reply_text(text)
def main():
def main() -> None:
"""Run bot."""
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

View file

@ -2,11 +2,11 @@
cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3
pre-commit
# Make sure that the versions specified here match the pre-commit settings
# Make sure that the versions specified here match the pre-commit settings!
black==20.8b1
flake8==3.8.4
pylint==2.6.0
mypy==0.800
pylint==2.7.2
mypy==0.812
pyupgrade==2.10.0
pytest==6.2.2

View file

@ -1,3 +1,5 @@
# Make sure to install those as additional_dependencies in the
# pre-commit hooks for pylint & mypy
certifi
# only telegram.ext: # Keep this line here; used in setup(-raw).py
tornado>=5.1

View file

@ -61,6 +61,10 @@ ignore_errors = True
[mypy-telegram.callbackquery,telegram.chat,telegram.message,telegram.user,telegram.files.*,telegram.inline.inlinequery,telegram.payment.precheckoutquery,telegram.payment.shippingquery,telegram.passport.passportdata,telegram.passport.credentials,telegram.passport.passportfile,telegram.ext.filters]
strict_optional = False
# type hinting for asyncio in webhookhandler is a bit tricky because it depends on the OS
[mypy-telegram.ext.utils.webhookhandler]
warn_unused_ignores = False
[mypy-urllib3.*]
ignore_missing_imports = True

View file

@ -40,8 +40,8 @@ from .files.videonote import VideoNote
from .chataction import ChatAction
from .dice import Dice
from .userprofilephotos import UserProfilePhotos
from .keyboardbutton import KeyboardButton
from .keyboardbuttonpolltype import KeyboardButtonPollType
from .keyboardbutton import KeyboardButton
from .replymarkup import ReplyMarkup
from .replykeyboardmarkup import ReplyKeyboardMarkup
from .replykeyboardremove import ReplyKeyboardRemove

View file

@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=E0401, C0114
# pylint: disable=C0114
import subprocess
import sys
from typing import Optional

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python
# pylint: disable=E0611,E0213,E1102,C0103,E1101,R0913,R0904
# pylint: disable=E0611,E0213,E1102,E1101,R0913,R0904
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2021
@ -17,7 +17,6 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=E0401
"""This module contains an object that represents a Telegram Bot."""
import functools
@ -35,6 +34,7 @@ from typing import (
no_type_check,
Dict,
cast,
Sequence,
)
try:
@ -324,7 +324,7 @@ class Bot(TelegramObject):
return self._bot
@property
def id(self) -> int:
def id(self) -> int: # pylint: disable=C0103
""":obj:`int`: Unique identifier for this bot."""
return self.bot.id
@ -1445,12 +1445,12 @@ class Bot(TelegramObject):
'allow_sending_without_reply': allow_sending_without_reply,
}
for m in data['media']:
if m.parse_mode == DEFAULT_NONE:
for med in data['media']:
if med.parse_mode == DEFAULT_NONE:
if self.defaults:
m.parse_mode = DefaultValue.get_value(self.defaults.parse_mode)
med.parse_mode = DefaultValue.get_value(self.defaults.parse_mode)
else:
m.parse_mode = None
med.parse_mode = None
if reply_to_message_id:
data['reply_to_message_id'] = reply_to_message_id
@ -1990,7 +1990,7 @@ class Bot(TelegramObject):
self,
inline_query_id: str,
results: Union[
List['InlineQueryResult'], Callable[[int], Optional[List['InlineQueryResult']]]
Sequence['InlineQueryResult'], Callable[[int], Optional[Sequence['InlineQueryResult']]]
],
cache_time: int = 300,
is_personal: bool = None,
@ -2103,7 +2103,7 @@ class Bot(TelegramObject):
if callable(results):
callable_output = results(current_offset_int)
if not callable_output:
effective_results = []
effective_results: Sequence['InlineQueryResult'] = []
else:
effective_results = callable_output
next_offset = str(current_offset_int + 1)
@ -3388,7 +3388,7 @@ class Bot(TelegramObject):
)
@log
def answer_shipping_query(
def answer_shipping_query( # pylint: disable=C0103
self,
shipping_query_id: str,
ok: bool,
@ -3453,7 +3453,7 @@ class Bot(TelegramObject):
return result # type: ignore[return-value]
@log
def answer_pre_checkout_query(
def answer_pre_checkout_query( # pylint: disable=C0103
self,
pre_checkout_query_id: str,
ok: bool,

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python
# pylint: disable=C0103,W0622
# pylint: disable=W0622
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2021
@ -165,7 +165,7 @@ class Chat(TelegramObject):
**_kwargs: Any,
):
# Required
self.id = int(id)
self.id = int(id) # pylint: disable=C0103
self.type = type
# Optionals
self.title = title

View file

@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=R0201, E0401
# pylint: disable=R0201
"""This module contains the class Defaults, which allows to pass default values to Updater."""
from typing import NoReturn, Optional, Dict, Any

View file

@ -497,7 +497,7 @@ class Filters:
def filter(self, message: Message) -> bool:
return bool(
message.entities
and any([e.type == MessageEntity.BOT_COMMAND for e in message.entities])
and any(e.type == MessageEntity.BOT_COMMAND for e in message.entities)
)
def __call__( # type: ignore[override]
@ -1896,7 +1896,7 @@ officedocument.wordprocessingml.document")``.
"""""" # remove method from docs
return bool(
message.from_user.language_code
and any([message.from_user.language_code.startswith(x) for x in self.lang])
and any(message.from_user.language_code.startswith(x) for x in self.lang)
)
class _UpdateType(UpdateFilter):

View file

@ -16,7 +16,6 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=E0401
"""This module contains the classes JobQueue and Job."""
import datetime

View file

@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=E0401, C0114
# pylint: disable=C0114
import asyncio
import logging
@ -95,7 +95,7 @@ class WebhookServer:
not force_event_loop
and os.name == 'nt'
and sys.version_info >= (3, 8)
and isinstance(loop, asyncio.ProactorEventLoop)
and isinstance(loop, asyncio.ProactorEventLoop) # type: ignore[attr-defined]
):
raise TypeError(
'`ProactorEventLoop` is incompatible with '
@ -123,7 +123,7 @@ class WebhookServer:
and (
isinstance(
asyncio.get_event_loop_policy(),
asyncio.WindowsProactorEventLoopPolicy, # pylint: disable=E1101
asyncio.WindowsProactorEventLoopPolicy, # type: ignore # pylint: disable
)
)
): # pylint: disable=E1101
@ -140,7 +140,7 @@ class WebhookAppClass(tornado.web.Application):
def __init__(self, webhook_path: str, bot: 'Bot', update_queue: Queue):
self.shared_objects = {"bot": bot, "update_queue": update_queue}
handlers = [(rf"{webhook_path}/?", WebhookHandler, self.shared_objects)] # noqa
tornado.web.Application.__init__(self, handlers)
tornado.web.Application.__init__(self, handlers) # type: ignore
def log_request(self, handler: tornado.web.RequestHandler) -> None:
pass
@ -149,7 +149,7 @@ class WebhookAppClass(tornado.web.Application):
# WebhookHandler, process webhook calls
# pylint: disable=W0223
class WebhookHandler(tornado.web.RequestHandler):
SUPPORTED_METHODS = ["POST"]
SUPPORTED_METHODS = ["POST"] # type: ignore
def __init__(
self,

View file

@ -19,7 +19,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram InlineQuery."""
from typing import TYPE_CHECKING, Any, Optional, List, Union, Callable, ClassVar
from typing import TYPE_CHECKING, Any, Optional, Union, Callable, ClassVar, Sequence
from telegram import Location, TelegramObject, User, constants
from telegram.utils.helpers import DEFAULT_NONE
@ -97,7 +97,7 @@ class InlineQuery(TelegramObject):
def answer(
self,
results: Union[
List['InlineQueryResult'], Callable[[int], Optional[List['InlineQueryResult']]]
Sequence['InlineQueryResult'], Callable[[int], Optional[Sequence['InlineQueryResult']]]
],
cache_time: int = 300,
is_personal: bool = None,

View file

@ -20,7 +20,7 @@
from typing import Any
from telegram import TelegramObject
from telegram import TelegramObject, KeyboardButtonPollType
class KeyboardButton(TelegramObject):
@ -63,7 +63,7 @@ class KeyboardButton(TelegramObject):
text: str,
request_contact: bool = None,
request_location: bool = None,
request_poll: bool = None,
request_poll: KeyboardButtonPollType = None,
**_kwargs: Any,
):
# Required

View file

@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=C0114, E0401, W0622
# pylint: disable=C0114, W0622
try:
import ujson as json
except ImportError:

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ReplyKeyboardMarkup."""
from typing import Any, List, Union
from typing import Any, List, Union, Sequence
from telegram import KeyboardButton, ReplyMarkup
from telegram.utils.types import JSONDict
@ -67,7 +67,7 @@ class ReplyKeyboardMarkup(ReplyMarkup):
def __init__(
self,
keyboard: List[List[Union[str, KeyboardButton]]],
keyboard: Sequence[Sequence[Union[str, KeyboardButton]]],
resize_keyboard: bool = False,
one_time_keyboard: bool = False,
selective: bool = False,

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python
# pylint: disable=C0103,W0622
# pylint: disable=W0622
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2021
@ -111,7 +111,7 @@ class User(TelegramObject):
**_kwargs: Any,
):
# Required
self.id = int(id)
self.id = int(id) # pylint: disable=C0103
self.first_name = first_name
self.is_bot = is_bot
# Optionals

View file

@ -51,7 +51,7 @@ if TYPE_CHECKING:
# in PTB-Raw we don't have pytz, so we make a little workaround here
DTM_UTC = dtm.timezone.utc
try:
import pytz # pylint: disable=E0401
import pytz
UTC = pytz.utc
except ImportError:

View file

@ -30,7 +30,7 @@ except ImportError:
from typing import Any, Union
import certifi # pylint: disable=E0401
import certifi
try:
import telegram.vendor.ptb_urllib3.urllib3 as urllib3