zstdlib 0.0.3__tar.gz → 0.0.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.
Files changed (28) hide show
  1. {zstdlib-0.0.3/zstdlib.egg-info → zstdlib-0.0.5}/PKG-INFO +1 -1
  2. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/test_frozen.py +32 -0
  3. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/__init__.py +1 -1
  4. zstdlib-0.0.5/zstdlib/frozen.py +97 -0
  5. {zstdlib-0.0.3 → zstdlib-0.0.5/zstdlib.egg-info}/PKG-INFO +1 -1
  6. zstdlib-0.0.3/zstdlib/frozen.py +0 -65
  7. {zstdlib-0.0.3 → zstdlib-0.0.5}/LICENSE +0 -0
  8. {zstdlib-0.0.3 → zstdlib-0.0.5}/README.md +0 -0
  9. {zstdlib-0.0.3 → zstdlib-0.0.5}/pyproject.toml +0 -0
  10. {zstdlib-0.0.3 → zstdlib-0.0.5}/setup.cfg +0 -0
  11. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/__init__.py +0 -0
  12. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/log/__init__.py +0 -0
  13. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/log/base.py +0 -0
  14. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/log/test_cute.py +0 -0
  15. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/log/test_trace.py +0 -0
  16. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/test_ansi.py +0 -0
  17. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/test_enum.py +0 -0
  18. {zstdlib-0.0.3 → zstdlib-0.0.5}/tests/test_singleton.py +0 -0
  19. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/ansi.py +0 -0
  20. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/enum.py +0 -0
  21. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/log/__init__.py +0 -0
  22. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/log/cute.py +0 -0
  23. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/log/trace.py +0 -0
  24. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/py.typed +0 -0
  25. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib/singleton.py +0 -0
  26. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib.egg-info/SOURCES.txt +0 -0
  27. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib.egg-info/dependency_links.txt +0 -0
  28. {zstdlib-0.0.3 → zstdlib-0.0.5}/zstdlib.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zstdlib
3
- Version: 0.0.3
3
+ Version: 0.0.5
4
4
  Summary: A set of useful python utilities
5
5
  License: GPLv3
6
6
  Project-URL: Homepage, https://github.com/zwimer/zstdlib
@@ -75,6 +75,38 @@ class TestFrozen(unittest.TestCase):
75
75
  with self.assertRaises(AttributeError):
76
76
  del f1.a
77
77
 
78
+ def test_metadata(self):
79
+ @frozen
80
+ class F2:
81
+ def __init__(self, a: int = 1, *, b: bool = False) -> None:
82
+ """
83
+ init doc
84
+ """
85
+
86
+ f2 = F2()
87
+ self.assertEqual(f2.__init__.__doc__.strip(), "init doc")
88
+ self.assertEqual(f2.__init__.__name__, "__init__")
89
+ self.assertEqual(f2.__init__.__qualname__, "TestFrozen.test_metadata.<locals>.F2.__init__")
90
+ self.assertTupleEqual(f2.__init__.__defaults__, (1,))
91
+ self.assertDictEqual(f2.__init__.__kwdefaults__, {"b": False})
92
+ self.assertDictEqual(f2.__init__.__annotations__, {"a": int, "b": bool, "return": None})
93
+
94
+ def test_frozen_custom(self):
95
+ @frozen("custom")
96
+ class F3:
97
+ def __init__(self):
98
+ self.a = 1
99
+
100
+ def custom(self):
101
+ self.a = 2
102
+
103
+ f3 = F3()
104
+ self.assertEqual(f3.a, 1)
105
+ f3.custom()
106
+ self.assertEqual(f3.a, 2)
107
+ with self.assertRaises(AttributeError):
108
+ f3.a = 1
109
+
78
110
 
79
111
  if __name__ == "__main__":
80
112
  unittest.main()
@@ -1,4 +1,4 @@
1
- __version__ = "0.0.3"
1
+ __version__ = "0.0.5"
2
2
 
3
3
  from .frozen import Freezable, frozen
4
4
  from .singleton import Singleton
