Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1d1ccb8
Add deepsource config
Bibo-Joshi Apr 6, 2021
cbd94a8
Update Badges
Bibo-Joshi Apr 6, 2021
e4b6fe1
Update Badges some more
Bibo-Joshi Apr 6, 2021
dd46c26
Stupid change to trigger analysis of all files
Bibo-Joshi Apr 6, 2021
99cd57e
Try to get ignore right
Bibo-Joshi Apr 6, 2021
bb50eaf
Update badges again
Bibo-Joshi Apr 7, 2021
6896192
Get started on fixing issues
Bibo-Joshi Apr 7, 2021
5f3dedc
Fix some more issues
Bibo-Joshi Apr 8, 2021
bcf25bf
Remove more plank lines
Bibo-Joshi Apr 8, 2021
c0e4a57
Docs for de_json/list & to_dict/json
Bibo-Joshi Apr 8, 2021
093ba06
Some improvements from deepcode.ai
Bibo-Joshi Apr 9, 2021
dec1ba9
Some more improvements
Bibo-Joshi Apr 9, 2021
a97a5da
Some more improvements
Bibo-Joshi Apr 9, 2021
7acd88d
More docstrnigs & let's run DS on the tests just for fun
Bibo-Joshi Apr 9, 2021
f655925
Autofix issues in 10 files
deepsource-autofix[bot] Apr 9, 2021
ae4d08b
Some more improvements for tests, but that shall be enough
Bibo-Joshi Apr 9, 2021
2644b83
Some more docstrings for functions
Bibo-Joshi Apr 15, 2021
3369fd0
Some minor stuff, try to fix tests
Bibo-Joshi Apr 15, 2021
76b2763
Update DS config
Bibo-Joshi Apr 18, 2021
30ee8bf
Still more docs
Bibo-Joshi Apr 18, 2021
0a1720e
Merge branch 'master' into repace-codacy-by-deepsource
Bibo-Joshi Apr 28, 2021
0f081ce
Merge branch 'master' into repace-codacy-by-deepsource
Bibo-Joshi May 3, 2021
691ccd7
Doc fixes
Bibo-Joshi May 3, 2021
4f3c79a
More fixes
Bibo-Joshi May 3, 2021
962c2b5
Merge branch 'master' into repace-codacy-by-deepsource
Bibo-Joshi May 11, 2021
f497164
Fix: indent docstring
Poolitzer May 14, 2021
183e905
Merge branch 'master' into repace-codacy-by-deepsource
Bibo-Joshi May 25, 2021
602e0cc
Some fixes
Bibo-Joshi May 25, 2021
28419f2
Revert "Stupid change to trigger analysis of all files"
Bibo-Joshi May 25, 2021
1395926
Review
Bibo-Joshi May 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .deepsource.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version = 1

test_patterns = ["tests/**"]

exclude_patterns = [
"tests/**",
"docs/**",
"telegram/vendor/**",
"setup.py",
"setup-raw.py"
]

[[analyzers]]
name = "python"
enabled = true

[analyzers.meta]
runtime_version = "3.x.x"
max_line_length = 99
skip_doc_coverage = ["module", "magic", "init", "nonpublic"]
8 changes: 6 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ We have a vibrant community of developers helping each other in our `Telegram gr

.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
:target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade
:alt: Code quality
:alt: Code quality: Codacy

.. image:: https://deepsource.io/gh/python-telegram-bot/python-telegram-bot.svg/?label=active+issues
:target: https://deepsource.io/gh/python-telegram-bot/python-telegram-bot/?ref=repository-badge
:alt: Code quality: DeepSource

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black
:target: https://github.com/psf/black

.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg?logo=telegram
:target: https://telegram.me/pythontelegrambotgroup
Expand Down
8 changes: 6 additions & 2 deletions README_RAW.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ We have a vibrant community of developers helping each other in our `Telegram gr

.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
:target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade
:alt: Code quality
:alt: Code quality: Codacy

.. image:: https://deepsource.io/gh/python-telegram-bot/python-telegram-bot.svg/?label=active+issues
:target: https://deepsource.io/gh/python-telegram-bot/python-telegram-bot/?ref=repository-badge
:alt: Code quality: DeepSource

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black
:target: https://github.com/psf/black

.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg?logo=telegram
:target: https://telegram.me/pythontelegrambotgroup
Expand Down
37 changes: 21 additions & 16 deletions examples/passportbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@


