stringjax-tools 0.1.0__tar.gz → 0.2.0__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.
- {stringjax_tools-0.1.0/src/stringjax_tools.egg-info → stringjax_tools-0.2.0}/PKG-INFO +47 -11
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/README.md +39 -3
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/pyproject.toml +8 -7
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/__init__.py +9 -2
- stringjax_tools-0.2.0/src/stringjax_tools/_worker.py +112 -0
- stringjax_tools-0.2.0/src/stringjax_tools/process.py +312 -0
- stringjax_tools-0.2.0/src/stringjax_tools/reproducibility.py +230 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0/src/stringjax_tools.egg-info}/PKG-INFO +47 -11
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools.egg-info/SOURCES.txt +5 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/tests/test_auto_vectorise.py +5 -0
- stringjax_tools-0.2.0/tests/test_process.py +424 -0
- stringjax_tools-0.2.0/tests/test_reproducibility.py +166 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/LICENSE +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/setup.cfg +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/__main__.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/_utils.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/auto_vectorise.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/cache.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/jit.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/py.typed +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/pytrees.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools/vmap.py +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools.egg-info/dependency_links.txt +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools.egg-info/requires.txt +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/src/stringjax_tools.egg-info/top_level.txt +0 -0
- {stringjax_tools-0.1.0 → stringjax_tools-0.2.0}/tests/test_transforms_and_pytrees.py +0 -0
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stringjax-tools
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Reusable JAX transform, vectorisation, cache
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Reusable JAX transform, vectorisation, cache and pytree helpers, and general-purpose infrastructure (child processes with enforced timeouts, provenance), for StringJAX packages.
|
|
5
5
|
Author-email: Andreas Schachner <as3475@cornell.edu>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
7
|
-
Project-URL: Homepage, https://github.com/StringJAX/
|
|
8
|
-
Project-URL:
|
|
9
|
-
|
|
7
|
+
Project-URL: Homepage, https://github.com/StringJAX/stringjax_tools
|
|
8
|
+
Project-URL: Documentation, https://stringjax-tools.readthedocs.io
|
|
9
|
+
Project-URL: Changelog, https://github.com/StringJAX/stringjax_tools/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/StringJAX/stringjax_tools/issues
|
|
11
|
+
Keywords: jax,stringjax,vmap,jit,pytrees,automatic-vectorisation,scientific-computing
|
|
10
12
|
Classifier: Development Status :: 3 - Alpha
|
|
11
13
|
Classifier: Intended Audience :: Developers
|
|
12
14
|
Classifier: Intended Audience :: Science/Research
|
|
13
15
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
18
|
Classifier: Topic :: Scientific/Engineering
|
|
19
|
-
Requires-Python: >=3.
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
Requires-Dist: jax>=0.4.26
|
|
@@ -44,13 +44,20 @@ Dynamic: license-file
|
|
|
44
44
|
# StringJAX Tools
|
|
45
45
|
|
|
46
46
|
`stringjax_tools` is a small utility package for reusable JAX transform
|
|
47
|
-
patterns used across StringJAX projects.
|
|
47
|
+
patterns used across [StringJAX](https://github.com/StringJAX) projects. Use
|
|
48
|
+
it when a package needs the same JAX mechanics in several places, but should
|
|
49
|
+
not carry domain-specific names or conventions into a shared helper layer.
|
|
50
|
+
|
|
51
|
+
It currently focuses on:
|
|
48
52
|
|
|
49
53
|
- conservative rank-checked automatic vectorisation;
|
|
50
54
|
- manual cached `jax.jit(jax.vmap(...))` wrappers;
|
|
51
55
|
- small helpers for explicit static-argument JIT compilation;
|
|
52
56
|
- explicit JAX persistent-compilation-cache setup;
|
|
53
|
-
- configurable pytree registration for stateful model classes
|
|
57
|
+
- configurable pytree registration for stateful model classes;
|
|
58
|
+
- running a call in a child process with an enforced timeout
|
|
59
|
+
(`run_in_subprocess`);
|
|
60
|
+
- recording which code produced a result (`provenance`).
|
|
54
61
|
|
|
55
62
|
The package keeps reusable transformation and pytree machinery separate from
|
|
56
63
|
domain-specific StringJAX model code.
|
|
@@ -63,7 +70,7 @@ From this directory:
|
|
|
63
70
|
pip install -e ".[dev,docs]"
|
|
64
71
|
```
|
|
65
72
|
|
|
66
|
-
|
|
73
|
+
From PyPI:
|
|
67
74
|
|
|
68
75
|
```bash
|
|
69
76
|
pip install stringjax-tools
|
|
@@ -92,6 +99,29 @@ make -C documentation html SPHINXOPTS="-W -q"
|
|
|
92
99
|
The feature notebooks are included under `documentation/source/notebooks/` and
|
|
93
100
|
are linked from the Sphinx tutorials page.
|
|
94
101
|
|
|
102
|
+
Start with the compact feature tour:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
documentation/source/notebooks/00_crucial_features.ipynb
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
It shows the pieces most StringJAX packages usually need first:
|
|
109
|
+
|
|
110
|
+
- `auto_vmap` for scalar-or-leading-batch public methods;
|
|
111
|
+
- exact shape validation for package-local model conventions;
|
|
112
|
+
- `vmapping_func_cached` for explicit `in_axes` kernels;
|
|
113
|
+
- static-argument JIT helpers;
|
|
114
|
+
- `PytreePolicy` for stateful model classes;
|
|
115
|
+
- explicit persistent compilation-cache setup.
|
|
116
|
+
|
|
117
|
+
## Package Boundary
|
|
118
|
+
|
|
119
|
+
`stringjax_tools` is intentionally application-agnostic. Consuming packages
|
|
120
|
+
should define their own shape names, static keys, ignored cache attributes and
|
|
121
|
+
state policies locally. For example, a downstream package can wrap
|
|
122
|
+
`stringjax_tools.auto_vmap` with package-specific defaults, while
|
|
123
|
+
`stringjax_tools` itself remains free of domain language.
|
|
124
|
+
|
|
95
125
|
## Automatic Vectorisation
|
|
96
126
|
|
|
97
127
|
Keep the single-sample function explicit, then wrap it at the boundary where
|
|
@@ -143,6 +173,12 @@ class Model:
|
|
|
143
173
|
String dimensions are resolved from a bound object, usually `self`. Derived
|
|
144
174
|
dimensions should be callables rather than expression strings.
|
|
145
175
|
|
|
176
|
+
The same public API can be imported from the package root when convenient:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from stringjax_tools import auto_vmap
|
|
180
|
+
```
|
|
181
|
+
|
|
146
182
|
## Manual Transform Helpers
|
|
147
183
|
|
|
148
184
|
When a function already has a deliberate `in_axes` structure, use:
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# StringJAX Tools
|
|
2
2
|
|
|
3
3
|
`stringjax_tools` is a small utility package for reusable JAX transform
|
|
4
|
-
patterns used across StringJAX projects.
|
|
4
|
+
patterns used across [StringJAX](https://github.com/StringJAX) projects. Use
|
|
5
|
+
it when a package needs the same JAX mechanics in several places, but should
|
|
6
|
+
not carry domain-specific names or conventions into a shared helper layer.
|
|
7
|
+
|
|
8
|
+
It currently focuses on:
|
|
5
9
|
|
|
6
10
|
- conservative rank-checked automatic vectorisation;
|
|
7
11
|
- manual cached `jax.jit(jax.vmap(...))` wrappers;
|
|
8
12
|
- small helpers for explicit static-argument JIT compilation;
|
|
9
13
|
- explicit JAX persistent-compilation-cache setup;
|
|
10
|
-
- configurable pytree registration for stateful model classes
|
|
14
|
+
- configurable pytree registration for stateful model classes;
|
|
15
|
+
- running a call in a child process with an enforced timeout
|
|
16
|
+
(`run_in_subprocess`);
|
|
17
|
+
- recording which code produced a result (`provenance`).
|
|
11
18
|
|
|
12
19
|
The package keeps reusable transformation and pytree machinery separate from
|
|
13
20
|
domain-specific StringJAX model code.
|
|
@@ -20,7 +27,7 @@ From this directory:
|
|
|
20
27
|
pip install -e ".[dev,docs]"
|
|
21
28
|
```
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
From PyPI:
|
|
24
31
|
|
|
25
32
|
```bash
|
|
26
33
|
pip install stringjax-tools
|
|
@@ -49,6 +56,29 @@ make -C documentation html SPHINXOPTS="-W -q"
|
|
|
49
56
|
The feature notebooks are included under `documentation/source/notebooks/` and
|
|
50
57
|
are linked from the Sphinx tutorials page.
|
|
51
58
|
|
|
59
|
+
Start with the compact feature tour:
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
documentation/source/notebooks/00_crucial_features.ipynb
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
It shows the pieces most StringJAX packages usually need first:
|
|
66
|
+
|
|
67
|
+
- `auto_vmap` for scalar-or-leading-batch public methods;
|
|
68
|
+
- exact shape validation for package-local model conventions;
|
|
69
|
+
- `vmapping_func_cached` for explicit `in_axes` kernels;
|
|
70
|
+
- static-argument JIT helpers;
|
|
71
|
+
- `PytreePolicy` for stateful model classes;
|
|
72
|
+
- explicit persistent compilation-cache setup.
|
|
73
|
+
|
|
74
|
+
## Package Boundary
|
|
75
|
+
|
|
76
|
+
`stringjax_tools` is intentionally application-agnostic. Consuming packages
|
|
77
|
+
should define their own shape names, static keys, ignored cache attributes and
|
|
78
|
+
state policies locally. For example, a downstream package can wrap
|
|
79
|
+
`stringjax_tools.auto_vmap` with package-specific defaults, while
|
|
80
|
+
`stringjax_tools` itself remains free of domain language.
|
|
81
|
+
|
|
52
82
|
## Automatic Vectorisation
|
|
53
83
|
|
|
54
84
|
Keep the single-sample function explicit, then wrap it at the boundary where
|
|
@@ -100,6 +130,12 @@ class Model:
|
|
|
100
130
|
String dimensions are resolved from a bound object, usually `self`. Derived
|
|
101
131
|
dimensions should be callables rather than expression strings.
|
|
102
132
|
|
|
133
|
+
The same public API can be imported from the package root when convenient:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from stringjax_tools import auto_vmap
|
|
137
|
+
```
|
|
138
|
+
|
|
103
139
|
## Manual Transform Helpers
|
|
104
140
|
|
|
105
141
|
When a function already has a deliberate `in_axes` structure, use:
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "stringjax-tools"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Reusable JAX transform, vectorisation, cache
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Reusable JAX transform, vectorisation, cache and pytree helpers, and general-purpose infrastructure (child processes with enforced timeouts, provenance), for StringJAX packages."
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
11
|
license = "GPL-3.0-or-later"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [
|
|
@@ -15,6 +15,7 @@ authors = [
|
|
|
15
15
|
]
|
|
16
16
|
keywords = [
|
|
17
17
|
"jax",
|
|
18
|
+
"stringjax",
|
|
18
19
|
"vmap",
|
|
19
20
|
"jit",
|
|
20
21
|
"pytrees",
|
|
@@ -26,8 +27,6 @@ classifiers = [
|
|
|
26
27
|
"Intended Audience :: Developers",
|
|
27
28
|
"Intended Audience :: Science/Research",
|
|
28
29
|
"Programming Language :: Python :: 3",
|
|
29
|
-
"Programming Language :: Python :: 3.10",
|
|
30
|
-
"Programming Language :: Python :: 3.11",
|
|
31
30
|
"Programming Language :: Python :: 3.12",
|
|
32
31
|
"Programming Language :: Python :: 3.13",
|
|
33
32
|
"Topic :: Scientific/Engineering",
|
|
@@ -60,8 +59,10 @@ docs = [
|
|
|
60
59
|
]
|
|
61
60
|
|
|
62
61
|
[project.urls]
|
|
63
|
-
Homepage = "https://github.com/StringJAX/
|
|
64
|
-
|
|
62
|
+
Homepage = "https://github.com/StringJAX/stringjax_tools"
|
|
63
|
+
Documentation = "https://stringjax-tools.readthedocs.io"
|
|
64
|
+
Changelog = "https://github.com/StringJAX/stringjax_tools/blob/main/CHANGELOG.md"
|
|
65
|
+
Issues = "https://github.com/StringJAX/stringjax_tools/issues"
|
|
65
66
|
|
|
66
67
|
[tool.setuptools.packages.find]
|
|
67
68
|
where = ["src"]
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# You should have received a copy of the GNU General Public License
|
|
16
16
|
# along with StringJAX Tools. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
|
-
"""Reusable JAX transform helpers for StringJAX packages."""
|
|
18
|
+
"""Reusable JAX transform helpers and general-purpose infrastructure for StringJAX packages."""
|
|
19
19
|
|
|
20
20
|
from .auto_vectorise import (
|
|
21
21
|
ArgSpec,
|
|
@@ -32,18 +32,21 @@ from .auto_vectorise import (
|
|
|
32
32
|
)
|
|
33
33
|
from .cache import configure_compilation_cache
|
|
34
34
|
from .jit import is_static, jit_with_dynamic_static_args, jit_with_static_args
|
|
35
|
+
from .process import ChildProcessFailed, run_in_subprocess
|
|
35
36
|
from .pytrees import (
|
|
36
37
|
PytreePolicy,
|
|
37
38
|
flatten_func,
|
|
38
39
|
make_pytree_flatteners,
|
|
39
40
|
unflatten_func_class,
|
|
40
41
|
)
|
|
42
|
+
from .reproducibility import git_state, package_info, provenance
|
|
41
43
|
from .vmap import clear_vmap_caches, vmapping_func, vmapping_func_cached
|
|
42
44
|
|
|
43
|
-
__version__ = "0.
|
|
45
|
+
__version__ = "0.2.0"
|
|
44
46
|
|
|
45
47
|
__all__ = [
|
|
46
48
|
"ArgSpec",
|
|
49
|
+
"ChildProcessFailed",
|
|
47
50
|
"PytreePolicy",
|
|
48
51
|
"auto_vmap",
|
|
49
52
|
"auto_vmap_default_shapes",
|
|
@@ -54,12 +57,16 @@ __all__ = [
|
|
|
54
57
|
"flatten_func",
|
|
55
58
|
"get_auto_vmap_default_shapes",
|
|
56
59
|
"get_auto_vmap_defaults",
|
|
60
|
+
"git_state",
|
|
57
61
|
"is_static",
|
|
58
62
|
"jit_with_dynamic_static_args",
|
|
59
63
|
"jit_with_static_args",
|
|
60
64
|
"make_pytree_flatteners",
|
|
65
|
+
"package_info",
|
|
66
|
+
"provenance",
|
|
61
67
|
"reset_auto_vmap_default_shapes",
|
|
62
68
|
"reset_auto_vmap_defaults",
|
|
69
|
+
"run_in_subprocess",
|
|
63
70
|
"set_auto_vmap_default_shapes",
|
|
64
71
|
"set_auto_vmap_defaults",
|
|
65
72
|
"unflatten_func_class",
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Copyright 2023-2026 Andreas Schachner
|
|
2
|
+
#
|
|
3
|
+
# This file is part of StringJAX Tools.
|
|
4
|
+
#
|
|
5
|
+
# StringJAX Tools is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# StringJAX Tools is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with StringJAX Tools. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
"""Child process of :func:`stringjax_tools.process.run_in_subprocess`.
|
|
19
|
+
|
|
20
|
+
Run as a script, ``python _worker.py <task> <result> <lifeline fd>``, so that it does not import
|
|
21
|
+
the ``stringjax_tools`` package (nor JAX), only the module of the target. The task file holds two
|
|
22
|
+
pickles: ``(target, sys.path)``, where ``target`` is ``"module:qualname"``, and then
|
|
23
|
+
``(args, kwargs)``, unpickled after ``sys.path`` is set; the file is removed once read. The
|
|
24
|
+
outcome is written atomically to ``<result>``: ``("ok", value, warnings)`` or ``("error",
|
|
25
|
+
exception type name, message, traceback)``; then the worker kills its process group, so nothing
|
|
26
|
+
the target started outlives the call. A daemon thread reads the lifeline pipe from the parent; at
|
|
27
|
+
end of file (the parent is gone) it removes the temporary directory and kills the process group.
|
|
28
|
+
The ``__main__`` guard is required: a target that starts workers with ``multiprocessing`` under
|
|
29
|
+
``spawn`` (the macOS default) re-imports this file.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
import os
|
|
33
|
+
import sys
|
|
34
|
+
|
|
35
|
+
# Run as a script, Python puts this script's directory (inside the package) first on the path;
|
|
36
|
+
# drop it before anything else is imported, so that no module of the package can shadow a
|
|
37
|
+
# top-level one. Only then: a ``multiprocessing`` worker started under ``spawn`` re-runs this
|
|
38
|
+
# file after restoring the parent's path, whose first entry must stay.
|
|
39
|
+
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
40
|
+
if sys.path and os.path.abspath(sys.path[0] or os.curdir) == _HERE:
|
|
41
|
+
del sys.path[0]
|
|
42
|
+
|
|
43
|
+
import importlib # noqa: E402
|
|
44
|
+
import pickle # noqa: E402
|
|
45
|
+
import shutil # noqa: E402
|
|
46
|
+
import signal # noqa: E402
|
|
47
|
+
import threading # noqa: E402
|
|
48
|
+
import traceback # noqa: E402
|
|
49
|
+
import warnings # noqa: E402
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _watch_lifeline(fd, tmp_dir):
|
|
53
|
+
"""Once the parent's end of the pipe closes: remove ``tmp_dir``, kill this process group."""
|
|
54
|
+
try:
|
|
55
|
+
while os.read(fd, 1):
|
|
56
|
+
pass
|
|
57
|
+
except OSError:
|
|
58
|
+
pass
|
|
59
|
+
shutil.rmtree(tmp_dir, ignore_errors=True)
|
|
60
|
+
os.killpg(0, signal.SIGKILL)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _resolve(target):
|
|
64
|
+
module_name, function_name = target.split(":", 1)
|
|
65
|
+
obj = importlib.import_module(module_name)
|
|
66
|
+
for part in function_name.split("."):
|
|
67
|
+
obj = getattr(obj, part)
|
|
68
|
+
return obj
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _describe(exc):
|
|
72
|
+
try:
|
|
73
|
+
return str(exc)
|
|
74
|
+
except Exception: # an exception whose __str__ fails
|
|
75
|
+
return f"<{type(exc).__name__}: str() failed>"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _flush():
|
|
79
|
+
for stream in (sys.stdout, sys.stderr):
|
|
80
|
+
try:
|
|
81
|
+
stream.flush()
|
|
82
|
+
except Exception:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def main(task_path, result_path, lifeline_fd):
|
|
87
|
+
threading.Thread(
|
|
88
|
+
target=_watch_lifeline, args=(lifeline_fd, os.path.dirname(task_path)), daemon=True
|
|
89
|
+
).start()
|
|
90
|
+
try:
|
|
91
|
+
with open(task_path, "rb") as f:
|
|
92
|
+
target, path = pickle.load(f)
|
|
93
|
+
sys.path[:] = path
|
|
94
|
+
args, kwargs = pickle.load(f)
|
|
95
|
+
os.remove(task_path)
|
|
96
|
+
function = _resolve(target)
|
|
97
|
+
with warnings.catch_warnings(record=True) as caught:
|
|
98
|
+
warnings.simplefilter("always")
|
|
99
|
+
value = function(*args, **kwargs)
|
|
100
|
+
records = [(_describe(w.message), [c.__name__ for c in w.category.__mro__]) for w in caught]
|
|
101
|
+
payload = pickle.dumps(("ok", value, records))
|
|
102
|
+
except BaseException as e: # report everything to the parent, including an interrupt here
|
|
103
|
+
payload = pickle.dumps(("error", type(e).__name__, _describe(e), traceback.format_exc()))
|
|
104
|
+
with open(result_path + ".tmp", "wb") as f:
|
|
105
|
+
f.write(payload)
|
|
106
|
+
os.replace(result_path + ".tmp", result_path)
|
|
107
|
+
_flush()
|
|
108
|
+
os.killpg(0, signal.SIGKILL) # this process and anything the target left running
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
main(sys.argv[1], sys.argv[2], int(sys.argv[3]))
|