Skip to content

Commit fe60272

Browse files
harshil21Bibo-Joshi
authored andcommitted
Remove __dict__ from __slots__ and drop Python 3.6 (python-telegram-bot#2619, python-telegram-bot#2636)
1 parent 60f6c38 commit fe60272

219 files changed

Lines changed: 277 additions & 924 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ${{matrix.os}}
1616
strategy:
1717
matrix:
18-
python-version: [3.6, 3.7, 3.8, 3.9]
18+
python-version: [3.7, 3.8, 3.9]
1919
os: [ubuntu-latest, windows-latest, macos-latest]
2020
fail-fast: False
2121
steps:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@ repos:
5656
- id: pyupgrade
5757
files: ^(telegram|examples|tests)/.*\.py$
5858
args:
59-
- --py36-plus
59+
- --py37-plus

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Introduction
9393

9494
This library provides a pure Python interface for the
9595
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
96-
It's compatible with Python versions 3.6.8+. PTB might also work on `PyPy <http://pypy.org/>`_, though there have been a lot of issues before. Hence, PyPy is not officially supported.
96+
It's compatible with Python versions **3.7+**. PTB might also work on `PyPy <http://pypy.org/>`_, though there have been a lot of issues before. Hence, PyPy is not officially supported.
9797

9898
In addition to the pure API implementation, this library features a number of high-level classes to
9999
make the development of bots easy and straightforward. These classes are contained in the

README_RAW.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Introduction
9191

9292
This library provides a pure Python, lightweight interface for the
9393
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
94-
It's compatible with Python versions 3.6.8+. PTB-Raw might also work on `PyPy <http://pypy.org/>`_, though there have been a lot of issues before. Hence, PyPy is not officially supported.
94+
It's compatible with Python versions **3.7+**. PTB-Raw might also work on `PyPy <http://pypy.org/>`_, though there have been a lot of issues before. Hence, PyPy is not officially supported.
9595

9696
``python-telegram-bot-raw`` is part of the `python-telegram-bot <https://python-telegram-bot.org>`_ ecosystem and provides the pure API functionality extracted from PTB. It therefore does *not* have independent release schedules, changelogs or documentation. Please consult the PTB resources.
9797

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.black]
22
line-length = 99
3-
target-version = ['py36']
3+
target-version = ['py37']
44
skip-string-normalization = true
55

66
# We need to force-exclude the negated include pattern

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,11 @@ def get_setup_kwargs(raw=False):
9898
'Topic :: Internet',
9999
'Programming Language :: Python',
100100
'Programming Language :: Python :: 3',
101-
'Programming Language :: Python :: 3.6',
102101
'Programming Language :: Python :: 3.7',
103102
'Programming Language :: Python :: 3.8',
104103
'Programming Language :: Python :: 3.9',
105104
],
106-
python_requires='>=3.6'
105+
python_requires='>=3.7'
107106
)
108107

109108
return kwargs

telegram/base.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@
2323
import json # type: ignore[no-redef]
2424

2525
import warnings
26-
from typing import TYPE_CHECKING, List, Optional, Tuple, Type, TypeVar
26+
from typing import TYPE_CHECKING, List, Optional, Type, TypeVar, Tuple
2727

2828
from telegram.utils.types import JSONDict
29-
from telegram.utils.deprecate import set_new_attribute_deprecated
3029

3130
if TYPE_CHECKING:
3231
from telegram import Bot
@@ -37,22 +36,28 @@
3736
class TelegramObject:
3837
"""Base class for most Telegram objects."""
3938

