pythagoras 0.8.14__tar.gz → 0.9.1__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.
- {pythagoras-0.8.14/pythagoras.egg-info → pythagoras-0.9.1}/PKG-INFO +1 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_01_foundational_objects/value_addresses.py +4 -4
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/__init__.py +1 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/autonomous_decorators.py +1 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/autonomous_funcs.py +16 -65
- pythagoras-0.9.1/pythagoras/_03_autonomous_functions/pth_available_names_retriever.py +13 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/__init__.py +3 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/idempotent_decorator.py +1 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/idempotent_func_and_address.py +127 -36
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/kw_args.py +1 -1
- pythagoras-0.9.1/pythagoras/_05_events_and_exceptions/__init__.py +5 -0
- pythagoras-0.9.1/pythagoras/_05_events_and_exceptions/event_poster.py +53 -0
- pythagoras-0.9.1/pythagoras/_05_events_and_exceptions/global_event_loggers.py +27 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/type_retrievers.py +12 -3
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/uncaught_exception_handlers.py +5 -5
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_06_mission_control/__init__.py +3 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_06_mission_control/global_state_management.py +43 -69
- pythagoras-0.9.1/pythagoras/_06_mission_control/operational_hub.py +17 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_06_mission_control/summary.py +2 -2
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/NEW_hash_address.py +1 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/__init__.py +6 -15
- {pythagoras-0.8.14 → pythagoras-0.9.1/pythagoras.egg-info}/PKG-INFO +1 -1
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras.egg-info/SOURCES.txt +4 -4
- {pythagoras-0.8.14 → pythagoras-0.9.1}/setup.py +1 -1
- pythagoras-0.8.14/pythagoras/NEW_exception_logging.py +0 -66
- pythagoras-0.8.14/pythagoras/_05_events_and_exceptions/__init__.py +0 -2
- pythagoras-0.8.14/pythagoras/_05_events_and_exceptions/event_logger.py +0 -94
- pythagoras-0.8.14/pythagoras/_06_mission_control/__events_and_exceptions_OLD__.py +0 -165
- pythagoras-0.8.14/pythagoras/__main__.py +0 -12
- {pythagoras-0.8.14 → pythagoras-0.9.1}/LICENSE +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/README.md +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pyproject.toml +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/OLD__main__.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/OLD_p_cloud.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/OLD_utils.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_01_foundational_objects/__init__.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_01_foundational_objects/hash_addresses.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_01_foundational_objects/hash_and_random_signatures.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/__init__.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/assert_ordinarity.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/check_n_positional_args.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/code_normalizer.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/code_normalizer_implementation.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/ordinary_decorator.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_02_ordinary_functions/ordinary_funcs.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/autonomicity_checks.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/call_graph_explorer.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/default_island_singleton.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/names_usage_analyzer.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/astkeywords_dict_convertors.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/idempotency_checks.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/process_augmented_func_src.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/context_utils.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/current_date_gmt_str.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/find_in_callstack.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/notebook_checker.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/__init__.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/base_16_32_convertors.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/function_name.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/id_examiner.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/long_infoname.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/output_capturer.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_99_misc_utils/package_manager.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/OLD_dependency_discovery.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/OLD_environmental.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/OLD_package_dependencies.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/OLD_persidicts.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/OLD_persiout.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/OLD_persistent_dicts.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/__init__.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/________OLD________/test_package_dependencies.py +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras.egg-info/dependency_links.txt +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras.egg-info/requires.txt +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras.egg-info/top_level.txt +0 -0
- {pythagoras-0.8.14 → pythagoras-0.9.1}/setup.cfg +0 -0
{pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_01_foundational_objects/value_addresses.py
RENAMED
@@ -38,8 +38,8 @@ class ValueAddress(HashAddress):
|
|
38
38
|
|
39
39
|
super().__init__(prefix, hash_value)
|
40
40
|
|
41
|
-
if push_to_cloud and not (self in pth.
|
42
|
-
pth.
|
41
|
+
if push_to_cloud and not (self in pth.value_store):
|
42
|
+
pth.value_store[self] = data
|
43
43
|
|
44
44
|
def get_ValueAddress(self):
|
45
45
|
return self
|
@@ -47,12 +47,12 @@ class ValueAddress(HashAddress):
|
|
47
47
|
@property
|
48
48
|
def ready(self):
|
49
49
|
"""Check if address points to a value that is ready to be retrieved."""
|
50
|
-
return self in pth.
|
50
|
+
return self in pth.value_store
|
51
51
|
|
52
52
|
|
53
53
|
def get(self, timeout:Optional[int] = None) -> Any:
|
54
54
|
"""Retrieve value, referenced by the address"""
|
55
|
-
return pth.
|
55
|
+
return pth.value_store[self]
|
56
56
|
|
57
57
|
def get_typed(self
|
58
58
|
,expected_type:Type[T]
|
@@ -44,7 +44,7 @@ from pythagoras._03_autonomous_functions.default_island_singleton import (
|
|
44
44
|
DefaultIsland, DefaultIslandType)
|
45
45
|
|
46
46
|
from pythagoras._03_autonomous_functions.autonomous_funcs import (
|
47
|
-
AutonomousFunction
|
47
|
+
AutonomousFunction)
|
48
48
|
|
49
49
|
from pythagoras._03_autonomous_functions.autonomicity_checks import (
|
50
50
|
is_autonomous, is_loosely_autonomous, is_strictly_autonomous)
|
{pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/autonomous_decorators.py
RENAMED
@@ -66,7 +66,7 @@ class autonomous:
|
|
66
66
|
self.island_name = island_name
|
67
67
|
self.require_pth = require_pth
|
68
68
|
|
69
|
-
def __call__(self, a_func: Callable) ->
|
69
|
+
def __call__(self, a_func: Callable) -> AutonomousFunction:
|
70
70
|
"""Decorator for autonomous functions.
|
71
71
|
|
72
72
|
It does both static and dynamic checks for autonomous functions.
|
{pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_03_autonomous_functions/autonomous_funcs.py
RENAMED
@@ -4,7 +4,7 @@ import sys
|
|
4
4
|
import traceback
|
5
5
|
from typing import Callable, Optional, Any
|
6
6
|
from persidict import replace_unsafe_chars
|
7
|
-
|
7
|
+
|
8
8
|
|
9
9
|
from pythagoras._02_ordinary_functions.ordinary_funcs import (
|
10
10
|
OrdinaryFunction)
|
@@ -18,15 +18,16 @@ from pythagoras._03_autonomous_functions.call_graph_explorer import (
|
|
18
18
|
from pythagoras._03_autonomous_functions.names_usage_analyzer import (
|
19
19
|
analyze_names_in_function)
|
20
20
|
|
21
|
-
from pythagoras.
|
22
|
-
|
21
|
+
from pythagoras._03_autonomous_functions.pth_available_names_retriever import (
|
22
|
+
retrieve_objs_available_inside_autonomous_functions)
|
23
23
|
|
24
|
-
from pythagoras._05_events_and_exceptions.
|
25
|
-
|
24
|
+
from pythagoras._05_events_and_exceptions.global_event_loggers import (
|
25
|
+
register_exception_globally)
|
26
26
|
|
27
27
|
from pythagoras._06_mission_control.global_state_management import (
|
28
28
|
is_correctly_initialized)
|
29
29
|
|
30
|
+
import pythagoras as pth
|
30
31
|
|
31
32
|
|
32
33
|
class AutonomousFunction(OrdinaryFunction):
|
@@ -123,6 +124,8 @@ class AutonomousFunction(OrdinaryFunction):
|
|
123
124
|
import_required -= set(pth.primary_decorators)
|
124
125
|
builtin_names = set(dir(builtins))
|
125
126
|
import_required -= builtin_names
|
127
|
+
pth_names = set(retrieve_objs_available_inside_autonomous_functions())
|
128
|
+
import_required -= pth_names
|
126
129
|
import_required -= {name}
|
127
130
|
if self.island_name is not None:
|
128
131
|
island = pth.all_autonomous_functions[self.island_name]
|
@@ -146,7 +149,7 @@ class AutonomousFunction(OrdinaryFunction):
|
|
146
149
|
def execute(self, **kwargs) -> Any:
|
147
150
|
try:
|
148
151
|
assert self.runtime_checks()
|
149
|
-
names_dict =
|
152
|
+
names_dict = retrieve_objs_available_inside_autonomous_functions()
|
150
153
|
island = pth.all_autonomous_functions[self.island_name]
|
151
154
|
names_dict["_pth_kwargs"] = kwargs
|
152
155
|
if self.island_name is not None:
|
@@ -155,6 +158,7 @@ class AutonomousFunction(OrdinaryFunction):
|
|
155
158
|
else:
|
156
159
|
names_dict[self.name] = island[self.name]
|
157
160
|
|
161
|
+
|
158
162
|
tmp_name = "_pth_tmp_" + self.name
|
159
163
|
source_to_exec = self.naked_source_code + "\n"
|
160
164
|
source_to_exec = source_to_exec.replace(
|
@@ -164,7 +168,11 @@ class AutonomousFunction(OrdinaryFunction):
|
|
164
168
|
result = names_dict["_pth_result"]
|
165
169
|
return result
|
166
170
|
except Exception as e:
|
167
|
-
|
171
|
+
if self.__class__ == AutonomousFunction:
|
172
|
+
exception_id = f"{self.name}_{self.island_name}"
|
173
|
+
exception_id += f"_{e.__class__.__name__}"
|
174
|
+
exception_id += f"_{pth.get_random_signature()}"
|
175
|
+
register_exception_globally(exception_id=exception_id)
|
168
176
|
raise e
|
169
177
|
|
170
178
|
def __call__(self, **kwargs) -> Any:
|
@@ -231,61 +239,4 @@ def register_autonomous_function(f: AutonomousFunction) -> None:
|
|
231
239
|
if f is not pth.all_autonomous_functions[f.island_name][f.name]:
|
232
240
|
assert not hasattr(f, "_static_checks_passed")
|
233
241
|
assert not hasattr(f, "_runtime_checks_passed")
|
234
|
-
assert not hasattr(f, "_dependencies")
|
235
|
-
|
236
|
-
|
237
|
-
class EventPosterFactory:
|
238
|
-
def __init__(self, silent:bool = False):
|
239
|
-
assert isinstance(silent, bool)
|
240
|
-
self.silent = silent
|
241
|
-
|
242
|
-
def __getitem__(self, item:str)-> EventPoster:
|
243
|
-
assert isinstance(item, str)
|
244
|
-
return EventPoster(item, silent=self.silent)
|
245
|
-
|
246
|
-
class EventPoster:
|
247
|
-
def __init__(self, label:str, silent:bool = False):
|
248
|
-
assert isinstance(label, str)
|
249
|
-
assert label == replace_unsafe_chars(label, "")
|
250
|
-
assert 0 < len(label) < 25
|
251
|
-
self.label = label
|
252
|
-
self.silent = silent
|
253
|
-
|
254
|
-
def __call__(self, **event_args)-> None:
|
255
|
-
callers = find_local_var_in_callstack(name_to_find="self"
|
256
|
-
, class_to_find=AutonomousFunction)
|
257
|
-
caller_name = ""
|
258
|
-
if len(callers) > 0:
|
259
|
-
caller_name = callers[0].name
|
260
|
-
caller_prefix = caller_name + "_"
|
261
|
-
caller_type = callers[0].__class__.__name__
|
262
|
-
else:
|
263
|
-
caller_name = "__none__"
|
264
|
-
caller_prefix = caller_name
|
265
|
-
caller_type = "AutonomousFunction"
|
266
|
-
prefix = caller_prefix + self.label
|
267
|
-
logger = EventLogger(event_log=pth.global_event_log
|
268
|
-
, prefix=prefix, save_context=False)
|
269
|
-
|
270
|
-
if not self.silent:
|
271
|
-
print(30*"~")
|
272
|
-
print(f"Event '{self.label}' "
|
273
|
-
+ f"inside an {caller_type} '{caller_name}':")
|
274
|
-
for key, value in event_args.items():
|
275
|
-
print(f" {key} = {value}")
|
276
|
-
print()
|
277
|
-
|
278
|
-
label_arg_name = "event_label"
|
279
|
-
while label_arg_name in event_args:
|
280
|
-
label_arg_name += "_"
|
281
|
-
event_args[label_arg_name] = self.label
|
282
|
-
|
283
|
-
caller_arg_name = "caller_name"
|
284
|
-
while caller_arg_name in event_args:
|
285
|
-
caller_arg_name += "_"
|
286
|
-
event_args[caller_arg_name] = caller_name
|
287
|
-
|
288
|
-
logger.log_event(**event_args)
|
289
|
-
|
290
|
-
post_event: EventPosterFactory = EventPosterFactory(silent=True)
|
291
|
-
print_event: EventPosterFactory = EventPosterFactory(silent=False)
|
242
|
+
assert not hasattr(f, "_dependencies")
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import sys
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
|
5
|
+
def retrieve_objs_available_inside_autonomous_functions() -> dict[str,Any]:
|
6
|
+
"""Names available inside autonomous functions without explicit import.
|
7
|
+
|
8
|
+
"""
|
9
|
+
result = dict(
|
10
|
+
pth = sys.modules['pythagoras']
|
11
|
+
, post_event = sys.modules['pythagoras'].post_event
|
12
|
+
)
|
13
|
+
return result
|
@@ -2,7 +2,9 @@ from pythagoras._04_idempotent_functions.kw_args import (
|
|
2
2
|
SortedKwArgs, PackedKwArgs, UnpackedKwArgs)
|
3
3
|
|
4
4
|
from pythagoras._04_idempotent_functions.idempotent_func_and_address import (
|
5
|
-
IdempotentFunction
|
5
|
+
IdempotentFunction
|
6
|
+
, FunctionExecutionResultAddress
|
7
|
+
, FunctionExecutionContext)
|
6
8
|
|
7
9
|
from pythagoras._04_idempotent_functions.idempotent_decorator import (
|
8
10
|
idempotent)
|
{pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_04_idempotent_functions/idempotent_decorator.py
RENAMED
@@ -28,7 +28,7 @@ class idempotent:
|
|
28
28
|
self.require_pth = require_pth
|
29
29
|
|
30
30
|
|
31
|
-
def __call__(self, a_func:Callable) ->
|
31
|
+
def __call__(self, a_func:Callable) -> IdempotentFunction:
|
32
32
|
if not self.require_pth and is_fully_unitialized():
|
33
33
|
wrapper = a_func
|
34
34
|
logging.warning(f"Decorator @{self.__class__.__name__}()"
|
@@ -1,10 +1,13 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import time
|
4
|
+
import traceback
|
4
5
|
from typing import Callable, Any
|
5
6
|
|
7
|
+
from persidict import PersiDict
|
8
|
+
|
6
9
|
import pythagoras as pth
|
7
|
-
from pythagoras import get_random_signature
|
10
|
+
from pythagoras import get_random_signature, OutputCapturer
|
8
11
|
|
9
12
|
from pythagoras._01_foundational_objects.hash_addresses import HashAddress
|
10
13
|
from pythagoras._01_foundational_objects.value_addresses import ValueAddress
|
@@ -22,7 +25,9 @@ from pythagoras._04_idempotent_functions.kw_args import (
|
|
22
25
|
UnpackedKwArgs, PackedKwArgs, SortedKwArgs)
|
23
26
|
from pythagoras._04_idempotent_functions.process_augmented_func_src import (
|
24
27
|
process_augmented_func_src)
|
25
|
-
from pythagoras._05_events_and_exceptions.context_utils import build_context
|
28
|
+
from pythagoras._05_events_and_exceptions.context_utils import build_context, add_context
|
29
|
+
from pythagoras._05_events_and_exceptions.global_event_loggers import (
|
30
|
+
register_exception_globally, register_event_globally)
|
26
31
|
|
27
32
|
|
28
33
|
class IdempotentFunction(AutonomousFunction):
|
@@ -108,21 +113,26 @@ class IdempotentFunction(AutonomousFunction):
|
|
108
113
|
|
109
114
|
self.augmented_code_checked = True
|
110
115
|
|
116
|
+
def get_address(self, **kwargs) -> FunctionExecutionResultAddress:
|
117
|
+
packed_kwargs = PackedKwArgs(**kwargs)
|
118
|
+
output_address = FunctionExecutionResultAddress(self, packed_kwargs)
|
119
|
+
return output_address
|
120
|
+
|
111
121
|
|
112
122
|
def execute(self, **kwargs) -> Any:
|
113
123
|
packed_kwargs = PackedKwArgs(**kwargs)
|
114
|
-
output_address =
|
124
|
+
output_address = FunctionExecutionResultAddress(self, packed_kwargs)
|
115
125
|
_pth_f_addr_ = output_address
|
116
126
|
if output_address.ready:
|
117
127
|
return output_address.get()
|
118
|
-
output_address
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
128
|
+
with FunctionExecutionContext(output_address) as _pth_ec:
|
129
|
+
output_address.request_execution()
|
130
|
+
_pth_ec.register_execution_attempt()
|
131
|
+
unpacked_kwargs = UnpackedKwArgs(**packed_kwargs)
|
132
|
+
result = super().execute(**unpacked_kwargs)
|
133
|
+
pth.execution_results[output_address] = ValueAddress(result)
|
134
|
+
output_address.drop_execution_request()
|
135
|
+
return result
|
126
136
|
|
127
137
|
def list_execute(self, list_of_kwargs:list[dict]) -> Any:
|
128
138
|
assert isinstance(list_of_kwargs, (list, tuple))
|
@@ -130,7 +140,7 @@ class IdempotentFunction(AutonomousFunction):
|
|
130
140
|
assert isinstance(kwargs, dict)
|
131
141
|
addrs = []
|
132
142
|
for kwargs in list_of_kwargs:
|
133
|
-
new_addr =
|
143
|
+
new_addr = FunctionExecutionResultAddress(self, kwargs)
|
134
144
|
new_addr.request_execution()
|
135
145
|
addrs.append(new_addr)
|
136
146
|
addrs_indexed = list(zip(range(len(addrs)), addrs))
|
@@ -141,11 +151,6 @@ class IdempotentFunction(AutonomousFunction):
|
|
141
151
|
results_list = [results_dict[n] for n in range(len(addrs))]
|
142
152
|
return results_list
|
143
153
|
|
144
|
-
def execution_attempts(self, **kwargs) -> list:
|
145
|
-
packed_kwargs = PackedKwArgs(**kwargs)
|
146
|
-
output_address = FuncOutputAddress(self, packed_kwargs)
|
147
|
-
return output_address.execution_attempts
|
148
|
-
|
149
154
|
|
150
155
|
def register_idempotent_function(f: IdempotentFunction) -> None:
|
151
156
|
"""Register an idempotent function in the Pythagoras system."""
|
@@ -166,7 +171,7 @@ class FunctionCallSignature:
|
|
166
171
|
self.f_addr = ValueAddress(f)
|
167
172
|
self.args_addr = ValueAddress(arguments.pack())
|
168
173
|
|
169
|
-
class
|
174
|
+
class FunctionExecutionResultAddress(HashAddress):
|
170
175
|
value_prefix: str|None = None
|
171
176
|
def __init__(self, f: IdempotentFunction, arguments:dict[str, Any]):
|
172
177
|
assert isinstance(f, IdempotentFunction)
|
@@ -186,16 +191,25 @@ class FuncOutputAddress(HashAddress):
|
|
186
191
|
|
187
192
|
@property
|
188
193
|
def ready(self):
|
189
|
-
result = self in pth.
|
194
|
+
result = self in pth.execution_results
|
190
195
|
return result
|
191
196
|
|
192
197
|
def request_execution(self):
|
193
|
-
|
194
|
-
|
195
|
-
|
198
|
+
request_address = self + ["execution_requested"]
|
199
|
+
if self in pth.execution_results:
|
200
|
+
if request_address in pth.operational_hub.binary:
|
201
|
+
del pth.operational_hub.binary[request_address]
|
196
202
|
else:
|
197
|
-
if
|
198
|
-
pth.
|
203
|
+
if request_address not in pth.operational_hub.binary:
|
204
|
+
pth.operational_hub.binary[request_address] = True
|
205
|
+
|
206
|
+
def drop_execution_request(self):
|
207
|
+
request_address = self + ["execution_requested"]
|
208
|
+
pth.operational_hub.binary.delete_if_exists(request_address)
|
209
|
+
|
210
|
+
def is_execution_requested(self):
|
211
|
+
request_address = self + ["execution_requested"]
|
212
|
+
return request_address in pth.operational_hub.binary
|
199
213
|
|
200
214
|
def get(self, timeout: int = None):
|
201
215
|
"""Retrieve value, referenced by the address.
|
@@ -204,7 +218,7 @@ class FuncOutputAddress(HashAddress):
|
|
204
218
|
till timeout is exceeded. If timeout is None, keep trying forever.
|
205
219
|
"""
|
206
220
|
if self.ready:
|
207
|
-
return pth.
|
221
|
+
return pth.value_store[pth.execution_results[self]]
|
208
222
|
self.request_execution()
|
209
223
|
|
210
224
|
start_time, backoff_period = time.time(), 1.0
|
@@ -213,8 +227,8 @@ class FuncOutputAddress(HashAddress):
|
|
213
227
|
|
214
228
|
while True:
|
215
229
|
if self.ready:
|
216
|
-
result = pth.
|
217
|
-
|
230
|
+
result = pth.value_store[pth.execution_results[self]]
|
231
|
+
self.drop_execution_request()
|
218
232
|
return result
|
219
233
|
else:
|
220
234
|
time.sleep(backoff_period)
|
@@ -273,7 +287,7 @@ class FuncOutputAddress(HashAddress):
|
|
273
287
|
# TODO: these should not be constants
|
274
288
|
if self.ready:
|
275
289
|
return False
|
276
|
-
past_attempts =
|
290
|
+
past_attempts = self.execution_attempts
|
277
291
|
n_past_attempts = len(past_attempts)
|
278
292
|
if n_past_attempts == 0:
|
279
293
|
return True
|
@@ -289,12 +303,89 @@ class FuncOutputAddress(HashAddress):
|
|
289
303
|
return False
|
290
304
|
|
291
305
|
@property
|
292
|
-
def execution_attempts(self) ->
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
306
|
+
def execution_attempts(self) -> PersiDict:
|
307
|
+
attempts_path = self + ["attempts"]
|
308
|
+
attempts = pth.operational_hub.jason.get_subdict(attempts_path)
|
309
|
+
return attempts
|
310
|
+
|
311
|
+
@property
|
312
|
+
def execution_outputs(self) -> PersiDict:
|
313
|
+
outputs_path = self + ["outputs"]
|
314
|
+
outputs = pth.operational_hub.text.get_subdict(outputs_path)
|
315
|
+
return outputs
|
300
316
|
|
317
|
+
@property
|
318
|
+
def crashes(self) -> PersiDict:
|
319
|
+
crashes_path = self + ["crashes"]
|
320
|
+
crashes = pth.operational_hub.jason.get_subdict(crashes_path)
|
321
|
+
return crashes
|
322
|
+
|
323
|
+
@property
|
324
|
+
def events(self) -> PersiDict:
|
325
|
+
events_path = self + ["events"]
|
326
|
+
events = pth.operational_hub.jason.get_subdict(events_path)
|
327
|
+
return events
|
328
|
+
|
329
|
+
class FunctionExecutionContext:
|
330
|
+
session_id: str
|
331
|
+
f_address: FunctionExecutionResultAddress
|
332
|
+
output_capturer = OutputCapturer
|
333
|
+
exception_counter: int
|
334
|
+
event_counter: int
|
335
|
+
|
336
|
+
def __init__(self, f_address: FunctionExecutionResultAddress):
|
337
|
+
self.session_id = get_random_signature()
|
338
|
+
self.f_address = f_address
|
339
|
+
self.output_capturer = OutputCapturer()
|
340
|
+
self.exception_counter = 0
|
341
|
+
self.event_counter = 0
|
342
|
+
|
343
|
+
def __enter__(self):
|
344
|
+
self.output_capturer.__enter__()
|
345
|
+
return self
|
346
|
+
|
347
|
+
def __exit__(self, exc_type, exc_value, trace_back):
|
348
|
+
self.output_capturer.__exit__(exc_type, exc_value, traceback)
|
349
|
+
|
350
|
+
output_id = self.session_id+"_o"
|
351
|
+
execution_outputs = self.f_address.execution_outputs
|
352
|
+
execution_outputs[output_id] = self.output_capturer.get_output()
|
353
|
+
|
354
|
+
self.register_exception(
|
355
|
+
exc_type=exc_type, exc_value=exc_value, trace_back=trace_back)
|
356
|
+
|
357
|
+
|
358
|
+
def register_execution_attempt(self):
|
359
|
+
execution_attempts = self.f_address.execution_attempts
|
360
|
+
attempt_id = self.session_id+"_a"
|
361
|
+
execution_attempts[attempt_id] = build_context()
|
362
|
+
|
363
|
+
|
364
|
+
def register_exception(self,exc_type, exc_value, trace_back, **kwargs):
|
365
|
+
if exc_value is None:
|
366
|
+
return
|
367
|
+
exception_id = self.session_id + f"_c_{self.exception_counter}"
|
368
|
+
self.f_address.crashes[exception_id] = add_context(
|
369
|
+
**kwargs, exc_value=exc_value)
|
370
|
+
self.exception_counter += 1
|
371
|
+
exception_id = exc_type.__name__ + "_"+ exception_id
|
372
|
+
exception_id = self.f_address.island_name + "_" + exception_id
|
373
|
+
exception_id = self.f_address.f_name + "_" + exception_id
|
374
|
+
register_exception_globally(**kwargs, exception_id=exception_id)
|
375
|
+
|
376
|
+
def register_event(self, event_type:str|None=None, **kwargs):
|
377
|
+
event_id = self.session_id + f"_e_{self.event_counter}"
|
378
|
+
if event_type is not None:
|
379
|
+
event_id += "_"+ event_type
|
380
|
+
events = self.f_address.events
|
381
|
+
events[event_id] = add_context(**kwargs, event_type=event_type)
|
382
|
+
|
383
|
+
event_id = self.session_id + f"_e_{self.event_counter}"
|
384
|
+
if event_type is not None:
|
385
|
+
kwargs["event_type"] = event_type
|
386
|
+
event_id = event_type + "_"+ event_id
|
387
|
+
event_id = self.f_address.island_name + "_" + event_id
|
388
|
+
event_id = self.f_address.f_name + "_" + event_id
|
389
|
+
register_event_globally(**kwargs, event_id=event_id)
|
390
|
+
|
391
|
+
self.event_counter += 1
|
@@ -25,7 +25,7 @@ class SortedKwArgs(dict):
|
|
25
25
|
unpacked_copy = dict()
|
26
26
|
for k,v in self.items():
|
27
27
|
if isinstance(v, ValueAddress):
|
28
|
-
unpacked_copy[k] = pth.
|
28
|
+
unpacked_copy[k] = pth.value_store[v]
|
29
29
|
else:
|
30
30
|
unpacked_copy[k] = v
|
31
31
|
return unpacked_copy
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
from pythagoras._01_foundational_objects.hash_and_random_signatures import (
|
3
|
+
get_random_signature)
|
4
|
+
from pythagoras._05_events_and_exceptions.type_retrievers import (
|
5
|
+
retrieve_FunctionExecutionContext_class)
|
6
|
+
from pythagoras._05_events_and_exceptions.find_in_callstack import \
|
7
|
+
find_local_var_in_callstack
|
8
|
+
from pythagoras._05_events_and_exceptions.global_event_loggers import (
|
9
|
+
register_event_globally)
|
10
|
+
|
11
|
+
import pythagoras as pth
|
12
|
+
|
13
|
+
|
14
|
+
def get_current_function_execution_context():
|
15
|
+
all_context_objects = find_local_var_in_callstack(name_to_find="_pth_ec"
|
16
|
+
, class_to_find=retrieve_FunctionExecutionContext_class())
|
17
|
+
if len(all_context_objects) > 0:
|
18
|
+
return all_context_objects[0]
|
19
|
+
else:
|
20
|
+
return None
|
21
|
+
|
22
|
+
|
23
|
+
class EventPosterFactory:
|
24
|
+
def __init__(self):
|
25
|
+
pass
|
26
|
+
|
27
|
+
def __getitem__(self, item):
|
28
|
+
return EventPoster(event_type = item)
|
29
|
+
|
30
|
+
def __call__(self, **kwargs):
|
31
|
+
return EventPoster(event_type = None)(**kwargs)
|
32
|
+
|
33
|
+
class EventPoster:
|
34
|
+
def __init__(self, event_type: str|None):
|
35
|
+
assert isinstance(event_type, (str, type(None)))
|
36
|
+
self.event_type = event_type
|
37
|
+
|
38
|
+
def __call__(self,**kwargs) -> None:
|
39
|
+
assert pth.is_correctly_initialized(), (
|
40
|
+
"The Pythagoras package has not been correctly initialized.")
|
41
|
+
context = get_current_function_execution_context()
|
42
|
+
if context is not None:
|
43
|
+
context.register_event(event_type = self.event_type, **kwargs)
|
44
|
+
else:
|
45
|
+
if self.event_type is not None:
|
46
|
+
kwargs["event_type"] = self.event_type
|
47
|
+
event_id = self.event_type + "_" + get_random_signature()
|
48
|
+
else:
|
49
|
+
event_id = get_random_signature()
|
50
|
+
register_event_globally(**kwargs, event_id = event_id)
|
51
|
+
|
52
|
+
post_event = EventPosterFactory()
|
53
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
from pythagoras._05_events_and_exceptions.context_utils import add_context
|
4
|
+
from pythagoras._05_events_and_exceptions.current_date_gmt_str import (
|
5
|
+
current_date_gmt_string)
|
6
|
+
from pythagoras import get_random_signature
|
7
|
+
|
8
|
+
import pythagoras as pth
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
def register_exception_globally(exception_id = None, **kwargs):
|
13
|
+
path = current_date_gmt_string()
|
14
|
+
exc_type, exc_value, trace_back = sys.exc_info()
|
15
|
+
if exception_id is None:
|
16
|
+
exception_id = exc_type.__name__ + "_" + get_random_signature()
|
17
|
+
full_path = [path, exception_id]
|
18
|
+
pth.crash_history[full_path] = add_context(
|
19
|
+
exc_value=exc_value, **kwargs)
|
20
|
+
|
21
|
+
|
22
|
+
def register_event_globally(event_id = None, **kwargs):
|
23
|
+
path = current_date_gmt_string()
|
24
|
+
if event_id is None:
|
25
|
+
event_id = get_random_signature()
|
26
|
+
full_path = [path, event_id]
|
27
|
+
pth.event_log[full_path] = add_context(**kwargs)
|
{pythagoras-0.8.14 → pythagoras-0.9.1}/pythagoras/_05_events_and_exceptions/type_retrievers.py
RENAMED
@@ -18,13 +18,22 @@ def retrieve_AutonomousFunction_class() -> type:
|
|
18
18
|
return sys.modules['pythagoras'].AutonomousFunction
|
19
19
|
|
20
20
|
|
21
|
-
def
|
22
|
-
"""Return the
|
21
|
+
def retrieve_FunctionExecutionResultAddress_class() -> type:
|
22
|
+
"""Return the FunctionExecutionResultAddress class.
|
23
23
|
|
24
24
|
This is for-internal-use-only function, created to
|
25
25
|
avoid circular import dependencies.
|
26
26
|
"""
|
27
|
-
return sys.modules['pythagoras'].
|
27
|
+
return sys.modules['pythagoras'].FunctionExecutionResultAddress
|
28
|
+
|
29
|
+
|
30
|
+
def retrieve_FunctionExecutionContext_class() -> type:
|
31
|
+
"""Return the FunctionExecutionContext class.
|
32
|
+
|
33
|
+
This is for-internal-use-only function, created to
|
34
|
+
avoid circular import dependencies.
|
35
|
+
"""
|
36
|
+
return sys.modules['pythagoras'].FunctionExecutionContext
|
28
37
|
|
29
38
|
|
30
39
|
|
@@ -1,14 +1,14 @@
|
|
1
1
|
import sys, traceback
|
2
2
|
|
3
3
|
from pythagoras._05_events_and_exceptions.notebook_checker import is_executed_in_notebook
|
4
|
-
from pythagoras._05_events_and_exceptions.
|
5
|
-
|
4
|
+
from pythagoras._05_events_and_exceptions.global_event_loggers import (
|
5
|
+
register_exception_globally)
|
6
6
|
|
7
7
|
import pythagoras as pth
|
8
8
|
|
9
9
|
|
10
10
|
# def log_uncaught_exception(exception: Exception, **kwargs):
|
11
|
-
# logger = EventLogger(event_log = pth.
|
11
|
+
# logger = EventLogger(event_log = pth.crash_history
|
12
12
|
# , prefix = "__none__"+ exception.__class__.__name__
|
13
13
|
# , save_context = True)
|
14
14
|
# logger.log_event(exception=exception, **kwargs)
|
@@ -21,7 +21,7 @@ def pth_excepthook(exc_type, exc_value, trace_back) -> None:
|
|
21
21
|
# exc_type, exc_value, trace_back)
|
22
22
|
# log_uncaught_exception(exception = exc_value
|
23
23
|
# , exception_description = exception_description)
|
24
|
-
|
24
|
+
register_exception_globally()
|
25
25
|
sys.__excepthook__(exc_type, exc_value, trace_back)
|
26
26
|
|
27
27
|
def pth_excepthandler(_, exc_type, exc_value
|
@@ -30,7 +30,7 @@ def pth_excepthandler(_, exc_type, exc_value
|
|
30
30
|
# exc_type, exc_value, trace_back)
|
31
31
|
# log_uncaught_exception(exception=exc_value
|
32
32
|
# , exception_description=exception_description)
|
33
|
-
|
33
|
+
register_exception_globally()
|
34
34
|
traceback.print_exception(exc_type, exc_value, trace_back)
|
35
35
|
|
36
36
|
|