QuLab 2.4.9__cp310-cp310-win_amd64.whl → 2.4.10__cp310-cp310-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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: QuLab
3
- Version: 2.4.9
3
+ Version: 2.4.10
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -1,12 +1,12 @@
1
1
  qulab/__init__.py,sha256=vkFybY8YSsQilYdThPRD83-btPAR41sy_WCXiM-6mME,141
2
2
  qulab/__main__.py,sha256=sQ1z8lk9Q4pq7X9lEzLcY8t6Izr6uxQXO0t3qnTUxEs,575
3
3
  qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
4
- qulab/fun.cp310-win_amd64.pyd,sha256=kvgVYLLYZWzfe1uDAS-sDrsxzSEFESt10F3b78Myiv0,31232
5
- qulab/version.py,sha256=85DENkQDPFKjENaBuXBqtMA83jQapfZmg5ANqmiCkYc,21
4
+ qulab/fun.cp310-win_amd64.pyd,sha256=KAsRuAJTtGSRKXTifm4XSgrCYw2fJgSo2okOeGjpzaU,31232
5
+ qulab/version.py,sha256=xpqAldAat_EPvLePX9Bp7bPX0gGKeKjd9kZbsEQVax4,22
6
6
  qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
7
- qulab/executor/__main__.py,sha256=1Mg5fJ0dYSWQnP6wgTa0s6U_WH7NT2lCnCQOHyx_I7c,2430
8
- qulab/executor/load.py,sha256=jZHkEzFF8ufFAIajkRDKmHYYJxbxI3RcEbAFIbl9VQ0,6208
9
- qulab/executor/schedule.py,sha256=koVlSw7ejoScW6RBm6HDbzIJZcGPckTGFQDVYaG1Kj8,9563
7
+ qulab/executor/__main__.py,sha256=MMkkqpCH-Upwb1gBfvaN2ZuehXkJIMJGa1amYXEjn-Q,4017
8
+ qulab/executor/load.py,sha256=pxq8oFaJLJOT21ue9q-BNlFeJZcjxmGNN0Cz_TColxA,6211
9
+ qulab/executor/schedule.py,sha256=edPjE9U6_WQisSiOCcqov4DVbBVKTPWrBFwcy0ReC2s,10213
10
10
  qulab/executor/storage.py,sha256=M66Q5_Uc5MMfc_QAuuaaexwAz7wxBPMkeleB5nRpQmI,4621
11
11
  qulab/executor/transform.py,sha256=inaOn6eqCs22ZZ0xAQl8s8YCoEACaXSwFNNu7jqdwAk,2148
12
12
  qulab/executor/utils.py,sha256=n3uCSKh-qdDFFeNvOpj7_es2_B4AaC-ASAlV9gPmSO0,3086
@@ -89,9 +89,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
89
89
  qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
90
90
  qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
91
91
  qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
92
- QuLab-2.4.9.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
93
- QuLab-2.4.9.dist-info/METADATA,sha256=AhSxsNn3xk_-YQ6pH1jA4fev09EnUxIdTdxi9PY-owg,3803
94
- QuLab-2.4.9.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
95
- QuLab-2.4.9.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
96
- QuLab-2.4.9.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
97
- QuLab-2.4.9.dist-info/RECORD,,
92
+ QuLab-2.4.10.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
93
+ QuLab-2.4.10.dist-info/METADATA,sha256=NaE66YybeLcxWfsqXuotu8HuNYogTN6I68L0N33IlUg,3804
94
+ QuLab-2.4.10.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
95
+ QuLab-2.4.10.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
96
+ QuLab-2.4.10.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
97
+ QuLab-2.4.10.dist-info/RECORD,,
@@ -1,7 +1,10 @@
1
+ import functools
1
2
  import importlib
3
+ import sys, os
2
4
  from pathlib import Path
3
5
 
4
6
  import click
7
+ from loguru import logger
5
8
 
6
9
  from .load import find_unreferenced_workflows
7
10
  from .schedule import maintain as maintain_workflow
@@ -10,6 +13,31 @@ from .transform import set_config_api
10
13
  from .utils import workflow_template
11
14
 
12
15
 
16
+ def log_options(func):
17
+
18
+ @click.option("--debug", is_flag=True, help="Enable debug mode.")
19
+ @click.option("--log", type=str, help="Log file path.")
20
+ @functools.wraps(func) # 保持函数元信息
21
+ def wrapper(*args, log=None, debug=False, **kwargs):
22
+ print(f"{func} {log=}, {debug=}")
23
+ if log is None and not debug:
24
+ logger.remove()
25
+ logger.add(sys.stderr, level='INFO')
26
+ elif log is None and debug:
27
+ logger.remove()
28
+ logger.add(sys.stderr, level='DEBUG')
29
+ elif log is not None and not debug:
30
+ logger.configure(handlers=[dict(sink=log, level='INFO')])
31
+ elif log is not None and debug:
32
+ logger.configure(handlers=[
33
+ dict(sink=log, level='DEBUG'),
34
+ dict(sink=sys.stderr, level='DEBUG')
35
+ ])
36
+ return func(*args, **kwargs)
37
+
38
+ return wrapper
39
+
40
+
13
41
  @click.group()
14
42
  def cli():
15
43
  pass
@@ -17,7 +45,7 @@ def cli():
17
45
 
18
46
  @click.command()
19
47
  @click.argument('workflow')
20
- @click.option('--code', '-c', default=None)
48
+ @click.option('--code', '-c', default=None, help='The path of the code.')
21
49
  def create(workflow, code):
