cmp3 0.6.3__tar.gz → 0.6.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cmp3
3
- Version: 0.6.3
3
+ Version: 0.6.5
4
4
  Summary: This project updates the concept of __cmp__ for python3.
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -26,7 +26,7 @@ keywords = []
26
26
  name = "cmp3"
27
27
  readme = "README.rst"
28
28
  requires-python = ">=3.11"
29
- version = "0.6.3"
29
+ version = "0.6.5"
30
30
 
31
31
  [project.license]
32
32
  file = "LICENSE.txt"
@@ -0,0 +1,68 @@
1
+ import unittest
2
+ from typing import *
3
+
4
+ from cmp3.core import CmpABC, cmpDeco
5
+
6
+ __all__ = ["TestCmpABCAndDeco"]
7
+
8
+
9
+ # A concrete implementation of CmpABC for testing
10
+ class Box(CmpABC):
11
+ def __init__(self: Self, value: Any) -> None:
12
+ self.value = value
13
+
14
+ def __cmp__(self: Self, other: Any) -> Any:
15
+ if not isinstance(other, Box):
16
+ return NotImplemented
17
+ return (self.value > other.value) - (self.value < other.value)
18
+
19
+
20
+ @cmpDeco
21
+ class DecoratedBox:
22
+ def __init__(self: Self, value: Any) -> None:
23
+ self.value = value
24
+
25
+ def __cmp__(self: Self, other: Any) -> Any:
26
+ if not isinstance(other, DecoratedBox):
27
+ return NotImplemented
28
+ return (self.value > other.value) - (self.value < other.value)
29
+
30
+
31
+ class TestCmpABCAndDeco(unittest.TestCase):
32
+ def test_cmpabc_is_abstract(self: Self) -> None:
33
+ with self.assertRaises(TypeError):
34
+ CmpABC() # type: ignore[abstract] # must not be instantiable
35
+
36
+ def test_cmpabc_comparisons(self: Self) -> None:
37
+ a: Box
38
+ b: Box
39
+ c: Box
40
+ a = Box(1)
41
+ b = Box(2)
42
+ c = Box(1)
43
+
44
+ self.assertTrue(a < b)
45
+ self.assertTrue(a <= b)
46
+ self.assertTrue(b > a)
47
+ self.assertTrue(b >= a)
48
+ self.assertTrue(a == c)
49
+ self.assertTrue(a != b)
50
+
51
+ def test_cmpdeco_on_regular_class(self: Self) -> None:
52
+ x: DecoratedBox
53
+ y: DecoratedBox
54
+ z: DecoratedBox
55
+ x = DecoratedBox(10)
56
+ y = DecoratedBox(20)
57
+ z = DecoratedBox(10)
58
+
59
+ self.assertTrue(x < y)
60
+ self.assertTrue(x <= y)
61
+ self.assertTrue(y > x)
62
+ self.assertTrue(y >= x)
63
+ self.assertTrue(x == z)
64
+ self.assertTrue(x != y)
65
+
66
+
67
+ if __name__ == "__main__":
68
+ unittest.main()
@@ -0,0 +1,34 @@
1
+ import unittest
2
+ from typing import *
3
+
4
+ from cmp3.core import cmp
5
+
6
+ __all__ = ["TestCmpFunction"]
7
+
8
+
9
+ class TestCmpFunction(unittest.TestCase):
10
+ def test_portingguide_less(self: Self) -> None:
11
+ self.assertEqual(cmp(1, 2), -1)
12
+ self.assertEqual(cmp(-5, -1), -1)
13
+
14
+ def test_portingguide_equal(self: Self) -> None:
15
+ self.assertEqual(cmp(3, 3), 0)
16
+ self.assertEqual(cmp("a", "a"), 0)
17
+
18
+ def test_portingguide_greater(self: Self) -> None:
19
+ self.assertEqual(cmp(2, 1), 1)
20
+ self.assertEqual(cmp("b", "a"), 1)
21
+
22
+ def test_poset_mode_uses_poset_semantics(self: Self) -> None:
23
+ # For totally ordered ints, this should behave like normal cmp
24
+ self.assertEqual(cmp(1, 2, mode="poset"), -1)
25
+ self.assertEqual(cmp(2, 1, mode="poset"), 1)
26
+ self.assertEqual(cmp(5, 5, mode="poset"), 0)
27
+
28
+ def test_invalid_mode_raises(self: Self) -> None:
29
+ with self.assertRaises(ValueError):
30
+ cmp(1, 2, mode="something-else")
31
+
32
+
33
+ if __name__ == "__main__":
34
+ unittest.main()
@@ -0,0 +1,33 @@
1
+ import math
2
+ import unittest
3
+ from typing import *
4
+
5
+ from cmp3.core import cmp_poset
6
+
7
+ __all__ = ["TestCmpPoset"]
8
+
9
+
10
+ class TestCmpPoset(unittest.TestCase):
11
+ def test_total_order_ints(self: Self) -> None:
12
+ self.assertEqual(cmp_poset(1, 2), -1)
13
+ self.assertEqual(cmp_poset(2, 1), 1)
14
+ self.assertEqual(cmp_poset(3, 3), 0)
15
+
16
+ def test_incomparable_returns_nan(self: Self) -> None:
17
+ class Incomparable:
18
+ def __le__(self: Self, other: Any) -> bool:
19
+ # Always False, so no order relation is established
20
+ return False
21
+
22
+ result: Any
23
+ x: Incomparable
24
+ y: Incomparable
25
+
26
+ x = Incomparable()
27
+ y = Incomparable()
28
+ result = cmp_poset(x, y)
29
+ self.assertTrue(math.isnan(result))
30
+
31
+
32
+ if __name__ == "__main__":
33
+ unittest.main()
@@ -0,0 +1,54 @@
1
+ import unittest
2
+ from typing import *
3
+
4
+ import setdoc
5
+
6
+ from cmp3 import core
7
+
8
+ __all__ = ["TestCmpDecoAndCmpABC"]
9
+
10
+
11
+ class Number(core.CmpABC):
12
+ @setdoc.basic
13
+ def __cmp__(self: Self, other: Any) -> Any:
14
+ if not isinstance(other, Number):
15
+ return NotImplemented
16
+ # classic 3-way comparison
17
+ return (self.value > other.value) - (self.value < other.value)
18
+
19
+ @setdoc.basic
20
+ def __init__(self: Self, value: int) -> None:
21
+ self.value = value
22
+
23
+
24
+ class TestCmpDecoAndCmpABC(unittest.TestCase):
25
+ def setUp(self: Self) -> None:
26
+ self.a = Number(1)
27
+ self.b = Number(2)
28
+ self.c = Number(1)
29
+
30
+ def test_eq_ne(self: Self) -> None:
31
+ self.assertTrue(self.a == self.c)
32
+ self.assertFalse(self.a == self.b)
33
+ self.assertTrue(self.a != self.b)
34
+ self.assertFalse(self.a != self.c)
35
+
36
+ def test_lt_le(self: Self) -> None:
37
+ self.assertTrue(self.a < self.b)
38
+ self.assertTrue(self.a <= self.b)
39
+ self.assertTrue(self.a <= self.c)
40
+ self.assertFalse(self.b < self.a)
41
+
42
+ def test_gt_ge(self: Self) -> None:
43
+ self.assertTrue(self.b > self.a)
44
+ self.assertTrue(self.b >= self.a)
45
+ self.assertTrue(self.b >= self.c)
46
+ self.assertFalse(self.a > self.b)
47
+
48
+ def test_cmpabc_is_abstract(self: Self) -> None:
49
+ with self.assertRaises(TypeError):
50
+ core.CmpABC() # abstract, cannot be instantiated
51
+
52
+
53
+ if __name__ == "__main__":
54
+ unittest.main()
@@ -0,0 +1,35 @@
1
+ import unittest
2
+ from typing import *
3
+
4
+ from cmp3 import core
5
+
6
+ __all__ = ["TestCmpDecoOnPlainClass"]
7
+
8
+
9
+ class TestCmpDecoOnPlainClass(unittest.TestCase):
10
+ def test_decorator_on_non_abc_class(self: Self) -> None:
11
+ @core.cmpDeco
12
+ class Plain:
13
+ def __init__(self: Self, x: int) -> None:
14
+ self.x = x
15
+
16
+ def __cmp__(self: Self, other: Any) -> Any:
17
+ if not isinstance(other, Plain):
18
+ return NotImplemented
19
+ return (self.x > other.x) - (self.x < other.x)
20
+
21
+ p1: Plain
22
+ p2: Plain
23
+ p3: Plain
24
+ p1 = Plain(1)
25
+ p2 = Plain(2)
26
+ p3 = Plain(1)
27
+
28
+ self.assertTrue(p1 < p2)
29
+ self.assertTrue(p2 > p1)
30
+ self.assertTrue(p1 == p3)
31
+ self.assertTrue(p1 != p2)
32
+
33
+
34
+ if __name__ == "__main__":
35
+ unittest.main()
@@ -0,0 +1,18 @@
1
+ import math
2
+ import unittest
3
+ from typing import *
4
+
5
+ from cmp3 import core
6
+
7
+ __all__ = ["TestCmpModePoset"]
8
+
9
+
10
+ class TestCmpModePoset(unittest.TestCase):
11
+ def test_cmp_uses_poset_mode(self: Self) -> None:
12
+ self.assertEqual(core.cmp({1}, {1, 2}, mode="poset"), -1)
13
+ self.assertEqual(core.cmp({1, 2}, {1}, mode="poset"), 1)
14
+ self.assertTrue(math.isnan(core.cmp({1}, {2}, mode="poset")))
15
+
16
+
17
+ if __name__ == "__main__":
18
+ unittest.main()
@@ -0,0 +1,28 @@
1
+ import unittest
2
+ from typing import *
3
+
4
+ from cmp3 import core
5
+
6
+ __all__ = ["TestCmpPortingGuide"]
7
+
8
+
9
+ class TestCmpPortingGuide(unittest.TestCase):
10
+ def test_equal(self: Self) -> None:
11
+ self.assertEqual(core.cmp(1, 1), 0)
12
+ self.assertEqual(core.cmp("a", "a"), 0)
13
+
14
+ def test_less(self: Self) -> None:
15
+ self.assertEqual(core.cmp(1, 2), -1)
16
+ self.assertEqual(core.cmp("a", "b"), -1)
17
+
18
+ def test_greater(self: Self) -> None:
19
+ self.assertEqual(core.cmp(2, 1), 1)
20
+ self.assertEqual(core.cmp("b", "a"), 1)
21
+
22
+ def test_invalid_mode_raises(self: Self) -> None:
23
+ with self.assertRaises(ValueError):
24
+ core.cmp(1, 2, mode="invalid-mode")
25
+
26
+
27
+ if __name__ == "__main__":
28
+ unittest.main()
@@ -0,0 +1,31 @@
1
+ import math
2
+ import unittest
3
+ from typing import *
4
+
5
+ from cmp3 import core
6
+
7
+ __all__ = ["TestCmpPoset"]
8
+
9
+
10
+ class TestCmpPoset(unittest.TestCase):
11
+ def test_poset_equal(self: Self) -> None:
12
+ # subset ordering: same set
13
+ self.assertEqual(core.cmp_poset({1, 2}, {1, 2}), 0)
14
+
15
+ def test_poset_less(self: Self) -> None:
16
+ # subset ordering: strict subset
17
+ self.assertEqual(core.cmp_poset({1}, {1, 2}), -1)
18
+
19
+ def test_poset_greater(self: Self) -> None:
20
+ # subset ordering: strict superset
21
+ self.assertEqual(core.cmp_poset({1, 2}, {1}), 1)
22
+
23
+ def test_poset_incomparable(self: Self) -> None:
24
+ # incomparable in subset ordering
25
+ res: Any
26
+ res = core.cmp_poset({1}, {2})
27
+ self.assertTrue(math.isnan(res))
28
+
29
+
30
+ if __name__ == "__main__":
31
+ unittest.main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cmp3
3
- Version: 0.6.3
3
+ Version: 0.6.5
4
4
  Summary: This project updates the concept of __cmp__ for python3.
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -0,0 +1,21 @@
1
+ LICENSE.txt
2
+ MANIFEST.in
3
+ README.rst
4
+ pyproject.toml
5
+ setup.cfg
6
+ src/cmp3/__init__.py
7
+ src/cmp3.egg-info/PKG-INFO
8
+ src/cmp3.egg-info/SOURCES.txt
9
+ src/cmp3.egg-info/dependency_links.txt
10
+ src/cmp3.egg-info/requires.txt
11
+ src/cmp3.egg-info/top_level.txt
12
+ src/cmp3/core/__init__.py
13
+ src/cmp3/tests/__init__.py
14
+ src/cmp3/tests/test_all_TestCmpABCAndDeco.py
15
+ src/cmp3/tests/test_all_TestCmpFunction.py
16
+ src/cmp3/tests/test_all_TestCmpPoset.py
17
+ src/cmp3/tests/test_core_TestCmpDecoAndCmpABC.py
18
+ src/cmp3/tests/test_core_TestCmpDecoOnPlainClass.py
19
+ src/cmp3/tests/test_core_TestCmpModePoset.py
20
+ src/cmp3/tests/test_core_TestCmpPortingGuide.py
21
+ src/cmp3/tests/test_core_TestCmpPoset.py
@@ -1,118 +0,0 @@
1
- import math
2
- import unittest
3
- from typing import *
4
-
5
- from cmp3 import core
6
-
7
-
8
- class TestCmpPortingGuide(unittest.TestCase):
9
- def test_equal(self: Self) -> None:
10
- self.assertEqual(core.cmp(1, 1), 0)
11
- self.assertEqual(core.cmp("a", "a"), 0)
12
-
13
- def test_less(self: Self) -> None:
14
- self.assertEqual(core.cmp(1, 2), -1)
15
- self.assertEqual(core.cmp("a", "b"), -1)
16
-
17
- def test_greater(self: Self) -> None:
18
- self.assertEqual(core.cmp(2, 1), 1)
19
- self.assertEqual(core.cmp("b", "a"), 1)
20
-
21
- def test_invalid_mode_raises(self: Self) -> None:
22
- with self.assertRaises(ValueError):
23
- core.cmp(1, 2, mode="invalid-mode")
24
-
25
-
26
- class TestCmpPoset(unittest.TestCase):
27
- def test_poset_equal(self: Self) -> None:
28
- # subset ordering: same set
29
- self.assertEqual(core.cmp_poset({1, 2}, {1, 2}), 0)
30
-
31
- def test_poset_less(self: Self) -> None:
32
- # subset ordering: strict subset
33
- self.assertEqual(core.cmp_poset({1}, {1, 2}), -1)
34
-
35
- def test_poset_greater(self: Self) -> None:
36
- # subset ordering: strict superset
37
- self.assertEqual(core.cmp_poset({1, 2}, {1}), 1)
38
-
39
- def test_poset_incomparable(self: Self) -> None:
40
- # incomparable in subset ordering
41
- res = core.cmp_poset({1}, {2})
42
- self.assertTrue(math.isnan(res))
43
-
44
-
45
- class TestCmpModePoset(unittest.TestCase):
46
- def test_cmp_uses_poset_mode(self: Self) -> None:
47
- self.assertEqual(core.cmp({1}, {1, 2}, mode="poset"), -1)
48
- self.assertEqual(core.cmp({1, 2}, {1}, mode="poset"), 1)
49
- self.assertTrue(math.isnan(core.cmp({1}, {2}, mode="poset")))
50
-
51
-
52
- class Number(core.CmpABC):
53
- def __init__(self: Self, value: int) -> None:
54
- self.value = value
55
-
56
- def __cmp__(self: Self, other: Any) -> Any:
57
- if not isinstance(other, Number):
58
- return NotImplemented
59
- # classic 3-way comparison
60
- return (self.value > other.value) - (self.value < other.value)
61
-
62
-
63
- class TestCmpDecoAndCmpABC(unittest.TestCase):
64
- def setUp(self: Self) -> None:
65
- self.a = Number(1)
66
- self.b = Number(2)
67
- self.c = Number(1)
68
-
69
- def test_eq_ne(self: Self) -> None:
70
- self.assertTrue(self.a == self.c)
71
- self.assertFalse(self.a == self.b)
72
- self.assertTrue(self.a != self.b)
73
- self.assertFalse(self.a != self.c)
74
-
75
- def test_lt_le(self: Self) -> None:
76
- self.assertTrue(self.a < self.b)
77
- self.assertTrue(self.a <= self.b)
78
- self.assertTrue(self.a <= self.c)
79
- self.assertFalse(self.b < self.a)
80
-
81
- def test_gt_ge(self: Self) -> None:
82
- self.assertTrue(self.b > self.a)
83
- self.assertTrue(self.b >= self.a)
84
- self.assertTrue(self.b >= self.c)
85
- self.assertFalse(self.a > self.b)
86
-
87
- def test_cmpabc_is_abstract(self: Self) -> None:
88
- with self.assertRaises(TypeError):
89
- core.CmpABC() # abstract, cannot be instantiated
90
-
91
-
92
- class TestCmpDecoOnPlainClass(unittest.TestCase):
93
- def test_decorator_on_non_abc_class(self: Self) -> None:
94
- @core.cmpDeco
95
- class Plain:
96
- def __init__(self: Self, x: int) -> None:
97
- self.x = x
98
-
99
- def __cmp__(self: Self, other: Any) -> Any:
100
- if not isinstance(other, Plain):
101
- return NotImplemented
102
- return (self.x > other.x) - (self.x < other.x)
103
-
104
- p1: Plain
105
- p2: Plain
106
- p3: Plain
107
- p1 = Plain(1)
108
- p2 = Plain(2)
109
- p3 = Plain(1)
110
-
111
- self.assertTrue(p1 < p2)
112
- self.assertTrue(p2 > p1)
113
- self.assertTrue(p1 == p3)
114
- self.assertTrue(p1 != p2)
115
-
116
-
117
- if __name__ == "__main__":
118
- unittest.main()
@@ -1,14 +0,0 @@
1
- LICENSE.txt
2
- MANIFEST.in
3
- README.rst
4
- pyproject.toml
5
- setup.cfg
6
- src/cmp3/__init__.py
7
- src/cmp3.egg-info/PKG-INFO
8
- src/cmp3.egg-info/SOURCES.txt
9
- src/cmp3.egg-info/dependency_links.txt
10
- src/cmp3.egg-info/requires.txt
11
- src/cmp3.egg-info/top_level.txt
12
- src/cmp3/core/__init__.py
13
- src/cmp3/tests/__init__.py
14
- src/cmp3/tests/test_cmp3_core.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes