QuLab 2.5.1__cp311-cp311-win_amd64.whl → 2.5.3__cp311-cp311-win_amd64.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.
- {QuLab-2.5.1.dist-info → QuLab-2.5.3.dist-info}/METADATA +1 -1
- {QuLab-2.5.1.dist-info → QuLab-2.5.3.dist-info}/RECORD +11 -11
- qulab/executor/cli.py +33 -5
- qulab/executor/load.py +22 -2
- qulab/executor/storage.py +1 -2
- qulab/fun.cp311-win_amd64.pyd +0 -0
- qulab/version.py +1 -1
- {QuLab-2.5.1.dist-info → QuLab-2.5.3.dist-info}/LICENSE +0 -0
- {QuLab-2.5.1.dist-info → QuLab-2.5.3.dist-info}/WHEEL +0 -0
- {QuLab-2.5.1.dist-info → QuLab-2.5.3.dist-info}/entry_points.txt +0 -0
- {QuLab-2.5.1.dist-info → QuLab-2.5.3.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
qulab/__init__.py,sha256=pdlicy07Dx39pTEGZ0i41Ox9tuuuKKIdsFIrE13bneg,249
|
|
2
2
|
qulab/__main__.py,sha256=FL4YsGZL1jEtmcPc5WbleArzhOHLMsWl7OH3O-1d1ss,72
|
|
3
3
|
qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
|
|
4
|
-
qulab/fun.cp311-win_amd64.pyd,sha256=
|
|
4
|
+
qulab/fun.cp311-win_amd64.pyd,sha256=t-CVWBBcwLUB10VOjj1x1whoNHZv3PqBIx2U9_hvUAE,31744
|
|
5
5
|
qulab/typing.py,sha256=3c0eKa1avEHIi5wPvh3-4l6Of5mu5Rn1MWPnMeLGNX0,71
|
|
6
|
-
qulab/version.py,sha256=
|
|
6
|
+
qulab/version.py,sha256=Znn1LprC8WFThPHcZ2uVYHDtCMP4LIy30e8v1CDWFvU,21
|
|
7
7
|
qulab/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
qulab/cli/commands.py,sha256=6xd2eYw32k1NmfAuYSu__1kaP12Oz1QVqwbkYXdWno4,588
|
|
9
9
|
qulab/cli/config.py,sha256=tNmH4ggdgrFqcQa2WZKLpidiYTg95_UnT0paDJ4fi4c,3204
|
|
10
10
|
qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
|
|
11
|
-
qulab/executor/cli.py,sha256=
|
|
12
|
-
qulab/executor/load.py,sha256=
|
|
11
|
+
qulab/executor/cli.py,sha256=5rbAOnG8Me46qeWh9LbutE3zIcPD-MZVqmYoWUY4l3o,6674
|
|
12
|
+
qulab/executor/load.py,sha256=OZmE_Pj2XcHzRDw5-1lF-ZDoMVqpaR-dWXf1K39ThXQ,12925
|
|
13
13
|
qulab/executor/schedule.py,sha256=4D8o68Cx6vCkpSTMHzULTwuuq1tS8unc2n8WdBA9oB0,12013
|
|
14
|
-
qulab/executor/storage.py,sha256=
|
|
14
|
+
qulab/executor/storage.py,sha256=s1xrI4bPTnyM4Nj0CkPxr3NdmnSp18LKnwm-ZoxR-Q0,7191
|
|
15
15
|
qulab/executor/transform.py,sha256=AazWdlkEoOBaUJpTYsT5J4f0RanzCEeo-ThwEg8BB4Y,1262
|
|
16
16
|
qulab/executor/utils.py,sha256=RNDEo17M-n_tge7uLITHxmoNNYSTm9OES75wQygR8dM,4065
|
|
17
17
|
qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
|
|
@@ -93,9 +93,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
|
|
|
93
93
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
|
94
94
|
qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
|
|
95
95
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
|
96
|
-
QuLab-2.5.
|
|
97
|
-
QuLab-2.5.
|
|
98
|
-
QuLab-2.5.
|
|
99
|
-
QuLab-2.5.
|
|
100
|
-
QuLab-2.5.
|
|
101
|
-
QuLab-2.5.
|
|
96
|
+
QuLab-2.5.3.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
|
97
|
+
QuLab-2.5.3.dist-info/METADATA,sha256=WWPbG4jg1FZhmAkhVvywBl8d8PR1wGjVhLWZVwhA6pA,3803
|
|
98
|
+
QuLab-2.5.3.dist-info/WHEEL,sha256=yNnHoQL2GZYIUXm9YvoaBpFjGlUoK9qq9oqYeudrWlE,101
|
|
99
|
+
QuLab-2.5.3.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
|
|
100
|
+
QuLab-2.5.3.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
|
101
|
+
QuLab-2.5.3.dist-info/RECORD,,
|
qulab/executor/cli.py
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
import functools
|
|
2
|
+
import graphlib
|
|
2
3
|
import importlib
|
|
3
4
|
import os
|
|
4
|
-
import sys
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
from loguru import logger
|
|
9
9
|
|
|
10
|
-
from ..cli.config import
|
|
11
|
-
from .load import find_unreferenced_workflows, get_entries,
|
|
10
|
+
from ..cli.config import get_config_value, log_options
|
|
11
|
+
from .load import (WorkflowType, find_unreferenced_workflows, get_entries,
|
|
12
|
+
load_workflow, make_graph)
|
|
12
13
|
from .schedule import maintain as maintain_workflow
|
|
13
14
|
from .schedule import run as run_workflow
|
|
14
15
|
from .transform import set_config_api
|
|
15
16
|
from .utils import workflow_template
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
@logger.catch(reraise=True)
|
|
20
|
+
def check_toplogy(workflow: WorkflowType, code_path: str | Path) -> dict:
|
|
21
|
+
graph = {}
|
|
22
|
+
try:
|
|
23
|
+
graphlib.TopologicalSorter(make_graph(workflow, graph,
|
|
24
|
+
code_path)).static_order()
|
|
25
|
+
except graphlib.CycleError as e:
|
|
26
|
+
logger.error(
|
|
27
|
+
f"Workflow {workflow.__workflow_id__} has a circular dependency: {e}"
|
|
28
|
+
)
|
|
29
|
+
raise e
|
|
30
|
+
return graph
|
|
31
|
+
|
|
32
|
+
|
|
18
33
|
def command_option(command_name):
|
|
19
34
|
"""命令专属配置装饰器工厂"""
|
|
20
35
|
|
|
@@ -142,6 +157,7 @@ def run(workflow, code, data, api, plot, no_dependents, update):
|
|
|
142
157
|
data = Path(os.path.expanduser(data))
|
|
143
158
|
|
|
144
159
|
wf = load_workflow(workflow, code)
|
|
160
|
+
check_toplogy(wf, code)
|
|
145
161
|
|
|
146
162
|
if no_dependents:
|
|
147
163
|
if hasattr(wf, 'entries'):
|
|
@@ -152,9 +168,19 @@ def run(workflow, code, data, api, plot, no_dependents, update):
|
|
|
152
168
|
else:
|
|
153
169
|
if hasattr(wf, 'entries'):
|
|
154
170
|
for entry in get_entries(wf, code):
|
|
155
|
-
maintain_workflow(entry,
|
|
171
|
+
maintain_workflow(entry,
|
|
172
|
+
code,
|
|
173
|
+
data,
|
|
174
|
+
run=True,
|
|
175
|
+
plot=plot,
|
|
176
|
+
update=update)
|
|
156
177
|
else:
|
|
157
|
-
maintain_workflow(wf,
|
|
178
|
+
maintain_workflow(wf,
|
|
179
|
+
code,
|
|
180
|
+
data,
|
|
181
|
+
run=True,
|
|
182
|
+
plot=plot,
|
|
183
|
+
update=update)
|
|
158
184
|
|
|
159
185
|
|
|
160
186
|
@click.command()
|
|
@@ -181,6 +207,8 @@ def maintain(workflow, code, data, api, plot):
|
|
|
181
207
|
data = Path(os.path.expanduser(data))
|
|
182
208
|
|
|
183
209
|
wf = load_workflow(workflow, code)
|
|
210
|
+
check_toplogy(wf, code)
|
|
211
|
+
|
|
184
212
|
if hasattr(wf, 'entries'):
|
|
185
213
|
for entry in get_entries(wf, code):
|
|
186
214
|
maintain_workflow(entry, code, data, run=False, plot=plot)
|
qulab/executor/load.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import base64
|
|
2
|
+
import graphlib
|
|
2
3
|
import hashlib
|
|
3
4
|
import inspect
|
|
4
5
|
import lzma
|
|
@@ -259,7 +260,7 @@ def load_workflow_from_template(template_path: str,
|
|
|
259
260
|
with open(base_path / path) as f:
|
|
260
261
|
content = f.read()
|
|
261
262
|
|
|
262
|
-
mtime = max(
|
|
263
|
+
mtime = max((base_path / template_path).stat().st_mtime, mtime)
|
|
263
264
|
hash_str, mapping_code = encode_mapping(mapping)
|
|
264
265
|
|
|
265
266
|
def replace(text):
|
|
@@ -360,8 +361,27 @@ def get_dependents(workflow: WorkflowType,
|
|
|
360
361
|
]
|
|
361
362
|
|
|
362
363
|
|
|
363
|
-
def get_entries(workflow: WorkflowType,
|
|
364
|
+
def get_entries(workflow: WorkflowType,
|
|
365
|
+
code_path: str | Path) -> list[WorkflowType]:
|
|
364
366
|
return [
|
|
365
367
|
load_workflow(n, code_path, mtime=workflow.__mtime__)
|
|
366
368
|
for n in workflow.entries()
|
|
367
369
|
]
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def make_graph(workflow: WorkflowType, graph: dict, code_path: str | Path):
|
|
373
|
+
if workflow.__workflow_id__ in graph:
|
|
374
|
+
raise graphlib.CycleError(
|
|
375
|
+
f"Workflow {workflow.__workflow_id__} has a circular dependency")
|
|
376
|
+
graph[workflow.__workflow_id__] = []
|
|
377
|
+
|
|
378
|
+
if hasattr(workflow, 'entries'):
|
|
379
|
+
for w in get_entries(workflow, code_path):
|
|
380
|
+
graph[workflow.__workflow_id__].append(w.__workflow_id__)
|
|
381
|
+
make_graph(w, graph=graph, code_path=code_path)
|
|
382
|
+
elif hasattr(workflow, 'depends'):
|
|
383
|
+
for w in get_dependents(workflow, code_path):
|
|
384
|
+
graph[workflow.__workflow_id__].append(w.__workflow_id__)
|
|
385
|
+
make_graph(w, graph=graph, code_path=code_path)
|
|
386
|
+
|
|
387
|
+
return graph
|
qulab/executor/storage.py
CHANGED
|
@@ -140,8 +140,7 @@ def revoke_result(workflow: str, base_path: str | Path):
|
|
|
140
140
|
base_path = Path(base_path)
|
|
141
141
|
path = get_head(workflow, base_path)
|
|
142
142
|
if path is not None:
|
|
143
|
-
|
|
144
|
-
result = pickle.load(f)
|
|
143
|
+
result = load_result(path, base_path)
|
|
145
144
|
result.in_spec = False
|
|
146
145
|
return save_result(workflow, result, base_path)
|
|
147
146
|
|
qulab/fun.cp311-win_amd64.pyd
CHANGED
|
Binary file
|
qulab/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.5.
|
|
1
|
+
__version__ = "2.5.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|