zstdlib 0.3.2__tar.gz → 0.4.0__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.
- {zstdlib-0.3.2 → zstdlib-0.4.0}/PKG-INFO +1 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/pyproject.toml +2 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/log/base.py +5 -5
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/log/test_cute.py +1 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/test_enum.py +2 -2
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/test_frozen.py +1 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/__init__.py +1 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/ansi.py +2 -3
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/enum.py +3 -3
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/frozen.py +0 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/io.py +7 -16
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/log/cute.py +10 -7
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/log/trace.py +1 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/singleton.py +3 -4
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib.egg-info/PKG-INFO +1 -1
- {zstdlib-0.3.2 → zstdlib-0.4.0}/LICENSE +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/README.md +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/setup.cfg +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/__init__.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/log/__init__.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/log/test_trace.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/not_set.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/test_ansi.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/test_io.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/tests/test_singleton.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/log/__init__.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/not_set.py +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib/py.typed +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib.egg-info/SOURCES.txt +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib.egg-info/dependency_links.txt +0 -0
- {zstdlib-0.3.2 → zstdlib-0.4.0}/zstdlib.egg-info/top_level.txt +0 -0
|
@@ -55,9 +55,10 @@ target-version = ["py314"]
|
|
|
55
55
|
[tool.ruff]
|
|
56
56
|
line-length = 110
|
|
57
57
|
[tool.ruff.lint]
|
|
58
|
-
ignore=["E731"]
|
|
58
|
+
ignore=["E731", "I001"]
|
|
59
59
|
[tool.ruff.lint.per-file-ignores]
|
|
60
60
|
"__init__.py" = ["F401", "F403"]
|
|
61
|
+
"tests/*" = ["DTZ005"]
|
|
61
62
|
|
|
62
63
|
[tool.bandit]
|
|
63
64
|
skips = ["B101", "B104", "B201"]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from logging.handlers import QueueHandler
|
|
2
2
|
from contextlib import contextmanager
|
|
3
3
|
from collections.abc import Callable
|
|
4
|
+
from typing import ClassVar, Any
|
|
4
5
|
from threading import Lock
|
|
5
|
-
from typing import Any
|
|
6
6
|
import logging
|
|
7
7
|
import queue
|
|
8
8
|
|
|
@@ -20,12 +20,12 @@ class LeftBase:
|
|
|
20
20
|
A base class for tests that hijack loggers
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
_hijacked: set[logging.Logger] = set() # Set of all loggers that have ever been hijacked
|
|
24
|
-
_qmap: dict[logging.Logger, queue.Queue[logging.LogRecord]] = {}
|
|
25
|
-
_lb_old: dict[logging.Logger, list[logging.Handler]] = {}
|
|
23
|
+
_hijacked: ClassVar[set[logging.Logger]] = set() # Set of all loggers that have ever been hijacked
|
|
24
|
+
_qmap: ClassVar[dict[logging.Logger, queue.Queue[logging.LogRecord]]] = {}
|
|
25
|
+
_lb_old: ClassVar[dict[logging.Logger, list[logging.Handler]]] = {}
|
|
26
26
|
_lb_lock = Lock()
|
|
27
27
|
|
|
28
|
-
messages: dict[logging.Logger, list[str]] = {}
|
|
28
|
+
messages: ClassVar[dict[logging.Logger, list[str]]] = {}
|
|
29
29
|
|
|
30
30
|
@classmethod
|
|
31
31
|
def hijack(cls, name: str, reuse: bool = False, fmt: logging.Formatter | None = None):
|
|
@@ -106,7 +106,7 @@ class TestCuteFormatter(LeftBase, unittest.TestCase):
|
|
|
106
106
|
try:
|
|
107
107
|
raise ValueError(name)
|
|
108
108
|
except ValueError:
|
|
109
|
-
log.
|
|
109
|
+
log.exception("test")
|
|
110
110
|
spt = self.messages[log][0].split("\n")
|
|
111
111
|
self.assertGreater(len(spt), 2)
|
|
112
112
|
self.assertEqual("Traceback (most recent call last):", spt[1].strip())
|
|
@@ -24,7 +24,7 @@ class TestEnumType(unittest.TestCase):
|
|
|
24
24
|
class ET1(metaclass=EnumType, dupes_ok=True):
|
|
25
25
|
a: int = 5
|
|
26
26
|
b: int = 5
|
|
27
|
-
c: dict = {}
|
|
27
|
+
c: dict = {} # noqa: RUF012
|
|
28
28
|
|
|
29
29
|
with self.assertRaises(ValueError):
|
|
30
30
|
|
|
@@ -35,7 +35,7 @@ class TestEnumType(unittest.TestCase):
|
|
|
35
35
|
with self.assertRaises(TypeError):
|
|
36
36
|
|
|
37
37
|
class ET3(metaclass=EnumType):
|
|
38
|
-
a: dict = {}
|
|
38
|
+
a: dict = {} # noqa: RUF012
|
|
39
39
|
|
|
40
40
|
def test_type_check(self) -> None:
|
|
41
41
|
class ET1(metaclass=EnumType, type_check=set()):
|
|
@@ -108,7 +108,7 @@ class TestFrozen(unittest.TestCase):
|
|
|
108
108
|
self.assertEqual(f1.__init__.__qualname__, "TestFrozen.test_metadata.<locals>.F1.__init__")
|
|
109
109
|
self.assertTupleEqual(f1.__init__.__defaults__, (1,))
|
|
110
110
|
self.assertDictEqual(f1.__init__.__kwdefaults__, {"b": False})
|
|
111
|
-
if version_info
|
|
111
|
+
if version_info < (3, 13, 0.1) or hasattr(f1.__init__, "__annotations__"):
|
|
112
112
|
self.assertDictEqual(f1.__init__.__annotations__, {"a": int, "b": bool, "return": None})
|
|
113
113
|
else: # annotations changed in 3.14, .__annotations__ *might* not exist
|
|
114
114
|
from annotationlib import get_annotations
|
|
@@ -3,7 +3,6 @@ from functools import cache
|
|
|
3
3
|
from typing import Self
|
|
4
4
|
import re
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
MODIFIERS = ("bold", "dim", "italic", "underline", "blinking", "inverse", "hidden", "strikethrough")
|
|
8
7
|
|
|
9
8
|
_PREFIX = "\033["
|
|
@@ -31,7 +30,7 @@ class RawColor:
|
|
|
31
30
|
A class that represents a color with all possible modifiers
|
|
32
31
|
"""
|
|
33
32
|
|
|
34
|
-
__slots__ = ("
|
|
33
|
+
__slots__ = ("background", "bright", "color", "value")
|
|
35
34
|
|
|
36
35
|
def __init__(self, color: PureColor | str | int, *, bright: bool = False, background: bool = False):
|
|
37
36
|
self.color = PureColor(getattr(PureColor, color) if isinstance(color, str) else color)
|
|
@@ -145,7 +144,7 @@ class Color(metaclass=_ColorMeta):
|
|
|
145
144
|
"""
|
|
146
145
|
:return: The ansi color code this object represents
|
|
147
146
|
"""
|
|
148
|
-
return f"<Color {
|
|
147
|
+
return f"<Color {self.code!r}>"
|
|
149
148
|
|
|
150
149
|
@classmethod
|
|
151
150
|
def factory(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from collections.abc import Iterator
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import ClassVar, Any
|
|
3
3
|
import annotationlib
|
|
4
4
|
|
|
5
5
|
|
|
@@ -22,7 +22,7 @@ class EnumType(type):
|
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
24
|
_AUTO_PREFIX = "Enum_Auto_"
|
|
25
|
-
_TC_DEFAULT: set[type | None] = {int, str, float, bool, complex, bytes, None, type(None)}
|
|
25
|
+
_TC_DEFAULT: ClassVar[set[type | None]] = {int, str, float, bool, complex, bytes, None, type(None)}
|
|
26
26
|
|
|
27
27
|
class _AutoValue:
|
|
28
28
|
"""A class representing an automatically assigned enum value"""
|
|
@@ -163,4 +163,4 @@ def values(enum: Any) -> tuple[Any, ...]:
|
|
|
163
163
|
return tuple(k[1] for k in enum.__entries__.values()) # type: ignore[attr-defined]
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
__all__ = ("Enum", "EnumType", "
|
|
166
|
+
__all__ = ("Enum", "EnumType", "auto", "entries", "values")
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
from io import
|
|
2
|
-
|
|
3
|
-
TextIOBase as _PyRawTextIOBase,
|
|
4
|
-
RawIOBase as _PyRawIOBase,
|
|
5
|
-
BufferedIOBase as _PyBufferedIOBase,
|
|
6
|
-
)
|
|
1
|
+
from io import BufferedIOBase, TextIOBase, RawIOBase, IOBase
|
|
2
|
+
from weakref import WeakKeyDictionary
|
|
7
3
|
from threading import RLock
|
|
8
4
|
from itertools import chain
|
|
9
5
|
from typing import Self
|
|
10
|
-
import weakref
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
__all__ = ("TextIO", "BinaryIO", "io")
|
|
14
|
-
|
|
15
|
-
type _BinaryBase = _PyRawIOBase | _PyBufferedIOBase
|
|
16
|
-
type _TextBase = _PyRawTextIOBase
|
|
7
|
+
__all__ = ("BinaryIO", "TextIO", "io")
|
|
17
8
|
|
|
18
9
|
|
|
19
10
|
class ProtectedFile:
|
|
@@ -52,8 +43,8 @@ class _IOWrapperBase[T: (str, bytes)]:
|
|
|
52
43
|
Note: This class takes ownership of the input object, do not use it elsewhere
|
|
53
44
|
"""
|
|
54
45
|
|
|
55
|
-
__slots__ = ("
|
|
56
|
-
_instances:
|
|
46
|
+
__slots__ = ("_buffer", "_eof", "f", "lock")
|
|
47
|
+
_instances: WeakKeyDictionary[IOBase, Self] = WeakKeyDictionary()
|
|
57
48
|
_wr_lock = RLock()
|
|
58
49
|
|
|
59
50
|
def __new__(cls, f: IOBase, binary: bool) -> Self:
|
|
@@ -189,8 +180,8 @@ class _IOWrapperBase[T: (str, bytes)]:
|
|
|
189
180
|
|
|
190
181
|
def _mode(f: IOBase, binary: bool | None) -> bool:
|
|
191
182
|
mode = getattr(f, "mode", "")
|
|
192
|
-
binary = binary or "b" in mode or isinstance(f, (
|
|
193
|
-
text = (binary is False) or (mode and "b" not in mode) or isinstance(f,
|
|
183
|
+
binary = binary or "b" in mode or isinstance(f, (RawIOBase, BufferedIOBase))
|
|
184
|
+
text = (binary is False) or (mode and "b" not in mode) or isinstance(f, TextIOBase)
|
|
194
185
|
if not text and not binary:
|
|
195
186
|
raise TypeError("Cannot determine if IO object is text or binary")
|
|
196
187
|
if text and binary:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from logging import CRITICAL, ERROR, WARNING, INFO, DEBUG, Formatter
|
|
2
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
2
3
|
from collections import defaultdict
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
4
|
from zlib import adler32
|
|
5
5
|
from copy import copy
|
|
6
6
|
|
|
@@ -15,9 +15,9 @@ class CuteFormatter(Formatter):
|
|
|
15
15
|
A log formatter that can print log messages with colors.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
__slots__ = ("
|
|
19
|
-
DEFAULT_CUTE_WIDTHS: dict[str, int] = {"cute_levelname": 8, "cute_time": 23, "cute_name": 12}
|
|
20
|
-
DEFAULT_LEVEL_COLORS: dict[int, Color] = {
|
|
18
|
+
__slots__ = ("_cmap", "_color", "_dim_level", "_lvl_cmap", "_name_width", "colored")
|
|
19
|
+
DEFAULT_CUTE_WIDTHS: ClassVar[dict[str, int]] = {"cute_levelname": 8, "cute_time": 23, "cute_name": 12}
|
|
20
|
+
DEFAULT_LEVEL_COLORS: ClassVar[dict[int, Color]] = {
|
|
21
21
|
INFO: Color.blue,
|
|
22
22
|
WARNING: Color.yellow,
|
|
23
23
|
ERROR: Color.red,
|
|
@@ -31,9 +31,9 @@ class CuteFormatter(Formatter):
|
|
|
31
31
|
*args,
|
|
32
32
|
colored: bool = True,
|
|
33
33
|
dim_level: int = DEBUG,
|
|
34
|
-
colors: dict[str, Color] =
|
|
35
|
-
level_colors: dict[int, Color] =
|
|
36
|
-
cute_widths: dict[str, int] =
|
|
34
|
+
colors: dict[str, Color] | None = None,
|
|
35
|
+
level_colors: dict[int, Color] | None = None,
|
|
36
|
+
cute_widths: dict[str, int] | None = None,
|
|
37
37
|
**kwargs,
|
|
38
38
|
):
|
|
39
39
|
"""
|
|
@@ -51,6 +51,9 @@ class CuteFormatter(Formatter):
|
|
|
51
51
|
:param cute_widths: The widths of the cute_ columns in the log message
|
|
52
52
|
:param kwargs: Passed to logging.Formatter
|
|
53
53
|
"""
|
|
54
|
+
colors = {} if colors is None else colors
|
|
55
|
+
level_colors = {} if level_colors is None else level_colors
|
|
56
|
+
cute_widths = {} if cute_widths is None else cute_widths
|
|
54
57
|
super().__init__(fmt, *args, **kwargs)
|
|
55
58
|
self._dim_level: int = dim_level
|
|
56
59
|
self._cmap: dict[str, Color] = dict(colors)
|
|
@@ -46,7 +46,7 @@ def _define_logging_trace(method: str, value: int) -> None:
|
|
|
46
46
|
has no handlers, call basicConfig() to add a console handler with a
|
|
47
47
|
pre-defined format.
|
|
48
48
|
"""
|
|
49
|
-
logging.log(value, msg, *args, **kwargs)
|
|
49
|
+
logging.log(value, msg, *args, **kwargs) # noqa: LOG015
|
|
50
50
|
|
|
51
51
|
setattr(logging, method, trace)
|
|
52
52
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
from typing import TypeVar, Self, Any, cast
|
|
1
|
+
from typing import ClassVar, TypeVar, Self, Any, cast
|
|
2
2
|
from collections import defaultdict
|
|
3
3
|
from threading import RLock
|
|
4
4
|
from functools import cache
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
T = TypeVar("T")
|
|
8
7
|
|
|
9
8
|
|
|
@@ -26,9 +25,9 @@ class _SingletonType(type):
|
|
|
26
25
|
"""
|
|
27
26
|
|
|
28
27
|
_disallow_init_subclass = False # If True, disallow __init_subclass__ in __new__'s attrs
|
|
29
|
-
_instances: dict[type, Any] = {} # Fully constructed and initialized singleton types
|
|
28
|
+
_instances: ClassVar[dict[type, Any]] = {} # Fully constructed and initialized singleton types
|
|
30
29
|
# Lock is preferred to RLock, but could deadlock if user write a constructor that invokes itself
|
|
31
|
-
_cls_locks: dict[type, RLock] = defaultdict(RLock)
|
|
30
|
+
_cls_locks: ClassVar[dict[type, RLock]] = defaultdict(RLock)
|
|
32
31
|
_lock = RLock()
|
|
33
32
|
|
|
34
33
|
def __new__(mcs, name, bases, attrs, **kwargs):
|
|
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
|