QuLab 2.11.12__tar.gz → 2.11.14__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.
Files changed (114) hide show
  1. {qulab-2.11.12 → qulab-2.11.14}/PKG-INFO +1 -1
  2. {qulab-2.11.12 → qulab-2.11.14}/QuLab.egg-info/PKG-INFO +1 -1
  3. {qulab-2.11.12 → qulab-2.11.14}/qulab/cli/config.py +1 -1
  4. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/registry.py +126 -0
  5. qulab-2.11.14/qulab/version.py +1 -0
  6. qulab-2.11.12/qulab/version.py +0 -1
  7. {qulab-2.11.12 → qulab-2.11.14}/LICENSE +0 -0
  8. {qulab-2.11.12 → qulab-2.11.14}/MANIFEST.in +0 -0
  9. {qulab-2.11.12 → qulab-2.11.14}/QuLab.egg-info/SOURCES.txt +0 -0
  10. {qulab-2.11.12 → qulab-2.11.14}/QuLab.egg-info/dependency_links.txt +0 -0
  11. {qulab-2.11.12 → qulab-2.11.14}/QuLab.egg-info/entry_points.txt +0 -0
  12. {qulab-2.11.12 → qulab-2.11.14}/QuLab.egg-info/requires.txt +0 -0
  13. {qulab-2.11.12 → qulab-2.11.14}/QuLab.egg-info/top_level.txt +0 -0
  14. {qulab-2.11.12 → qulab-2.11.14}/README.md +0 -0
  15. {qulab-2.11.12 → qulab-2.11.14}/pyproject.toml +0 -0
  16. {qulab-2.11.12 → qulab-2.11.14}/qulab/__init__.py +0 -0
  17. {qulab-2.11.12 → qulab-2.11.14}/qulab/__main__.py +0 -0
  18. {qulab-2.11.12 → qulab-2.11.14}/qulab/cli/__init__.py +0 -0
  19. {qulab-2.11.12 → qulab-2.11.14}/qulab/cli/commands.py +0 -0
  20. {qulab-2.11.12 → qulab-2.11.14}/qulab/cli/decorators.py +0 -0
  21. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/__init__.py +0 -0
  22. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/analyze.py +0 -0
  23. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/cli.py +0 -0
  24. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/load.py +0 -0
  25. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/schedule.py +0 -0
  26. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/storage.py +0 -0
  27. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/template.py +0 -0
  28. {qulab-2.11.12 → qulab-2.11.14}/qulab/executor/utils.py +0 -0
  29. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/__init__.py +0 -0
  30. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/__main__.py +0 -0
  31. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/config.py +0 -0
  32. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/dataset.py +0 -0
  33. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/event_queue.py +0 -0
  34. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/mainwindow.py +0 -0
  35. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/monitor.py +0 -0
  36. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/ploter.py +0 -0
  37. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/qt_compat.py +0 -0
  38. {qulab-2.11.12 → qulab-2.11.14}/qulab/monitor/toolbar.py +0 -0
  39. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/__init__.py +0 -0
  40. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/curd.py +0 -0
  41. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/models.py +0 -0
  42. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/optimize.py +0 -0
  43. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/query.py +0 -0
  44. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/record.py +0 -0
  45. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/scan.py +0 -0
  46. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/server.py +0 -0
  47. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/space.py +0 -0
  48. {qulab-2.11.12 → qulab-2.11.14}/qulab/scan/utils.py +0 -0
  49. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/__init__.py +0 -0
  50. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/__main__.py +0 -0
  51. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/backend/__init__.py +0 -0
  52. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/backend/redis.py +0 -0
  53. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/base_dataset.py +0 -0
  54. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/chunk.py +0 -0
  55. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/dataset.py +0 -0
  56. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/file.py +0 -0
  57. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/__init__.py +0 -0
  58. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/base.py +0 -0
  59. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/config.py +0 -0
  60. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/file.py +0 -0
  61. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/ipy.py +0 -0
  62. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/models.py +0 -0
  63. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/record.py +0 -0
  64. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/report.py +0 -0
  65. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/models/tag.py +0 -0
  66. {qulab-2.11.12 → qulab-2.11.14}/qulab/storage/storage.py +0 -0
  67. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/__init__.py +0 -0
  68. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/chat.py +0 -0
  69. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/device/__init__.py +0 -0
  70. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/device/basedevice.py +0 -0
  71. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/device/loader.py +0 -0
  72. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/device/utils.py +0 -0
  73. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/drivers/FakeInstrument.py +0 -0
  74. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/drivers/__init__.py +0 -0
  75. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/ipy_events.py +0 -0
  76. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/__init__.py +0 -0
  77. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/bencoder.py +0 -0
  78. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/cli.py +0 -0
  79. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/dhcp.py +0 -0
  80. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/dhcpd.py +0 -0
  81. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/kad.py +0 -0
  82. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/kcp.py +0 -0
  83. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/net/nginx.py +0 -0
  84. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/progress.py +0 -0
  85. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/__init__.py +0 -0
  86. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/client.py +0 -0
  87. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/exceptions.py +0 -0
  88. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/msgpack.py +0 -0
  89. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/msgpack.pyi +0 -0
  90. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/router.py +0 -0
  91. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/rpc.py +0 -0
  92. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/serialize.py +0 -0
  93. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/server.py +0 -0
  94. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/socket.py +0 -0
  95. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/utils.py +0 -0
  96. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/worker.py +0 -0
  97. {qulab-2.11.12 → qulab-2.11.14}/qulab/sys/rpc/zmq_socket.py +0 -0
  98. {qulab-2.11.12 → qulab-2.11.14}/qulab/tools/__init__.py +0 -0
  99. {qulab-2.11.12 → qulab-2.11.14}/qulab/tools/connection_helper.py +0 -0
  100. {qulab-2.11.12 → qulab-2.11.14}/qulab/typing.py +0 -0
  101. {qulab-2.11.12 → qulab-2.11.14}/qulab/utils.py +0 -0
  102. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/__init__.py +0 -0
  103. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/__main__.py +0 -0
  104. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/_autoplot.py +0 -0
  105. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/plot_circ.py +0 -0
  106. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/plot_layout.py +0 -0
  107. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/plot_seq.py +0 -0
  108. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/qdat.py +0 -0
  109. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/rot3d.py +0 -0
  110. {qulab-2.11.12 → qulab-2.11.14}/qulab/visualization/widgets.py +0 -0
  111. {qulab-2.11.12 → qulab-2.11.14}/setup.cfg +0 -0
  112. {qulab-2.11.12 → qulab-2.11.14}/setup.py +0 -0
  113. {qulab-2.11.12 → qulab-2.11.14}/src/qulab.h +0 -0
  114. {qulab-2.11.12 → qulab-2.11.14}/tests/test_scan.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QuLab