def msg(update: Update, _: CallbackContext) -> None:
"""Downloads and prints the received passport data."""
# Retrieve passport data
passport_data = update.message.passport_data
# If our nonce doesn't match what we think, this Update did not originate from us
Expand Down Expand Up @@ -61,21 +62,24 @@ def msg(update: Update, _: CallbackContext) -> None:
actual_file = file.get_file()
print(actual_file)
actual_file.download()
if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'):
if data.front_side:
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:
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:
selfie_file = data.selfie.get_file()
print(data.type, selfie_file)
selfie_file.download()
if (
data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport')
and data.front_side
):
front_file = data.front_side.get_file()
print(data.type, front_file)
front_file.download()
if data.type in ('driver_license' and 'identity_card') and data.reverse_side:
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')
and data.selfie
):
selfie_file = data.selfie.get_file()
print(data.type, selfie_file)
selfie_file.download()
if data.type in (
'passport',
'driver_license',
Expand All @@ -97,7 +101,8 @@ def msg(update: Update, _: CallbackContext) -> None:
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())
with open('private.key', 'rb') as private_key:
updater = Updater("TOKEN", private_key=private_key.read())

# Get the dispatcher to register handlers
dispatcher = updater.dispatcher
Expand Down
6 changes: 3 additions & 3 deletions telegram/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@

