copyable 0.0.0.dev1__tar.gz → 0.0.0.dev2__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: copyable
3
- Version: 0.0.0.dev1
3
+ Version: 0.0.0.dev2
4
4
  Summary: This project provides a copyable ABC.
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -26,7 +26,7 @@ keywords = []
26
26
  name = "copyable"
27
27
  readme = "README.rst"
28
28
  requires-python = ">=3.11"
29
- version = "0.0.0.dev1"
29
+ version = "0.0.0.dev2"
30
30
 
31
31
  [project.license]
32
32
  file = "LICENSE.txt"
@@ -1,5 +1,2 @@
1
1
  from copyable.core import *
2
2
  from copyable.tests import *
3
-
4
- if __name__ == "__main__":
5
- main()
@@ -9,6 +9,8 @@ __all__ = ["Copyable"]
9
9
  class Copyable(ABC):
10
10
  __slots__ = ()
11
11
 
12
+ __hash__ = None
13
+
12
14
  @abstractmethod
13
15
  @setdoc.basic
14
16
  def copy(self: Self) -> Self: ...
@@ -0,0 +1,60 @@
1
+ import inspect
2
+ import unittest
3
+ from abc import ABCMeta
4
+ from typing import *
5
+
6
+ from copyable.core import Copyable
7
+
8
+
9
+ class TestCopyable(unittest.TestCase):
10
+ def test_is_abstract(self: Self) -> None:
11
+ # Copyable must be an abstract base class and not directly instantiable.
12
+ self.assertIsInstance(Copyable, ABCMeta)
13
+ with self.assertRaises(TypeError):
14
+ Copyable() # type: ignore[abstract]
15
+
16
+ def test_slots_hash_and_abstractmethod(self: Self) -> None:
17
+ copy_attr: Any
18
+ # __slots__ is explicitly empty and __hash__ disabled.
19
+ self.assertTrue(hasattr(Copyable, "__slots__"))
20
+ self.assertEqual(getattr(Copyable, "__slots__"), ())
21
+ self.assertIsNone(getattr(Copyable, "__hash__"))
22
+
23
+ # "copy" exists and is marked abstract.
24
+ self.assertTrue(hasattr(Copyable, "copy"))
25
+ copy_attr = getattr(Copyable, "copy")
26
+ self.assertTrue(getattr(copy_attr, "__isabstractmethod__", False))
27
+
28
+ def test_copy_signature_and_annotations(self: Self) -> None:
29
+ # Ensure there's a "copy" method and it has type hints present.
30
+ # Note: runtime "Self" may or may not resolve depending on Python version;
31
+ # we just verify annotations are present and consistent.
32
+ hints: dict[str, Any]
33
+ sig: inspect.Signature
34
+ params: list[inspect.Parameter]
35
+ self.assertTrue(callable(getattr(Copyable, "copy")))
36
+ hints = get_type_hints(Copyable.copy, include_extras=True)
37
+ self.assertIn("return", hints)
38
+
39
+ sig = inspect.signature(Copyable.copy)
40
+ params = list(sig.parameters.values())
41
+ self.assertEqual(len(params), 1)
42
+ self.assertEqual(params[0].name, "self")
43
+
44
+ def test_subclass_must_implement_copy(self: Self) -> None:
45
+ class Bad(Copyable):
46
+ pass
47
+
48
+ class Good(Copyable):
49
+ def copy(self: Self) -> Self:
50
+ return self
51
+
52
+ g: Good
53
+ with self.assertRaises(TypeError):
54
+ Bad() # still abstract
55
+ g = Good()
56
+ self.assertIs(g.copy(), g)
57
+
58
+
59
+ if __name__ == "__main__":
60
+ unittest.main()
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ import unittest
4
+ from typing import *
5
+
6
+ from copyable.core import Copyable
7
+
8
+
9
+ class TestCopyable(unittest.TestCase):
10
+ def test_copyable_cannot_be_instantiated(self: Self) -> None:
11
+ with self.assertRaises(TypeError):
12
+ Copyable() # abstract
13
+
14
+ def test_subclass_without_copy_is_abstract(self: Self) -> None:
15
+ class Bad(Copyable):
16
+ pass
17
+
18
+ with self.assertRaises(TypeError):
19
+ Bad()
20
+
21
+ def test_copy_returns_same_type_and_new_instance(self: Self) -> None:
22
+ class Point(Copyable):
23
+ __slots__ = ("x", "y")
24
+
25
+ def __init__(self: Self, x: int, y: int) -> None:
26
+ self.x = x
27
+ self.y = y
28
+
29
+ def copy(self: Self) -> Self:
30
+ return type(self)(self.x, self.y)
31
+
32
+ p: Point
33
+ c: Point
34
+ p = Point(1, 2)
35
+ c = p.copy()
36
+
37
+ self.assertIsInstance(c, Point)
38
+ self.assertIsNot(c, p)
39
+ self.assertEqual((c.x, c.y), (p.x, p.y))
40
+
41
+
42
+ if __name__ == "__main__":
43
+ unittest.main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copyable
3
- Version: 0.0.0.dev1
3
+ Version: 0.0.0.dev2
4
4
  Summary: This project provides a copyable ABC.
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -11,4 +11,5 @@ src/copyable.egg-info/requires.txt
11
11
  src/copyable.egg-info/top_level.txt
12
12
  src/copyable/core/__init__.py
13
13
  src/copyable/tests/__init__.py
14
- src/copyable/tests/test_1984.py
14
+ src/copyable/tests/test_0.py
15
+ src/copyable/tests/test_1.py
@@ -1,11 +0,0 @@
1
- import unittest
2
- from typing import *
3
-
4
-
5
- class Test1984(unittest.TestCase):
6
- def test_1984(self: Self) -> None:
7
- self.assertEqual(2 + 2, 4, "Ignorance is Strength")
8
-
9
-
10
- if __name__ == "__main__":
11
- unittest.main()
File without changes
File without changes
File without changes
File without changes