Repository: piotrmaslanka/satella

Issue:
@typed(Callable) does not accept lambdas

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a55c8e3..2f6f6c64 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
-## v2.0.22
+## v2.0.22rc1
 
-* ...
+* fixes #16
 
 ## v2.0.21
 
diff --git a/satella/coding/typecheck.py b/satella/coding/typecheck.py
index 84bd8097..010121d5 100644
--- a/satella/coding/typecheck.py
+++ b/satella/coding/typecheck.py
@@ -293,19 +293,21 @@ def istype(var, type_):
         return any(istype(var, subtype) for subtype in type_)
 
     try:
+        if type_ in (Callable, Iterable, Sequence, Mapping):
+            raise TypeError()
+
         if isinstance(var, type_):
             return True
 
     except TypeError as e:   # must be a typing.* annotation
-        try:
-            return all(hasattr(var, n) for n in {
-                Iterable: ('__iter__',),
-                Sequence: ('__iter__', '__getattr__', '__len__'),
-                Callable: ('__call__', ),
-                Mapping: ('__getitem__', ),
-            }[type(var)])
-        except KeyError:
-            pass
+        if type_ == Callable:
+            return hasattr(var, '__call__')
+        elif type_ == Iterable:
+            return hasattr(var, '__iter__')
+        elif type_ == Sequence:
+            return hasattr(var, '__iter__') and hasattr(var, '__getattr__') and hasattr(var, '__len__')
+        elif type_ == Mapping:
+            return hasattr(var, '__getitem__')
 
         return type(var) == type_
 
diff --git a/setup.cfg b/setup.cfg
index 5a0931c8..63ace994 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = satella
-version = 2.0.22a1
+version = 2.0.22rc1
 description-file = README.md
 author = Piotr Maślanka
 author_email = piotrm@smok.co


Test patch:
diff --git a/tests/test_coding/test_debug.py b/tests/test_coding/test_debug.py
index 2256def1..504638ae 100644
--- a/tests/test_coding/test_debug.py
+++ b/tests/test_coding/test_debug.py
@@ -48,6 +48,13 @@ class TestTypecheck(unittest.TestCase):
         p(None)
         self.assertRaises(TypeError, lambda: p(5.0))
 
+    def test_lambda(self):
+        @typed(Callable)
+        def q(p):
+            pass
+
+        q(lambda: None)
+
     def test_forarg(self):
         @for_argument(int)
         def testa(a):