copyable 0.0.0.dev0__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.
- {copyable-0.0.0.dev0/src/copyable.egg-info → copyable-0.0.0.dev2}/PKG-INFO +4 -2
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/pyproject.toml +6 -3
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/src/copyable/__init__.py +0 -3
- copyable-0.0.0.dev2/src/copyable/core/__init__.py +16 -0
- copyable-0.0.0.dev2/src/copyable/tests/test_0.py +60 -0
- copyable-0.0.0.dev2/src/copyable/tests/test_1.py +43 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2/src/copyable.egg-info}/PKG-INFO +4 -2
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/src/copyable.egg-info/SOURCES.txt +3 -2
- copyable-0.0.0.dev2/src/copyable.egg-info/requires.txt +1 -0
- copyable-0.0.0.dev0/src/copyable/__main__.py +0 -4
- copyable-0.0.0.dev0/src/copyable/core/__init__.py +0 -8
- copyable-0.0.0.dev0/src/copyable/tests/test_1984.py +0 -11
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/LICENSE.txt +0 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/MANIFEST.in +0 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/README.rst +0 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/setup.cfg +0 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/src/copyable/tests/__init__.py +0 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/src/copyable.egg-info/dependency_links.txt +0 -0
- {copyable-0.0.0.dev0 → copyable-0.0.0.dev2}/src/copyable.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: copyable
|
|
3
|
-
Version: 0.0.0.
|
|
4
|
-
Summary: copyable
|
|
3
|
+
Version: 0.0.0.dev2
|
|
4
|
+
Summary: This project provides a copyable ABC.
|
|
5
5
|
Author-email: Johannes <johannes.programming@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
7
7
|
|
|
@@ -27,6 +27,7 @@ License: The MIT License (MIT)
|
|
|
27
27
|
Project-URL: Download, https://pypi.org/project/copyable/#files
|
|
28
28
|
Project-URL: Index, https://pypi.org/project/copyable/
|
|
29
29
|
Project-URL: Source, https://github.com/johannes-programming/copyable/
|
|
30
|
+
Project-URL: Website, https://copyable.johannes-programming.online/
|
|
30
31
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
31
32
|
Classifier: License :: OSI Approved :: MIT License
|
|
32
33
|
Classifier: Natural Language :: English
|
|
@@ -38,6 +39,7 @@ Classifier: Typing :: Typed
|
|
|
38
39
|
Requires-Python: >=3.11
|
|
39
40
|
Description-Content-Type: text/x-rst
|
|
40
41
|
License-File: LICENSE.txt
|
|
42
|
+
Requires-Dist: setdoc<2,>=1.2.7
|
|
41
43
|
Dynamic: license-file
|
|
42
44
|
|
|
43
45
|
========
|
|
@@ -18,13 +18,15 @@ classifiers = [
|
|
|
18
18
|
"Programming Language :: Python :: 3 :: Only",
|
|
19
19
|
"Typing :: Typed",
|
|
20
20
|
]
|
|
21
|
-
dependencies = [
|
|
22
|
-
|
|
21
|
+
dependencies = [
|
|
22
|
+
"setdoc>=1.2.7,<2",
|
|
23
|
+
]
|
|
24
|
+
description = "This project provides a copyable ABC."
|
|
23
25
|
keywords = []
|
|
24
26
|
name = "copyable"
|
|
25
27
|
readme = "README.rst"
|
|
26
28
|
requires-python = ">=3.11"
|
|
27
|
-
version = "0.0.0.
|
|
29
|
+
version = "0.0.0.dev2"
|
|
28
30
|
|
|
29
31
|
[project.license]
|
|
30
32
|
file = "LICENSE.txt"
|
|
@@ -33,3 +35,4 @@ file = "LICENSE.txt"
|
|
|
33
35
|
Download = "https://pypi.org/project/copyable/#files"
|
|
34
36
|
Index = "https://pypi.org/project/copyable/"
|
|
35
37
|
Source = "https://github.com/johannes-programming/copyable/"
|
|
38
|
+
Website = "https://copyable.johannes-programming.online/"
|
|
@@ -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,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: copyable
|
|
3
|
-
Version: 0.0.0.
|
|
4
|
-
Summary: copyable
|
|
3
|
+
Version: 0.0.0.dev2
|
|
4
|
+
Summary: This project provides a copyable ABC.
|
|
5
5
|
Author-email: Johannes <johannes.programming@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
7
7
|
|
|
@@ -27,6 +27,7 @@ License: The MIT License (MIT)
|
|
|
27
27
|
Project-URL: Download, https://pypi.org/project/copyable/#files
|
|
28
28
|
Project-URL: Index, https://pypi.org/project/copyable/
|
|
29
29
|
Project-URL: Source, https://github.com/johannes-programming/copyable/
|
|
30
|
+
Project-URL: Website, https://copyable.johannes-programming.online/
|
|
30
31
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
31
32
|
Classifier: License :: OSI Approved :: MIT License
|
|
32
33
|
Classifier: Natural Language :: English
|
|
@@ -38,6 +39,7 @@ Classifier: Typing :: Typed
|
|
|
38
39
|
Requires-Python: >=3.11
|
|
39
40
|
Description-Content-Type: text/x-rst
|
|
40
41
|
License-File: LICENSE.txt
|
|
42
|
+
Requires-Dist: setdoc<2,>=1.2.7
|
|
41
43
|
Dynamic: license-file
|
|
42
44
|
|
|
43
45
|
========
|
|
@@ -4,11 +4,12 @@ README.rst
|
|
|
4
4
|
pyproject.toml
|
|
5
5
|
setup.cfg
|
|
6
6
|
src/copyable/__init__.py
|
|
7
|
-
src/copyable/__main__.py
|
|
8
7
|
src/copyable.egg-info/PKG-INFO
|
|
9
8
|
src/copyable.egg-info/SOURCES.txt
|
|
10
9
|
src/copyable.egg-info/dependency_links.txt
|
|
10
|
+
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/
|
|
14
|
+
src/copyable/tests/test_0.py
|
|
15
|
+
src/copyable/tests/test_1.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
setdoc<2,>=1.2.7
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|