labmate 0.8.2__py3-none-any.whl → 0.8.4__py3-none-any.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.
- labmate/__config__.py +1 -1
- labmate/acquisition/acquisition_data.py +47 -8
- labmate/acquisition/acquisition_loop.py +1 -3
- labmate/acquisition/acquisition_manager.py +32 -10
- labmate/acquisition/analysis_data.py +36 -18
- labmate/acquisition/analysis_loop.py +4 -2
- labmate/acquisition/custom_lint.py +4 -1
- labmate/acquisition_notebook/acquisition_analysis_manager.py +53 -15
- labmate/acquisition_notebook/display_widget.py +3 -3
- labmate/attrdict/attrdict_class.py +15 -11
- labmate/display/__init__.py +6 -5
- labmate/display/platform_utils/windows_utils.py +11 -5
- labmate/parsing/saving.py +8 -2
- labmate/utils/lint.py +4 -1
- labmate/utils/random_utils.py +6 -2
- labmate/utils/title_parsing.py +7 -2
- {labmate-0.8.2.dist-info → labmate-0.8.4.dist-info}/METADATA +1 -1
- {labmate-0.8.2.dist-info → labmate-0.8.4.dist-info}/RECORD +21 -21
- {labmate-0.8.2.dist-info → labmate-0.8.4.dist-info}/LICENCE +0 -0
- {labmate-0.8.2.dist-info → labmate-0.8.4.dist-info}/WHEEL +0 -0
- {labmate-0.8.2.dist-info → labmate-0.8.4.dist-info}/top_level.txt +0 -0
labmate/__config__.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Module that contains NotebookAcquisitionData class."""
|
|
2
|
+
|
|
2
3
|
from typing import Dict, List, Optional, Union
|
|
3
4
|
|
|
4
5
|
from dh5 import DH5
|
|
5
|
-
from ..utils.file_read import read_files
|
|
6
6
|
|
|
7
|
+
from ..utils.file_read import read_files
|
|
7
8
|
from .logger_setup import logger
|
|
8
9
|
|
|
9
10
|
|
|
@@ -14,6 +15,9 @@ class NotebookAcquisitionData(DH5):
|
|
|
14
15
|
`cell` is a str. It saves using `save_cell` function that will save it to `..._CELL.py` file
|
|
15
16
|
"""
|
|
16
17
|
|
|
18
|
+
_current_step: int
|
|
19
|
+
_cells: Dict[int, Optional[str]]
|
|
20
|
+
|
|
17
21
|
def __init__(
|
|
18
22
|
self,
|
|
19
23
|
filepath: str,
|
|
@@ -58,10 +62,11 @@ class NotebookAcquisitionData(DH5):
|
|
|
58
62
|
self._config = configs
|
|
59
63
|
self.save_configs()
|
|
60
64
|
|
|
61
|
-
self.
|
|
62
|
-
self.save_cell(cell=cell)
|
|
65
|
+
self._cells = {1: cell}
|
|
66
|
+
self.save_cell(cell=cell, suffix="1")
|
|
63
67
|
|
|
64
68
|
self.experiment_name = experiment_name
|
|
69
|
+
self.current_step = 1
|
|
65
70
|
|
|
66
71
|
self["useful"] = False
|
|
67
72
|
|
|
@@ -95,7 +100,12 @@ class NotebookAcquisitionData(DH5):
|
|
|
95
100
|
with open(filepath + "_" + name, "w", encoding="utf-8") as file:
|
|
96
101
|
file.write(value)
|
|
97
102
|
|
|
98
|
-
def save_cell(
|
|
103
|
+
def save_cell(
|
|
104
|
+
self,
|
|
105
|
+
cell: Optional[str] = None,
|
|
106
|
+
filepath: Optional[str] = None,
|
|
107
|
+
suffix: Optional[str] = None,
|
|
108
|
+
):
|
|
99
109
|
"""Save the cell code to the h5 file and possibly to a file.
|
|
100
110
|
|
|
101
111
|
If `save_files` during init was set to True, then it will create a '.py' file near
|
|
@@ -108,14 +118,15 @@ class NotebookAcquisitionData(DH5):
|
|
|
108
118
|
the desired location, i.e. it should end with the file prefix to which the suffix and
|
|
109
119
|
'py' extension will be added. Defaults to save filepath as h5 file.
|
|
110
120
|
"""
|
|
111
|
-
cell = cell or self._cell
|
|
112
121
|
if cell == "none":
|
|
113
122
|
return
|
|
114
123
|
if cell is None or cell == "":
|
|
115
124
|
logger.warning("Acquisition cell is not set. Nothing to save")
|
|
116
125
|
return
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
if suffix is not None:
|
|
127
|
+
self[f"acquisition_cell/{suffix}"] = cell
|
|
128
|
+
else:
|
|
129
|
+
self["acquisition_cell/0"] = cell
|
|
119
130
|
|
|
120
131
|
if not self._save_files:
|
|
121
132
|
return
|
|
@@ -124,13 +135,26 @@ class NotebookAcquisitionData(DH5):
|
|
|
124
135
|
with open(filepath + "_CELL.py", "w", encoding="utf-8") as file:
|
|
125
136
|
file.write(cell)
|
|
126
137
|
|
|
138
|
+
def save_cells(
|
|
139
|
+
self,
|
|
140
|
+
cells: Optional[Dict[int, Optional[str]]] = None,
|
|
141
|
+
filepath: Optional[str] = None,
|
|
142
|
+
):
|
|
143
|
+
"""Save all sells that are provided or pushed into self._cells array."""
|
|
144
|
+
cells = cells or self._cells
|
|
145
|
+
# if len(cells) == 1:
|
|
146
|
+
# self.save_cell(cells.popitem()[1], filepath)
|
|
147
|
+
# return
|
|
148
|
+
for i, cell in cells.items():
|
|
149
|
+
self.save_cell(cell, filepath, suffix=str(i))
|
|
150
|
+
|
|
127
151
|
def save_additional_info(self):
|
|
128
152
|
"""Save all additional information, i.e. cell code, configs. Put useful key to True."""
|
|
129
153
|
self["useful"] = True
|
|
130
154
|
|
|
131
155
|
if not self._save_files:
|
|
132
156
|
return
|
|
133
|
-
self.
|
|
157
|
+
self.save_cells()
|
|
134
158
|
self.save_configs()
|
|
135
159
|
|
|
136
160
|
def save_acquisition(self, **kwds) -> "NotebookAcquisitionData":
|
|
@@ -140,3 +164,18 @@ class NotebookAcquisitionData(DH5):
|
|
|
140
164
|
if self.save_on_edit is False:
|
|
141
165
|
self.save()
|
|
142
166
|
return self
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def current_step(self):
|
|
170
|
+
"""Return the current step of the acquisition."""
|
|
171
|
+
return self._current_step
|
|
172
|
+
|
|
173
|
+
@current_step.setter
|
|
174
|
+
def current_step(self, value: int):
|
|
175
|
+
self._current_step = value
|
|
176
|
+
|
|
177
|
+
def set_cell(self, cell: Optional[str], step: Optional[int] = None):
|
|
178
|
+
"""Set the cell code."""
|
|
179
|
+
if step is None:
|
|
180
|
+
step = self.current_step
|
|
181
|
+
self._cells[step] = cell
|
|
@@ -185,9 +185,7 @@ class AcquisitionLoop(DH5):
|
|
|
185
185
|
)
|
|
186
186
|
self[key][iteration] = value
|
|
187
187
|
else:
|
|
188
|
-
if
|
|
189
|
-
isinstance(value, (np.ndarray,)) and value.dtype == np.complex_
|
|
190
|
-
):
|
|
188
|
+
if np.iscomplexobj(value):
|
|
191
189
|
self[key] = SyncNp(np.zeros(key_shape, dtype=np.complex128))
|
|
192
190
|
else:
|
|
193
191
|
self[key] = SyncNp(np.zeros(key_shape))
|
|
@@ -104,9 +104,13 @@ class AcquisitionManager:
|
|
|
104
104
|
configs: dict of configurations files to save
|
|
105
105
|
directory: directory where the data is stored
|
|
106
106
|
"""
|
|
107
|
-
acquisition_tmp_data = self._acquisition_tmp_data or self.get_temp_data(
|
|
107
|
+
acquisition_tmp_data = self._acquisition_tmp_data or self.get_temp_data(
|
|
108
|
+
self.temp_file_path
|
|
109
|
+
)
|
|
108
110
|
if acquisition_tmp_data is None:
|
|
109
|
-
raise ValueError(
|
|
111
|
+
raise ValueError(
|
|
112
|
+
"You should create a new acquisition. It will create temp.json file."
|
|
113
|
+
)
|
|
110
114
|
return acquisition_tmp_data
|
|
111
115
|
|
|
112
116
|
@acquisition_tmp_data.setter
|
|
@@ -122,11 +126,15 @@ class AcquisitionManager:
|
|
|
122
126
|
self, filename: Union[str, List[str], Tuple[str, ...]]
|
|
123
127
|
) -> "AcquisitionManager":
|
|
124
128
|
"""Set self.config_file to filename. Verify if exists.
|
|
125
|
-
Only set config file for future acquisition and will not change current acquisition
|
|
129
|
+
Only set config file for future acquisition and will not change current acquisition
|
|
130
|
+
"""
|
|
126
131
|
if not isinstance(filename, (list, set, tuple)):
|
|
127
132
|
filename = [str(filename)]
|
|
128
133
|
|
|
129
134
|
self.config_files = list(filename)
|
|
135
|
+
self._config_files_names_to_path = {
|
|
136
|
+
os.path.basename(file): file for file in self.config_files
|
|
137
|
+
}
|
|
130
138
|
|
|
131
139
|
for config_file in self.config_files:
|
|
132
140
|
if not os.path.exists(config_file):
|
|
@@ -156,9 +164,13 @@ class AcquisitionManager:
|
|
|
156
164
|
if not experiment_path.exists():
|
|
157
165
|
experiment_path.makedirs()
|
|
158
166
|
if self._init_code and not os.path.exists(experiment_path / "init_analyse.py"):
|
|
159
|
-
with open(
|
|
167
|
+
with open(
|
|
168
|
+
experiment_path / "init_analyse.py", "w", encoding="utf-8"
|
|
169
|
+
) as file:
|
|
160
170
|
file.write(self._init_code)
|
|
161
|
-
filepath_original = filepath =
|
|
171
|
+
filepath_original = filepath = (
|
|
172
|
+
experiment_path / f"{dic.time_stamp}__{dic.experiment_name}"
|
|
173
|
+
)
|
|
162
174
|
if ignore_existence:
|
|
163
175
|
return filepath
|
|
164
176
|
|
|
@@ -183,7 +195,9 @@ class AcquisitionManager:
|
|
|
183
195
|
self.cell = cell
|
|
184
196
|
configs = read_files(self.config_files)
|
|
185
197
|
if self.config_files_eval:
|
|
186
|
-
configs = append_values_from_modules_to_files(
|
|
198
|
+
configs = append_values_from_modules_to_files(
|
|
199
|
+
configs, self.config_files_eval
|
|
200
|
+
)
|
|
187
201
|
|
|
188
202
|
dic = AcquisitionTmpData(
|
|
189
203
|
experiment_name=name,
|
|
@@ -194,7 +208,9 @@ class AcquisitionManager:
|
|
|
194
208
|
|
|
195
209
|
self.acquisition_tmp_data = dic
|
|
196
210
|
|
|
197
|
-
self._current_acquisition = self.get_acquisition(
|
|
211
|
+
self._current_acquisition = self.get_acquisition(
|
|
212
|
+
replace=True, save_on_edit=save_on_edit
|
|
213
|
+
)
|
|
198
214
|
|
|
199
215
|
return self.current_acquisition
|
|
200
216
|
|
|
@@ -208,7 +224,9 @@ class AcquisitionManager:
|
|
|
208
224
|
configs = read_files(self.config_files)
|
|
209
225
|
|
|
210
226
|
if self.config_files_eval:
|
|
211
|
-
configs = append_values_from_modules_to_files(
|
|
227
|
+
configs = append_values_from_modules_to_files(
|
|
228
|
+
configs, self.config_files_eval
|
|
229
|
+
)
|
|
212
230
|
|
|
213
231
|
if name is None:
|
|
214
232
|
name = self.current_experiment_name + "_item"
|
|
@@ -252,13 +270,17 @@ class AcquisitionManager:
|
|
|
252
270
|
|
|
253
271
|
@property
|
|
254
272
|
def current_experiment_name(self) -> str:
|
|
255
|
-
return
|
|
273
|
+
return (
|
|
274
|
+
self.acquisition_tmp_data.experiment_name
|
|
275
|
+
) # self.current_acquisition.name
|
|
256
276
|
|
|
257
277
|
def get_acquisition(
|
|
258
278
|
self, replace: Optional[bool] = False, save_on_edit: Optional[bool] = None
|
|
259
279
|
) -> NotebookAcquisitionData:
|
|
260
280
|
acquisition_tmp_data = self.acquisition_tmp_data
|
|
261
|
-
filepath = self.create_path_from_tmp_data(
|
|
281
|
+
filepath = self.create_path_from_tmp_data(
|
|
282
|
+
acquisition_tmp_data, ignore_existence=True
|
|
283
|
+
)
|
|
262
284
|
configs = acquisition_tmp_data.configs
|
|
263
285
|
configs = configs if configs else None
|
|
264
286
|
cell = self.cell
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"""AnalysisData class."""
|
|
2
|
+
|
|
2
3
|
import os
|
|
3
4
|
from typing import List, Literal, Optional, Protocol, Tuple, TypeVar, Union
|
|
4
5
|
|
|
5
|
-
|
|
6
6
|
from dh5 import DH5
|
|
7
7
|
from dh5.path import Path
|
|
8
8
|
|
|
9
|
+
from .. import utils
|
|
9
10
|
from .analysis_loop import AnalysisLoop
|
|
10
|
-
|
|
11
11
|
from .config_file import ConfigFile
|
|
12
|
-
from .. import utils
|
|
13
12
|
from .logger_setup import logger
|
|
14
13
|
|
|
15
14
|
_T = TypeVar("_T", bound="AnalysisData")
|
|
@@ -95,7 +94,10 @@ class AnalysisData(DH5):
|
|
|
95
94
|
raise ValueError(f"File '{filepath}' does not exist.")
|
|
96
95
|
|
|
97
96
|
super().__init__(
|
|
98
|
-
filepath=filepath,
|
|
97
|
+
filepath=filepath,
|
|
98
|
+
overwrite=False,
|
|
99
|
+
read_only=False,
|
|
100
|
+
save_on_edit=save_on_edit,
|
|
99
101
|
)
|
|
100
102
|
|
|
101
103
|
self.lock_data()
|
|
@@ -146,9 +148,9 @@ class AnalysisData(DH5):
|
|
|
146
148
|
logger.warning("Analysis cell is not set. Nothing to save")
|
|
147
149
|
return self
|
|
148
150
|
|
|
149
|
-
self.unlock_data(cell_name_key).update({cell_name_key: code}).lock_data(
|
|
150
|
-
|
|
151
|
-
)
|
|
151
|
+
self.unlock_data(cell_name_key).update({cell_name_key: code}).lock_data(
|
|
152
|
+
cell_name_key
|
|
153
|
+
).save([cell_name_key])
|
|
152
154
|
|
|
153
155
|
if self._save_files:
|
|
154
156
|
assert self.filepath, "You must set self.filepath before saving"
|
|
@@ -185,13 +187,18 @@ class AnalysisData(DH5):
|
|
|
185
187
|
"inside_h5", False
|
|
186
188
|
):
|
|
187
189
|
try:
|
|
188
|
-
|
|
190
|
+
raise NotImplementedError(
|
|
191
|
+
"save_fig_inside_h5 is not implemented for the moment."
|
|
192
|
+
)
|
|
193
|
+
# import pltsave
|
|
189
194
|
|
|
190
|
-
data = pltsave.dumps(fig).to_json()
|
|
191
|
-
self[f"figures/{fig_name}"] = data
|
|
192
|
-
self.save([f"figures/{fig_name}"])
|
|
195
|
+
# data = pltsave.dumps(fig).to_json()
|
|
196
|
+
# self[f"figures/{fig_name}"] = data
|
|
197
|
+
# self.save([f"figures/{fig_name}"])
|
|
193
198
|
except Exception as error:
|
|
194
|
-
logger.exception(
|
|
199
|
+
logger.exception(
|
|
200
|
+
"Failed to save the figure inside h5 file due to %s", error
|
|
201
|
+
)
|
|
195
202
|
if tight_layout and hasattr(fig, "tight_layout"):
|
|
196
203
|
fig.tight_layout() # type: ignore
|
|
197
204
|
fig.savefig(full_fig_name, **kwargs)
|
|
@@ -229,7 +236,9 @@ class AnalysisData(DH5):
|
|
|
229
236
|
|
|
230
237
|
return "FIG" + name
|
|
231
238
|
|
|
232
|
-
def parse_config(
|
|
239
|
+
def parse_config(
|
|
240
|
+
self, config_files: Optional[Tuple[str, ...]] = None
|
|
241
|
+
) -> "ConfigFile":
|
|
233
242
|
"""Parse config files. If `config_files` are not provided takes `default_config_files`."""
|
|
234
243
|
|
|
235
244
|
config_files = config_files or self._default_config_files
|
|
@@ -240,7 +249,8 @@ class AnalysisData(DH5):
|
|
|
240
249
|
return self._parsed_configs[hash(config_files)]
|
|
241
250
|
|
|
242
251
|
config_data = sum(
|
|
243
|
-
(self.parse_config_file(config_file) for config_file in config_files),
|
|
252
|
+
(self.parse_config_file(config_file) for config_file in config_files),
|
|
253
|
+
ConfigFile(),
|
|
244
254
|
)
|
|
245
255
|
|
|
246
256
|
self._parsed_configs[hash(config_files)] = config_data
|
|
@@ -263,7 +273,9 @@ class AnalysisData(DH5):
|
|
|
263
273
|
if key_value == "filename" or key_value == "file" or key_value == "f":
|
|
264
274
|
filename = os.path.split(self.filepath)[-1]
|
|
265
275
|
keys_with_values.append(
|
|
266
|
-
utils.title_parsing.ValueForPrint(
|
|
276
|
+
utils.title_parsing.ValueForPrint(
|
|
277
|
+
key_value, filename, key_units, key_format
|
|
278
|
+
)
|
|
267
279
|
)
|
|
268
280
|
elif key_value in config_data:
|
|
269
281
|
keys_with_values.append(
|
|
@@ -316,7 +328,9 @@ class AnalysisData(DH5):
|
|
|
316
328
|
)
|
|
317
329
|
|
|
318
330
|
if config_file_name in self._parsed_configs:
|
|
319
|
-
self._parsed_configs[original_config_name] = self._parsed_configs[
|
|
331
|
+
self._parsed_configs[original_config_name] = self._parsed_configs[
|
|
332
|
+
config_file_name
|
|
333
|
+
]
|
|
320
334
|
return self._parsed_configs[config_file_name]
|
|
321
335
|
|
|
322
336
|
else:
|
|
@@ -339,7 +353,9 @@ class AnalysisData(DH5):
|
|
|
339
353
|
(config_files,) if isinstance(config_files, str) else tuple(config_files)
|
|
340
354
|
)
|
|
341
355
|
|
|
342
|
-
def get_analysis_code(
|
|
356
|
+
def get_analysis_code(
|
|
357
|
+
self, name: str = "default", /, update_code: bool = True
|
|
358
|
+
) -> str:
|
|
343
359
|
code: Optional[dict] = self.get("analysis_cells")
|
|
344
360
|
if code is None:
|
|
345
361
|
raise ValueError(
|
|
@@ -350,7 +366,9 @@ class AnalysisData(DH5):
|
|
|
350
366
|
# if isinstance(code, bytes):
|
|
351
367
|
# code = code.decode()
|
|
352
368
|
if name not in code:
|
|
353
|
-
raise KeyError(
|
|
369
|
+
raise KeyError(
|
|
370
|
+
f"Cannot get cell '{name}'. Possible cells are: {tuple(code.keys())}"
|
|
371
|
+
)
|
|
354
372
|
|
|
355
373
|
code_str: str = code[name]
|
|
356
374
|
if update_code:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
It has mainly __iter__ method and __getitem__ method for slicing.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from typing import Any, List, Optional,
|
|
5
|
+
from typing import Any, Iterable, List, Optional, Tuple, Union
|
|
6
6
|
|
|
7
7
|
from dh5 import DH5
|
|
8
8
|
|
|
@@ -39,7 +39,9 @@ class AnalysisLoop(DH5):
|
|
|
39
39
|
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
-
def __init__(
|
|
42
|
+
def __init__(
|
|
43
|
+
self, data: Optional[dict] = None, loop_shape: Optional[List[int]] = None
|
|
44
|
+
):
|
|
43
45
|
"""Initialize an AnalysisLoop object.
|
|
44
46
|
|
|
45
47
|
Args:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Custom additional linter functions for the acquisition module."""
|
|
2
|
+
|
|
2
3
|
import ast
|
|
3
4
|
from typing import Any, Dict
|
|
4
5
|
|
|
@@ -24,7 +25,9 @@ def on_call_functions(node: ast.Call, db: Dict[str, Any]):
|
|
|
24
25
|
h = hash(tuple(get_all_args_from_call(node)))
|
|
25
26
|
data = db.setdefault("save_fig", [])
|
|
26
27
|
if h in data:
|
|
27
|
-
errors.append(
|
|
28
|
+
errors.append(
|
|
29
|
+
"save_fig with the save arguments is used more then ones."
|
|
30
|
+
)
|
|
28
31
|
|
|
29
32
|
data.append(h)
|
|
30
33
|
return errors
|
|
@@ -264,7 +264,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
264
264
|
|
|
265
265
|
def load_file(self, filename) -> "AnalysisData":
|
|
266
266
|
filename = self._get_full_filename(filename)
|
|
267
|
-
if not os.path.exists(
|
|
267
|
+
if not os.path.exists(
|
|
268
|
+
filename if filename.endswith(".h5") else filename + ".h5"
|
|
269
|
+
):
|
|
268
270
|
raise ValueError(f"File {filename} cannot be found")
|
|
269
271
|
|
|
270
272
|
data = AnalysisData(
|
|
@@ -288,6 +290,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
288
290
|
cell: Optional[str] = None,
|
|
289
291
|
prerun: Optional[Union[_CallableWithNoArgs, List[_CallableWithNoArgs]]] = None,
|
|
290
292
|
save_on_edit: Optional[bool] = None,
|
|
293
|
+
step: int = 1,
|
|
291
294
|
) -> "AcquisitionAnalysisManager":
|
|
292
295
|
self._analysis_cell_str = None
|
|
293
296
|
self._analysis_data = None
|
|
@@ -295,8 +298,19 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
295
298
|
self._acquisition_started = time.time()
|
|
296
299
|
|
|
297
300
|
cell = cell or get_current_cell(self.shell)
|
|
298
|
-
|
|
299
|
-
|
|
301
|
+
if step != 1 and self._current_acquisition is not None:
|
|
302
|
+
if self._current_acquisition.experiment_name != name:
|
|
303
|
+
raise ValueError(
|
|
304
|
+
f"Current acquisition ('{self.current_experiment_name}') "
|
|
305
|
+
f"isn't the one expected ('{name}') for this acquisition. "
|
|
306
|
+
f"Possible solutions: run acquisition '{name}' with step 1; "
|
|
307
|
+
f"or change current acquisition name to '{self.current_experiment_name}'"
|
|
308
|
+
)
|
|
309
|
+
self._current_acquisition.current_step = step
|
|
310
|
+
self._current_acquisition.set_cell(cell, step=step)
|
|
311
|
+
self._current_acquisition.save_cell(cell, suffix=str(step))
|
|
312
|
+
else:
|
|
313
|
+
self.new_acquisition(name=name, cell=cell, save_on_edit=save_on_edit)
|
|
300
314
|
|
|
301
315
|
logger.info(self.current_filepath.basename)
|
|
302
316
|
|
|
@@ -325,7 +339,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
325
339
|
display_warning("Old data analysis")
|
|
326
340
|
|
|
327
341
|
filename = str(filepath or self._get_full_filename(filename)) # type: ignore
|
|
328
|
-
filename = (
|
|
342
|
+
filename = (
|
|
343
|
+
(filename.rsplit(".h5", 1)[0]) if filename.endswith(".h5") else filename
|
|
344
|
+
)
|
|
329
345
|
|
|
330
346
|
else:
|
|
331
347
|
self._is_old_data = False
|
|
@@ -340,7 +356,8 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
340
356
|
)
|
|
341
357
|
or (
|
|
342
358
|
acquisition_name[0] == r"^"
|
|
343
|
-
and re.match(acquisition_name, self.current_experiment_name)
|
|
359
|
+
and re.match(acquisition_name, self.current_experiment_name)
|
|
360
|
+
is None
|
|
344
361
|
)
|
|
345
362
|
):
|
|
346
363
|
raise ValueError(
|
|
@@ -374,7 +391,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
374
391
|
if cell is not None:
|
|
375
392
|
self.save_analysis_cell(cell=cell)
|
|
376
393
|
|
|
377
|
-
if (self._analysis_cell_str is not None) and (
|
|
394
|
+
if (self._analysis_cell_str is not None) and (
|
|
395
|
+
self._linting_external_vars is not None
|
|
396
|
+
):
|
|
378
397
|
from ..acquisition import custom_lint
|
|
379
398
|
from ..utils import lint
|
|
380
399
|
|
|
@@ -387,7 +406,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
387
406
|
run_on_call=custom_lint.on_call_functions,
|
|
388
407
|
)
|
|
389
408
|
for var in lint_result.external_vars:
|
|
390
|
-
logger.warning(
|
|
409
|
+
logger.warning(
|
|
410
|
+
"External variable used inside the analysis code: %s", var
|
|
411
|
+
)
|
|
391
412
|
for error in lint_result.errors:
|
|
392
413
|
logger.warning(error)
|
|
393
414
|
utils.run_functions(self._analysis_cell_prerun_hook)
|
|
@@ -417,7 +438,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
417
438
|
def parse_config_file(self, config_file_name: str, /) -> "ConfigFile":
|
|
418
439
|
return self.data.parse_config_file(config_file_name)
|
|
419
440
|
|
|
420
|
-
def parse_config(
|
|
441
|
+
def parse_config(
|
|
442
|
+
self, config_files: Optional[Tuple[str, ...]] = None
|
|
443
|
+
) -> "ConfigFile":
|
|
421
444
|
return self.data.parse_config(config_files=config_files)
|
|
422
445
|
|
|
423
446
|
@property
|
|
@@ -433,16 +456,22 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
433
456
|
return self.data.parse_config_str(values, max_length=max_length)
|
|
434
457
|
|
|
435
458
|
def linting(
|
|
436
|
-
self,
|
|
459
|
+
self,
|
|
460
|
+
allowed_variables: Optional[Iterable[str]] = None,
|
|
461
|
+
init_file: Optional[str] = None,
|
|
437
462
|
):
|
|
438
463
|
from ..utils import lint
|
|
439
464
|
|
|
440
|
-
allowed_variables =
|
|
465
|
+
allowed_variables = (
|
|
466
|
+
set() if allowed_variables is None else set(allowed_variables)
|
|
467
|
+
)
|
|
441
468
|
if init_file is not None:
|
|
442
469
|
allowed_variables.update(lint.find_variables_from_file(init_file)[0])
|
|
443
470
|
self._linting_external_vars = allowed_variables
|
|
444
471
|
|
|
445
|
-
def set_default_config_files(
|
|
472
|
+
def set_default_config_files(
|
|
473
|
+
self, config_files: Union[str, Tuple[str, ...], List[str]], /
|
|
474
|
+
):
|
|
446
475
|
self._default_config_files = (
|
|
447
476
|
(config_files,) if isinstance(config_files, str) else tuple(config_files)
|
|
448
477
|
)
|
|
@@ -452,7 +481,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
452
481
|
def set_analysis_cell_prerun_hook(
|
|
453
482
|
self,
|
|
454
483
|
hook: Union[
|
|
455
|
-
_CallableWithNoArgs,
|
|
484
|
+
_CallableWithNoArgs,
|
|
485
|
+
List[_CallableWithNoArgs],
|
|
486
|
+
Tuple[_CallableWithNoArgs, ...],
|
|
456
487
|
],
|
|
457
488
|
):
|
|
458
489
|
self._analysis_cell_prerun_hook = (
|
|
@@ -462,7 +493,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
462
493
|
def set_acquisition_cell_prerun_hook(
|
|
463
494
|
self,
|
|
464
495
|
hook: Union[
|
|
465
|
-
_CallableWithNoArgs,
|
|
496
|
+
_CallableWithNoArgs,
|
|
497
|
+
List[_CallableWithNoArgs],
|
|
498
|
+
Tuple[_CallableWithNoArgs, ...],
|
|
466
499
|
],
|
|
467
500
|
):
|
|
468
501
|
self._acquisition_cell_prerun_hook = (
|
|
@@ -502,16 +535,21 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
502
535
|
|
|
503
536
|
res = self.find_param_in_config(param_text)
|
|
504
537
|
if res is None:
|
|
505
|
-
logger.warning(
|
|
538
|
+
logger.warning(
|
|
539
|
+
"Parameter '%s' cannot be found in default config files.", param
|
|
540
|
+
)
|
|
506
541
|
continue
|
|
507
542
|
file, line_no = res
|
|
543
|
+
file = self._config_files_names_to_path.get(file, file)
|
|
508
544
|
link = display.links.create_link(param_text, file, line_no, after_text)
|
|
509
545
|
links += link + "<br/>"
|
|
510
546
|
return display.display_html(links)
|
|
511
547
|
|
|
512
548
|
def connect_default_widget(
|
|
513
549
|
self,
|
|
514
|
-
objs: Union[
|
|
550
|
+
objs: Union[
|
|
551
|
+
"display_widget.WidgetProtocol", List["display_widget.WidgetProtocol"]
|
|
552
|
+
],
|
|
515
553
|
):
|
|
516
554
|
if not isinstance(objs, (list, tuple)):
|
|
517
555
|
objs = [objs]
|
|
@@ -198,9 +198,9 @@ def _create_file_link(aqm: "AcquisitionAnalysisManager", level_up) -> str:
|
|
|
198
198
|
if filepath is None:
|
|
199
199
|
return ""
|
|
200
200
|
link_name = os.path.basename(filepath)
|
|
201
|
-
link = "/".join(
|
|
202
|
-
"
|
|
203
|
-
)
|
|
201
|
+
link = "/".join(
|
|
202
|
+
os.path.abspath(filepath).replace("\\", "/").split("/")[-level_up:]
|
|
203
|
+
).replace(" ", "%20")
|
|
204
204
|
link = f"[{link_name}](//kyrylo-gr.github.io/h5viewer/open?url={link})"
|
|
205
205
|
return link
|
|
206
206
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""This module contains the AttrDict class."""
|
|
2
|
+
|
|
2
3
|
from typing import Any, List, Optional, Tuple, Union, overload
|
|
4
|
+
|
|
3
5
|
from ..utils import title_parsing as utils_parse
|
|
4
6
|
|
|
5
7
|
|
|
@@ -30,12 +32,10 @@ class AttrDict(dict):
|
|
|
30
32
|
return type(self)(result)
|
|
31
33
|
|
|
32
34
|
@overload
|
|
33
|
-
def find_all(self, key: str) -> List[Tuple[str, Any]]:
|
|
34
|
-
...
|
|
35
|
+
def find_all(self, key: str) -> List[Tuple[str, Any]]: ... # noqa
|
|
35
36
|
|
|
36
37
|
@overload
|
|
37
|
-
def find_all(self, key: list) -> List[List[Tuple[str, Any]]]:
|
|
38
|
-
...
|
|
38
|
+
def find_all(self, key: list) -> List[List[Tuple[str, Any]]]: ... # noqa
|
|
39
39
|
|
|
40
40
|
def find_all(self, key: Union[str, list]):
|
|
41
41
|
"""Find all keys that contain the given string.
|
|
@@ -54,12 +54,10 @@ class AttrDict(dict):
|
|
|
54
54
|
return elms
|
|
55
55
|
|
|
56
56
|
@overload
|
|
57
|
-
def find(self, key: str) -> Optional[Tuple[str, Any]]:
|
|
58
|
-
...
|
|
57
|
+
def find(self, key: str) -> Optional[Tuple[str, Any]]: ... # noqa
|
|
59
58
|
|
|
60
59
|
@overload
|
|
61
|
-
def find(self, key: list) -> List[Optional[Tuple[str, Any]]]:
|
|
62
|
-
...
|
|
60
|
+
def find(self, key: list) -> List[Optional[Tuple[str, Any]]]: ... # noqa
|
|
63
61
|
|
|
64
62
|
def find(self, key: Union[str, list]) -> Union[Optional[tuple], list]:
|
|
65
63
|
"""Find the first key that contain the given string.
|
|
@@ -94,15 +92,21 @@ class AttrDict(dict):
|
|
|
94
92
|
keys_with_values = self.__get_value_for_output(keys)
|
|
95
93
|
return utils_parse.format_title(keys_with_values, max_length=max_length)
|
|
96
94
|
|
|
97
|
-
def __get_value_for_output(
|
|
95
|
+
def __get_value_for_output(
|
|
96
|
+
self, keys: List[str]
|
|
97
|
+
) -> List[utils_parse.ValueForPrint]:
|
|
98
98
|
"""Prepare the values for output. Returns list of ValueForPrint(key, value, unit, format))."""
|
|
99
99
|
keys_with_values = []
|
|
100
100
|
for key in keys:
|
|
101
101
|
key_value, key_units, key_format = utils_parse.parse_get_format(key)
|
|
102
102
|
if key_value in self:
|
|
103
103
|
keys_with_values.append(
|
|
104
|
-
utils_parse.ValueForPrint(
|
|
104
|
+
utils_parse.ValueForPrint(
|
|
105
|
+
key_value, self[key_value], key_units, key_format
|
|
106
|
+
)
|
|
105
107
|
)
|
|
106
108
|
else:
|
|
107
|
-
raise ValueError(
|
|
109
|
+
raise ValueError(
|
|
110
|
+
f"Cannot find key={key} inside {self.__class__.__name__}"
|
|
111
|
+
)
|
|
108
112
|
return keys_with_values
|
labmate/display/__init__.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# flake8: noqa: F401
|
|
2
|
-
from typing import Any, TYPE_CHECKING
|
|
3
2
|
import importlib
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
|
-
from .main import display_html,
|
|
5
|
+
from .main import display, display_html, display_widgets, logger
|
|
6
6
|
|
|
7
7
|
__all__ = ["links", "buttons", "logger"]
|
|
8
8
|
|
|
@@ -14,7 +14,9 @@ class _LazyModule:
|
|
|
14
14
|
|
|
15
15
|
def __getattr__(self, name):
|
|
16
16
|
if self.__module is None:
|
|
17
|
-
self.__module = importlib.import_module(
|
|
17
|
+
self.__module = importlib.import_module(
|
|
18
|
+
f".{self.__name}", package=__package__
|
|
19
|
+
)
|
|
18
20
|
return getattr(self.__module, name)
|
|
19
21
|
|
|
20
22
|
# @property
|
|
@@ -29,5 +31,4 @@ buttons = _LazyModule("buttons")
|
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
if TYPE_CHECKING:
|
|
32
|
-
from . import links
|
|
33
|
-
from . import buttons
|
|
34
|
+
from . import buttons, links
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""This submodule contains functions that are specific for windows."""
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
def copy_fig(
|
|
4
|
+
def copy_fig(
|
|
5
|
+
fig=None, format_=None, text_to_copy=None, **kwargs
|
|
6
|
+
): # pragma: no cover <--
|
|
5
7
|
"""Copy fig to the clipboard.
|
|
6
8
|
|
|
7
9
|
Parameters
|
|
@@ -24,10 +26,10 @@ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no
|
|
|
24
26
|
If no figure is found
|
|
25
27
|
"""
|
|
26
28
|
# from win32gui import GetWindowText, GetForegroundWindow # type: ignore import warnings
|
|
27
|
-
|
|
29
|
+
from io import BytesIO
|
|
28
30
|
|
|
29
31
|
import matplotlib.pyplot as plt
|
|
30
|
-
|
|
32
|
+
import win32clipboard # type: ignore import warnings
|
|
31
33
|
|
|
32
34
|
# Determined available values by digging into windows API
|
|
33
35
|
format_map = {
|
|
@@ -71,7 +73,9 @@ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no
|
|
|
71
73
|
im = Image.open(buf)
|
|
72
74
|
with BytesIO() as output:
|
|
73
75
|
im.convert("RGB").save(output, "BMP")
|
|
74
|
-
data = output.getvalue()[
|
|
76
|
+
data = output.getvalue()[
|
|
77
|
+
14:
|
|
78
|
+
] # The file header off-set of BMP is 14 bytes
|
|
75
79
|
format_id = win32clipboard.CF_DIB # DIB = device independent bitmap
|
|
76
80
|
|
|
77
81
|
except ImportError:
|
|
@@ -85,6 +89,8 @@ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no
|
|
|
85
89
|
win32clipboard.EmptyClipboard()
|
|
86
90
|
win32clipboard.SetClipboardData(format_id, data)
|
|
87
91
|
if text_to_copy:
|
|
88
|
-
win32clipboard.SetClipboardData(
|
|
92
|
+
win32clipboard.SetClipboardData(
|
|
93
|
+
win32clipboard.CF_TEXT, text_to_copy.encode("utf-8")
|
|
94
|
+
)
|
|
89
95
|
|
|
90
96
|
win32clipboard.CloseClipboard()
|
labmate/parsing/saving.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""This file contains functions that prepare file for saving for further parsing."""
|
|
2
|
+
|
|
2
3
|
from typing import Dict
|
|
4
|
+
|
|
3
5
|
from . import parse_str
|
|
4
6
|
|
|
5
7
|
|
|
@@ -25,7 +27,9 @@ def append_values_from_modules_to_files(
|
|
|
25
27
|
return configs
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
def append_values_from_module_to_file(
|
|
30
|
+
def append_values_from_module_to_file(
|
|
31
|
+
body: str, module, separator=" # value: "
|
|
32
|
+
) -> str:
|
|
29
33
|
"""Add values from a module to a given file body.
|
|
30
34
|
|
|
31
35
|
Args:
|
|
@@ -64,7 +68,9 @@ def append_values_from_module_to_file(body: str, module, separator=" # value: "
|
|
|
64
68
|
for key, (val, _) in parse_str(line).items():
|
|
65
69
|
real_val = variables.get(key, "")
|
|
66
70
|
if (
|
|
67
|
-
isinstance(val, str)
|
|
71
|
+
isinstance(val, str)
|
|
72
|
+
and isinstance(real_val, str)
|
|
73
|
+
and real_val != val.strip("\"'")
|
|
68
74
|
) or (
|
|
69
75
|
isinstance(val, str)
|
|
70
76
|
and isinstance(real_val, (float, int, complex))
|
labmate/utils/lint.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Linting module that detects bad practice with AcquisitionAnalysisManager."""
|
|
2
|
+
|
|
2
3
|
import ast
|
|
3
4
|
from typing import Any, Callable, Dict, List, NamedTuple, Optional, Set
|
|
4
5
|
|
|
@@ -197,7 +198,9 @@ class LintResult(NamedTuple):
|
|
|
197
198
|
errors: List[str]
|
|
198
199
|
|
|
199
200
|
|
|
200
|
-
def find_variables_from_node(
|
|
201
|
+
def find_variables_from_node(
|
|
202
|
+
node, ignore_var: Optional[set] = None, **kwargs
|
|
203
|
+
) -> LintResult:
|
|
201
204
|
"""Walk through ast.node and find the variable that was never declared inside this node, but used.
|
|
202
205
|
|
|
203
206
|
Variables from ingore_var set is allowed external variables to use.
|
labmate/utils/random_utils.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Random utilities."""
|
|
2
|
+
|
|
2
3
|
from typing import Any, Callable, List, Optional, Tuple, Union
|
|
3
4
|
|
|
4
5
|
from dh5.utils.random_utils import ( # pylint: disable=unused-import # noqa: F401
|
|
@@ -6,13 +7,16 @@ from dh5.utils.random_utils import ( # pylint: disable=unused-import # noqa: F4
|
|
|
6
7
|
get_timestamp,
|
|
7
8
|
)
|
|
8
9
|
|
|
9
|
-
|
|
10
10
|
_CallableWithNoArgs = Callable[[], Any]
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def run_functions(
|
|
14
14
|
functions: Optional[
|
|
15
|
-
Union[
|
|
15
|
+
Union[
|
|
16
|
+
_CallableWithNoArgs,
|
|
17
|
+
List[_CallableWithNoArgs],
|
|
18
|
+
Tuple[_CallableWithNoArgs, ...],
|
|
19
|
+
]
|
|
16
20
|
] = None,
|
|
17
21
|
/,
|
|
18
22
|
):
|
labmate/utils/title_parsing.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""This file contains function of title generation.
|
|
2
2
|
(parsing expected units and format, creating title)
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from typing import Any, List, NamedTuple, Optional, Tuple
|
|
5
6
|
|
|
6
7
|
|
|
@@ -47,10 +48,14 @@ def format_title(values: List[ValueForPrint], max_length: Optional[int] = None)
|
|
|
47
48
|
for value in values:
|
|
48
49
|
units = f" ({value.units})" if value.units is not None else ""
|
|
49
50
|
value_str = (
|
|
50
|
-
value.value
|
|
51
|
+
value.value
|
|
52
|
+
if value.format is None
|
|
53
|
+
else value.value.__format__(f".{value.format}")
|
|
51
54
|
)
|
|
52
55
|
new_txt = f"{value.key} = {value_str}{units}"
|
|
53
|
-
if not max_length or (
|
|
56
|
+
if not max_length or (
|
|
57
|
+
(last_line_len + len(new_txt) < max_length) or last_line_len == 0
|
|
58
|
+
):
|
|
54
59
|
txt += ("; " if txt != "" else "") + new_txt
|
|
55
60
|
last_line_len += len(new_txt) + 2
|
|
56
61
|
else:
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
labmate/__config__.py,sha256=
|
|
1
|
+
labmate/__config__.py,sha256=vSn0Wg7zasd-lKnYyP7LRB_e4JcnIeULAsgcJKNrSgM,71
|
|
2
2
|
labmate/__init__.py,sha256=aHQiPLldCXIJqz6wwcfyFU9sGLofUR3W5sXBIRzK2n4,182
|
|
3
3
|
labmate/acquisition/__init__.py,sha256=8q3dy18lL32A9y_Du8GggpLgJqDMFcFKddHrySMavrM,269
|
|
4
|
-
labmate/acquisition/acquisition_data.py,sha256=
|
|
5
|
-
labmate/acquisition/acquisition_loop.py,sha256=
|
|
6
|
-
labmate/acquisition/acquisition_manager.py,sha256=
|
|
7
|
-
labmate/acquisition/analysis_data.py,sha256=
|
|
8
|
-
labmate/acquisition/analysis_loop.py,sha256=
|
|
4
|
+
labmate/acquisition/acquisition_data.py,sha256=FUF0JTHl5_nmgPHUHFocTQEwPlxuCAVT5Xsf338jVhI,6686
|
|
5
|
+
labmate/acquisition/acquisition_loop.py,sha256=fiiseV21GB7pczHSEJrlLPiTSQ2u9y5VMDyCO7Hn0vY,11106
|
|
6
|
+
labmate/acquisition/acquisition_manager.py,sha256=uzGCWKCcOIwKTZsKp12OY1rvyWaFBlBsBDRR7mFZwj0,10496
|
|
7
|
+
labmate/acquisition/analysis_data.py,sha256=DF9NshXBWu74gK8b_ZOGIuveabkzbLIDXfyui1c4yK8,14695
|
|
8
|
+
labmate/acquisition/analysis_loop.py,sha256=1Y8lyPkTCNwskM8DkwrMXSOt0hNmBHcWJaQjdVZ81Hs,5075
|
|
9
9
|
labmate/acquisition/config_file.py,sha256=1WwqaKTM-R5xZQHqqqGUi2QCF0PC1ag2mFgPOJuEdWI,2212
|
|
10
|
-
labmate/acquisition/custom_lint.py,sha256=
|
|
10
|
+
labmate/acquisition/custom_lint.py,sha256=x4vNoOnbH3A4Odu2DQVtBsuSPo5JfvRpo8_EP0EOmgM,1005
|
|
11
11
|
labmate/acquisition/logger_setup.py,sha256=udTp-0S4cqhGdUGQlk3G3Eg51wePEGraNG-69P9fTOo,129
|
|
12
12
|
labmate/acquisition_notebook/__init__.py,sha256=ZtOGQtmPqEM1IRrL-_JYo4xYA87lFQ5JY5GmKcZz9z0,251
|
|
13
|
-
labmate/acquisition_notebook/acquisition_analysis_manager.py,sha256=
|
|
14
|
-
labmate/acquisition_notebook/display_widget.py,sha256=
|
|
13
|
+
labmate/acquisition_notebook/acquisition_analysis_manager.py,sha256=PEP5gXnuB2EMazjM-aMcLt4Ws81AgqYZCgZmoD20Lo8,20105
|
|
14
|
+
labmate/acquisition_notebook/display_widget.py,sha256=VNSo7r5nY_8biq-PAJeLvU_nzJ71kS82gFuOy-762BQ,6918
|
|
15
15
|
labmate/attrdict/__init__.py,sha256=MvuZVe7j4a0HxGMxim_K2cv-dhqZOfzdeMiTX-SRgDg,58
|
|
16
|
-
labmate/attrdict/attrdict_class.py,sha256=
|
|
17
|
-
labmate/display/__init__.py,sha256=
|
|
16
|
+
labmate/attrdict/attrdict_class.py,sha256=4lKXe7oZo_lLHefmf5vAOKhibWgGDffJcxMhaWLvGs4,4047
|
|
17
|
+
labmate/display/__init__.py,sha256=tD9kCR-2VpV2Fvm7cpw4mDgqMCEXIXh_AOO5KLawxEo,844
|
|
18
18
|
labmate/display/buttons.py,sha256=_WbtS5PVpjgH2UEaSM5MACGHqcWiCSV3xN8di-MI7hk,2861
|
|
19
19
|
labmate/display/html_output.py,sha256=SRsrszxBxuv-sQaWEkW_fyxFbImyJVj76iMTysqxKa4,425
|
|
20
20
|
labmate/display/links.py,sha256=YgCNxowca-oHxqozGWbe4oGLzwltnZ-C0v3E5fQnK0U,746
|
|
21
21
|
labmate/display/main.py,sha256=5M0-ckxhkCH0LXaZN6HD61b0noMypolKC9foEQmXx9w,1852
|
|
22
22
|
labmate/display/platform_utils/__init__.py,sha256=GOWB9vXF-wxGZfdHQJlQWy-hy2V2KXUP3JwxgN91Fq4,1136
|
|
23
|
-
labmate/display/platform_utils/windows_utils.py,sha256=
|
|
23
|
+
labmate/display/platform_utils/windows_utils.py,sha256=4Z_avuJIZ_KoXkuRZOH2667t2wEljzNBMP6fbNDknuk,3268
|
|
24
24
|
labmate/parsing/__init__.py,sha256=AHNB502jlm6PGd49_PJjvSxt97fxJeXnIfXYh8HV5x0,1312
|
|
25
25
|
labmate/parsing/brackets_score.py,sha256=zzup7z6o57YUGeMr5FOSTo3nz9Z62s2omxqFV3M9MmI,988
|
|
26
26
|
labmate/parsing/parsed_value.py,sha256=UYB_gCkV3DiFQRjcprnQUPw--FqYPqb3pii-PQsbHf0,5261
|
|
27
|
-
labmate/parsing/saving.py,sha256=
|
|
27
|
+
labmate/parsing/saving.py,sha256=pwCdYI9shrpKyFceRPNbPcbEfJbNQ7Xj0AMsDOr5qLA,2548
|
|
28
28
|
labmate/utils/__init__.py,sha256=PExO1TzVGwb9dXVZ733iML2H-ZFly-dksiHLgFU1xr4,72
|
|
29
29
|
labmate/utils/async_utils.py,sha256=mSfmpF7I3M5KePkPtoS-OcuoCkFDHPKjf-RVF0P3R48,118
|
|
30
30
|
labmate/utils/autoreload.py,sha256=wKi1GgWyRu1h101OguVRpO3zQXZ8qsFj-K-1P8PKuq8,305
|
|
31
31
|
labmate/utils/errors.py,sha256=ly7-JQStTKmPiMuT0w3eXFw1O8-1kpTsqZT2jebpJ-I,140
|
|
32
32
|
labmate/utils/file_read.py,sha256=DAalvKehwEqVZjWSPhKZm8Myh6gfFA5gGT6WM0dPmyw,1536
|
|
33
|
-
labmate/utils/lint.py,sha256=
|
|
34
|
-
labmate/utils/random_utils.py,sha256=
|
|
35
|
-
labmate/utils/title_parsing.py,sha256=
|
|
36
|
-
labmate-0.8.
|
|
37
|
-
labmate-0.8.
|
|
38
|
-
labmate-0.8.
|
|
39
|
-
labmate-0.8.
|
|
40
|
-
labmate-0.8.
|
|
33
|
+
labmate/utils/lint.py,sha256=7llJbZUAM-ikEpmU_ZzraqOwGUuJPgk1wAf3aYMJdxg,9312
|
|
34
|
+
labmate/utils/random_utils.py,sha256=ZA3gK9P-eTcd_a3BTS_ZeJI5A0GM_GXL7X3yUqnPTO4,690
|
|
35
|
+
labmate/utils/title_parsing.py,sha256=RpbiZwuKnpIq-X5S5iS90oD8iOqocWcI27MGuB4kTLU,1988
|
|
36
|
+
labmate-0.8.4.dist-info/LICENCE,sha256=J9XIxdJExlWYZuxhhKtk4oYILvUz8-JM0y_leRQCKUE,7488
|
|
37
|
+
labmate-0.8.4.dist-info/METADATA,sha256=_VWg55ngbUh7P6kxlZ38iK3i89oWgIDis0PJ3EoDN4A,3210
|
|
38
|
+
labmate-0.8.4.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
39
|
+
labmate-0.8.4.dist-info/top_level.txt,sha256=WWAn6t2zNWsp02gRq6f5cSsGebcs-4L6HBFk0XrcY0o,8
|
|
40
|
+
labmate-0.8.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|