From 8a564ef8a2d734ade23b837bf63bcc3ea78c26c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Sat, 13 Feb 2021 17:16:13 +0100
Subject: [PATCH] v2.14.36

---
 CHANGELOG.md                           |  1 +
 pytest.ini                             |  3 +++
 satella/__init__.py                    |  2 +-
 satella/coding/decorators/arguments.py | 14 ++++++++++++--
 satella/coding/misc.py                 | 24 +++++++++++++++---------
 tests/test_coding/test_misc.py         | 19 ++++++++++++++++++-
 6 files changed, 50 insertions(+), 13 deletions(-)
 create mode 100644 pytest.ini

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ad95b67..4804b24e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,3 +2,4 @@
 
 * fixed `AlreadySeen` to support non-hashable objects
 * improved `ComparableIntEnum`
+* fixed a bug in `get_argument` while comparing uncomparable items
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 00000000..20341273
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+log_cli = true
+
diff --git a/satella/__init__.py b/satella/__init__.py
index 041b19ad..90cfa8cc 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.14.36a3'
+__version__ = '2.14.36'
diff --git a/satella/coding/decorators/arguments.py b/satella/coding/decorators/arguments.py
index 04fe264f..dfda9fdf 100644
--- a/satella/coding/decorators/arguments.py
+++ b/satella/coding/decorators/arguments.py
@@ -326,8 +326,18 @@ def for_argument(*t_ops: ForArgumentArg, **t_kwops: ForArgumentArg):
             t_kwops[key] = source_to_function(value)
 
     def outer(fun):
-        if any(param.default != Parameter.empty for param in
-               inspect.signature(fun).parameters.values()):
+        comparison = False
+        # Check whether this function has any default arguments
+        for param in inspect.signature(fun).parameters.values():
+            try:
+                if Parameter.empty != param.default:
+                    comparison = True
+                    break
+            except (AttributeError, TypeError):
+                comparison = True
+                break
+
+        if comparison:
             @wraps(fun)
             def inner(*args, **kwargs):
                 dict_operations = _get_arguments(fun, True, *t_ops, **t_kwops)
diff --git a/satella/coding/misc.py b/satella/coding/misc.py
index d6d65d05..5cfcd394 100644
--- a/satella/coding/misc.py
+++ b/satella/coding/misc.py
@@ -267,9 +267,12 @@ def _get_arguments(function: tp.Callable, special_behaviour: bool, *args, **kwar
                 v = args.pop()
                 arguments_left.remove(arg_name)
             except IndexError:
-                if arg.default == Parameter.empty:
-                    break
-                else:
+                try:
+                    if arg.default != Parameter.empty:
+                        raise AttributeError()
+                    else:
+                        break
+                except (AttributeError, TypeError):
                     v = arg.default
             local_vars[arg_name] = v
 
@@ -286,13 +289,16 @@ def _get_arguments(function: tp.Callable, special_behaviour: bool, *args, **kwar
             try:
                 v = kwargs.pop(keyword_name)
             except KeyError:
-                if keyword.default == Parameter.empty:
-                    if special_behaviour:
-                        v = None
+                try:
+                    if Parameter.empty == keyword.default:
+                        if special_behaviour:
+                            v = None
+                        else:
+                            raise TypeError('Not enough keyword arguments')
                     else:
-                        raise TypeError('Not enough keyword arguments')
-                else:
-                    v = keyword.default
+                        v = keyword.default
+                except (AttributeError, TypeError):
+                    continue    # comparison was impossible
 
             local_vars[keyword_name] = v
 
diff --git a/tests/test_coding/test_misc.py b/tests/test_coding/test_misc.py
index a44ec131..19f53ce7 100644
--- a/tests/test_coding/test_misc.py
+++ b/tests/test_coding/test_misc.py
@@ -1,16 +1,33 @@
+import logging
 import enum
 import gc
 import unittest
 
 from satella.coding import update_key_if_not_none, overload, class_or_instancemethod, \
     update_key_if_true, get_arguments, call_with_arguments, chain_callables, Closeable, \
-    contains, enum_value
+    contains, enum_value, for_argument
 from satella.coding.structures import HashableMixin, ComparableEnum
 from satella.coding.transforms import jsonify, intify
 
+logger = logging.getLogger(__name__)
 
 class TestCase(unittest.TestCase):
 
+    def test_cant_compare_me(self):
+        class Uncomparable:
+            def __eq__(self, other):
+                raise TypeError()
+
+            def __str__(self):
+                return 'test'
+
+        @for_argument(y=str)
+        def test(y = Uncomparable()):
+            return y
+
+        b = test()
+        self.assertEqual(b, 'test')
+
     def test_contains(self):
         class CEnum(ComparableEnum):
             A = 1
-- 
GitLab