22
50
  """
23
51
  Create a new workflow file.
@@ -26,6 +54,7 @@ def create(workflow, code):
26
54
  code = Path.cwd()
27
55
 
28
56
  fname = Path(code) / f'{workflow}'
57
+ fname = Path(os.path.expanduser(fname))
29
58
  if fname.exists():
30
59
  click.echo(f'{workflow} already exists')
31
60
  return
@@ -40,11 +69,15 @@ def create(workflow, code):
40
69
 
41
70
  @click.command()
42
71
  @click.argument('workflow')
43
- @click.option('--code', '-c', default=None)
44
- @click.option('--data', '-d', default=None)
45
- @click.option('--api', '-a', default=None)
46
- @click.option('--plot', '-p', is_flag=True)
47
- @click.option('--no-dependents', '-n', is_flag=True)
72
+ @click.option('--code', '-c', default=None, help='The path of the code.')
73
+ @click.option('--data', '-d', default=None, help='The path of the data.')
74
+ @click.option('--api', '-a', default=None, help='The modlule name of the api.')
75
+ @click.option('--plot', '-p', is_flag=True, help='Plot the result.')
76
+ @click.option('--no-dependents',
77
+ '-n',
78
+ is_flag=True,
79
+ help='Do not run dependents.')
80
+ @log_options
48
81
  def run(workflow, code, data, api, plot, no_dependents):
49
82
  """
50
83
  Run a workflow.
@@ -57,6 +90,9 @@ def run(workflow, code, data, api, plot, no_dependents):
57
90
  if data is None:
58
91
  data = Path(code) / 'logs'
59
92
 
93
+ code = Path(os.path.expanduser(code))
94
+ data = Path(os.path.expanduser(data))
95
+
60
96
  if no_dependents:
61
97
  run_workflow(workflow, code, data, plot=plot)
62
98
  else:
@@ -65,10 +101,11 @@ def run(workflow, code, data, api, plot, no_dependents):
65
101
 
66
102
  @click.command()
67
103
  @click.argument('workflow')
68
- @click.option('--code', '-c', default=None)
69
- @click.option('--data', '-d', default=None)
70
- @click.option('--api', '-a', default=None)
71
- @click.option('--plot', '-p', is_flag=True)
104
+ @click.option('--code', '-c', default=None, help='The path of the code.')
105
+ @click.option('--data', '-d', default=None, help='The path of the data.')
106
+ @click.option('--api', '-a', default=None, help='The modlule name of the api.')
107
+ @click.option('--plot', '-p', is_flag=True, help='Plot the result.')
108
+ @log_options
72
109
  def maintain(workflow, code, data, api, plot):
73
110
  """
74
111
  Maintain a workflow.
@@ -81,6 +118,9 @@ def maintain(workflow, code, data, api, plot):
81
118
  if data is None:
82
119
  data = Path(code) / 'logs'
83
120
 
121
+ code = Path(os.path.expanduser(code))
122
+ data = Path(os.path.expanduser(data))
123
+
84
124
  maintain_workflow(workflow, code, data, run=False, plot=plot)
85
125
 
86
126
 
qulab/executor/load.py CHANGED
@@ -150,7 +150,7 @@ def find_unreferenced_workflows(path: str) -> list[str]:
150
150
  )
151
151
  continue
152
152
  try:
153
- depends_list = depends_func()
153
+ depends_list = depends_func()[0]
154
154
  except Exception as e:
155
155
  warnings.warn(f"Error calling depends() in {rel_str}: {e}")
156
156
  continue
@@ -172,15 +172,29 @@ def diagnose(node, code_path: str | Path, state_path: str | Path, plot: bool,
172
172
  # bad data case
173
173
  recalibrated = []
174
174
  if result.bad_data:
175
+ logger.debug(f'"{node}": Bad data, diagnosing dependents')
175
176
  recalibrated = [
176
177
  diagnose(n, code_path, state_path, plot, session_id)
177
178
  for n in get_dependents(node, code_path)
178
179
  ]
179
- if not any(recalibrated) and recalibrated:
180
+ if not any(recalibrated):
181
+ if result.bad_data:
182
+ raise CalibrationFailedError(
183
+ f'"{node}": bad data but no dependents recalibrated.')
180
184
  logger.debug(f'"{node}": no dependents recalibrated.')
181
- return False
182
185
  # calibrate
183
- logger.debug(f'recalibrate "{node}" because some dependents recalibrated')
186
+ if any(recalibrated):
187
+ logger.debug(
188
+ f'recalibrate "{node}" because some dependents recalibrated.')
189
+ elif not result.in_spec and not result.bad_data:
190
+ logger.debug(f'recalibrate "{node}" because out of spec.')
191
+ elif result.in_spec:
192
+ logger.error(f'Never reach: recalibrate "{node}" because in spec.')
193
+ elif result.bad_data:
194
+ logger.error(f'Never reach: recalibrate "{node}" because bad data.')
195
+ else:
196
+ logger.error(f'Never reach: recalibrate "{node}"')
197
+
184
198
  result = calibrate(node, code_path, state_path, plot, session_id)
185
199
  if result.bad_data or not result.in_spec:
186
200
  raise CalibrationFailedError(
@@ -193,7 +207,7 @@ def get_dependents(workflow: str, code_path: str | Path) -> list[str]:
193
207
  return [n for n in load_workflow(workflow, code_path).depends()[0]]
194
208
 
195
209
 
196
- #@logger.catch(reraise=True)
210
+ @logger.catch(reraise=True)
197
211
  def maintain(node,
198
212
  code_path: str | Path,
199
213
  state_path: str | Path,
@@ -236,6 +250,7 @@ def maintain(node,
236
250
  return
237
251
 
238
252
 
253
+ @logger.catch(reraise=True)
239
254
  def run(node,
240
255
  code_path: str | Path,
241
256
  state_path: str | Path,
Binary file
qulab/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.4.9"
1
+ __version__ = "2.4.10"
File without changes