QuLab 2.4.20__cp312-cp312-macosx_10_13_universal2.whl → 2.5.0__cp312-cp312-macosx_10_13_universal2.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.4.20.dist-info → QuLab-2.5.0.dist-info}/METADATA +1 -1
- {QuLab-2.4.20.dist-info → QuLab-2.5.0.dist-info}/RECORD +17 -16
- qulab/__init__.py +2 -0
- qulab/__main__.py +1 -1
- qulab/cli/__init__.py +0 -29
- qulab/cli/commands.py +29 -0
- qulab/cli/config.py +23 -15
- qulab/executor/load.py +1 -1
- qulab/executor/schedule.py +11 -9
- qulab/executor/storage.py +96 -52
- qulab/executor/utils.py +2 -3
- qulab/fun.cpython-312-darwin.so +0 -0
- qulab/version.py +1 -1
- {QuLab-2.4.20.dist-info → QuLab-2.5.0.dist-info}/LICENSE +0 -0
- {QuLab-2.4.20.dist-info → QuLab-2.5.0.dist-info}/WHEEL +0 -0
- {QuLab-2.4.20.dist-info → QuLab-2.5.0.dist-info}/entry_points.txt +0 -0
- {QuLab-2.4.20.dist-info → QuLab-2.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
qulab/__init__.py,sha256=
|
|
2
|
-
qulab/__main__.py,sha256=
|
|
1
|
+
qulab/__init__.py,sha256=XnSePkDDgfbmEpu5uXK6spygxaqVt9emMubHYKIjSwc,244
|
|
2
|
+
qulab/__main__.py,sha256=fjaRSL_uUjNIzBGNgjlGswb9TJ2VD5qnkZHW3hItrD4,68
|
|
3
3
|
qulab/dicttree.py,sha256=tRRMpGZYVOLw0TEByE3_2Ss8FdOmzuGL9e1DWbs8qoY,13684
|
|
4
|
-
qulab/fun.cpython-312-darwin.so,sha256
|
|
5
|
-
qulab/version.py,sha256=
|
|
6
|
-
qulab/cli/__init__.py,sha256=
|
|
7
|
-
qulab/cli/
|
|
4
|
+
qulab/fun.cpython-312-darwin.so,sha256=5YZEOBhH4G5EBs0J7ONhSL4MfYBuvosLahm--KX2Z4I,126864
|
|
5
|
+
qulab/version.py,sha256=b9PgnIDmp0TYLJmDYb-w9iqcfWXZk22bBNQQjBVgaf0,21
|
|
6
|
+
qulab/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
qulab/cli/commands.py,sha256=tgDIkkeIoasQXAifJZ6NU8jDgpNgb2a-B0C4nF0evrE,559
|
|
8
|
+
qulab/cli/config.py,sha256=SdNmWzweWAdyk8M2oKYhMxnkaJ0qIayPlsLGCNlVqME,3108
|
|
8
9
|
qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
|
|
9
10
|
qulab/executor/cli.py,sha256=owdDSaSuzTPQA5SlNCxX4nHWITU1BF0VZMj7tLqCZhM,5781
|
|
10
|
-
qulab/executor/load.py,sha256=
|
|
11
|
-
qulab/executor/schedule.py,sha256=
|
|
12
|
-
qulab/executor/storage.py,sha256=
|
|
11
|
+
qulab/executor/load.py,sha256=4QJI_jWUCrn0MW_ieTAyhUXmujrOU5D9ywSOqzNduu0,11992
|
|
12
|
+
qulab/executor/schedule.py,sha256=u-eM9Cw8GrvWmRFhHQWSXcdKomxp6AqSwnSm3gDwkrM,11920
|
|
13
|
+
qulab/executor/storage.py,sha256=V91y8z62GseJLm2-1k-empbw68pCq93Lk-nUAwtfVfs,6068
|
|
13
14
|
qulab/executor/transform.py,sha256=inaOn6eqCs22ZZ0xAQl8s8YCoEACaXSwFNNu7jqdwAk,2148
|
|
14
|
-
qulab/executor/utils.py,sha256=
|
|
15
|
+
qulab/executor/utils.py,sha256=OVBYuAC4Pw8-kT_s0AJUiLAS5QTeV-mXF8zjdQFTwrM,3163
|
|
15
16
|
qulab/monitor/__init__.py,sha256=nTHelnDpxRS_fl_B38TsN0njgq8eVTEz9IAnN3NbDlM,42
|
|
16
17
|
qulab/monitor/__main__.py,sha256=w3yUcqq195LzSnXTkQcuC1RSFRhy4oQ_PEBmucXguME,97
|
|
17
18
|
qulab/monitor/config.py,sha256=fQ5JcsMApKc1UwANEnIvbDQZl8uYW0tle92SaYtX9lI,744
|
|
@@ -91,9 +92,9 @@ qulab/visualization/plot_seq.py,sha256=UWTS6p9nfX_7B8ehcYo6UnSTUCjkBsNU9jiOeW2ca
|
|
|
91
92
|
qulab/visualization/qdat.py,sha256=ZeevBYWkzbww4xZnsjHhw7wRorJCBzbG0iEu-XQB4EA,5735
|
|
92
93
|
qulab/visualization/rot3d.py,sha256=lMrEJlRLwYe6NMBlGkKYpp_V9CTipOAuDy6QW_cQK00,734
|
|
93
94
|
qulab/visualization/widgets.py,sha256=6KkiTyQ8J-ei70LbPQZAK35wjktY47w2IveOa682ftA,3180
|
|
94
|
-
QuLab-2.
|
|
95
|
-
QuLab-2.
|
|
96
|
-
QuLab-2.
|
|
97
|
-
QuLab-2.
|
|
98
|
-
QuLab-2.
|
|
99
|
-
QuLab-2.
|
|
95
|
+
QuLab-2.5.0.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
|
|
96
|
+
QuLab-2.5.0.dist-info/METADATA,sha256=nhF6INmUcbg6NXuVw94WUh7gTa76SypHB6OPcuhYy74,3698
|
|
97
|
+
QuLab-2.5.0.dist-info/WHEEL,sha256=iDXcyuxg-66TzzqHGH-kgw_HJdaJE_1RHznrvPNCSNs,115
|
|
98
|
+
QuLab-2.5.0.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
|
|
99
|
+
QuLab-2.5.0.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
|
100
|
+
QuLab-2.5.0.dist-info/RECORD,,
|
qulab/__init__.py
CHANGED
qulab/__main__.py
CHANGED
qulab/cli/__init__.py
CHANGED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
|
|
3
|
-
from ..executor.cli import create, get, maintain, run, set
|
|
4
|
-
from ..monitor.__main__ import main as monitor
|
|
5
|
-
from ..scan.server import server
|
|
6
|
-
from ..sys.net.cli import dht
|
|
7
|
-
from ..visualization.__main__ import plot
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@click.group()
|
|
11
|
-
def cli():
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@cli.command()
|
|
16
|
-
def hello():
|
|
17
|
-
"""Print hello world."""
|
|
18
|
-
click.echo('hello, world')
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
cli.add_command(monitor)
|
|
22
|
-
cli.add_command(plot)
|
|
23
|
-
cli.add_command(dht)
|
|
24
|
-
cli.add_command(server)
|
|
25
|
-
cli.add_command(maintain)
|
|
26
|
-
cli.add_command(run)
|
|
27
|
-
cli.add_command(create)
|
|
28
|
-
cli.add_command(set)
|
|
29
|
-
cli.add_command(get)
|
qulab/cli/commands.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from ..executor.cli import create, get, maintain, run, set
|
|
4
|
+
from ..monitor.__main__ import main as monitor
|
|
5
|
+
from ..scan.server import server
|
|
6
|
+
from ..sys.net.cli import dht
|
|
7
|
+
from ..visualization.__main__ import plot
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@click.group()
|
|
11
|
+
def cli():
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@cli.command()
|
|
16
|
+
def hello():
|
|
17
|
+
"""Print hello world."""
|
|
18
|
+
click.echo('hello, world')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
cli.add_command(monitor)
|
|
22
|
+
cli.add_command(plot)
|
|
23
|
+
cli.add_command(dht)
|
|
24
|
+
cli.add_command(server)
|
|
25
|
+
cli.add_command(maintain)
|
|
26
|
+
cli.add_command(run)
|
|
27
|
+
cli.add_command(create)
|
|
28
|
+
cli.add_command(set)
|
|
29
|
+
cli.add_command(get)
|
qulab/cli/config.py
CHANGED
|
@@ -62,27 +62,35 @@ def log_options(func):
|
|
|
62
62
|
|
|
63
63
|
@click.option("--debug",
|
|
64
64
|
is_flag=True,
|
|
65
|
-
default=
|
|
65
|
+
default=get_config_value("debug", bool),
|
|
66
66
|
help=f"Enable debug mode")
|
|
67
67
|
@click.option("--log",
|
|
68
68
|
type=click.Path(),
|
|
69
69
|
default=lambda: get_config_value("log", Path),
|
|
70
70
|
help=f"Log file path")
|
|
71
|
+
@click.option("--quiet",
|
|
72
|
+
is_flag=True,
|
|
73
|
+
default=get_config_value("quiet", bool),
|
|
74
|
+
help=f"Disable log output")
|
|
71
75
|
@functools.wraps(func)
|
|
72
|
-
def wrapper(*args,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
def wrapper(*args, **kwargs):
|
|
77
|
+
debug = bool(kwargs.pop("debug"))
|
|
78
|
+
log = kwargs.pop("log")
|
|
79
|
+
quiet = bool(kwargs.pop("quiet"))
|
|
80
|
+
|
|
81
|
+
if debug:
|
|
82
|
+
log_level = "DEBUG"
|
|
83
|
+
else:
|
|
84
|
+
log_level = "INFO"
|
|
85
|
+
|
|
86
|
+
handlers = []
|
|
87
|
+
if log is not None:
|
|
88
|
+
handlers.append(dict(sink=log, level=log_level))
|
|
89
|
+
if not quiet or debug:
|
|
90
|
+
handlers.append(dict(sink=sys.stderr, level=log_level))
|
|
91
|
+
|
|
92
|
+
logger.configure(handlers=handlers)
|
|
93
|
+
|
|
86
94
|
return func(*args, **kwargs)
|
|
87
95
|
|
|
88
96
|
return wrapper
|
qulab/executor/load.py
CHANGED
|
@@ -269,7 +269,7 @@ def load_workflow_from_template(template_path: str,
|
|
|
269
269
|
str: 已经替换的新字符串。
|
|
270
270
|
"""
|
|
271
271
|
pattern = re.compile(r'VAR\s*\(\s*(["\'])(\w+)\1\s*\)')
|
|
272
|
-
replacement = f'__VAR_{hash_str}' + r'[
|
|
272
|
+
replacement = f'__VAR_{hash_str}' + r'[\1\2\1]'
|
|
273
273
|
new_text = re.sub(pattern, replacement, text)
|
|
274
274
|
return new_text
|
|
275
275
|
|
qulab/executor/schedule.py
CHANGED
|
@@ -7,8 +7,8 @@ from loguru import logger
|
|
|
7
7
|
|
|
8
8
|
from . import transform
|
|
9
9
|
from .load import WorkflowType, get_dependents
|
|
10
|
-
from .storage import (Result, find_result,
|
|
11
|
-
|
|
10
|
+
from .storage import (Result, find_result, renew_result, revoke_result,
|
|
11
|
+
save_result)
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class CalibrationFailedError(Exception):
|
|
@@ -120,13 +120,14 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
|
120
120
|
|
|
121
121
|
if hasattr(workflow, 'check') and callable(workflow.check) and hasattr(
|
|
122
122
|
workflow, 'check_analyze') and callable(workflow.check_analyze):
|
|
123
|
-
logger.debug(
|
|
123
|
+
logger.debug(
|
|
124
|
+
f'Checking "{workflow.__workflow_id__}" with "check" method ...')
|
|
124
125
|
data = workflow.check()
|
|
125
126
|
result = Result()
|
|
126
127
|
result.data = data
|
|
127
|
-
save_result(workflow.__workflow_id__, result, state_path)
|
|
128
|
+
#save_result(workflow.__workflow_id__, result, state_path)
|
|
128
129
|
|
|
129
|
-
logger.debug(f'Checked "{workflow}" !')
|
|
130
|
+
logger.debug(f'Checked "{workflow.__workflow_id__}" !')
|
|
130
131
|
result = call_analyzer(workflow, data, history, check=True, plot=plot)
|
|
131
132
|
if result.in_spec:
|
|
132
133
|
logger.debug(
|
|
@@ -149,8 +150,10 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
|
149
150
|
|
|
150
151
|
logger.debug(f'Calibrated "{workflow}" !')
|
|
151
152
|
result = call_analyzer(workflow, data, history, check=False, plot=plot)
|
|
152
|
-
save_result(workflow.__workflow_id__,
|
|
153
|
-
|
|
153
|
+
save_result(workflow.__workflow_id__,
|
|
154
|
+
result,
|
|
155
|
+
state_path,
|
|
156
|
+
overwrite=True)
|
|
154
157
|
|
|
155
158
|
return result
|
|
156
159
|
|
|
@@ -167,8 +170,7 @@ def calibrate(workflow: WorkflowType, code_path: str | Path,
|
|
|
167
170
|
save_result(workflow.__workflow_id__, result, state_path)
|
|
168
171
|
logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
|
|
169
172
|
result = call_analyzer(workflow, data, history, check=False, plot=plot)
|
|
170
|
-
save_result(workflow.__workflow_id__, result, state_path,
|
|
171
|
-
get_head(workflow.__workflow_id__, state_path))
|
|
173
|
+
save_result(workflow.__workflow_id__, result, state_path, overwrite=True)
|
|
172
174
|
return result
|
|
173
175
|
|
|
174
176
|
|
qulab/executor/storage.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import lzma
|
|
1
2
|
import pickle
|
|
2
3
|
import uuid
|
|
3
4
|
from dataclasses import dataclass, field
|
|
@@ -6,6 +7,8 @@ from pathlib import Path
|
|
|
6
7
|
|
|
7
8
|
from loguru import logger
|
|
8
9
|
|
|
10
|
+
from ..cli.config import get_config_value
|
|
11
|
+
|
|
9
12
|
|
|
10
13
|
@dataclass
|
|
11
14
|
class Result():
|
|
@@ -18,25 +21,16 @@ class Result():
|
|
|
18
21
|
params: dict = field(default_factory=dict)
|
|
19
22
|
info: dict = field(default_factory=dict)
|
|
20
23
|
data: tuple = field(default_factory=tuple)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class Graph:
|
|
25
|
-
|
|
26
|
-
def __init__(self):
|
|
27
|
-
self.nodes = {}
|
|
28
|
-
self.heads = set()
|
|
29
|
-
self.roots = set()
|
|
24
|
+
index: int = -1
|
|
25
|
+
previous_path: Path | None = None
|
|
26
|
+
base_path: Path | None = None
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if dep not in self.nodes:
|
|
38
|
-
self.nodes[dep] = []
|
|
39
|
-
self.roots.discard(dep)
|
|
28
|
+
@property
|
|
29
|
+
def previous(self):
|
|
30
|
+
if self.previous_path is not None and self.base_path is not None:
|
|
31
|
+
return load_result(self.previous_path, self.base_path)
|
|
32
|
+
else:
|
|
33
|
+
return None
|
|
40
34
|
|
|
41
35
|
|
|
42
36
|
def random_path(base: Path) -> Path:
|
|
@@ -50,27 +44,54 @@ def random_path(base: Path) -> Path:
|
|
|
50
44
|
def save_result(workflow: str,
|
|
51
45
|
result: Result,
|
|
52
46
|
base_path: str | Path,
|
|
53
|
-
|
|
47
|
+
overwrite: bool = False):
|
|
54
48
|
logger.debug(
|
|
55
49
|
f'Saving result for "{workflow}", {result.in_spec=}, {result.bad_data=}, {result.fully_calibrated=}'
|
|
56
50
|
)
|
|
57
51
|
base_path = Path(base_path)
|
|
58
|
-
if
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
if overwrite:
|
|
53
|
+
buf = lzma.compress(pickle.dumps(result))
|
|
54
|
+
path = get_head(workflow, base_path)
|
|
55
|
+
with open(base_path / 'objects' / path, "rb") as f:
|
|
56
|
+
index = int.from_bytes(f.read(8), 'big')
|
|
57
|
+
result.index = index
|
|
58
|
+
else:
|
|
59
|
+
result.previous_path = get_head(workflow, base_path)
|
|
60
|
+
buf = lzma.compress(pickle.dumps(result))
|
|
61
|
+
path = random_path(base_path / 'objects')
|
|
62
|
+
(base_path / 'objects' / path).parent.mkdir(parents=True,
|
|
63
|
+
exist_ok=True)
|
|
64
|
+
result.index = create_index("result",
|
|
65
|
+
base_path,
|
|
66
|
+
context=str(path),
|
|
67
|
+
width=35)
|
|
68
|
+
|
|
62
69
|
with open(base_path / 'objects' / path, "wb") as f:
|
|
63
|
-
|
|
70
|
+
f.write(result.index.to_bytes(8, 'big'))
|
|
71
|
+
f.write(buf)
|
|
64
72
|
set_head(workflow, path, base_path)
|
|
65
73
|
|
|
66
74
|
|
|
67
|
-
def
|
|
75
|
+
def load_result(path: str | Path, base_path: str | Path) -> Result | None:
|
|
76
|
+
base_path = Path(base_path)
|
|
77
|
+
path = base_path / 'objects' / path
|
|
78
|
+
|
|
79
|
+
with open(base_path / 'objects' / path, "rb") as f:
|
|
80
|
+
index = int.from_bytes(f.read(8), 'big')
|
|
81
|
+
result = pickle.loads(lzma.decompress(f.read()))
|
|
82
|
+
result.base_path = base_path
|
|
83
|
+
result.index = index
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def find_result(
|
|
88
|
+
workflow: str, base_path: str | Path = get_config_value("data", Path)
|
|
89
|
+
) -> Result | None:
|
|
68
90
|
base_path = Path(base_path)
|
|
69
91
|
path = get_head(workflow, base_path)
|
|
70
92
|
if path is None:
|
|
71
93
|
return None
|
|
72
|
-
|
|
73
|
-
return pickle.load(f)
|
|
94
|
+
return load_result(path, base_path)
|
|
74
95
|
|
|
75
96
|
|
|
76
97
|
def renew_result(workflow: str, base_path: str | Path):
|
|
@@ -115,33 +136,56 @@ def get_head(workflow: str, base_path: str | Path) -> Path | None:
|
|
|
115
136
|
return None
|
|
116
137
|
|
|
117
138
|
|
|
118
|
-
def
|
|
139
|
+
def get_heads(base_path: str | Path) -> Path | None:
|
|
119
140
|
base_path = Path(base_path)
|
|
120
141
|
try:
|
|
121
142
|
with open(base_path / "heads", "rb") as f:
|
|
122
143
|
heads = pickle.load(f)
|
|
144
|
+
return heads
|
|
123
145
|
except:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
return {}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def create_index(name: str,
|
|
150
|
+
base_path: str | Path,
|
|
151
|
+
context: str,
|
|
152
|
+
width: int,
|
|
153
|
+
start: int = 0):
|
|
154
|
+
path = Path(base_path) / "index" / f"{name}.seq"
|
|
155
|
+
if path.exists():
|
|
156
|
+
with open(path, "r") as f:
|
|
157
|
+
index = int(f.read())
|
|
158
|
+
else:
|
|
159
|
+
index = start
|
|
160
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
161
|
+
with open(path, "w") as f:
|
|
162
|
+
f.write(str(index + 1))
|
|
163
|
+
|
|
164
|
+
path = Path(base_path) / "index" / f"{name}.width"
|
|
165
|
+
with open(path, "w") as f:
|
|
166
|
+
f.write(str(width))
|
|
167
|
+
|
|
168
|
+
path = Path(base_path) / "index" / f"{name}.idx"
|
|
169
|
+
with open(path, "a") as f:
|
|
170
|
+
|
|
171
|
+
f.write(f"{context.ljust(width)}\n")
|
|
172
|
+
|
|
173
|
+
return index
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def query_index(name: str, base_path: str | Path, index: int):
|
|
177
|
+
path = Path(base_path) / "index" / f"{name}.width"
|
|
178
|
+
with open(path, "r") as f:
|
|
179
|
+
width = int(f.read())
|
|
180
|
+
path = Path(base_path) / "index" / f"{name}.idx"
|
|
181
|
+
with open(path, "r") as f:
|
|
182
|
+
f.seek(index * (width + 1))
|
|
183
|
+
context = f.read(width)
|
|
184
|
+
return context.rstrip()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def get_result_by_index(
|
|
188
|
+
index: int, base_path: str | Path = get_config_value("data", Path)
|
|
189
|
+
) -> Result | None:
|
|
190
|
+
path = query_index("result", base_path, index)
|
|
191
|
+
return load_result(path, base_path)
|
qulab/executor/utils.py
CHANGED
|
@@ -31,10 +31,9 @@ def dependent_tree(node: str, code_path: str | Path) -> dict[str, list[str]]:
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
def workflow_template(deps: list[str]) -> str:
|
|
34
|
-
return f"""
|
|
35
|
-
from loguru import logger
|
|
34
|
+
return f"""from loguru import logger
|
|
36
35
|
|
|
37
|
-
def VAR(s): pass
|
|
36
|
+
def VAR(s): pass # 没有实际作用,只是用来抑制编辑器的警告。
|
|
38
37
|
|
|
39
38
|
import numpy as np
|
|
40
39
|
|
qulab/fun.cpython-312-darwin.so
CHANGED
|
Binary file
|
qulab/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.
|
|
1
|
+
__version__ = "2.5.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|