diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f903c7..267769a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # Changelog +## Pedantic 2.3.1 +- improve robustness of `WithDecoratedMethods` + ## Pedantic 2.3.0 - added support for Python 3.14 - updated dependencies diff --git a/pedantic/mixins/with_decorated_methods.py b/pedantic/mixins/with_decorated_methods.py index 7a86abf..79bd478 100644 --- a/pedantic/mixins/with_decorated_methods.py +++ b/pedantic/mixins/with_decorated_methods.py @@ -88,7 +88,10 @@ def get_decorated_functions(self) -> dict[DecoratorTypeVar, dict[C, T]]: if attribute_name.startswith('__') or attribute_name in ['type_var', 'type_vars']: continue - attribute = getattr(self, attribute_name) + try: + attribute = getattr(self, attribute_name) + except BaseException: + continue # ignore bad attributes for decorator_type in decorator_types: # type: ignore if hasattr(attribute, decorator_type): diff --git a/pedantic/tests/test_with_decorated_methods.py b/pedantic/tests/test_with_decorated_methods.py index b05325c..1f17e8e 100644 --- a/pedantic/tests/test_with_decorated_methods.py +++ b/pedantic/tests/test_with_decorated_methods.py @@ -1,6 +1,6 @@ import unittest from functools import wraps -from typing import TypeVar, Generic +from typing import TypeVar, Generic, NoReturn from pedantic import DecoratorType, create_decorator, WithDecoratedMethods @@ -16,6 +16,22 @@ class Decorators(DecoratorType): class TestWithDecoratedMethods(unittest.TestCase): + def test_no_decorated_methods(self): + class MyClass(WithDecoratedMethods[Decorators]): + pass + + instance = MyClass() + assert instance.get_decorated_functions() == {Decorators.FOO: {}, Decorators.BAR: {}} + + def test_class_with_bad_property(self): + class MyClass(WithDecoratedMethods[Decorators]): + @property + def bad(self) -> NoReturn: + raise RuntimeError('bad man') + + instance = MyClass() + assert instance.get_decorated_functions() == {Decorators.FOO: {}, Decorators.BAR: {}} + def test_with_decorated_methods_sync(self): class MyClass(WithDecoratedMethods[Decorators]): @foo(42) diff --git a/pyproject.toml b/pyproject.toml index d461db9..fb845d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pedantic" -version = "2.3.0" +version = "2.3.1" description = "Some useful Python decorators for cleaner software development." readme = "README.md" requires-python = ">=3.11"