40-
_id_attrs: Tuple[object, ...] = ()
41-
39+
# type hints in __new__ are not read by mypy (https://github.com/python/mypy/issues/1021). As a
40+
# workaround we can type hint instance variables in __new__ using a syntax defined in PEP 526 -
41+
# https://www.python.org/dev/peps/pep-0526/#class-and-instance-variable-annotations
42+
if TYPE_CHECKING:
43+
_id_attrs: Tuple[object, ...]
4244
# Adding slots reduces memory usage & allows for faster attribute access.
4345
# Only instance variables should be added to __slots__.
44-
# We add __dict__ here for backward compatibility & also to avoid repetition for subclasses.
45-
__slots__ = ('__dict__',)
46+
__slots__ = ('_id_attrs',)
47+
48+
def __new__(cls, *args: object, **kwargs: object) -> 'TelegramObject': # pylint: disable=W0613
49+
# We add _id_attrs in __new__ instead of __init__ since we want to add this to the slots
50+
# w/o calling __init__ in all of the subclasses. This is what we also do in BaseFilter.
51+
instance = super().__new__(cls)
52+
instance._id_attrs = ()
53+
return instance
4654

4755
def __str__(self) -> str:
4856
return str(self.to_dict())
4957

5058
def __getitem__(self, item: str) -> object:
5159
return getattr(self, item, None)
5260

53-
def __setattr__(self, key: str, value: object) -> None:
54-
set_new_attribute_deprecated(self, key, value)
55-
5661
@staticmethod
5762
def _parse_data(data: Optional[JSONDict]) -> Optional[JSONDict]:
5863
return None if data is None else data.copy()
@@ -76,7 +81,7 @@ def de_json(cls: Type[TO], data: Optional[JSONDict], bot: 'Bot') -> Optional[TO]
7681

7782
if cls == TelegramObject:
7883
return cls()
79-
return cls(bot=bot, **data) # type: ignore[call-arg]
84+
return cls(bot=bot, **data)
8085

8186
@classmethod
8287
def de_list(cls: Type[TO], data: Optional[List[JSONDict]], bot: 'Bot') -> List[Optional[TO]]:
@@ -132,6 +137,7 @@ def to_dict(self) -> JSONDict:
132137
return data
133138

134139
def __eq__(self, other: object) -> bool:
140+
# pylint: disable=no-member
135141
if isinstance(other, self.__class__):
136142
if self._id_attrs == ():
137143
warnings.warn(
@@ -144,9 +150,10 @@ def __eq__(self, other: object) -> bool:
144150
" for equivalence."
145151
)
146152
return self._id_attrs == other._id_attrs
147-
return super().__eq__(other) # pylint: disable=no-member
153+
return super().__eq__(other)
148154

149155
def __hash__(self) -> int:
156+
# pylint: disable=no-member
150157
if self._id_attrs:
151-
return hash((self.__class__, self._id_attrs)) # pylint: disable=no-member
158+
return hash((self.__class__, self._id_attrs))
152159
return super().__hash__()

telegram/bot.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,6 @@ def __init__(
224224
private_key, password=private_key_password, backend=default_backend()
225225
)
226226

227-
# The ext_bot argument is a little hack to get warnings handled correctly.
228-
# It's not very clean, but the warnings will be dropped at some point anyway.
229-
def __setattr__(self, key: str, value: object, ext_bot: bool = False) -> None:
230-
if issubclass(self.__class__, Bot) and self.__class__ is not Bot and not ext_bot:
231-
object.__setattr__(self, key, value)
232-
return
233-
super().__setattr__(key, value)
234-
235227
def _insert_defaults(
236228
self, data: Dict[str, object], timeout: ODVInput[float]
237229
) -> Optional[float]:

telegram/botcommand.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class BotCommand(TelegramObject):
4141
4242
"""
4343

44-
__slots__ = ('description', '_id_attrs', 'command')
44+
__slots__ = ('description', 'command')
4545

4646
def __init__(self, command: str, description: str, **_kwargs: Any):
4747
self.command = command

telegram/botcommandscope.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class BotCommandScope(TelegramObject):
5757
type (:obj:`str`): Scope type.
5858
"""
5959

60-
__slots__ = ('type', '_id_attrs')
60+
__slots__ = ('type',)
6161

6262
DEFAULT = constants.BOT_COMMAND_SCOPE_DEFAULT
6363
""":const:`telegram.constants.BOT_COMMAND_SCOPE_DEFAULT`"""

0 commit comments

Comments
 (0)