danielutils 0.9.80__tar.gz → 0.9.82__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.
- {danielutils-0.9.80/danielutils.egg-info → danielutils-0.9.82}/PKG-INFO +2 -2
- {danielutils-0.9.80 → danielutils-0.9.82}/README.md +1 -1
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/__init__.py +2 -1
- danielutils-0.9.82/danielutils/context_managers/__init__.py +2 -0
- danielutils-0.9.82/danielutils/context_managers/attr_context.py +25 -0
- danielutils-0.9.82/danielutils/context_managers/temporary_file.py +46 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/__init__.py +1 -0
- danielutils-0.9.82/danielutils/system/layered_command.py +110 -0
- {danielutils-0.9.80 → danielutils-0.9.82/danielutils.egg-info}/PKG-INFO +2 -2
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils.egg-info/SOURCES.txt +4 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/pyproject.toml +1 -1
- {danielutils-0.9.80 → danielutils-0.9.82}/LICENSE +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/MANIFEST.in +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/cached_database.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/database.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/redis_database.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/repl.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/aliases.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/counter.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/frange.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/colors.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/convenience.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/main_conversions.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/comparer.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/default_dict.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/functions.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/binary_node.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/graph.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/multinode.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/graph/node.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/heap.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/max_heap.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/heap/min_heap.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/atomic_queue.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/priority_queue.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/queue.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/stack.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_tree.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/date.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/date_time.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/atomic.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/attach.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/chain_decorators.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/decorate_conditionally.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/delay_call.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/deprecate.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/final.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/limit_recursion.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/memo.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/overload.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/partially_implemented.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/processify.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/property.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/singleton.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/threadify.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/timeout.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/total_ordering.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/decorators/validate.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/exceptions.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/areoneof.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/check_foreach.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/flatten.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/isoftype.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/isoneof.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/multiloop.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/powerset.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/subseteq.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/functions/types_subseteq.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/conditional_generator.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/generator_from_stream.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/generators/join_generators.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/internet.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/io_.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/constants.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/functions.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/math_print.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/math_symbols.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/polynomial/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/math_/polynomial/polinomial.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/atomic_class_meta.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/instance_cache_meta.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/interface.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/overload_meta.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/mock_/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/mock_/mock_database.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/mock_/mock_module.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/path.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/print_.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/protocols/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/protocols/dictable.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/protocols/evaluable.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/py.typed +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/class_/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/class_/class_reflection.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/file/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/file/file_reflection.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/function/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/function/function_reflections.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/callstack.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/get_traceback.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/os_.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/packages.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/python_version.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/signals.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/tracer.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/module_reflections.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/package_reflection.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/snippets/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/snippets/try_get.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/independent.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/utils/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/utils/filetime.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/win32_ctime.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/system/windows/windows.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/text.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/time.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/tqdm_.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/databases/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/databases/all.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/oop/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/oop/observer.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/oop/strategy.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/conditional_variable.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/bernoulli.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/binomial.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/discrete.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/geometric.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/poisson.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/uniform.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/distributions.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/accumulation_expression.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/probability_expression.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/__init__.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/covariance.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/expected_value.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/probability_function.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/variance.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/operator.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/protocols.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/supp.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/transformation.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils/versioned_imports.py +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils.egg-info/dependency_links.txt +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/danielutils.egg-info/top_level.txt +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/setup.cfg +0 -0
- {danielutils-0.9.80 → danielutils-0.9.82}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: danielutils
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.82
|
|
4
4
|
Summary: A python utils library for things I find useful
|
|
5
5
|
Author-email: danielnachumdev <danielnachumdev@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -41,7 +41,7 @@ License-File: LICENSE
|
|
|
41
41
|
[](https://www.python.org/downloads/release/python-31011/)
|
|
42
42
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
|
|
43
43
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
|
|
44
|
-
# danielutils v=0.9.
|
|
44
|
+
# danielutils v=0.9.82
|
|
45
45
|
A utils library for things that I find useful for my coding workflow.\
|
|
46
46
|
Feel free to use and / or contribute / improve my code :)
|
|
47
47
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://www.python.org/downloads/release/python-31011/)
|
|
5
5
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
|
|
6
6
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
|
|
7
|
-
# danielutils v=0.9.
|
|
7
|
+
# danielutils v=0.9.82
|
|
8
8
|
A utils library for things that I find useful for my coding workflow.\
|
|
9
9
|
Feel free to use and / or contribute / improve my code :)
|
|
10
10
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class AttrContext:
|
|
2
|
+
def __init__(self, obj: object, attr: str, new_value: object, *, nonexistent_is_error: bool = True) -> None:
|
|
3
|
+
self.obj = obj
|
|
4
|
+
self.attr = attr
|
|
5
|
+
self.new_value = new_value
|
|
6
|
+
self.old_value = None
|
|
7
|
+
self._has_attr: bool = hasattr(self.obj, self.attr)
|
|
8
|
+
if nonexistent_is_error and not self._has_attr:
|
|
9
|
+
raise RuntimeError(f"Nonexistent attribute '{self.attr}' in '{self.obj}'")
|
|
10
|
+
|
|
11
|
+
def __enter__(self) -> 'AttrContext':
|
|
12
|
+
self.old_value = getattr(self.obj, self.attr, None)
|
|
13
|
+
setattr(self.obj, self.attr, self.new_value)
|
|
14
|
+
return self
|
|
15
|
+
|
|
16
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
17
|
+
if self._has_attr:
|
|
18
|
+
setattr(self.obj, self.attr, self.old_value)
|
|
19
|
+
else:
|
|
20
|
+
delattr(self.obj, self.attr)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
'AttrContext'
|
|
25
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from ..io_ import file_exists, delete_file
|
|
2
|
+
import atexit
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TemporaryFile:
|
|
6
|
+
_instances: set['TemporaryFile'] = set()
|
|
7
|
+
|
|
8
|
+
def __init__(self, path: str):
|
|
9
|
+
if file_exists(path):
|
|
10
|
+
raise RuntimeError(f"Can't create a temporary file if file '{path}' already exists.")
|
|
11
|
+
self.path = path
|
|
12
|
+
TemporaryFile._instances.add(self)
|
|
13
|
+
|
|
14
|
+
def __enter__(self):
|
|
15
|
+
return self
|
|
16
|
+
|
|
17
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
18
|
+
self.close()
|
|
19
|
+
|
|
20
|
+
@atexit.register
|
|
21
|
+
@staticmethod
|
|
22
|
+
def _global_close():
|
|
23
|
+
for inst in TemporaryFile._instances:
|
|
24
|
+
inst.close()
|
|
25
|
+
|
|
26
|
+
def close(self) -> None:
|
|
27
|
+
delete_file(self.path)
|
|
28
|
+
|
|
29
|
+
def read(self) -> list[str]:
|
|
30
|
+
if not file_exists(self.path):
|
|
31
|
+
return []
|
|
32
|
+
with open(self.path, 'r') as f:
|
|
33
|
+
return f.readlines()
|
|
34
|
+
|
|
35
|
+
def write(self, lines: list[str]) -> None:
|
|
36
|
+
with open(self.path, 'a') as f:
|
|
37
|
+
f.writelines(lines)
|
|
38
|
+
|
|
39
|
+
def clear(self):
|
|
40
|
+
with open(self.path, 'w') as _:
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
'TemporaryFile'
|
|
46
|
+
]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import sys, os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from ..context_managers import TemporaryFile
|
|
4
|
+
import random
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LayeredCommand:
|
|
8
|
+
class_flush_stdout: bool = True
|
|
9
|
+
class_flush_stderr: bool = True
|
|
10
|
+
class_raise_on_fail: bool = True
|
|
11
|
+
class_verbose: bool = False
|
|
12
|
+
_class_prev_instance: Optional['LayeredCommand'] = None
|
|
13
|
+
_id: int = 0
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
command: Optional[str] = None,
|
|
18
|
+
*,
|
|
19
|
+
prev_instance: Optional['LayeredCommand'] = None,
|
|
20
|
+
instance_flush_stdout: Optional[bool] = None,
|
|
21
|
+
instance_flush_stderr: Optional[bool] = None,
|
|
22
|
+
instance_raise_on_fail: Optional[bool] = None,
|
|
23
|
+
instance_verbose: Optional[bool] = None
|
|
24
|
+
):
|
|
25
|
+
self._command = command if command is not None else ""
|
|
26
|
+
self._instance_flush_stdout = instance_flush_stdout
|
|
27
|
+
self._instance_flush_stderr = instance_flush_stderr
|
|
28
|
+
self._instance_raise_on_fail = instance_raise_on_fail
|
|
29
|
+
self._instance_verbose = instance_verbose
|
|
30
|
+
self._prev_instance = prev_instance if prev_instance is not None else LayeredCommand._class_prev_instance
|
|
31
|
+
self._cur_class_prev_instance = LayeredCommand._class_prev_instance
|
|
32
|
+
LayeredCommand._class_prev_instance = self
|
|
33
|
+
self._executor = os.system
|
|
34
|
+
self._has_entered: bool = False
|
|
35
|
+
|
|
36
|
+
def __enter__(self):
|
|
37
|
+
self._open()
|
|
38
|
+
return self
|
|
39
|
+
|
|
40
|
+
def _open(self) -> None:
|
|
41
|
+
self._has_entered = True
|
|
42
|
+
|
|
43
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
44
|
+
if self._prev_instance is self._cur_class_prev_instance:
|
|
45
|
+
LayeredCommand._class_prev_instance = self._prev_instance
|
|
46
|
+
|
|
47
|
+
def _build_command(self, *commands: str) -> str:
|
|
48
|
+
res = ""
|
|
49
|
+
if self._prev_instance is not None:
|
|
50
|
+
prev = self._prev_instance._build_command()
|
|
51
|
+
res += f"{prev} & " if prev != "" else ""
|
|
52
|
+
if self._command != "":
|
|
53
|
+
return res + " & ".join([self._command, *commands])
|
|
54
|
+
return res + " & ".join(commands)
|
|
55
|
+
|
|
56
|
+
def _error(self, predicate: bool, command: str, code: int, command_verbose: Optional[bool]) -> None:
|
|
57
|
+
if predicate:
|
|
58
|
+
verbose = self._merge_values(command_verbose, self._instance_verbose, LayeredCommand.class_verbose)
|
|
59
|
+
if verbose:
|
|
60
|
+
raise RuntimeError(f"command '{command}' failed with exit code {code}")
|
|
61
|
+
sys.exit(1)
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def _merge_values(command: Optional[bool], instance: Optional[bool], class_: bool) -> bool:
|
|
65
|
+
return command if command is not None else (instance if instance is not None else class_)
|
|
66
|
+
|
|
67
|
+
def execute(
|
|
68
|
+
self,
|
|
69
|
+
*commands: str,
|
|
70
|
+
command_flush_stdout: Optional[bool] = None,
|
|
71
|
+
command_flush_stderr: Optional[bool] = None,
|
|
72
|
+
command_raise_on_fail: Optional[bool] = None,
|
|
73
|
+
command_verbose: Optional[bool] = None
|
|
74
|
+
) -> tuple[int, list[str], list[str]]:
|
|
75
|
+
if not self._has_entered:
|
|
76
|
+
raise RuntimeError(
|
|
77
|
+
"LayeredCommand must be used with a context manager. Use as: `with LayeredCommand(...) as l1:`")
|
|
78
|
+
flush_stdout = self._merge_values(command_flush_stdout, self._instance_flush_stdout, self.class_flush_stdout)
|
|
79
|
+
flush_stderr = self._merge_values(command_flush_stderr, self._instance_flush_stderr, self.class_flush_stderr)
|
|
80
|
+
raise_on_fail = self._merge_values(command_raise_on_fail, self._instance_raise_on_fail,
|
|
81
|
+
self.class_raise_on_fail)
|
|
82
|
+
|
|
83
|
+
command = self._build_command(*commands)
|
|
84
|
+
if flush_stdout and flush_stderr:
|
|
85
|
+
code = self._executor(command)
|
|
86
|
+
self._error(raise_on_fail and code != 0, command, code, command_verbose)
|
|
87
|
+
return code, [], []
|
|
88
|
+
|
|
89
|
+
letters = "abcdefghijklmnopqrstuvwxyz"
|
|
90
|
+
temp_name = "".join(random.choices(letters, k=50)) + f"_{LayeredCommand._id}"
|
|
91
|
+
stdout_path = f"./{temp_name}_stdout.log"
|
|
92
|
+
stderr_path = f"./{temp_name}_stderr.log"
|
|
93
|
+
LayeredCommand._id += 1
|
|
94
|
+
with TemporaryFile(stdout_path) as stdout:
|
|
95
|
+
with TemporaryFile(stderr_path) as stderr:
|
|
96
|
+
if not flush_stdout:
|
|
97
|
+
command += f" > {stdout_path}"
|
|
98
|
+
if not flush_stderr:
|
|
99
|
+
command += f" 2> {stderr_path}"
|
|
100
|
+
code = self._executor(command)
|
|
101
|
+
self._error(raise_on_fail and code != 0, command, code, command_verbose)
|
|
102
|
+
return code, stdout.read(), stderr.read()
|
|
103
|
+
|
|
104
|
+
def __call__(self, *args, **kwargs) -> tuple[int, list[str], list[str]]:
|
|
105
|
+
return self.execute(*args, **kwargs)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
__all__ = [
|
|
109
|
+
'LayeredCommand'
|
|
110
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: danielutils
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.82
|
|
4
4
|
Summary: A python utils library for things I find useful
|
|
5
5
|
Author-email: danielnachumdev <danielnachumdev@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -41,7 +41,7 @@ License-File: LICENSE
|
|
|
41
41
|
[](https://www.python.org/downloads/release/python-31011/)
|
|
42
42
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
|
|
43
43
|
[](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
|
|
44
|
-
# danielutils v=0.9.
|
|
44
|
+
# danielutils v=0.9.82
|
|
45
45
|
A utils library for things that I find useful for my coding workflow.\
|
|
46
46
|
Feel free to use and / or contribute / improve my code :)
|
|
47
47
|
|
|
@@ -42,6 +42,9 @@ danielutils/better_builtins/typed_builtins/tdict.py
|
|
|
42
42
|
danielutils/better_builtins/typed_builtins/tlist.py
|
|
43
43
|
danielutils/better_builtins/typed_builtins/tset.py
|
|
44
44
|
danielutils/better_builtins/typed_builtins/ttuple.py
|
|
45
|
+
danielutils/context_managers/__init__.py
|
|
46
|
+
danielutils/context_managers/attr_context.py
|
|
47
|
+
danielutils/context_managers/temporary_file.py
|
|
45
48
|
danielutils/conversions/__init__.py
|
|
46
49
|
danielutils/conversions/main_conversions.py
|
|
47
50
|
danielutils/conversions/specialized_conversions/__init__.py
|
|
@@ -142,6 +145,7 @@ danielutils/snippets/__init__.py
|
|
|
142
145
|
danielutils/snippets/try_get.py
|
|
143
146
|
danielutils/system/__init__.py
|
|
144
147
|
danielutils/system/independent.py
|
|
148
|
+
danielutils/system/layered_command.py
|
|
145
149
|
danielutils/system/windows/__init__.py
|
|
146
150
|
danielutils/system/windows/win32_ctime.py
|
|
147
151
|
danielutils/system/windows/windows.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/cached_database.py
RENAMED
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/database/redis_database.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/__init__.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/multi_id.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker_pool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/__init__.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/factory.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tdict.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tlist.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tset.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/ttuple.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_hex.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_int.py
RENAMED
|
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
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/queue/priority_queue.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_syntax_tree.py
RENAMED
|
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
|
|
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
|
|
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
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/metaclasses/implicit_data_deleter_meta.py
RENAMED
|
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
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/function/function_reflections.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/get_traceback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/interpreter/python_version.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/module_reflections.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/reflection/module/package_reflection.py
RENAMED
|
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
|
|
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
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/distributions.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/expressions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/__init__.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/covariance.py
RENAMED
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/expected_value.py
RENAMED
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/funcs/variance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.80 → danielutils-0.9.82}/danielutils/university/probability/transformation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|