Skip to content

Commit

Permalink
Fixed wrong wrapping of class/static methods when @TypeChecked is app…
Browse files Browse the repository at this point in the history
…lied to the class

Fixes #91.
  • Loading branch information
agronholm committed Nov 10, 2019
1 parent 70c29ef commit a28cee8
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ This library adheres to `Semantic Versioning 2.0 <https://semver.org/#semantic-v
- Fixed resolution of forward references in certain cases (inner classes, function-local classes)
- Fixed ``AttributeError`` when a class has contains a variable that is an instance of a class
that has a ``__call__()`` method
- Fixed class methods and static methods being wrapped incorrectly when ``@typechecked`` is applied
to the class

**2.6.0** (2019-11-06)

Expand Down
14 changes: 14 additions & 0 deletions tests/test_typeguard.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,20 @@ def __call__(self):
class LocalClass:
some_callable = CallableClass()

def test_inherited_class_method(self):
@typechecked
class Parent:
@classmethod
def foo(cls, x: str) -> str:
return cls.__name__

@typechecked
class Child(Parent):
pass

assert Child.foo('bar') == 'Child'
pytest.raises(TypeError, Child.foo, 1)


class TestTypeChecker:
@pytest.fixture
Expand Down
6 changes: 4 additions & 2 deletions typeguard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,11 +729,13 @@ class with this decorator.

if isclass(func):
prefix = func.__qualname__ + '.'
for key in dir(func):
attr = getattr(func, key, None)
for key, attr in func.__dict__.items():
if inspect.isfunction(attr) or inspect.ismethod(attr) or inspect.isclass(attr):
if attr.__qualname__.startswith(prefix) and getattr(attr, '__annotations__', None):
setattr(func, key, typechecked(attr, always=always, _localns=func.__dict__))
elif isinstance(attr, (classmethod, staticmethod)):
wrapped = typechecked(attr.__func__, always=always, _localns=func.__dict__)
setattr(func, key, type(attr)(wrapped))

return func

Expand Down

0 comments on commit a28cee8

Please sign in to comment.