approval-utilities 14.5.0__py3-none-any.whl → 14.7.1__py3-none-any.whl
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.
Potentially problematic release.
This version of approval-utilities might be problematic. Click here for more details.
- approval_utilities/approvaltests/core/executable_command.py +1 -1
- approval_utilities/approvaltests/core/verifiable.py +1 -0
- approval_utilities/approvaltests/core/verify_parameters.py +6 -0
- approval_utilities/list_utils.py +3 -3
- approval_utilities/utilities/clipboard_utilities.py +1 -1
- approval_utilities/utilities/deprecated.py +2 -2
- approval_utilities/utilities/exceptions/exception_collector.py +5 -5
- approval_utilities/utilities/exceptions/exception_utils.py +1 -1
- approval_utilities/utilities/logger/logging_instance.py +57 -35
- approval_utilities/utilities/logger/simple_logger.py +17 -13
- approval_utilities/utilities/map_reduce.py +13 -2
- approval_utilities/utilities/markdown_table.py +10 -3
- approval_utilities/utilities/multiline_string_utils.py +2 -1
- approval_utilities/utilities/persistence/loader.py +1 -1
- approval_utilities/utilities/persistence/saver.py +1 -1
- approval_utilities/utilities/string_wrapper.py +9 -4
- approval_utilities/utilities/time_utilities.py +12 -5
- approval_utilities/utilities/wrapper.py +16 -9
- approval_utilities/utils.py +9 -7
- {approval_utilities-14.5.0.dist-info → approval_utilities-14.7.1.dist-info}/METADATA +1 -1
- approval_utilities-14.7.1.dist-info/RECORD +35 -0
- {approval_utilities-14.5.0.dist-info → approval_utilities-14.7.1.dist-info}/WHEEL +1 -1
- approval_utilities-14.5.0.dist-info/RECORD +0 -35
- {approval_utilities-14.5.0.dist-info → approval_utilities-14.7.1.dist-info}/licenses/LICENSE +0 -0
- {approval_utilities-14.5.0.dist-info → approval_utilities-14.7.1.dist-info}/top_level.txt +0 -0
approval_utilities/list_utils.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from typing import Callable, List, Optional
|
|
1
|
+
from typing import Any, Callable, List, Optional
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
def format_list(alist: List[
|
|
4
|
+
def format_list(alist: List[Any], formatter: Optional[Callable], header: str) -> str:
|
|
5
5
|
if formatter is None:
|
|
6
6
|
formatter = FormatLineItem().print_item
|
|
7
7
|
text = (header + "\n\n") if header else ""
|
|
@@ -14,7 +14,7 @@ class FormatLineItem(object):
|
|
|
14
14
|
def __init__(self) -> None:
|
|
15
15
|
self.index = 0
|
|
16
16
|
|
|
17
|
-
def print_item(self, item:
|
|
17
|
+
def print_item(self, item: Any) -> str:
|
|
18
18
|
text = str(self.index) + ") " + str(item)
|
|
19
19
|
self.index += 1
|
|
20
20
|
return text
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import warnings
|
|
2
1
|
import functools
|
|
2
|
+
import warnings
|
|
3
3
|
from typing import Callable
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def deprecated(reason: str) -> Callable:
|
|
7
|
-
def decorator(func):
|
|
7
|
+
def decorator(func: Callable) -> Callable:
|
|
8
8
|
"""This is a decorator which can be used to mark functions
|
|
9
9
|
as deprecated. It will result in a warning being emitted
|
|
10
10
|
when the function is used."""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Callable,
|
|
1
|
+
from typing import Any, Callable, List, Sequence
|
|
2
2
|
|
|
3
3
|
from approval_utilities.utilities.exceptions.multiple_exceptions import (
|
|
4
4
|
MultipleExceptions,
|
|
@@ -6,16 +6,16 @@ from approval_utilities.utilities.exceptions.multiple_exceptions import (
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class ExceptionCollector:
|
|
9
|
-
def __init__(self):
|
|
10
|
-
self._exceptions = []
|
|
9
|
+
def __init__(self) -> None:
|
|
10
|
+
self._exceptions: List[Exception] = []
|
|
11
11
|
|
|
12
|
-
def gather(self, code_to_execute: Callable):
|
|
12
|
+
def gather(self, code_to_execute: Callable[[], Any]) -> None:
|
|
13
13
|
try:
|
|
14
14
|
code_to_execute()
|
|
15
15
|
except Exception as exception:
|
|
16
16
|
self._exceptions.append(exception)
|
|
17
17
|
|
|
18
|
-
def release(self):
|
|
18
|
+
def release(self) -> None:
|
|
19
19
|
if len(self._exceptions) == 0:
|
|
20
20
|
return
|
|
21
21
|
if len(self._exceptions) == 1:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
def to_string(exception:
|
|
1
|
+
def to_string(exception: BaseException) -> str:
|
|
2
2
|
return f"{type(exception).__name__}: {str(exception)}"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import inspect
|
|
3
3
|
import traceback
|
|
4
|
-
from
|
|
5
|
-
|
|
4
|
+
from types import TracebackType
|
|
5
|
+
from typing import Any, Callable, ContextManager, Iterable, Optional, Type, Union
|
|
6
6
|
|
|
7
7
|
from approval_utilities.utilities.exceptions.exception_utils import to_string
|
|
8
|
-
from approval_utilities.utilities.string_wrapper import StringWrapper
|
|
9
8
|
from approval_utilities.utilities.stack_frame_utilities import get_class_name_for_frame
|
|
9
|
+
from approval_utilities.utilities.string_wrapper import StringWrapper
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Toggles:
|
|
@@ -19,21 +19,21 @@ class Toggles:
|
|
|
19
19
|
self.events = show
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def _is_iterable(arg):
|
|
22
|
+
def _is_iterable(arg: Any) -> bool:
|
|
23
23
|
return isinstance(arg, Iterable) and not isinstance(arg, str)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def print_type(value):
|
|
26
|
+
def print_type(value: Any) -> str:
|
|
27
27
|
return f"<{type(value).__name__}>"
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class LoggingInstance:
|
|
31
|
-
def __init__(self):
|
|
31
|
+
def __init__(self) -> None:
|
|
32
32
|
self.log_stack_traces = True
|
|
33
33
|
self.toggles = Toggles(True)
|
|
34
|
-
self.previous_timestamp = None
|
|
35
|
-
self.logger = lambda t: print(t, end="")
|
|
36
|
-
self.tabbing = 0
|
|
34
|
+
self.previous_timestamp: Optional[datetime.datetime] = None
|
|
35
|
+
self.logger: Callable[[str], None] = lambda t: print(t, end="")
|
|
36
|
+
self.tabbing: int = 0
|
|
37
37
|
self.counter = 0
|
|
38
38
|
self.log_with_timestamps = True
|
|
39
39
|
self.timer: Callable[[], datetime.datetime] = datetime.datetime.now
|
|
@@ -45,53 +45,71 @@ class LoggingInstance:
|
|
|
45
45
|
self.log_stack_traces = False
|
|
46
46
|
return buffer
|
|
47
47
|
|
|
48
|
-
def indent(self) -> ContextManager:
|
|
48
|
+
def indent(self) -> ContextManager[None]:
|
|
49
49
|
class Indent:
|
|
50
|
-
def __init__(self, log):
|
|
50
|
+
def __init__(self, log: "LoggingInstance") -> None:
|
|
51
51
|
self.log = log
|
|
52
52
|
|
|
53
|
-
def __enter__(self):
|
|
53
|
+
def __enter__(self) -> None:
|
|
54
54
|
self.log.tabbing += 1
|
|
55
55
|
|
|
56
|
-
def __exit__(
|
|
56
|
+
def __exit__(
|
|
57
|
+
self,
|
|
58
|
+
exc_type: Optional[Type[BaseException]],
|
|
59
|
+
exc_val: Optional[BaseException],
|
|
60
|
+
exc_tb: Optional[TracebackType],
|
|
61
|
+
) -> None:
|
|
57
62
|
self.log.tabbing -= 1
|
|
58
63
|
|
|
59
64
|
return Indent(self)
|
|
60
65
|
|
|
61
66
|
def use_markers(
|
|
62
|
-
self,
|
|
63
|
-
|
|
67
|
+
self,
|
|
68
|
+
parameter_text: Optional[Union[str, Callable[[], str]]] = None,
|
|
69
|
+
additional_stack: int = 0,
|
|
70
|
+
) -> ContextManager[None]:
|
|
64
71
|
class Nothing:
|
|
65
|
-
def __enter__(self):
|
|
72
|
+
def __enter__(self) -> None:
|
|
66
73
|
pass
|
|
67
74
|
|
|
68
|
-
def __exit__(
|
|
75
|
+
def __exit__(
|
|
76
|
+
self,
|
|
77
|
+
exc_type: Optional[type],
|
|
78
|
+
exc_val: Optional[BaseException],
|
|
79
|
+
exc_tb: Optional[TracebackType],
|
|
80
|
+
) -> None:
|
|
69
81
|
pass
|
|
70
82
|
|
|
71
83
|
if not self.toggles.markers:
|
|
72
84
|
return Nothing()
|
|
73
85
|
|
|
74
86
|
class Markers:
|
|
75
|
-
def __init__(
|
|
87
|
+
def __init__(
|
|
88
|
+
self, log: "LoggingInstance", method_name: str, filename: str
|
|
89
|
+
) -> None:
|
|
76
90
|
self.log = log
|
|
77
91
|
self.method_name = method_name
|
|
78
92
|
self.filename = filename
|
|
79
|
-
self.parameter_text = parameter_text
|
|
80
93
|
|
|
81
|
-
def __enter__(self):
|
|
94
|
+
def __enter__(self) -> None:
|
|
82
95
|
expected = f"-> in: {self.method_name}({self.get_parameters(False)}) in {self.filename}"
|
|
83
96
|
self.log.log_line(expected)
|
|
84
97
|
self.log.tabbing = self.log.tabbing + 1
|
|
85
98
|
|
|
86
|
-
def __exit__(
|
|
99
|
+
def __exit__(
|
|
100
|
+
self,
|
|
101
|
+
exc_type: Optional[type],
|
|
102
|
+
exc_val: Optional[BaseException],
|
|
103
|
+
exc_tb: Optional[TracebackType],
|
|
104
|
+
) -> None:
|
|
87
105
|
self.log.tabbing = self.log.tabbing - 1
|
|
88
106
|
expected = f"<- out: {self.method_name}({self.get_parameters(True)})"
|
|
89
107
|
self.log.log_line(expected)
|
|
90
108
|
|
|
91
|
-
def get_parameters(self, is_exit: bool):
|
|
92
|
-
if
|
|
109
|
+
def get_parameters(self, is_exit: bool) -> str:
|
|
110
|
+
if callable(parameter_text):
|
|
93
111
|
return parameter_text()
|
|
94
|
-
elif
|
|
112
|
+
elif parameter_text is None or is_exit:
|
|
95
113
|
return ""
|
|
96
114
|
else:
|
|
97
115
|
return str(parameter_text)
|
|
@@ -101,9 +119,9 @@ class LoggingInstance:
|
|
|
101
119
|
method_name = stack.function
|
|
102
120
|
|
|
103
121
|
filename = get_class_name_for_frame(stack)
|
|
104
|
-
return Markers(self, method_name, filename
|
|
122
|
+
return Markers(self, method_name, filename)
|
|
105
123
|
|
|
106
|
-
def log_line(self, text: str, use_timestamps=True) -> None:
|
|
124
|
+
def log_line(self, text: str, use_timestamps: bool = True) -> None:
|
|
107
125
|
if self.counter != 0:
|
|
108
126
|
self.logger("\n")
|
|
109
127
|
self.counter = 0
|
|
@@ -152,7 +170,7 @@ class LoggingInstance:
|
|
|
152
170
|
if not self.toggles.variables:
|
|
153
171
|
return
|
|
154
172
|
|
|
155
|
-
def to_type(value: Any, spacing=" ") -> str:
|
|
173
|
+
def to_type(value: Any, spacing: str = " ") -> str:
|
|
156
174
|
return f"{spacing}{print_type(value)}" if show_types else ""
|
|
157
175
|
|
|
158
176
|
if _is_iterable(value):
|
|
@@ -176,12 +194,16 @@ class LoggingInstance:
|
|
|
176
194
|
return
|
|
177
195
|
self.log_line(f"Sql: {query_text}")
|
|
178
196
|
|
|
179
|
-
def message(self, message):
|
|
197
|
+
def message(self, message: str) -> None:
|
|
180
198
|
if not self.toggles.messages:
|
|
181
199
|
return
|
|
182
200
|
self.log_line(f"message: {message}")
|
|
183
201
|
|
|
184
|
-
def warning(
|
|
202
|
+
def warning(
|
|
203
|
+
self,
|
|
204
|
+
text: Union[str, BaseException] = "",
|
|
205
|
+
exception: Optional[BaseException] = None,
|
|
206
|
+
) -> None:
|
|
185
207
|
if isinstance(text, Exception):
|
|
186
208
|
temp = ""
|
|
187
209
|
if exception:
|
|
@@ -206,23 +228,23 @@ class LoggingInstance:
|
|
|
206
228
|
self.log_line(stack_trace, use_timestamps=False)
|
|
207
229
|
self.log_line(warning_stars, use_timestamps=False)
|
|
208
230
|
|
|
209
|
-
def show_queries(self, show):
|
|
231
|
+
def show_queries(self, show: bool) -> None:
|
|
210
232
|
self.toggles.queries = show
|
|
211
233
|
|
|
212
234
|
def show_all(self, show: bool) -> None:
|
|
213
235
|
self.toggles = Toggles(show)
|
|
214
236
|
|
|
215
|
-
def show_messages(self, show):
|
|
237
|
+
def show_messages(self, show: bool) -> None:
|
|
216
238
|
self.toggles.messages = show
|
|
217
239
|
|
|
218
|
-
def show_variables(self, show):
|
|
240
|
+
def show_variables(self, show: bool) -> None:
|
|
219
241
|
self.toggles.variables = show
|
|
220
242
|
|
|
221
|
-
def show_hour_glass(self, show):
|
|
243
|
+
def show_hour_glass(self, show: bool) -> None:
|
|
222
244
|
self.toggles.hour_glass = show
|
|
223
245
|
|
|
224
|
-
def show_markers(self, show):
|
|
246
|
+
def show_markers(self, show: bool) -> None:
|
|
225
247
|
self.toggles.markers = show
|
|
226
248
|
|
|
227
|
-
def show_events(self, show):
|
|
249
|
+
def show_events(self, show: bool) -> None:
|
|
228
250
|
self.toggles.events = show
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import threading
|
|
2
|
-
from typing import Iterator,
|
|
2
|
+
from typing import Any, Callable, ContextManager, Iterator, Optional, Union
|
|
3
3
|
|
|
4
4
|
from approval_utilities.utilities.logger.logging_instance import LoggingInstance
|
|
5
5
|
from approval_utilities.utilities.string_wrapper import StringWrapper
|
|
6
|
-
from approval_utilities.utilities.wrapper import SingleWrapper, ThreadedWrapper
|
|
6
|
+
from approval_utilities.utilities.wrapper import SingleWrapper, ThreadedWrapper, Wrapper
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class SimpleLogger:
|
|
10
|
-
_wrapper = SingleWrapper(LoggingInstance())
|
|
10
|
+
_wrapper: Wrapper[LoggingInstance] = SingleWrapper(LoggingInstance())
|
|
11
11
|
|
|
12
12
|
@staticmethod
|
|
13
13
|
def register_logger(log_method: Callable[[str], None]) -> None:
|
|
14
14
|
SimpleLogger._wrapper.get().logger = log_method
|
|
15
15
|
|
|
16
16
|
@staticmethod
|
|
17
|
-
def log_to_string(log_separate_threads=True) -> StringWrapper:
|
|
17
|
+
def log_to_string(log_separate_threads: bool = True) -> StringWrapper:
|
|
18
18
|
with threading.Lock():
|
|
19
19
|
if log_separate_threads and not isinstance(
|
|
20
20
|
SimpleLogger._wrapper, ThreadedWrapper
|
|
@@ -23,7 +23,9 @@ class SimpleLogger:
|
|
|
23
23
|
return SimpleLogger._wrapper.get().log_to_string()
|
|
24
24
|
|
|
25
25
|
@staticmethod
|
|
26
|
-
def use_markers(
|
|
26
|
+
def use_markers(
|
|
27
|
+
parameter_text: Optional[Union[str, Callable[[], str]]] = None,
|
|
28
|
+
) -> ContextManager[None]:
|
|
27
29
|
return SimpleLogger._wrapper.get().use_markers(
|
|
28
30
|
parameter_text, additional_stack=1
|
|
29
31
|
)
|
|
@@ -53,33 +55,35 @@ class SimpleLogger:
|
|
|
53
55
|
SimpleLogger._wrapper.get().message(message)
|
|
54
56
|
|
|
55
57
|
@staticmethod
|
|
56
|
-
def warning(
|
|
58
|
+
def warning(
|
|
59
|
+
text: Union[str, BaseException] = "", exception: Optional[BaseException] = None
|
|
60
|
+
) -> None:
|
|
57
61
|
SimpleLogger._wrapper.get().warning(text, exception)
|
|
58
62
|
|
|
59
63
|
@staticmethod
|
|
60
|
-
def show_queries(show: bool):
|
|
64
|
+
def show_queries(show: bool) -> None:
|
|
61
65
|
SimpleLogger._wrapper.get().show_queries(show)
|
|
62
66
|
|
|
63
67
|
@staticmethod
|
|
64
|
-
def show_all(show: bool):
|
|
68
|
+
def show_all(show: bool) -> None:
|
|
65
69
|
SimpleLogger._wrapper.get().show_all(show)
|
|
66
70
|
|
|
67
71
|
@staticmethod
|
|
68
|
-
def show_messages(show: bool):
|
|
72
|
+
def show_messages(show: bool) -> None:
|
|
69
73
|
SimpleLogger._wrapper.get().show_messages(show)
|
|
70
74
|
|
|
71
75
|
@staticmethod
|
|
72
|
-
def show_variables(show: bool):
|
|
76
|
+
def show_variables(show: bool) -> None:
|
|
73
77
|
SimpleLogger._wrapper.get().show_variables(show)
|
|
74
78
|
|
|
75
79
|
@staticmethod
|
|
76
|
-
def show_hour_glass(show: bool):
|
|
80
|
+
def show_hour_glass(show: bool) -> None:
|
|
77
81
|
SimpleLogger._wrapper.get().show_hour_glass(show)
|
|
78
82
|
|
|
79
83
|
@staticmethod
|
|
80
|
-
def show_markers(show: bool):
|
|
84
|
+
def show_markers(show: bool) -> None:
|
|
81
85
|
SimpleLogger._wrapper.get().show_markers(show)
|
|
82
86
|
|
|
83
87
|
@staticmethod
|
|
84
|
-
def show_events(show: bool):
|
|
88
|
+
def show_events(show: bool) -> None:
|
|
85
89
|
SimpleLogger._wrapper.get().show_events(show)
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import itertools
|
|
2
|
+
from typing import Any, Callable, Dict, Generator, Sequence
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def first(sequence: Sequence[Any], predicate: Callable[[Any], bool]) -> Any:
|
|
5
6
|
matching = filter(predicate, sequence)
|
|
6
|
-
return next(matching)
|
|
7
|
+
return next(matching, None)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def product_dict(**kwargs: Sequence[Any]) -> Generator[Dict[str, Any], None, None]:
|
|
11
|
+
"""
|
|
12
|
+
Similar to `itertools.product`, but the resulting combinations retain the names.
|
|
13
|
+
"""
|
|
14
|
+
keys = kwargs.keys()
|
|
15
|
+
vals = kwargs.values()
|
|
16
|
+
for instance in itertools.product(*vals):
|
|
17
|
+
yield dict(zip(keys, instance))
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
from typing import Any, Callable, Iterable
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Callable, Iterable
|
|
2
|
+
|
|
3
|
+
from typing_extensions import override
|
|
2
4
|
|
|
3
5
|
from approval_utilities.approvaltests.core.verifiable import Verifiable
|
|
4
6
|
from approval_utilities.approvaltests.core.verify_parameters import VerifyParameters
|
|
5
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from approvaltests.core.options import Options
|
|
10
|
+
|
|
6
11
|
|
|
7
12
|
class MarkdownTable(Verifiable):
|
|
8
|
-
def __init__(self):
|
|
9
|
-
self.markdown = ""
|
|
13
|
+
def __init__(self) -> None:
|
|
14
|
+
self.markdown: str = ""
|
|
10
15
|
|
|
16
|
+
@override
|
|
11
17
|
def get_verify_parameters(self, options: "Options") -> VerifyParameters:
|
|
12
18
|
return VerifyParameters(options.for_file.with_extension(".md"))
|
|
13
19
|
|
|
@@ -23,6 +29,7 @@ class MarkdownTable(Verifiable):
|
|
|
23
29
|
self.markdown += MarkdownTable.print_row(*column_names)
|
|
24
30
|
return self
|
|
25
31
|
|
|
32
|
+
@override
|
|
26
33
|
def __str__(self) -> str:
|
|
27
34
|
return self.markdown
|
|
28
35
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import textwrap
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from approval_utilities.utilities.logger.simple_logger import SimpleLogger
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def remove_indentation_from(text: str) -> str:
|
|
7
|
+
def remove_indentation_from(text: Optional[str]) -> str:
|
|
7
8
|
SimpleLogger.variable("text", text)
|
|
8
9
|
if not text:
|
|
9
10
|
return ""
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
from typing_extensions import override
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class StringWrapper:
|
|
2
|
-
def __init__(self):
|
|
5
|
+
def __init__(self) -> None:
|
|
3
6
|
self.string = ""
|
|
4
7
|
|
|
5
|
-
def append(self, text):
|
|
8
|
+
def append(self, text: str) -> None:
|
|
6
9
|
self.string += text
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
@override
|
|
12
|
+
def __str__(self) -> str:
|
|
9
13
|
return self.string
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
@override
|
|
16
|
+
def __repr__(self) -> str:
|
|
12
17
|
return self.string
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from types import TracebackType
|
|
3
|
+
from typing import Optional, Type
|
|
2
4
|
|
|
3
5
|
from typing_extensions import ContextManager
|
|
4
6
|
|
|
5
7
|
|
|
6
|
-
def use_utc_timezone() -> ContextManager:
|
|
8
|
+
def use_utc_timezone() -> ContextManager[None]:
|
|
7
9
|
class TimeZoneSwap:
|
|
8
|
-
def __init__(self):
|
|
9
|
-
self.timezone = ""
|
|
10
|
+
def __init__(self) -> None:
|
|
11
|
+
self.timezone: Optional[str] = ""
|
|
10
12
|
|
|
11
|
-
def __enter__(self):
|
|
13
|
+
def __enter__(self) -> None:
|
|
12
14
|
self.timezone = os.environ.get("TZ")
|
|
13
15
|
os.environ["TZ"] = "UTC"
|
|
14
16
|
|
|
15
|
-
def __exit__(
|
|
17
|
+
def __exit__(
|
|
18
|
+
self,
|
|
19
|
+
exc_type: Optional[Type[BaseException]],
|
|
20
|
+
exc_val: Optional[BaseException],
|
|
21
|
+
exc_tb: Optional[TracebackType],
|
|
22
|
+
) -> bool:
|
|
16
23
|
if self.timezone is None:
|
|
17
24
|
os.environ.pop("TZ")
|
|
18
25
|
else:
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
import threading
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import Callable, Generic, TypeVar, cast
|
|
3
4
|
|
|
5
|
+
from typing_extensions import override
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
_T = TypeVar("_T")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Wrapper(ABC, Generic[_T]):
|
|
6
11
|
@abstractmethod
|
|
7
|
-
def get(self):
|
|
12
|
+
def get(self) -> _T:
|
|
8
13
|
pass
|
|
9
14
|
|
|
10
15
|
|
|
11
|
-
class SingleWrapper(Wrapper):
|
|
12
|
-
def __init__(self, instance):
|
|
16
|
+
class SingleWrapper(Wrapper[_T]):
|
|
17
|
+
def __init__(self, instance: _T):
|
|
13
18
|
self.instance = instance
|
|
14
19
|
|
|
15
|
-
|
|
20
|
+
@override
|
|
21
|
+
def get(self) -> _T:
|
|
16
22
|
return self.instance
|
|
17
23
|
|
|
18
24
|
|
|
19
|
-
class ThreadedWrapper(Wrapper):
|
|
20
|
-
def __init__(self, generator):
|
|
25
|
+
class ThreadedWrapper(Wrapper[_T]):
|
|
26
|
+
def __init__(self, generator: Callable[[], _T]):
|
|
21
27
|
self.generator = generator
|
|
22
28
|
self.local = threading.local()
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
@override
|
|
31
|
+
def get(self) -> _T:
|
|
25
32
|
if not hasattr(self.local, "value"):
|
|
26
33
|
self.local.value = self.generator()
|
|
27
|
-
return self.local.value
|
|
34
|
+
return cast(_T, self.local.value)
|
approval_utilities/utils.py
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
|
-
|
|
5
4
|
from copy import deepcopy
|
|
6
5
|
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
from typing import Callable, Dict, TypeVar
|
|
6
|
+
from typing import Any, Callable, Dict, Optional, TypeVar
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
def get_adjacent_file(name: str) -> str:
|
|
@@ -14,7 +12,9 @@ def get_adjacent_file(name: str) -> str:
|
|
|
14
12
|
return os.path.join(directory, name)
|
|
15
13
|
|
|
16
14
|
|
|
17
|
-
def write_to_temporary_file(
|
|
15
|
+
def write_to_temporary_file(
|
|
16
|
+
text: str, name: str, file_extention_with_dot: Optional[str] = None
|
|
17
|
+
) -> str:
|
|
18
18
|
import tempfile
|
|
19
19
|
|
|
20
20
|
file_extention_with_dot = file_extention_with_dot or ".txt"
|
|
@@ -25,7 +25,7 @@ def write_to_temporary_file(text: str, name: str, file_extention_with_dot: str =
|
|
|
25
25
|
return temp.name
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def to_json(object_to_verify) -> str:
|
|
28
|
+
def to_json(object_to_verify: Any) -> str:
|
|
29
29
|
return json.dumps(
|
|
30
30
|
object_to_verify,
|
|
31
31
|
sort_keys=True,
|
|
@@ -78,7 +78,9 @@ def create_directory_if_needed(received_file: str) -> None:
|
|
|
78
78
|
os.makedirs(directory, exist_ok=True)
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
def print_grid(
|
|
81
|
+
def print_grid(
|
|
82
|
+
width: int, height: int, cell_print_func: Callable[[int, int], str]
|
|
83
|
+
) -> str:
|
|
82
84
|
result = ""
|
|
83
85
|
for y in range(height):
|
|
84
86
|
for x in range(width):
|
|
@@ -95,6 +97,6 @@ def filter_values(filter: Callable[[_V], bool], a_dict: Dict[_K, _V]) -> Dict[_K
|
|
|
95
97
|
return {k: v for k, v in a_dict.items() if filter(v)}
|
|
96
98
|
|
|
97
99
|
|
|
98
|
-
def append_to_file(file: Path, text: str):
|
|
100
|
+
def append_to_file(file: Path, text: str) -> None:
|
|
99
101
|
with file.open(mode="a") as f:
|
|
100
102
|
f.write(text)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
approval_utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
approval_utilities/list_utils.py,sha256=bGdn0Dw7Y9OQgIXOio-ljcKkrH6VbR6epvGHSL0FD64,556
|
|
3
|
+
approval_utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
approval_utilities/utils.py,sha256=nVX7i6d7FaBHLoyejZ4Cei3BvuuIKNfV9nJ0IuG7NsY,2722
|
|
5
|
+
approval_utilities/approvaltests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
approval_utilities/approvaltests/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
approval_utilities/approvaltests/core/executable_command.py,sha256=zDsfRElIaSYEV-xWoaifrjMemeuT-fyZ9jmqEEFdpfQ,428
|
|
8
|
+
approval_utilities/approvaltests/core/verifiable.py,sha256=D2EltH8Sbbx-ItqG-VICMrdjPNVAOm9j1veTUpRH00I,304
|
|
9
|
+
approval_utilities/approvaltests/core/verify_parameters.py,sha256=5j9L5slW-vJc01OuPbHDvllxVFQM8mtgB80kSrSzwg0,204
|
|
10
|
+
approval_utilities/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
approval_utilities/utilities/clipboard_utilities.py,sha256=fr7rZ9GokvguhaXo0YwBjIXtuGg-0BsFsv54BbKUlfI,201
|
|
12
|
+
approval_utilities/utilities/deprecated.py,sha256=1Z9AYXExNQ0P-rWn5qlnwwa1FXvUc-YnaQxfIL5pUSw,844
|
|
13
|
+
approval_utilities/utilities/map_reduce.py,sha256=PUQv0P4OvaG2T_JVPA64Cq7fVCyoHN9rjMx9ugPt-kM,556
|
|
14
|
+
approval_utilities/utilities/markdown_table.py,sha256=5N_hO-iQ99nkfYOiu1fIR5PaCJPwdbDlO4NqpvC6QyI,1768
|
|
15
|
+
approval_utilities/utilities/multiline_string_utils.py,sha256=QbROUrqwmQZANkESt4BgYt_Vk5iizPju42Xevxo87pc,383
|
|
16
|
+
approval_utilities/utilities/os_utilities.py,sha256=UuvmHM1SXf9O-M7hDBfxrNvHo9C74NDSOY9n22bInPY,150
|
|
17
|
+
approval_utilities/utilities/stack_frame_utilities.py,sha256=SawZgr7B0WanlDbURB_oHExhRpA8i9uQHduJBGdQm0U,311
|
|
18
|
+
approval_utilities/utilities/string_wrapper.py,sha256=78aWJuxaY_B5n_So9eKWFR4VVLBVQAxEe3TX-5qI-rA,334
|
|
19
|
+
approval_utilities/utilities/time_utilities.py,sha256=1-0We_XzXcYMCjJPf50HYHHD2n26dUaLElbeDJyYG9s,775
|
|
20
|
+
approval_utilities/utilities/wrapper.py,sha256=gQw917dQ-uCjxlOs0Yj0FMCKdCTkUT9Gm1uB4dXpNXk,774
|
|
21
|
+
approval_utilities/utilities/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
approval_utilities/utilities/exceptions/exception_collector.py,sha256=T82ooGbSuvc6ZuouJx-gJ3hUzubOJsmAe1fqmmN4zSY,1136
|
|
23
|
+
approval_utilities/utilities/exceptions/exception_utils.py,sha256=sv-94S9BqkPmZumqYgOqqxuyHpiDrIyeCFkTP2Q9g9I,107
|
|
24
|
+
approval_utilities/utilities/exceptions/multiple_exceptions.py,sha256=QyMCyEn5bTqgTQZN2CDkG0NqKVcVRABSR63sBBb8qqw,296
|
|
25
|
+
approval_utilities/utilities/logger/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
approval_utilities/utilities/logger/logging_instance.py,sha256=sKLhmV3Xg6kCJAd51ouFXcO_t2Gj9_ed6WiMKjEeV7Y,8360
|
|
27
|
+
approval_utilities/utilities/logger/simple_logger.py,sha256=HzLjhFMAB2xLg6PUt0aULAVhIaHttmHYiIQH3-5LHxA,2979
|
|
28
|
+
approval_utilities/utilities/persistence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
approval_utilities/utilities/persistence/loader.py,sha256=W4trRgNWyZcbWDSuw87DrbPQ5k1AUes8m6FCtJlLegg,218
|
|
30
|
+
approval_utilities/utilities/persistence/saver.py,sha256=qpjCSlw0rEkHCv-Dmn_fWPWU-JBqIq931uIDV--8qvA,223
|
|
31
|
+
approval_utilities-14.7.1.dist-info/licenses/LICENSE,sha256=c7p036pSC0mkAbXSFFmoUjoUbzt1GKgz7qXvqFEwv2g,10273
|
|
32
|
+
approval_utilities-14.7.1.dist-info/METADATA,sha256=jQTVDPqpAPMWU9D0O6rdhg3eyKwqO0EwjwBHJceOxVE,1145
|
|
33
|
+
approval_utilities-14.7.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
34
|
+
approval_utilities-14.7.1.dist-info/top_level.txt,sha256=9uDtIZHmdLyDNIBh-jNfEM1dA6lBDmo5ftR376zOiv4,19
|
|
35
|
+
approval_utilities-14.7.1.dist-info/RECORD,,
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
approval_utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
approval_utilities/list_utils.py,sha256=7OT3YkysNmq3ZD7shzirQ8S9Yqf2rS7ckcMNKbC1Jf0,551
|
|
3
|
-
approval_utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
approval_utilities/utils.py,sha256=dMdQzmtTcWG49zxjio6OxB-d-hB7D_NGrCcMXR8pPUo,2623
|
|
5
|
-
approval_utilities/approvaltests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
approval_utilities/approvaltests/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
approval_utilities/approvaltests/core/executable_command.py,sha256=LFLD36fAe1ek8YlKdZbj8j3dfJ8InFBnIGS8OzaDxDQ,428
|
|
8
|
-
approval_utilities/approvaltests/core/verifiable.py,sha256=RBjSLWFnvXLwLfgswl8vSvMQbBJUd2tdvf6yurslEBQ,257
|
|
9
|
-
approval_utilities/approvaltests/core/verify_parameters.py,sha256=sq7V0n9VaZKZ0hxTJEvY-SnPO8W_F6C4_GhlxLk20Rc,99
|
|
10
|
-
approval_utilities/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
approval_utilities/utilities/clipboard_utilities.py,sha256=MPwS_OoVZkjDAOv1IoM_iAGt3J80lU07N9j3uLGeA2M,188
|
|
12
|
-
approval_utilities/utilities/deprecated.py,sha256=_x0zM73WaXvqAiWFTM08m-jSdEEtEEbEHUIFCKzzjf8,822
|
|
13
|
-
approval_utilities/utilities/map_reduce.py,sha256=tkW3MnI3kkHnyMGhULKi-e8jStoKILURrwusRd7ZKuw,191
|
|
14
|
-
approval_utilities/utilities/markdown_table.py,sha256=SNCJKZJ976zNzkYEgCgEMyhGJ3Yox4CyVSBBIaXKBnM,1602
|
|
15
|
-
approval_utilities/utilities/multiline_string_utils.py,sha256=RzjyPZyj9gc6CJy-FwQNkKDh2uCOI168_R-72-J471Q,345
|
|
16
|
-
approval_utilities/utilities/os_utilities.py,sha256=UuvmHM1SXf9O-M7hDBfxrNvHo9C74NDSOY9n22bInPY,150
|
|
17
|
-
approval_utilities/utilities/stack_frame_utilities.py,sha256=SawZgr7B0WanlDbURB_oHExhRpA8i9uQHduJBGdQm0U,311
|
|
18
|
-
approval_utilities/utilities/string_wrapper.py,sha256=ceV763aiaE-o1WwQI21jEiFBgHaxsXjB1Y9PzQgwwwg,230
|
|
19
|
-
approval_utilities/utilities/time_utilities.py,sha256=D6hye77Qxkyr3TOCUb8FtPMB1fA_GN8MrS6vnwU6jmc,524
|
|
20
|
-
approval_utilities/utilities/wrapper.py,sha256=JCqu66EpkqTxgwy5GSSOTOoInHl-BAzPuswjxE3I788,563
|
|
21
|
-
approval_utilities/utilities/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
approval_utilities/utilities/exceptions/exception_collector.py,sha256=mocSfZnIE0SVckDUTf2zJtX2S_tT4zF0hJgoodCLyqU,1080
|
|
23
|
-
approval_utilities/utilities/exceptions/exception_utils.py,sha256=hclXePur8ynnri8bLAlzemRz-6akVf0Xt6a5E9eydJk,103
|
|
24
|
-
approval_utilities/utilities/exceptions/multiple_exceptions.py,sha256=QyMCyEn5bTqgTQZN2CDkG0NqKVcVRABSR63sBBb8qqw,296
|
|
25
|
-
approval_utilities/utilities/logger/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
approval_utilities/utilities/logger/logging_instance.py,sha256=5l2XxbrcgkU0EFRKvWf0LvRm-PN6ButP01wKovpD-r0,7505
|
|
27
|
-
approval_utilities/utilities/logger/simple_logger.py,sha256=-MQ1sii7u5VYFO_Zle51HMJ7wo-2NNXf70fEzUJXuo0,2765
|
|
28
|
-
approval_utilities/utilities/persistence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
approval_utilities/utilities/persistence/loader.py,sha256=0kLYZRhJh_SX4j6Fxf_9jN64WcgcgMoFTKkUd10S9vM,218
|
|
30
|
-
approval_utilities/utilities/persistence/saver.py,sha256=_xZxyeNkzAweicun69mgBYSakyeObJxesy7aVAIdWl0,223
|
|
31
|
-
approval_utilities-14.5.0.dist-info/licenses/LICENSE,sha256=c7p036pSC0mkAbXSFFmoUjoUbzt1GKgz7qXvqFEwv2g,10273
|
|
32
|
-
approval_utilities-14.5.0.dist-info/METADATA,sha256=E42MA4Xql5amy69gVgumQnLCgV9Gm2cdw5cYfZe_Eb8,1145
|
|
33
|
-
approval_utilities-14.5.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
34
|
-
approval_utilities-14.5.0.dist-info/top_level.txt,sha256=9uDtIZHmdLyDNIBh-jNfEM1dA6lBDmo5ftR376zOiv4,19
|
|
35
|
-
approval_utilities-14.5.0.dist-info/RECORD,,
|
{approval_utilities-14.5.0.dist-info → approval_utilities-14.7.1.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|