3
- Version: 2.11.12
3
+ Version: 2.11.14
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QuLab
3
- Version: 2.11.12
3
+ Version: 2.11.14
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -7,7 +7,7 @@ from pathlib import Path
7
7
  import click
8
8
  from loguru import logger
9
9
 
10
- DEFAULT_CONFIG_PATH = os.path.expanduser("~/.qulab.ini")
10
+ DEFAULT_CONFIG_PATH = Path(os.path.expanduser("~/.qulab.ini"))
11
11
  ENV_PREFIX = "QULAB_"
12
12
 
13
13
 
@@ -1,3 +1,4 @@
1
+ import copy
1
2
  import importlib
2
3
  import os
3
4
  import sys
@@ -157,6 +158,128 @@ def _init():
157
158
  _init()
158
159
 
159
160
 
161
+ class RegistrySnapshot:
162
+
163
+ def __init__(self, data: dict[str, Any]):
164
+ self.data = copy.deepcopy(data)
165
+
166
+ def query(self, key: str, default=...) -> Any:
167
+ """
168
+ Query a value from the nested dictionary using dot-separated keys.
169
+
170
+ Args:
171
+ key: Dot-separated key path (e.g., 'level1.level2.level3')
172
+ default: Default value to return if key not found.
173
+ If not provided and key is missing, raises KeyError.
174
+
175
+ Returns:
176
+ The value at the specified path, default value, or raises KeyError
177
+ """
178
+ keys = key.split('.')
179
+ current = self.data
180
+
181
+ # Track which level we're at for error reporting
182
+ for i, k in enumerate(keys):
183
+ if isinstance(current, dict) and k in current:
184
+ current = current[k]
185
+ else:
186
+ # Key not found at this level
187
+ missing_path = '.'.join(keys[:i + 1])
188
+ if default is ...:
189
+ raise KeyError(
190
+ f"Key '{missing_path}' not found in registry (failed at level {i+1})"
191
+ )
192
+ return default
193
+
194
+ return current
195
+
196
+ def get(self, key: str, default=...) -> Any:
197
+ """
198
+ Query a value from the nested dictionary using dot-separated keys.
199
+
200
+ Args:
201
+ key: Dot-separated key path (e.g., 'level1.level2.level3')
202
+ default: Default value to return if key not found.
203
+ If not provided and key is missing, raises KeyError.
204
+
205
+ Returns:
206
+ The value at the specified path, default value, or raises KeyError
207
+ """
208
+ return self.query(key, default)
209
+
210
+ def export(self) -> dict[str, Any]:
211
+ return self.data
212
+
213
+ def set(self, key: str, value: Any):
214
+ """
215
+ Set a value in the nested dictionary using dot-separated keys.
216
+ Creates intermediate dictionaries if they don't exist.
217
+
218
+ Args:
219
+ key: Dot-separated key path (e.g., 'level1.level2.level3')
220
+ value: Value to set
221
+ """
222
+ keys = key.split('.')
223
+ current = self.data
224
+
225
+ # Navigate to the parent of the target key, creating dicts as needed
226
+ for k in keys[:-1]:
227
+ if k not in current:
228
+ current[k] = {}
229
+ elif not isinstance(current[k], dict):
230
+ # If existing value is not a dict, replace it with a dict
231
+ current[k] = {}
232
+ current = current[k]
233
+
234
+ # Set the final value
235
+ current[keys[-1]] = value
236
+
237
+ def delete(self, key: str):
238
+ """
239
+ Delete a value from the nested dictionary using dot-separated keys.
240
+ Also cleans up empty parent dictionaries after deletion.
241
+
242
+ Args:
243
+ key: Dot-separated key path (e.g., 'level1.level2.level3')
244
+ """
245
+ keys = key.split('.')
246
+
247
+ # First check if the path exists
248
+ try:
249
+ self.query(key)
250
+ except KeyError:
251
+ return # Path doesn't exist, nothing to delete
252
+
253
+ # Navigate and collect references to all parent dictionaries
254
+ path_refs = []
255
+ current = self.data
256
+
257
+ for k in keys[:-1]:
258
+ path_refs.append((current, k))
259
+ current = current[k]
260
+
261
+ # Delete the final key
262
+ if isinstance(current, dict) and keys[-1] in current:
263
+ del current[keys[-1]]
264
+
265
+ # Clean up empty dictionaries from leaf to root
266
+ for parent_dict, parent_key in reversed(path_refs):
267
+ # Check if the current dictionary is empty
268
+ if isinstance(current, dict) and len(current) == 0:
269
+ del parent_dict[parent_key]
270
+ current = parent_dict
271
+ else:
272
+ # Stop if we encounter a non-empty dictionary
273
+ break
274
+
275
+ def clear(self):
276
+ self.data.clear()
277
+
278
+ def update(self, parameters: dict[str, Any]):
279
+ for k, v in parameters.items():
280
+ self.set(k, v)
281
+
282
+
160
283
  class Registry():
161
284
 
162
285
  def __init__(self):
@@ -183,3 +306,6 @@ class Registry():
183
306
 
184
307
  def update(self, parameters: dict[str, Any]):
185
308
  return self.api[1](parameters)
309
+
310
+ def snapshot(self) -> RegistrySnapshot:
311
+ return RegistrySnapshot(self.export())
@@ -0,0 +1 @@
1
+ __version__ = "2.11.14"
@@ -1 +0,0 @@
1
- __version__ = "2.11.12"
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
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
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
File without changes
File without changes