Conversation
Except `inputmedia.py` classes and `Bot`
That makes all TOs, other application classes still have their tests
dataclasses generated `hash()` does not include `self.__class__` so this is to preserve old behaviour of different classes, having same field level hashes, not being equal
Note: this failure revealed a minor breaking change in how `__eq__()` works, worth documenting and adding to changelog later
Old test for a now breaking change unfortunately.
I temporarily broke old TO.__hash__ behaviour that used identity hashing when two objects had no _id_attrs (i.e empty tuple). Not sure why it was that way since empty id attrs mean their equall in terms of __eq__ (yes we did issue a warning but still), so they should have same hash. Anyways that should be restored now because otherwis it would be a breaking change.
Conflicts: tests/_files/test_animation.py tests/_files/test_audio.py tests/_files/test_chatphoto.py tests/_files/test_document.py tests/_files/test_photo.py tests/_files/test_sticker.py tests/_files/test_video.py tests/_files/test_videonote.py tests/_files/test_videoquality.py tests/_files/test_voice.py tests/test_forum.py
Same breaking change caused by a bug in old `__eq__()`. tl;dr previously __eq__ allowed parent == child # True
|
So I had this drafted for a bit of time now, I intended to send it earlier on to get your feedback on it, especially the logic around the after-processing of generated Then I was tempted to walk till (near) the finish line and see how (simple v.s complicated) it will turn to be.
This did not age well. from dataclasses import InitVar, dataclass, field
@dataclass(frozen=True)
class Example:
value: InitVar[int | None] = None
_value: int | None = field(init=False, default=None)
def __post_init__(self, value: int | None, /):
object.__setattr__(self, "_value", value)
@property
def value(self) -> int | None:
print("value is deprecated and will be removed")
return self._value
a = Example()
print(a._value) # output: <property object at 0x7ff25e629e40>
b = Example(10)
print(b._value) # output: 10When not providing an explicit argument for value, the default So i tried giving this alias Field specifier parameters a shot:
The outcome of it is pretty neat and less verbose, however, and just like Aliased parameter MWE# No runtime support fo alias, this is just to demonstrate type checkers support
from dataclasses import MISSING, dataclass, field
from typing import Any, TypeVar, dataclass_transform
_T = TypeVar("_T")
def tg_field(
*,
default: Any = MISSING,
alias: str | None = None,
) -> Any:
return field(default=default)
@dataclass_transform(field_specifiers=(tg_field,))
def tg_dataclass(cls: type[_T]) -> type[_T]:
return dataclass(frozen=True)(cls)
@tg_dataclass
class Example:
_value: int | None = tg_field(alias="value", default=None)
@property
def value(self) -> int | None:
print("value is deprecated and will be removed")
return self._value
# Wroks in runtime
c = Example(_value=10)
# TypeError: Example.__init__() got an unexpected keyword argument 'value'
d = Example(value=10)Its well supported in type checkers that common IDEs use IDE SupportPyright
Pycharm, should be supported from 2024.3 onwards. https://youtrack.jetbrains.com/issue/PY-73832/Pycharm-doesnt-properly-recognizes-aliases-for-Pydantic-dataclass mypy also support aliases running it through the above MWE gives:
I just did nothing. Excluding test files, there was very minimal unfreezing of objects outside of old CISadly pylint and mypy have a bunch of false positives that we'll have to fight some way. I still got some polishing to do, specifically I want to:
The last two points can further simplify I'm going to be working on these items in the following days, would be great to get some initial review since Doesn't have to be the whole thing, just |



Closes #5279
Discussed Priorly: #2698