mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Add dynamic dataclass and class attribute resolvers
Introduced `dataclass_kwargs` to ensure compatibility with different Python versions and modular attribute handling. Added utilities for resolving class attributes dynamically, enhancing flexibility with MRO-based resolvers. Updated tests to verify new features and ensure proper functionality across various scenarios.
This commit is contained in:
parent
d36a10d428
commit
b146b7aa85
7 changed files with 349 additions and 13 deletions
81
tests/test_utils/test_class_attrs_resolver.py
Normal file
81
tests/test_utils/test_class_attrs_resolver.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import pytest
|
||||
|
||||
from aiogram.utils.class_attrs_resolver import (
|
||||
get_reversed_mro_unique_attrs_resolver,
|
||||
get_sorted_mro_attrs_resolver,
|
||||
inspect_members_resolver,
|
||||
)
|
||||
|
||||
|
||||
class SimpleClass1:
|
||||
def method1(self):
|
||||
pass
|
||||
|
||||
def method2(self):
|
||||
pass
|
||||
|
||||
|
||||
class SimpleClass2:
|
||||
def method2(self):
|
||||
pass
|
||||
|
||||
def method1(self):
|
||||
pass
|
||||
|
||||
|
||||
class InheritedClass1(SimpleClass1):
|
||||
def method3(self):
|
||||
pass
|
||||
|
||||
def method4(self):
|
||||
pass
|
||||
|
||||
|
||||
class InheritedClass2(SimpleClass1):
|
||||
def method2(self):
|
||||
pass
|
||||
|
||||
def method3(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestClassAttrsResolver:
|
||||
@pytest.mark.parametrize(
|
||||
"cls, resolver, expected",
|
||||
[
|
||||
# inspect_members_resolver
|
||||
(SimpleClass1, inspect_members_resolver, ["method1", "method2"]),
|
||||
(SimpleClass2, inspect_members_resolver, ["method1", "method2"]),
|
||||
(
|
||||
InheritedClass1,
|
||||
inspect_members_resolver,
|
||||
["method1", "method2", "method3", "method4"],
|
||||
),
|
||||
(InheritedClass2, inspect_members_resolver, ["method1", "method2", "method3"]),
|
||||
# get_reversed_mro_unique_attrs_resolver
|
||||
(SimpleClass1, get_reversed_mro_unique_attrs_resolver, ["method1", "method2"]),
|
||||
(SimpleClass2, get_reversed_mro_unique_attrs_resolver, ["method2", "method1"]),
|
||||
(
|
||||
InheritedClass1,
|
||||
get_reversed_mro_unique_attrs_resolver,
|
||||
["method1", "method2", "method3", "method4"],
|
||||
),
|
||||
(
|
||||
InheritedClass2,
|
||||
get_reversed_mro_unique_attrs_resolver,
|
||||
["method1", "method2", "method3"],
|
||||
),
|
||||
# get_sorted_mro_attrs_resolver
|
||||
(SimpleClass1, get_sorted_mro_attrs_resolver, ["method1", "method2"]),
|
||||
(SimpleClass2, get_sorted_mro_attrs_resolver, ["method2", "method1"]),
|
||||
(
|
||||
InheritedClass1,
|
||||
get_sorted_mro_attrs_resolver,
|
||||
["method3", "method4", "method1", "method2"],
|
||||
),
|
||||
(InheritedClass2, get_sorted_mro_attrs_resolver, ["method3", "method1", "method2"]),
|
||||
],
|
||||
)
|
||||
def test_resolve_class_attrs(self, cls, resolver, expected):
|
||||
names = [name for name, _ in resolver(cls) if not name.startswith("__")]
|
||||
assert names == expected
|
||||
51
tests/test_utils/test_dataclass.py
Normal file
51
tests/test_utils/test_dataclass.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from aiogram.utils.dataclass import dataclass_kwargs
|
||||
|
||||
ALL_VERSIONS = {
|
||||
"init": True,
|
||||
"repr": True,
|
||||
"eq": True,
|
||||
"order": True,
|
||||
"unsafe_hash": True,
|
||||
"frozen": True,
|
||||
}
|
||||
ADDED_IN_3_10 = {"match_args": True, "kw_only": True, "slots": True}
|
||||
ADDED_IN_3_11 = {"weakref_slot": True}
|
||||
|
||||
PY_310 = {**ALL_VERSIONS, **ADDED_IN_3_10}
|
||||
PY_311 = {**PY_310, **ADDED_IN_3_11}
|
||||
LATEST_PY = PY_311
|
||||
|
||||
|
||||
class TestDataclassKwargs:
|
||||
@pytest.mark.parametrize(
|
||||
"py_version,expected",
|
||||
[
|
||||
((3, 9, 0), ALL_VERSIONS),
|
||||
((3, 9, 2), ALL_VERSIONS),
|
||||
((3, 10, 2), PY_310),
|
||||
((3, 11, 0), PY_311),
|
||||
((4, 13, 0), LATEST_PY),
|
||||
],
|
||||
)
|
||||
def test_dataclass_kwargs(self, py_version, expected):
|
||||
with patch("sys.version_info", py_version):
|
||||
|
||||
assert (
|
||||
dataclass_kwargs(
|
||||
init=True,
|
||||
repr=True,
|
||||
eq=True,
|
||||
order=True,
|
||||
unsafe_hash=True,
|
||||
frozen=True,
|
||||
match_args=True,
|
||||
kw_only=True,
|
||||
slots=True,
|
||||
weakref_slot=True,
|
||||
)
|
||||
== expected
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue