aiida-pythonjob 0.4.4__tar.gz → 0.4.6__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.
- {aiida_pythonjob-0.4.4/src/aiida_pythonjob.egg-info → aiida_pythonjob-0.4.6}/PKG-INFO +2 -2
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/pyproject.toml +1 -1
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/__init__.py +1 -1
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/launch.py +2 -2
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/parsers/utils.py +6 -8
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/utils.py +10 -8
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6/src/aiida_pythonjob.egg-info}/PKG-INFO +2 -2
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/requires.txt +1 -1
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_parser.py +22 -1
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_pyfunction.py +8 -4
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/LICENSE +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/README.md +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/setup.cfg +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/__init__.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/common.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/pyfunction.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/pythonjob.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/tasks.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/utils.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/config.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/__init__.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/atoms.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/common_data.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/deserializer.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/jsonable_data.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/pickled_data.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/serializer.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/data/utils.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/decorator.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/parsers/__init__.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/parsers/pythonjob.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/SOURCES.txt +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/dependency_links.txt +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/entry_points.txt +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/top_level.txt +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_async.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_create_env.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_data.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_entry_points.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_jsonable_data.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_monitor.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_pickled_data.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_pythonjob.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_serializer.py +0 -0
- {aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiida-pythonjob
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.6
|
|
4
4
|
Summary: Run Python functions on a remote computer.
|
|
5
5
|
Author-email: Xing Wang <xingwang1991@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
|
|
|
38
38
|
License-File: LICENSE
|
|
39
39
|
Requires-Dist: aiida-core<3,>=2.7.1
|
|
40
40
|
Requires-Dist: ase
|
|
41
|
-
Requires-Dist: node-graph
|
|
41
|
+
Requires-Dist: node-graph~=0.4.0
|
|
42
42
|
Provides-Extra: test
|
|
43
43
|
Requires-Dist: pgtest>=1.3.1,~=1.3; extra == "test"
|
|
44
44
|
Requires-Dist: coverage~=7.0; extra == "test"
|
|
@@ -22,8 +22,8 @@ def _unwrap_callable(func: Any) -> Callable[..., Any] | None:
|
|
|
22
22
|
"""
|
|
23
23
|
if func is None:
|
|
24
24
|
return None
|
|
25
|
-
if isinstance(func, BaseHandle) and hasattr(func, "
|
|
26
|
-
return func.
|
|
25
|
+
if isinstance(func, BaseHandle) and hasattr(func, "_callable"):
|
|
26
|
+
return func._callable
|
|
27
27
|
if getattr(func, "is_process_function", False):
|
|
28
28
|
# aiida process_function wrapper (e.g., calcfunction/workfunction)
|
|
29
29
|
return func.func
|
|
@@ -44,8 +44,7 @@ def parse_outputs(
|
|
|
44
44
|
spec = _ensure_spec(output_spec)
|
|
45
45
|
|
|
46
46
|
fields = spec.fields or {}
|
|
47
|
-
is_dyn =
|
|
48
|
-
item_spec = spec.item if is_dyn else None
|
|
47
|
+
is_dyn = spec.meta.dynamic
|
|
49
48
|
|
|
50
49
|
if already_serialized(results):
|
|
51
50
|
return {"result": results}, None
|
|
@@ -105,14 +104,13 @@ def parse_outputs(
|
|
|
105
104
|
return None, exit_codes.ERROR_MISSING_OUTPUT
|
|
106
105
|
# dynamic items
|
|
107
106
|
if is_dyn:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
value,
|
|
113
|
-
item_spec or SocketSpec(identifier="node_graph.any"),
|
|
107
|
+
outs.update(
|
|
108
|
+
serialize_ports(
|
|
109
|
+
remaining,
|
|
110
|
+
spec or SocketSpec(identifier="node_graph.any"),
|
|
114
111
|
serializers=serializers,
|
|
115
112
|
)
|
|
113
|
+
)
|
|
116
114
|
return outs, None
|
|
117
115
|
# not dynamic -> leftovers are unexpected (warn but continue)
|
|
118
116
|
if remaining:
|
|
@@ -16,6 +16,7 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
from aiida.common.exceptions import NotExistent
|
|
18
18
|
from aiida.orm import Computer, InstalledCode, Str, User, load_code, load_computer
|
|
19
|
+
from node_graph.socket_meta import SocketMeta
|
|
19
20
|
from node_graph.socket_spec import SocketSpec
|
|
20
21
|
|
|
21
22
|
from aiida_pythonjob.data.serializer import general_serializer
|
|
@@ -298,10 +299,6 @@ def serialize_ports(
|
|
|
298
299
|
|
|
299
300
|
out: Dict[str, Any] = {}
|
|
300
301
|
fields = spec.fields or {}
|
|
301
|
-
is_dyn = bool(spec.dynamic)
|
|
302
|
-
item_spec = spec.item if is_dyn else None
|
|
303
|
-
allow_extra = _has_var_kwargs(spec)
|
|
304
|
-
catch_schema = item_spec or SocketSpec(identifier="node_graph.any")
|
|
305
302
|
|
|
306
303
|
for key, value in python_data.items():
|
|
307
304
|
if key in fields:
|
|
@@ -313,10 +310,15 @@ def serialize_ports(
|
|
|
313
310
|
out[key] = serialize_ports(value, child_spec, serializers=serializers)
|
|
314
311
|
else:
|
|
315
312
|
out[key] = general_serializer(value, serializers=serializers, store=False)
|
|
316
|
-
elif
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
313
|
+
elif spec.meta.dynamic:
|
|
314
|
+
if spec.item is None:
|
|
315
|
+
if isinstance(value, dict):
|
|
316
|
+
item = SocketSpec(identifier="node_graph.namespace", meta=SocketMeta(dynamic=True))
|
|
317
|
+
out[key] = serialize_ports(value, item, serializers=serializers)
|
|
318
|
+
else:
|
|
319
|
+
out[key] = general_serializer(value, serializers=serializers, store=False)
|
|
320
|
+
elif spec.item.is_namespace():
|
|
321
|
+
out[key] = serialize_ports(value, spec.item, serializers=serializers)
|
|
320
322
|
else:
|
|
321
323
|
out[key] = general_serializer(value, serializers=serializers, store=False)
|
|
322
324
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiida-pythonjob
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.6
|
|
4
4
|
Summary: Run Python functions on a remote computer.
|
|
5
5
|
Author-email: Xing Wang <xingwang1991@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
|
|
|
38
38
|
License-File: LICENSE
|
|
39
39
|
Requires-Dist: aiida-core<3,>=2.7.1
|
|
40
40
|
Requires-Dist: ase
|
|
41
|
-
Requires-Dist: node-graph
|
|
41
|
+
Requires-Dist: node-graph~=0.4.0
|
|
42
42
|
Provides-Extra: test
|
|
43
43
|
Requires-Dist: pgtest>=1.3.1,~=1.3; extra == "test"
|
|
44
44
|
Requires-Dist: coverage~=7.0; extra == "test"
|
|
@@ -10,7 +10,7 @@ import pytest
|
|
|
10
10
|
from aiida import orm
|
|
11
11
|
from aiida.cmdline.utils.common import get_workchain_report
|
|
12
12
|
from aiida.common.links import LinkType
|
|
13
|
-
from node_graph.socket_spec import namespace
|
|
13
|
+
from node_graph.socket_spec import dynamic, namespace
|
|
14
14
|
|
|
15
15
|
from aiida_pythonjob.data.deserializer import all_deserializers
|
|
16
16
|
from aiida_pythonjob.data.serializer import all_serializers
|
|
@@ -136,6 +136,27 @@ def test_no_output_file(fixture_localhost):
|
|
|
136
136
|
assert exit_code == parser.exit_codes.ERROR_READING_OUTPUT_FILE
|
|
137
137
|
|
|
138
138
|
|
|
139
|
+
def test_dynamic_spec(fixture_localhost):
|
|
140
|
+
# Test with dynamic spec without item
|
|
141
|
+
result = {"a": 1, "b": 2, "nested": {"c": 3}}
|
|
142
|
+
spec_data = {"outputs_spec": dynamic().to_dict()}
|
|
143
|
+
parser = create_parser(result, spec_data)
|
|
144
|
+
exit_code = parser.parse()
|
|
145
|
+
assert exit_code is None
|
|
146
|
+
assert parser.outputs["a"] == 1
|
|
147
|
+
assert parser.outputs["b"] == 2
|
|
148
|
+
assert isinstance(parser.outputs["nested"], dict)
|
|
149
|
+
assert parser.outputs["nested"]["c"] == 3
|
|
150
|
+
# Test with dynamic spec with Any item
|
|
151
|
+
spec_data = {"outputs_spec": dynamic(Any).to_dict()}
|
|
152
|
+
parser = create_parser(result, spec_data)
|
|
153
|
+
exit_code = parser.parse()
|
|
154
|
+
assert exit_code is None
|
|
155
|
+
assert parser.outputs["a"] == 1
|
|
156
|
+
assert parser.outputs["b"] == 2
|
|
157
|
+
assert isinstance(parser.outputs["nested"], orm.Dict)
|
|
158
|
+
|
|
159
|
+
|
|
139
160
|
@pytest.mark.parametrize(
|
|
140
161
|
"error_type, status",
|
|
141
162
|
[
|
|
@@ -258,7 +258,7 @@ def test_top_level_outputs_dynamic():
|
|
|
258
258
|
def test_dynamic_rows():
|
|
259
259
|
"""Test function with dynamic rows."""
|
|
260
260
|
|
|
261
|
-
row = spec.namespace(sum=any, product=
|
|
261
|
+
row = spec.namespace(sum=any, product=spec.dynamic())
|
|
262
262
|
|
|
263
263
|
@pyfunction(outputs=spec.dynamic(row, sum=int))
|
|
264
264
|
def test_dynamic_rows(data: spec.dynamic(row, sum=int)):
|
|
@@ -267,9 +267,9 @@ def test_dynamic_rows():
|
|
|
267
267
|
result, node = run_get_node(
|
|
268
268
|
test_dynamic_rows,
|
|
269
269
|
data={
|
|
270
|
-
"data_0": {"sum": 0, "product": 0},
|
|
271
|
-
"data_1": {"sum": 1, "product": 2},
|
|
272
|
-
"data_2": {"sum": 2, "product": 4},
|
|
270
|
+
"data_0": {"sum": 0, "product": {"a": 0}},
|
|
271
|
+
"data_1": {"sum": 1, "product": {"a": 2, "b": {"c": 3}}},
|
|
272
|
+
"data_2": {"sum": 2, "product": {"a": 4}},
|
|
273
273
|
"sum": 1,
|
|
274
274
|
},
|
|
275
275
|
)
|
|
@@ -277,9 +277,13 @@ def test_dynamic_rows():
|
|
|
277
277
|
# inputs should be serialized as dynamic rows
|
|
278
278
|
assert node.inputs.function_inputs.data.sum.value == 1
|
|
279
279
|
assert node.inputs.function_inputs.data.data_0.sum.value == 0
|
|
280
|
+
assert node.inputs.function_inputs.data.data_1.product.a.value == 2
|
|
281
|
+
assert node.inputs.function_inputs.data.data_1.product.b.c.value == 3
|
|
280
282
|
# outputs should be serialized as dynamic rows
|
|
281
283
|
assert node.outputs.sum.value == 1
|
|
282
284
|
assert node.outputs.data_0.sum.value == 0
|
|
285
|
+
assert node.outputs.data_1.product.a.value == 2
|
|
286
|
+
assert node.outputs.data_1.product.b.c.value == 3
|
|
283
287
|
|
|
284
288
|
|
|
285
289
|
def test_only_data_with_value():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/pyfunction.py
RENAMED
|
File without changes
|
{aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob/calculations/pythonjob.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
|
{aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{aiida_pythonjob-0.4.4 → aiida_pythonjob-0.4.6}/src/aiida_pythonjob.egg-info/entry_points.txt
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
|