@@ -0,0 +1,97 @@
1
+ from collections.abc import Callable
2
+
3
+
4
+ _FN_ATTRS = (
5
+ "__annotations__",
6
+ "__type_params__",
7
+ "__qualname__",
8
+ "__module__",
9
+ "__name__",
10
+ "__doc__",
11
+ "__defaults__",
12
+ "__kwdefaults__",
13
+ )
14
+
15
+
16
+ class Freezable:
17
+ """
18
+ A base class for objects that can be frozen
19
+ """
20
+
21
+ def __init__(self, *args, **kwargs) -> None:
22
+ super().__init__(*args, **kwargs) # For MRO super classes
23
+ if hasattr(self, "_frozen") or hasattr(self, "_can_thaw"):
24
+ raise ValueError("Base class defines _frozen or _can_thaw")
25
+ self._can_thaw: bool = True
26
+ self._frozen: bool = False
27
+
28
+ def freeze(self, *, permanent: bool = False):
29
+ """
30
+ Prevent further modifications to this object
31
+ """
32
+ if permanent:
33
+ self._can_thaw = False
34
+ self._frozen = True
35
+
36
+ def thaw(self):
37
+ """
38
+ Allow modifications to this object
39
+ """
40
+ if not self._can_thaw:
41
+ raise RuntimeError("Cannot thaw permanently frozen object")
42
+ object.__setattr__(self, "_frozen", False)
43
+
44
+ def __setattr__(self, key: str, value) -> None:
45
+ if getattr(self, "_frozen", False):
46
+ raise AttributeError("Cannot modify frozen object")
47
+ super().__setattr__(key, value)
48
+
49
+ def __delattr__(self, item: str) -> None:
50
+ if getattr(self, "_frozen", False):
51
+ raise AttributeError("Cannot modify frozen object")
52
+ super().__delattr__(item)
53
+
54
+
55
+ def frozen(arg: str | type):
56
+ """
57
+ A class decorator to permanently freeze a class after some method, __init__ by default
58
+ If passed a string, will freeze after the method with that name
59
+ """
60
+
61
+ def shim_method(cls: type, name, new) -> None:
62
+ original = getattr(cls, name)
63
+ for i in _FN_ATTRS:
64
+ if hasattr(original, i):
65
+ setattr(new, i, getattr(original, i))
66
+ setattr(cls, name, new)
67
+
68
+ def mk_frozen(cls: type, method: str) -> type:
69
+ original_method: Callable = getattr(cls, method)
70
+ original_setattr: Callable = cls.__setattr__
71
+ original_delattr: Callable = cls.__delattr__
72
+
73
+ def new_method(self, *args, **kwargs):
74
+ ret = original_method(self, *args, **kwargs)
75
+ # pylint: disable=protected-access
76
+ self._frozen = True # type: ignore[attr-defined]
77
+ return ret
78
+
79
+ def __setattr__(self, key: str, value):
80
+ if getattr(self, "_frozen", False):
81
+ raise AttributeError("Cannot modify frozen object")
82
+ return original_setattr(self, key, value)
83
+
84
+ def __delattr__(self, item: str):
85
+ if getattr(self, "_frozen", False):
86
+ raise AttributeError("Cannot modify frozen object")
87
+ return original_delattr(self, item)
88
+
89
+ # Update cls with the new methods
90
+ shim_method(cls, method, new_method)
91
+ shim_method(cls, "__delattr__", __delattr__)
92
+ shim_method(cls, "__setattr__", __setattr__)
93
+ return cls
94
+
95
+ if isinstance(arg, str):
96
+ return lambda cls: mk_frozen(cls, arg)
97
+ return mk_frozen(arg, "__init__")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zstdlib
3
- Version: 0.0.3
3
+ Version: 0.0.5
4
4
  Summary: A set of useful python utilities
5
5
  License: GPLv3
6
6
  Project-URL: Homepage, https://github.com/zwimer/zstdlib
@@ -1,65 +0,0 @@
1
- class Freezable:
2
- """
3
- A base class for objects that can be frozen
4
- """
5
-
6
- def __init__(self, *args, **kwargs) -> None:
7
- super().__init__(*args, **kwargs) # For MRO super classes
8
- if hasattr(self, "_frozen") or hasattr(self, "_can_thaw"):
9
- raise ValueError("Base class defines _frozen or _can_thaw")
10
- self._can_thaw: bool = True
11
- self._frozen: bool = False
12
-
13
- def freeze(self, *, permanent: bool = False):
14
- """
15
- Prevent further modifications to this object
16
- """
17
- if permanent:
18
- self._can_thaw = False
19
- self._frozen = True
20
-
21
- def thaw(self):
22
- """
23
- Allow modifications to this object
24
- """
25
- if not self._can_thaw:
26
- raise RuntimeError("Cannot thaw permanently frozen object")
27
- object.__setattr__(self, "_frozen", False)
28
-
29
- def __setattr__(self, key: str, value) -> None:
30
- if getattr(self, "_frozen", False):
31
- raise AttributeError("Cannot modify frozen object")
32
- super().__setattr__(key, value)
33
-
34
- def __delattr__(self, item: str) -> None:
35
- if getattr(self, "_frozen", False):
36
- raise AttributeError("Cannot modify frozen object")
37
- super().__delattr__(item)
38
-
39
-
40
- def frozen(cls):
41
- """
42
- A class decorator to permanently freeze a class after __init__
43
- """
44
-
45
- def __setattr__(self, key: str, value) -> None:
46
- if getattr(self, "_frozen", False):
47
- raise AttributeError("Cannot modify frozen object")
48
- super(cls, self).__setattr__(key, value)
49
-
50
- def __delattr__(self, item: str) -> None:
51
- if getattr(self, "_frozen", False):
52
- raise AttributeError("Cannot modify frozen object")
53
- super(cls, self).__delattr__(item)
54
-
55
- init = cls.__init__
56
-
57
- def __init__(self, *args, **kwargs):
58
- init(self, *args, **kwargs)
59
- self._frozen = True # pylint: disable=protected-access
60
-
61
- # Update cls with the new methods
62
- cls.__setattr__ = __setattr__
63
- cls.__delattr__ = __delattr__
64
- cls.__init__ = __init__
65
- return cls
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes