Skip to content

Commit 783adc3

Browse files
fix WithDecoratedMethods
1 parent 382e89d commit 783adc3

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Changelog
2+
## Pedantic 2.2.3
3+
- fix `WithDecoratedMethods`
4+
25
## Pedantic 2.2.2
36
- fix `GenericMixin`
47

pedantic/mixins/with_decorated_methods.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ class DecoratorType(StrEnum):
1111
1212
The values of this enum are used as property names and the properties are added to the decorated functions.
1313
So I would recommend naming them with a leading underscore to keep them private and also write it lowercase.
14+
1415
Example:
1516
>>> class Decorators(DecoratorType):
1617
... FOO = '_foo'
1718
"""
1819

1920

20-
E = TypeVar('E', bound=DecoratorType)
21+
DecoratorTypeVar = TypeVar('DecoratorTypeVar', bound=DecoratorType)
2122
T = TypeVar('T')
2223
C = TypeVar('C', bound=Callable)
2324

@@ -45,7 +46,7 @@ def fun(f: C) -> C:
4546
return decorator
4647

4748

48-
class WithDecoratedMethods(ABC, Generic[E], GenericMixin):
49+
class WithDecoratedMethods(ABC, Generic[DecoratorTypeVar], GenericMixin):
4950
"""
5051
A mixin that is used to figure out which method is decorated with custom parameterized decorators.
5152
Example:
@@ -79,12 +80,12 @@ class WithDecoratedMethods(ABC, Generic[E], GenericMixin):
7980
}
8081
"""
8182

82-
def get_decorated_functions(self) -> dict[E, dict[C, T]]:
83-
decorator_types = self.type_var
83+
def get_decorated_functions(self) -> dict[DecoratorTypeVar, dict[C, T]]:
84+
decorator_types = self.type_vars[DecoratorTypeVar]
8485
decorated_functions = {t: dict() for t in decorator_types} # type: ignore
8586

8687
for attribute_name in dir(self):
87-
if attribute_name.startswith('__'):
88+
if attribute_name.startswith('__') or attribute_name in ['type_var', 'type_vars']:
8889
continue
8990

9091
attribute = getattr(self, attribute_name)

pedantic/tests/test_with_decorated_methods.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import unittest
22
from functools import wraps
3+
from typing import TypeVar, Generic
34

45
from pedantic import DecoratorType, create_decorator, WithDecoratedMethods
56

7+
T = TypeVar('T')
68

79
class Decorators(DecoratorType):
810
FOO = '_foo'
@@ -96,3 +98,12 @@ def m1(self) -> int:
9698
assert instance.get_decorated_functions() == expected
9799

98100
assert instance.m1() == 4422 # check that transformation was applied
101+
102+
def test_with_decorated_methods_can_have_generic_child_class(self):
103+
class MyClass(Generic[T], WithDecoratedMethods[Decorators]):
104+
@foo(42)
105+
def m1(self) -> None: ...
106+
107+
instance = MyClass[int]()
108+
actual = instance.get_decorated_functions()
109+
assert actual == {Decorators.FOO: {instance.m1: 42}, Decorators.BAR: {}}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "pedantic"
7-
version = "2.2.2"
7+
version = "2.2.3"
88
description = "Some useful Python decorators for cleaner software development."
99
readme = "README.md"
1010
requires-python = ">=3.11"

0 commit comments

Comments
 (0)