danielutils 0.9.81__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.81/danielutils.egg-info → danielutils-0.9.82}/PKG-INFO +2 -2
- {danielutils-0.9.81 → danielutils-0.9.82}/README.md +1 -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.81 → danielutils-0.9.82}/danielutils/context_managers/temporary_file.py +12 -0
- danielutils-0.9.82/danielutils/system/layered_command.py +110 -0
- {danielutils-0.9.81 → danielutils-0.9.82/danielutils.egg-info}/PKG-INFO +2 -2
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils.egg-info/SOURCES.txt +1 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/pyproject.toml +1 -1
- danielutils-0.9.81/danielutils/context_managers/__init__.py +0 -1
- danielutils-0.9.81/danielutils/system/layered_command.py +0 -86
- {danielutils-0.9.81 → danielutils-0.9.82}/LICENSE +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/MANIFEST.in +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/database/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/database/cached_database.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/database/database.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/database/redis_database.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/multi_id.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker_pool.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/repl.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/aliases.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/counter.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/frange.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/factory.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tdict.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tlist.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tset.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/ttuple.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/colors.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/convenience.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/conversions/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/conversions/main_conversions.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/comparer.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/default_dict.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/functions.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/graph/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/graph/binary_node.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/graph/graph.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/graph/multinode.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/graph/node.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/heap/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/heap/heap.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/heap/max_heap.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/heap/min_heap.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/queue/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/queue/atomic_queue.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/queue/priority_queue.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/queue/queue.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/stack.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/trees/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_syntax_tree.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/data_structures/trees/binary_tree.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/date.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/date_time.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/atomic.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/attach.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/chain_decorators.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/decorate_conditionally.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/delay_call.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/deprecate.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/final.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/limit_recursion.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/memo.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/overload.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/partially_implemented.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/processify.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/property.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/singleton.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/threadify.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/timeout.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/total_ordering.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/decorators/validate.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/exceptions.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/areoneof.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/check_foreach.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/flatten.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/isoftype.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/isoneof.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/multiloop.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/powerset.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/subseteq.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/functions/types_subseteq.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/generators/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/generators/conditional_generator.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/generators/generator_from_stream.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/generators/join_generators.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/internet.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/io_.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/constants.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/functions.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/math_print.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/math_symbols.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/polynomial/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/math_/polynomial/polinomial.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/metaclasses/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/metaclasses/atomic_class_meta.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/metaclasses/instance_cache_meta.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/metaclasses/interface.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/metaclasses/overload_meta.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/mock_/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/mock_/mock_database.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/mock_/mock_module.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/path.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/print_.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/protocols/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/protocols/dictable.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/protocols/evaluable.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/py.typed +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/class_/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/class_/class_reflection.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/file/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/file/file_reflection.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/function/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/function/function_reflections.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/callstack.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/get_traceback.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/os_.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/packages.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/python_version.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/signals.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/tracer.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/module/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/module/module_reflections.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/module/package_reflection.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/snippets/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/snippets/try_get.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/independent.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/windows/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/windows/utils/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/windows/utils/filetime.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/windows/win32_ctime.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/system/windows/windows.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/text.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/time.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/tqdm_.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/databases/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/databases/all.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/oop/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/oop/observer.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/oop/strategy.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/conditional_variable.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/bernoulli.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/binomial.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/discrete.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/geometric.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/poisson.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/conditional_variable/discrete/uniform.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/distributions.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/expressions/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/expressions/accumulation_expression.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/expressions/probability_expression.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/__init__.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/covariance.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/expected_value.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/probability_function.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/variance.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/operator.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/protocols.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/supp.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/transformation.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils/versioned_imports.py +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils.egg-info/dependency_links.txt +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/danielutils.egg-info/top_level.txt +0 -0
- {danielutils-0.9.81 → danielutils-0.9.82}/setup.cfg +0 -0
- {danielutils-0.9.81 → 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
|
+
]
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
from ..io_ import file_exists, delete_file
|
|
2
|
+
import atexit
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class TemporaryFile:
|
|
6
|
+
_instances: set['TemporaryFile'] = set()
|
|
7
|
+
|
|
5
8
|
def __init__(self, path: str):
|
|
6
9
|
if file_exists(path):
|
|
7
10
|
raise RuntimeError(f"Can't create a temporary file if file '{path}' already exists.")
|
|
8
11
|
self.path = path
|
|
12
|
+
TemporaryFile._instances.add(self)
|
|
9
13
|
|
|
10
14
|
def __enter__(self):
|
|
11
15
|
return self
|
|
@@ -13,10 +17,18 @@ class TemporaryFile:
|
|
|
13
17
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
14
18
|
self.close()
|
|
15
19
|
|
|
20
|
+
@atexit.register
|
|
21
|
+
@staticmethod
|
|
22
|
+
def _global_close():
|
|
23
|
+
for inst in TemporaryFile._instances:
|
|
24
|
+
inst.close()
|
|
25
|
+
|
|
16
26
|
def close(self) -> None:
|
|
17
27
|
delete_file(self.path)
|
|
18
28
|
|
|
19
29
|
def read(self) -> list[str]:
|
|
30
|
+
if not file_exists(self.path):
|
|
31
|
+
return []
|
|
20
32
|
with open(self.path, 'r') as f:
|
|
21
33
|
return f.readlines()
|
|
22
34
|
|
|
@@ -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
|
|
|
@@ -43,6 +43,7 @@ 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
45
|
danielutils/context_managers/__init__.py
|
|
46
|
+
danielutils/context_managers/attr_context.py
|
|
46
47
|
danielutils/context_managers/temporary_file.py
|
|
47
48
|
danielutils/conversions/__init__.py
|
|
48
49
|
danielutils/conversions/main_conversions.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .temporary_file import *
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import sys, os
|
|
2
|
-
from typing import Optional
|
|
3
|
-
from ..context_managers import TemporaryFile
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class LayeredCommand:
|
|
7
|
-
class_flush_stdout: bool = True
|
|
8
|
-
class_raise_on_fail: bool = True
|
|
9
|
-
class_verbose: bool = False
|
|
10
|
-
_cls_prev_instance: Optional['LayeredCommand'] = None
|
|
11
|
-
_id: int = 0
|
|
12
|
-
|
|
13
|
-
def __init__(
|
|
14
|
-
self,
|
|
15
|
-
command: Optional[str] = None,
|
|
16
|
-
instance_flush_stdout: Optional[bool] = None,
|
|
17
|
-
instance_raise_on_fail: Optional[bool] = None,
|
|
18
|
-
instance_verbose: Optional[bool] = None
|
|
19
|
-
):
|
|
20
|
-
self._command = command if command is not None else ""
|
|
21
|
-
self._instance_flush_stdout = instance_flush_stdout
|
|
22
|
-
self._instance_raise_on_fail = instance_raise_on_fail
|
|
23
|
-
self._instance_verbose = instance_verbose
|
|
24
|
-
self._prev_instance = LayeredCommand._cls_prev_instance
|
|
25
|
-
LayeredCommand._cls_prev_instance = self
|
|
26
|
-
self._executor = os.system
|
|
27
|
-
self._has_entered: bool = False
|
|
28
|
-
|
|
29
|
-
def __enter__(self):
|
|
30
|
-
self._has_entered = True
|
|
31
|
-
return self
|
|
32
|
-
|
|
33
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
34
|
-
LayeredCommand._cls_prev_instance = self._prev_instance
|
|
35
|
-
|
|
36
|
-
def _build_command(self, *commands: str) -> str:
|
|
37
|
-
res = ""
|
|
38
|
-
if self._prev_instance is not None:
|
|
39
|
-
prev = self._prev_instance._build_command()
|
|
40
|
-
res += f"{prev} & " if prev != "" else ""
|
|
41
|
-
if self._command != "":
|
|
42
|
-
return res + " & ".join([self._command, *commands])
|
|
43
|
-
return res + " & ".join(commands)
|
|
44
|
-
|
|
45
|
-
def _error(self, predicate: bool, command: str, code: int, command_verbose: Optional[bool]) -> None:
|
|
46
|
-
verbose = command_verbose if command_verbose is not None else (
|
|
47
|
-
self._instance_verbose if self._instance_verbose is not None
|
|
48
|
-
else LayeredCommand.class_verbose)
|
|
49
|
-
if predicate:
|
|
50
|
-
if verbose:
|
|
51
|
-
raise RuntimeError(f"command '{command}' failed with exit code {code}")
|
|
52
|
-
sys.exit(1)
|
|
53
|
-
|
|
54
|
-
def execute(self, *commands: str, command_flush_stdout: Optional[bool] = None,
|
|
55
|
-
command_raise_on_fail: bool = None, command_verbose: Optional[bool] = None) -> tuple[int, list[str]]:
|
|
56
|
-
if not self._has_entered:
|
|
57
|
-
raise RuntimeError(
|
|
58
|
-
"LayeredCommand must be used with a context manager. Use as: `with LayeredCommand(...) as l1:`")
|
|
59
|
-
command_flush_stdout = command_flush_stdout if command_flush_stdout is not None else (
|
|
60
|
-
self._instance_flush_stdout if self._instance_flush_stdout is not None
|
|
61
|
-
else LayeredCommand.class_flush_stdout)
|
|
62
|
-
raise_on_fail = command_raise_on_fail if command_raise_on_fail is not None else (
|
|
63
|
-
self._instance_raise_on_fail if self._instance_raise_on_fail is not None
|
|
64
|
-
else LayeredCommand.class_raise_on_fail)
|
|
65
|
-
|
|
66
|
-
command = self._build_command(*commands)
|
|
67
|
-
if command_flush_stdout:
|
|
68
|
-
code = self._executor(command)
|
|
69
|
-
self._error(raise_on_fail and code != 0, command, code, command_verbose)
|
|
70
|
-
return code, []
|
|
71
|
-
|
|
72
|
-
temp_name = f"./alkjgaprgijfpeasjkegnrtlskdjfnbvlkajdertnbolrijk_{LayeredCommand._id}"
|
|
73
|
-
LayeredCommand._id += 1
|
|
74
|
-
with TemporaryFile(temp_name) as temp:
|
|
75
|
-
command += f" >> {temp_name}"
|
|
76
|
-
code = self._executor(command)
|
|
77
|
-
self._error(raise_on_fail and code != 0, command, code, command_verbose)
|
|
78
|
-
return code, temp.read()
|
|
79
|
-
|
|
80
|
-
def __call__(self, *args, **kwargs) -> tuple[int, list[str]]:
|
|
81
|
-
return self.execute(*args, **kwargs)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
__all__ = [
|
|
85
|
-
'LayeredCommand'
|
|
86
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/database/cached_database.py
RENAMED
|
File without changes
|
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/database/redis_database.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/__init__.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/multi_id.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/abstractions/multiprogramming/worker.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → 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.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/__init__.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/factory.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tdict.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tlist.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/better_builtins/typed_builtins/tset.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → 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.81 → danielutils-0.9.82}/danielutils/conversions/specialized_conversions/to_hex.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → 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.81 → 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.81 → 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.81 → 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.81 → danielutils-0.9.82}/danielutils/reflection/function/function_reflections.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/reflection/interpreter/get_traceback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.81 → 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.81 → danielutils-0.9.82}/danielutils/reflection/module/module_reflections.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → 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
|
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/distributions.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/expressions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/__init__.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/covariance.py
RENAMED
|
File without changes
|
{danielutils-0.9.81 → danielutils-0.9.82}/danielutils/university/probability/funcs/expected_value.py
RENAMED
|
File without changes
|
|
File without changes
|
{danielutils-0.9.81 → 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.81 → 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
|