Repository: Parquery/icontract (language: python)

Issue:
Outdated deal & typeguard
The typeguard version used is two mayor versions behind. Which makes it difficult to package icontract for package managers because of package name collision. The deal version used is also 3 years outdated


Discussion / hints:
@Luis-Hebendanz thanks for the signal! Is there a particular version I should pin the packages to?

We actually use typeguard and deal only for benchmarks. Would it be easier for distributions if I move them to `[benchmark]` dependencies in `setup.py`?
@mristin ahh yes please, that would be quite nice! :-) 
@Luis-Hebendanz actually, the dependencies `dev` are meant for *internal* development and should not be included in a package of a distribution.

Sorry, it only dawned on me right now that there's a confusion due to bad naming: you are probably packaging `dev` in `icontract-dev` package or something like that, which is in practice a useless package. If anybody wants to develop icontract further, they will fork the repository and make a pull request, and cerainly not install `icontract-dev` and change it locally.

Can you perhaps suggest a better name than `dev` for the dependencies category, and then exclude these dependencies completely in the distributions?
@mristin Ah no we run the tests for the python packages to make sure it still works, but we only have the newest version of the packages available. 

Fix patch:
diff --git a/setup.py b/setup.py
index 1fd168b..6acfaa4 100644
--- a/setup.py
+++ b/setup.py
@@ -63,12 +63,12 @@
             "dpcontracts==0.6.0",
             "tabulate>=0.8.7,<1",
             "py-cpuinfo>=5.0.0,<6",
-            "typeguard>=2,<3",
+            "typeguard>=2,<5",
             "astor==0.8.1",
             "numpy>=1,<2",
             'mypy==1.5.1;python_version>="3.8"',
             'black==23.9.1;python_version>="3.8"',
-            'deal==4.23.3;python_version>="3.8"',
+            'deal>=4,<5;python_version>="3.8"',
             'asyncstdlib==3.9.1;python_version>="3.8"',
         ]
     },


Test patch:
diff --git a/tests/test_typeguard.py b/tests/test_typeguard.py
index b6f37f9..9aaf5b9 100644
--- a/tests/test_typeguard.py
+++ b/tests/test_typeguard.py
@@ -14,8 +14,8 @@
 
 class TestPrecondition(unittest.TestCase):
     def test_both_precondition_and_typeguard_ok(self) -> None:
-        @typeguard.typechecked
         @icontract.require(lambda x: x > 0)
+        @typeguard.typechecked
         def some_func(x: int) -> None:
             pass
 
@@ -30,24 +30,23 @@ class B:
             def is_ok(self) -> bool:
                 return True
 
-        @typeguard.typechecked
         @icontract.require(lambda x: x.is_ok())
+        @typeguard.typechecked
         def some_func(x: A) -> None:
             pass
 
         b = B()
-        type_error = None  # type: Optional[TypeError]
+        type_check_error = None  # type: Optional[typeguard.TypeCheckError]
         try:
             some_func(b)  # type: ignore
-        except TypeError as err:
-            type_error = err
+        except typeguard.TypeCheckError as err:
+            type_check_error = err
 
-        expected = 'type of argument "x" must be '
-        self.assertEqual(expected, str(type_error)[: len(expected)])
+        self.assertIsNotNone(type_check_error)
 
     def test_precondition_fails_and_typeguard_ok(self) -> None:
-        @typeguard.typechecked
         @icontract.require(lambda x: x > 0)
+        @typeguard.typechecked
         def some_func(x: int) -> None:
             pass
 
@@ -65,8 +64,8 @@ def some_func(x: int) -> None:
 
 class TestInvariant(unittest.TestCase):
     def test_both_invariant_and_typeguard_ok(self) -> None:
-        @typeguard.typechecked
         @icontract.invariant(lambda self: self.x > 0)
+        @typeguard.typechecked
         class A:
             def __init__(self, x: int) -> None:
                 self.x = x
@@ -86,26 +85,25 @@ class B:
             def is_ok(self) -> bool:
                 return True
 
-        @typeguard.typechecked
         @icontract.invariant(lambda self: self.x.is_ok())
+        @typeguard.typechecked
         class C:
             def __init__(self, a: A) -> None:
                 self.a = a
 
         b = B()
 
-        type_error = None  # type: Optional[TypeError]
+        type_check_error = None  # type: Optional[typeguard.TypeCheckError]
         try:
             _ = C(a=b)  # type: ignore
-        except TypeError as err:
-            type_error = err
+        except typeguard.TypeCheckError as err:
+            type_check_error = err
 
-        expected = 'type of argument "a" must be '
-        self.assertEqual(expected, str(type_error)[: len(expected)])
+        self.assertIsNotNone(type_check_error)
 
     def test_invariant_fails_and_typeguard_ok(self) -> None:
-        @typeguard.typechecked
         @icontract.invariant(lambda self: self.x > 0)
+        @typeguard.typechecked
         class A:
             def __init__(self, x: int) -> None:
                 self.x = x
@@ -133,8 +131,8 @@ def __repr__(self) -> str:
 
 class TestInheritance(unittest.TestCase):
     def test_both_invariant_and_typeguard_ok(self) -> None:
-        @typeguard.typechecked
         @icontract.invariant(lambda self: self.x > 0)
+        @typeguard.typechecked
         class A(icontract.DBC):
             def __init__(self, x: int) -> None:
                 self.x = x
@@ -157,8 +155,8 @@ class B:
             def is_ok(self) -> bool:
                 return True
 
-        @typeguard.typechecked
         @icontract.invariant(lambda self: self.x.is_ok())
+        @typeguard.typechecked
         class C(icontract.DBC):
             def __init__(self, a: A) -> None:
                 self.a = a
@@ -168,20 +166,17 @@ class D(C):
 
         b = B()
 
-        type_error = None  # type: Optional[TypeError]
+        type_check_error = None  # type: Optional[typeguard.TypeCheckError]
         try:
             _ = D(a=b)  # type: ignore
-        except TypeError as err:
-            type_error = err
-
-        self.assertIsNotNone(type_error)
+        except typeguard.TypeCheckError as err:
+            type_check_error = err
 
-        expected = 'type of argument "a" must be '
-        self.assertEqual(expected, str(type_error)[: len(expected)])
+        self.assertIsNotNone(type_check_error)
 
     def test_invariant_fails_and_typeguard_ok(self) -> None:
-        @typeguard.typechecked
         @icontract.invariant(lambda self: self.x > 0)
+        @typeguard.typechecked
         class A:
             def __init__(self, x: int) -> None:
                 self.x = x