pythagoras 0.24.3__py3-none-any.whl → 0.24.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pythagoras/_020_ordinary_code_portals/code_normalizer.py +37 -9
- pythagoras/_020_ordinary_code_portals/function_processing.py +58 -15
- pythagoras/_020_ordinary_code_portals/ordinary_decorator.py +14 -0
- pythagoras/_020_ordinary_code_portals/ordinary_portal_core_classes.py +196 -24
- pythagoras/_030_data_portals/data_portal_core_classes.py +74 -22
- pythagoras/_030_data_portals/ready_and_get.py +45 -4
- pythagoras/_030_data_portals/storable_decorator.py +18 -1
- pythagoras/_040_logging_code_portals/exception_processing_tracking.py +30 -2
- pythagoras/_040_logging_code_portals/execution_environment_summary.py +60 -24
- pythagoras/_040_logging_code_portals/kw_args.py +74 -12
- pythagoras/_040_logging_code_portals/logging_decorator.py +23 -1
- pythagoras/_040_logging_code_portals/logging_portal_core_classes.py +365 -12
- pythagoras/_040_logging_code_portals/notebook_checker.py +9 -1
- pythagoras/_040_logging_code_portals/uncaught_exceptions.py +40 -0
- pythagoras/_050_safe_code_portals/safe_decorator.py +27 -1
- pythagoras/_050_safe_code_portals/safe_portal_core_classes.py +87 -11
- pythagoras/_090_swarming_portals/swarming_portals.py +4 -6
- {pythagoras-0.24.3.dist-info → pythagoras-0.24.4.dist-info}/METADATA +1 -1
- {pythagoras-0.24.3.dist-info → pythagoras-0.24.4.dist-info}/RECORD +20 -20
- {pythagoras-0.24.3.dist-info → pythagoras-0.24.4.dist-info}/WHEEL +0 -0
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
_is_in_notebook: bool|None = None
|
|
3
3
|
|
|
4
4
|
def is_executed_in_notebook() -> bool:
|
|
5
|
-
"""
|
|
5
|
+
"""Return whether code is running inside a Jupyter/IPython notebook.
|
|
6
|
+
|
|
7
|
+
Uses a lightweight heuristic: checks if IPython is present and whether the
|
|
8
|
+
current shell exposes the set_custom_exc attribute, which is specific to
|
|
9
|
+
IPython interactive environments (including Jupyter).
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
bool: True if running inside a Jupyter/IPython notebook, False otherwise.
|
|
13
|
+
"""
|
|
6
14
|
global _is_in_notebook
|
|
7
15
|
if _is_in_notebook is not None:
|
|
8
16
|
return _is_in_notebook
|
|
@@ -16,6 +16,17 @@ from .._800_signatures_and_converters.random_signatures import (
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def pth_excepthook(exc_type, exc_value, trace_back) -> None:
|
|
19
|
+
"""sys.excepthook replacement that logs uncaught exceptions.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
exc_type: The exception class.
|
|
23
|
+
exc_value: The exception instance.
|
|
24
|
+
trace_back: Traceback object for the exception.
|
|
25
|
+
|
|
26
|
+
Side Effects:
|
|
27
|
+
- Records the exception in the active LoggingCodePortal's crash history.
|
|
28
|
+
- Calls the original sys.__excepthook__ after logging.
|
|
29
|
+
"""
|
|
19
30
|
if _exception_needs_to_be_processed(exc_type, exc_value, trace_back):
|
|
20
31
|
exception_id = "app_"+ get_random_signature() + "_crash"
|
|
21
32
|
event_body = add_execution_environment_summary(
|
|
@@ -30,6 +41,17 @@ def pth_excepthook(exc_type, exc_value, trace_back) -> None:
|
|
|
30
41
|
|
|
31
42
|
def pth_excepthandler(_, exc_type, exc_value
|
|
32
43
|
, trace_back, tb_offset=None) -> None:
|
|
44
|
+
"""IPython custom exception handler that logs uncaught exceptions.
|
|
45
|
+
|
|
46
|
+
This signature matches IPython's set_custom_exc handler protocol.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
_: Unused first parameter required by IPython.
|
|
50
|
+
exc_type: The exception class.
|
|
51
|
+
exc_value: The exception instance.
|
|
52
|
+
trace_back: Traceback object for the exception.
|
|
53
|
+
tb_offset: Optional traceback offset used by IPython. Unused.
|
|
54
|
+
"""
|
|
33
55
|
if _exception_needs_to_be_processed(exc_type, exc_value, trace_back):
|
|
34
56
|
exception_id = "app_" + get_random_signature() + "_crash"
|
|
35
57
|
event_body = add_execution_environment_summary(
|
|
@@ -45,6 +67,15 @@ _previous_excepthook = None
|
|
|
45
67
|
_number_of_handlers_registrations = 0
|
|
46
68
|
|
|
47
69
|
def register_systemwide_uncaught_exception_handlers() -> None:
|
|
70
|
+
"""Install Pythagoras handlers for uncaught exceptions system-wide.
|
|
71
|
+
|
|
72
|
+
In standard Python, replaces sys.excepthook; in Jupyter/IPython,
|
|
73
|
+
registers a custom exception handler via IPython.set_custom_exc when
|
|
74
|
+
available. Multiple registrations are reference-counted and idempotent.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
None
|
|
78
|
+
"""
|
|
48
79
|
global _number_of_handlers_registrations, _previous_excepthook
|
|
49
80
|
_number_of_handlers_registrations += 1
|
|
50
81
|
if _number_of_handlers_registrations > 1:
|
|
@@ -64,6 +95,15 @@ def register_systemwide_uncaught_exception_handlers() -> None:
|
|
|
64
95
|
|
|
65
96
|
|
|
66
97
|
def unregister_systemwide_uncaught_exception_handlers() -> None:
|
|
98
|
+
"""Uninstall previously registered Pythagoras exception handlers.
|
|
99
|
+
|
|
100
|
+
Decrements the registration reference counter. When it reaches zero,
|
|
101
|
+
restores the previous sys.excepthook (if any) and removes the custom
|
|
102
|
+
IPython exception handler in notebook environments.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
None
|
|
106
|
+
"""
|
|
67
107
|
global _number_of_handlers_registrations, _previous_excepthook
|
|
68
108
|
_number_of_handlers_registrations -= 1
|
|
69
109
|
if _number_of_handlers_registrations > 0:
|
|
@@ -7,12 +7,29 @@ from .safe_portal_core_classes import SafeFn, SafeCodePortal
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class safe(logging):
|
|
10
|
-
"""
|
|
10
|
+
"""Decorator that wraps a callable into a SafeFn for portal execution.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
@safe()
|
|
14
|
+
def my_fn(x: int) -> int:
|
|
15
|
+
return x + 1
|
|
16
|
+
|
|
17
|
+
Notes:
|
|
18
|
+
This decorator configures only logging-related behavior for now. Actual
|
|
19
|
+
safety/sandboxing is not yet implemented.
|
|
11
20
|
"""
|
|
12
21
|
|
|
13
22
|
def __init__(self
|
|
14
23
|
, excessive_logging: bool|None|Joker = KEEP_CURRENT
|
|
15
24
|
, portal: SafeCodePortal | None = None):
|
|
25
|
+
"""Create a safe decorator bound to an optional portal.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
excessive_logging: Whether to enable verbose logging for wrapped
|
|
29
|
+
calls. KEEP_CURRENT inherits from current context.
|
|
30
|
+
portal: The SafeCodePortal to attach the resulting SafeFn to. If
|
|
31
|
+
None, the active portal (if any) may be used by lower layers.
|
|
32
|
+
"""
|
|
16
33
|
assert isinstance(portal, SafeCodePortal) or portal is None
|
|
17
34
|
logging.__init__(self=self
|
|
18
35
|
, portal=portal
|
|
@@ -20,6 +37,15 @@ class safe(logging):
|
|
|
20
37
|
|
|
21
38
|
|
|
22
39
|
def __call__(self,fn:Callable)->SafeFn:
|
|
40
|
+
"""Wrap a Python callable into a SafeFn.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
fn: The function to wrap.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
SafeFn: The wrapped function that can be executed via a portal and
|
|
47
|
+
will record logging information.
|
|
48
|
+
"""
|
|
23
49
|
wrapper = SafeFn(fn
|
|
24
50
|
, portal=self._portal
|
|
25
51
|
, excessive_logging=self._excessive_logging)
|
|
@@ -13,20 +13,43 @@ It will be done soon by integrating https://pypi.org/project/RestrictedPython/
|
|
|
13
13
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
|
-
from typing import Callable
|
|
17
|
-
|
|
18
|
-
# from parameterizable import register_parameterizable_class
|
|
19
|
-
from persidict import PersiDict, Joker, KEEP_CURRENT
|
|
20
|
-
|
|
21
16
|
from .._040_logging_code_portals.logging_portal_core_classes import *
|
|
22
17
|
|
|
23
18
|
|
|
24
19
|
class SafeCodePortal(LoggingCodePortal):
|
|
20
|
+
"""A portal that executes functions with logging under a "safe" contract.
|
|
21
|
+
|
|
22
|
+
Currently, SafeCodePortal inherits all behavior from LoggingCodePortal.
|
|
23
|
+
True sandboxing/isolation has not yet been implemented and will be
|
|
24
|
+
introduced in the future (see Notes).
|
|
25
|
+
|
|
26
|
+
Notes:
|
|
27
|
+
The actual safety guarantees (prohibiting access to external
|
|
28
|
+
filesystem, network, process state, etc.) are not yet enforced.
|
|
29
|
+
The plan is to integrate RestrictedPython to implement a proper
|
|
30
|
+
sandbox. Until then, SafeCodePortal behaves like LoggingCodePortal
|
|
31
|
+
but keeps the API intended for safe execution.
|
|
32
|
+
"""
|
|
33
|
+
|
|
25
34
|
def __init__(self
|
|
26
35
|
, root_dict: PersiDict|str|None = None
|
|
27
36
|
, p_consistency_checks: float|Joker = KEEP_CURRENT
|
|
28
37
|
, excessive_logging: bool|Joker = KEEP_CURRENT
|
|
29
38
|
):
|
|
39
|
+
"""Initialize a SafeCodePortal.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
root_dict: Root persistent dictionary or its path used by the
|
|
43
|
+
underlying data portal for storing execution artifacts. If a
|
|
44
|
+
string is provided, it is treated as a path on disk. If None,
|
|
45
|
+
an in-memory structure may be used (depending on configuration).
|
|
46
|
+
p_consistency_checks: Probability in [0, 1] of running additional
|
|
47
|
+
consistency checks on persistent state mutations. Use
|
|
48
|
+
KEEP_CURRENT to inherit the active setting from parent context.
|
|
49
|
+
excessive_logging: Whether to enable verbose logging of execution
|
|
50
|
+
attempts, results, outputs and events. Use KEEP_CURRENT to
|
|
51
|
+
inherit the active setting from parent context.
|
|
52
|
+
"""
|
|
30
53
|
LoggingCodePortal.__init__(self
|
|
31
54
|
, root_dict=root_dict
|
|
32
55
|
, p_consistency_checks=p_consistency_checks
|
|
@@ -34,26 +57,60 @@ class SafeCodePortal(LoggingCodePortal):
|
|
|
34
57
|
|
|
35
58
|
|
|
36
59
|
class SafeFnCallSignature(LoggingFnCallSignature):
|
|
37
|
-
"""A signature
|
|
60
|
+
"""A signature object describing a call to a SafeFn.
|
|
61
|
+
|
|
62
|
+
This specialization only narrows the types returned by some accessors
|
|
63
|
+
(e.g., fn) to Safe* counterparts. All logging behavior and storage layout
|
|
64
|
+
are inherited from LoggingFnCallSignature.
|
|
65
|
+
"""
|
|
38
66
|
_fn_cache: SafeFn | None
|
|
39
67
|
|
|
40
68
|
def __init__(self, fn: SafeFn, arguments: dict):
|
|
69
|
+
"""Construct a signature for a specific SafeFn call.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
fn: The safe function object to be called.
|
|
73
|
+
arguments: The keyword arguments to use for the call.
|
|
74
|
+
"""
|
|
41
75
|
assert isinstance(fn, SafeFn)
|
|
42
76
|
assert isinstance(arguments, dict)
|
|
43
77
|
super().__init__(fn, arguments)
|
|
44
78
|
|
|
45
79
|
@property
|
|
46
80
|
def fn(self) -> SafeFn:
|
|
47
|
-
"""Return the
|
|
81
|
+
"""Return the SafeFn referenced by this signature.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
SafeFn: The underlying safe function instance.
|
|
85
|
+
"""
|
|
48
86
|
return super().fn
|
|
49
87
|
|
|
50
88
|
|
|
51
89
|
class SafeFn(LoggingFn):
|
|
90
|
+
"""A function wrapper intended for safe execution within a portal.
|
|
91
|
+
|
|
92
|
+
SafeFn currently behaves like LoggingFn, adding only type-narrowed
|
|
93
|
+
accessors for convenience. Future versions will enforce sandboxed
|
|
94
|
+
execution (see Notes).
|
|
95
|
+
|
|
96
|
+
Notes:
|
|
97
|
+
No actual sandboxing is performed yet. Behavior equals LoggingFn.
|
|
98
|
+
"""
|
|
99
|
+
|
|
52
100
|
def __init__(self
|
|
53
101
|
, fn: Callable|str
|
|
54
102
|
, portal: LoggingCodePortal|None = None
|
|
55
103
|
, excessive_logging: bool|Joker = KEEP_CURRENT
|
|
56
104
|
):
|
|
105
|
+
"""Create a SafeFn wrapper.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
fn: The Python callable to wrap or its import string.
|
|
109
|
+
portal: The portal to associate with this function. If None, the
|
|
110
|
+
active portal (if any) may be used by the underlying layers.
|
|
111
|
+
excessive_logging: Whether to enable verbose logging for this fn.
|
|
112
|
+
Use KEEP_CURRENT to inherit from the surrounding context.
|
|
113
|
+
"""
|
|
57
114
|
LoggingFn.__init__(self
|
|
58
115
|
, fn = fn
|
|
59
116
|
, portal=portal
|
|
@@ -61,23 +118,42 @@ class SafeFn(LoggingFn):
|
|
|
61
118
|
|
|
62
119
|
|
|
63
120
|
def __getstate__(self):
|
|
64
|
-
"""
|
|
121
|
+
"""Return picklable state.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
dict: The state returned by the parent LoggingFn for pickling.
|
|
125
|
+
"""
|
|
65
126
|
state = super().__getstate__()
|
|
66
127
|
return state
|
|
67
128
|
|
|
68
129
|
|
|
69
130
|
def __setstate__(self, state):
|
|
70
|
-
"""
|
|
131
|
+
"""Restore object state after unpickling.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
state: The state previously produced by __getstate__.
|
|
135
|
+
"""
|
|
71
136
|
super().__setstate__(state)
|
|
72
137
|
|
|
73
138
|
|
|
74
139
|
@property
|
|
75
140
|
def portal(self) -> SafeCodePortal:
|
|
141
|
+
"""Return the associated SafeCodePortal.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
SafeCodePortal: The portal that owns this function.
|
|
145
|
+
"""
|
|
76
146
|
return super().portal
|
|
77
147
|
|
|
78
148
|
|
|
79
149
|
def get_signature(self, arguments:dict) -> SafeFnCallSignature:
|
|
80
|
-
|
|
150
|
+
"""Create a SafeFnCallSignature for a given call.
|
|
81
151
|
|
|
152
|
+
Args:
|
|
153
|
+
arguments: The keyword arguments for the call.
|
|
82
154
|
|
|
83
|
-
|
|
155
|
+
Returns:
|
|
156
|
+
SafeFnCallSignature: A typed call signature suitable for execution
|
|
157
|
+
and logging through the portal.
|
|
158
|
+
"""
|
|
159
|
+
return SafeFnCallSignature(fn=self, arguments=arguments)
|
|
@@ -23,7 +23,7 @@ from parameterizable import (
|
|
|
23
23
|
access_jsparams)
|
|
24
24
|
from persidict import PersiDict, Joker, KEEP_CURRENT
|
|
25
25
|
|
|
26
|
-
from parameterizable
|
|
26
|
+
from parameterizable import *
|
|
27
27
|
|
|
28
28
|
from .. import VALIDATION_SUCCESSFUL
|
|
29
29
|
from .._010_basic_portals import get_all_known_portals
|
|
@@ -212,10 +212,8 @@ class SwarmingPortal(PureCodePortal):
|
|
|
212
212
|
del self._max_n_workers_cache
|
|
213
213
|
super()._invalidate_cache()
|
|
214
214
|
|
|
215
|
-
# parameterizable.register_parameterizable_class(SwarmingPortal)
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
def _launch_many_background_workers(portal_init_jsparams:JsonSerializedParams) -> None:
|
|
216
|
+
def _launch_many_background_workers(portal_init_jsparams:JsonSerializedObject) -> None:
|
|
219
217
|
"""Launch many background worker processes."""
|
|
220
218
|
|
|
221
219
|
|
|
@@ -265,7 +263,7 @@ def _launch_many_background_workers(portal_init_jsparams:JsonSerializedParams) -
|
|
|
265
263
|
list_of_all_workers = new_list_of_all_workers
|
|
266
264
|
|
|
267
265
|
|
|
268
|
-
def _background_worker(portal_init_jsparams:
|
|
266
|
+
def _background_worker(portal_init_jsparams:JsonSerializedObject) -> None:
|
|
269
267
|
"""Background worker that keeps processing random execution requests."""
|
|
270
268
|
portal = parameterizable.loadjs(portal_init_jsparams)
|
|
271
269
|
assert isinstance(portal, SwarmingPortal)
|
|
@@ -283,7 +281,7 @@ def _background_worker(portal_init_jsparams:JsonSerializedParams) -> None:
|
|
|
283
281
|
portal._randomly_delay_execution()
|
|
284
282
|
|
|
285
283
|
|
|
286
|
-
def _process_random_execution_request(portal_init_jsparams:
|
|
284
|
+
def _process_random_execution_request(portal_init_jsparams:JsonSerializedObject):
|
|
287
285
|
"""Process one random execution request."""
|
|
288
286
|
# portal = parameterizable.get_object_from_portable_params(
|
|
289
287
|
# portal_init_params)
|
|
@@ -6,26 +6,26 @@ pythagoras/_010_basic_portals/long_infoname.py,sha256=KXOmHfQ_5hdZNqfB3Cif2CQiZ3
|
|
|
6
6
|
pythagoras/_010_basic_portals/portal_tester.py,sha256=x6HiJ3GW9XWplnsT6Ob7QCy2J_JPgGpdaJ8QRyFH-e8,3353
|
|
7
7
|
pythagoras/_010_basic_portals/post_init_metaclass.py,sha256=94FEVMCJBUReRb-fo2-LW8YWXUXw5lLLYlXMnlxHJuU,1495
|
|
8
8
|
pythagoras/_020_ordinary_code_portals/__init__.py,sha256=p3kSqaQYj0xlhk9BwptFgA1USdTbfHkAB5Q9MH-ANI0,1295
|
|
9
|
-
pythagoras/_020_ordinary_code_portals/code_normalizer.py,sha256=
|
|
10
|
-
pythagoras/_020_ordinary_code_portals/function_processing.py,sha256=
|
|
11
|
-
pythagoras/_020_ordinary_code_portals/ordinary_decorator.py,sha256=
|
|
12
|
-
pythagoras/_020_ordinary_code_portals/ordinary_portal_core_classes.py,sha256=
|
|
9
|
+
pythagoras/_020_ordinary_code_portals/code_normalizer.py,sha256=GJXvBX85W230OcwNAg8XXHAE4m39Q70piJ9g2jcIr4Q,6616
|
|
10
|
+
pythagoras/_020_ordinary_code_portals/function_processing.py,sha256=b9Y4vNf1KSRkpUfS9UmWj3N_CNuPDgUMXdnR3IeyAoM,5021
|
|
11
|
+
pythagoras/_020_ordinary_code_portals/ordinary_decorator.py,sha256=ETmy-HKRzCJfzTPOI-gelQT2tlJpVLRu4I85yv02vuo,1437
|
|
12
|
+
pythagoras/_020_ordinary_code_portals/ordinary_portal_core_classes.py,sha256=C5nobGkYZBi2IHc1Pjfxjx_8h_ajF3Sf9Jq3yxFIR68,15963
|
|
13
13
|
pythagoras/_030_data_portals/__init__.py,sha256=f_F9DCmuVgPMgzwRjuNj6FI63S3oXu7lj3zU66Nw7Hc,1427
|
|
14
|
-
pythagoras/_030_data_portals/data_portal_core_classes.py,sha256=
|
|
15
|
-
pythagoras/_030_data_portals/ready_and_get.py,sha256=
|
|
16
|
-
pythagoras/_030_data_portals/storable_decorator.py,sha256=
|
|
14
|
+
pythagoras/_030_data_portals/data_portal_core_classes.py,sha256=D_Zg-q15II7IwweEGdBAMhGt09DYN_v_G0XFb5K3WB4,22459
|
|
15
|
+
pythagoras/_030_data_portals/ready_and_get.py,sha256=lgkDygF4lFnZXcCvP5dmvzQX64wrZ8AnYJTI7v2ppng,4172
|
|
16
|
+
pythagoras/_030_data_portals/storable_decorator.py,sha256=u70K8J44NTlofc4HmKHtxxbwKdUkBz6BDsIWds4dALQ,1160
|
|
17
17
|
pythagoras/_040_logging_code_portals/__init__.py,sha256=q2hVyOVgE-9Ru3ycilK98YS9Rat8tSc6erd7AtGxpaA,996
|
|
18
|
-
pythagoras/_040_logging_code_portals/exception_processing_tracking.py,sha256=
|
|
19
|
-
pythagoras/_040_logging_code_portals/execution_environment_summary.py,sha256
|
|
20
|
-
pythagoras/_040_logging_code_portals/kw_args.py,sha256=
|
|
21
|
-
pythagoras/_040_logging_code_portals/logging_decorator.py,sha256
|
|
22
|
-
pythagoras/_040_logging_code_portals/logging_portal_core_classes.py,sha256=
|
|
23
|
-
pythagoras/_040_logging_code_portals/notebook_checker.py,sha256=
|
|
18
|
+
pythagoras/_040_logging_code_portals/exception_processing_tracking.py,sha256=DH1eeJAeVL6Fn-6sXBqx3Ocu2RXxVhLqdH1mvhM24VY,1850
|
|
19
|
+
pythagoras/_040_logging_code_portals/execution_environment_summary.py,sha256=-0ynNibGfRh3J1Sq-N9j7eN1FlGvetEBiW0L4K_qJ30,3813
|
|
20
|
+
pythagoras/_040_logging_code_portals/kw_args.py,sha256=j3Iao80gTBjPx6dk1Azd9D8pcdQ3QdfpkQtQq-4ATV0,4954
|
|
21
|
+
pythagoras/_040_logging_code_portals/logging_decorator.py,sha256=-BGduV2U5SJ40qW8afRCUMrzYv5Pf_CgB4HlSEGDmlA,1766
|
|
22
|
+
pythagoras/_040_logging_code_portals/logging_portal_core_classes.py,sha256=R--DuvPGKzEB4ojWrmmuVU2SezUBVrSXrmdFjnrf72g,34977
|
|
23
|
+
pythagoras/_040_logging_code_portals/notebook_checker.py,sha256=qO7zfMC20hM4tSxlqB7gy6WI4imWX4Xl7ojSwgeVu0A,871
|
|
24
24
|
pythagoras/_040_logging_code_portals/output_capturer.py,sha256=ohCp6qqxL7IuJGfnFuCIgj5Oc4HmC8c7uZGE_uzWkZk,4216
|
|
25
|
-
pythagoras/_040_logging_code_portals/uncaught_exceptions.py,sha256=
|
|
25
|
+
pythagoras/_040_logging_code_portals/uncaught_exceptions.py,sha256=vQrY1mOYdAeKaCmCCY1MUy4xoXurQkfwQuDA43giPl0,4564
|
|
26
26
|
pythagoras/_050_safe_code_portals/__init__.py,sha256=YR-V6W2WZ17SjqmTyY2xdY16xTVEEuLs2MddJj_WCZU,557
|
|
27
|
-
pythagoras/_050_safe_code_portals/safe_decorator.py,sha256=
|
|
28
|
-
pythagoras/_050_safe_code_portals/safe_portal_core_classes.py,sha256=
|
|
27
|
+
pythagoras/_050_safe_code_portals/safe_decorator.py,sha256=AYvX7-km2reRMZ55ndO_2IS2SfHbnpyFv79AVwGg7Po,1681
|
|
28
|
+
pythagoras/_050_safe_code_portals/safe_portal_core_classes.py,sha256=naY4R91N5bcCq8C_-YeBqhrr6UG8zkEQ5t8C3O8ytOw,5673
|
|
29
29
|
pythagoras/_060_autonomous_code_portals/__init__.py,sha256=hnv_dxxRx8c7IDf1QgVYHfYoeVAz8oD9K0oWI_o9N20,1704
|
|
30
30
|
pythagoras/_060_autonomous_code_portals/autonomous_decorators.py,sha256=diWX03jZaInc55jAg391ZRBh-St5exJRLDZiS7dqYvg,2895
|
|
31
31
|
pythagoras/_060_autonomous_code_portals/autonomous_portal_core_classes.py,sha256=21JNwBgEoIHXwCrBPb_eN5vMaHTZ98LdFkHuaMHtkI0,6665
|
|
@@ -45,7 +45,7 @@ pythagoras/_080_pure_code_portals/pure_decorator.py,sha256=WHZQzmyxgCpALHrqfeiOM
|
|
|
45
45
|
pythagoras/_080_pure_code_portals/recursion_pre_validator.py,sha256=n03ooGISJvuwNWteBN9t7CFFSLYAu86AHHFJVcywPqg,1865
|
|
46
46
|
pythagoras/_090_swarming_portals/__init__.py,sha256=TuA17PftTBudptAblNtBlD46BqUiitksOtf3y01QKm0,514
|
|
47
47
|
pythagoras/_090_swarming_portals/output_suppressor.py,sha256=ENRtQtK_-7A94lAqtUQsIWrvtcgKniEpaWcZZZrpfQM,611
|
|
48
|
-
pythagoras/_090_swarming_portals/swarming_portals.py,sha256=
|
|
48
|
+
pythagoras/_090_swarming_portals/swarming_portals.py,sha256=3d8sRniGdW_rKp2zKxdqoCvLA4Em1XW5xofhFtzDLf0,12696
|
|
49
49
|
pythagoras/_100_top_level_API/__init__.py,sha256=s5LtwskY2nwkRPFKzP0PrCzQ1c9oScZO0kM9_bWLi3U,64
|
|
50
50
|
pythagoras/_100_top_level_API/default_local_portal.py,sha256=SnykTpTXg1KuT1qwDnrAZ63lYshMy-0nNiUgoOVMxCs,339
|
|
51
51
|
pythagoras/_100_top_level_API/top_level_API.py,sha256=S2NXW4bfL98o6Txn6NM0EeBb1nzwFtPSl-yWNevAQIE,906
|
|
@@ -59,6 +59,6 @@ pythagoras/_900_project_stats_collector/__init__.py,sha256=Eagt-BhPPtBGgpMywx2lk
|
|
|
59
59
|
pythagoras/_900_project_stats_collector/project_analyzer.py,sha256=uhycFKjUIXEpYcZYnak3yn4JFhchl-oZ7wt6spFxhoY,3574
|
|
60
60
|
pythagoras/__init__.py,sha256=TMPtJdSi_WShCpJnsVVdO48Wcvs78GMbUi5gHc1eMLw,1233
|
|
61
61
|
pythagoras/core/__init__.py,sha256=cXtQ-Vbm8TqzazvkFws5cV3AEEYbEKzNXYeuHeLGFK0,328
|
|
62
|
-
pythagoras-0.24.
|
|
63
|
-
pythagoras-0.24.
|
|
64
|
-
pythagoras-0.24.
|
|
62
|
+
pythagoras-0.24.4.dist-info/WHEEL,sha256=X16MKk8bp2DRsAuyteHJ-9qOjzmnY0x1aj0P1ftqqWA,78
|
|
63
|
+
pythagoras-0.24.4.dist-info/METADATA,sha256=o7l1zf9TCe9tz4nhG5KtKVU_z4qI9QQV-h0IHSitI_g,7467
|
|
64
|
+
pythagoras-0.24.4.dist-info/RECORD,,
|
|
File without changes
|