def _git_revision() -> Optional[str]:
try:
output = subprocess.check_output(
output = subprocess.check_output( # skipcq: BAN-B607
["git", "describe", "--long", "--tags"], stderr=subprocess.STDOUT
)
except (subprocess.SubprocessError, OSError):
return None
return output.decode().strip()


def print_ver_info() -> None:
def print_ver_info() -> None: # skipcq: PY-D0003
git_revision = _git_revision()
print(f'python-telegram-bot {telegram_ver}' + (f' ({git_revision})' if git_revision else ''))
print(f'Bot API {BOT_API_VERSION}')
Expand All @@ -46,7 +46,7 @@ def print_ver_info() -> None:
print(f'Python {sys_version}')


def main() -> None:
def main() -> None: # skipcq: PY-D0003
print_ver_info()


Expand Down
36 changes: 30 additions & 6 deletions telegram/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@


class TelegramObject:
"""Base class for most telegram objects."""
"""Base class for most Telegram objects."""

_id_attrs: Tuple[object, ...] = ()

Expand All @@ -45,12 +45,22 @@ def __getitem__(self, item: str) -> object:
return self.__dict__[item]

@staticmethod
def parse_data(data: Optional[JSONDict]) -> Optional[JSONDict]:
def _parse_data(data: Optional[JSONDict]) -> Optional[JSONDict]:
return None if data is None else data.copy()

@classmethod
def de_json(cls: Type[TO], data: Optional[JSONDict], bot: 'Bot') -> Optional[TO]:
data = cls.parse_data(data)
"""Converts JSON data to a Telegram object.

Args:
data (Dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`): The bot associated with this object.

Returns:
The Telegram object.

"""
data = cls._parse_data(data)

if data is None:
return None
Expand All @@ -61,21 +71,35 @@ def de_json(cls: Type[TO], data: Optional[JSONDict], bot: 'Bot') -> Optional[TO]

@classmethod
def de_list(cls: Type[TO], data: Optional[List[JSONDict]], bot: 'Bot') -> List[Optional[TO]]:
"""Converts JSON data to a list of Telegram objects.

Args:
data (Dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`): The bot associated with these objects.

Returns:
A list of Telegram objects.

"""
if not data:
return []

return [cls.de_json(d, bot) for d in data]

def to_json(self) -> str:
"""
"""Gives a JSON representation of object.

Returns:
:obj:`str`

"""

return json.dumps(self.to_dict())

def to_dict(self) -> JSONDict:
"""Gives representation of object as :obj:`dict`.

Returns:
:obj:`dict`
"""
data = {}

for key in iter(self.__dict__):
Expand Down
18 changes: 3 additions & 15 deletions telegram/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
RT = TypeVar('RT')


def log(
def log( # skipcq: PY-D0003
func: Callable[..., RT], *args: object, **kwargs: object # pylint: disable=W0613
) -> Callable[..., RT]:
logger = logging.getLogger(func.__module__)
Expand Down Expand Up @@ -301,7 +301,7 @@ def _message(
return Message.de_json(result, self) # type: ignore[return-value, arg-type]

@property
def request(self) -> Request:
def request(self) -> Request: # skip-cq: PY-D0003
return self._request

@staticmethod
Expand All @@ -319,71 +319,60 @@ def _validate_token(token: str) -> str:
@property
def bot(self) -> User:
""":class:`telegram.User`: User instance for the bot as returned by :meth:`get_me`."""

if self._bot is None:
self._bot = self.get_me()
return self._bot

@property
def id(self) -> int: # pylint: disable=C0103
""":obj:`int`: Unique identifier for this bot."""

return self.bot.id

@property
def first_name(self) -> str:
""":obj:`str`: Bot's first name."""

return self.bot.first_name

@property
def last_name(self) -> str:
""":obj:`str`: Optional. Bot's last name."""

return self.bot.last_name # type: ignore

@property
def username(self) -> str:
""":obj:`str`: Bot's username."""

return self.bot.username # type: ignore

@property
def link(self) -> str:
""":obj:`str`: Convenience property. Returns the t.me link of the bot."""

return f"https://t.me/{self.username}"

@property
def can_join_groups(self) -> bool:
""":obj:`bool`: Bot's :attr:`telegram.User.can_join_groups` attribute."""

return self.bot.can_join_groups # type: ignore

@property
def can_read_all_group_messages(self) -> bool:
""":obj:`bool`: Bot's :attr:`telegram.User.can_read_all_group_messages` attribute."""

return self.bot.can_read_all_group_messages # type: ignore

@property
def supports_inline_queries(self) -> bool:
""":obj:`bool`: Bot's :attr:`telegram.User.supports_inline_queries` attribute."""

return self.bot.supports_inline_queries # type: ignore

@property
def commands(self) -> List[BotCommand]:
"""List[:class:`BotCommand`]: Bot's commands."""

if self._commands is None:
self._commands = self.get_my_commands()
return self._commands

@property
def name(self) -> str:
""":obj:`str`: Bot's @username."""

return f'@{self.username}'

@log
Expand Down Expand Up @@ -2606,7 +2595,6 @@ def edit_message_media(
Raises:
:class:`telegram.error.TelegramError`
"""

if inline_message_id is None and (chat_id is None or message_id is None):
raise ValueError(
'edit_message_media: Both chat_id and message_id are required when '
Expand Down Expand Up @@ -4257,7 +4245,6 @@ def unpin_all_chat_messages(
:class:`telegram.error.TelegramError`

"""

data: JSONDict = {'chat_id': chat_id}

return self._post( # type: ignore[return-value]
Expand Down Expand Up @@ -5089,6 +5076,7 @@ def copy_message(
return MessageId.de_json(result, self) # type: ignore[return-value, arg-type]

def to_dict(self) -> JSONDict:
"""See :meth:`telegram.TelegramObject.to_dict`."""
data: JSONDict = {'id': self.id, 'username': self.username, 'first_name': self.first_name}

if self.last_name:
Expand Down
3 changes: 2 additions & 1 deletion telegram/callbackquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ def __init__(

@classmethod
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['CallbackQuery']:
data = cls.parse_data(data)
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)

if not data:
return None
Expand Down
6 changes: 4 additions & 2 deletions telegram/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,16 @@ def full_name(self) -> Optional[str]:
@property
def link(self) -> Optional[str]:
""":obj:`str`: Convenience property. If the chat has a :attr:`username`, returns a t.me
link of the chat."""
link of the chat.
"""
if self.username:
return f"https://t.me/{self.username}"
return None

@classmethod
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['Chat']:
data = cls.parse_data(data)
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)

if not data:
return None
Expand Down
4 changes: 3 additions & 1 deletion telegram/chatinvitelink.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ def __init__(

@classmethod
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatInviteLink']:
data = cls.parse_data(data)
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)

if not data:
return None
Expand All @@ -95,6 +96,7 @@ def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatInviteLi
return cls(**data)

def to_dict(self) -> JSONDict:
"""See :meth:`telegram.TelegramObject.to_dict`."""
data = super().to_dict()

data['expire_date'] = to_timestamp(self.expire_date)
Expand Down
3 changes: 2 additions & 1 deletion telegram/chatlocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ def __init__(

@classmethod
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatLocation']:
data = cls.parse_data(data)
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)

if not data:
return None
Expand Down
Loading