labmate 0.10.5__py3-none-any.whl → 0.10.6__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.
Files changed (34) hide show
  1. labmate/__config__.py +1 -1
  2. labmate/acquisition/__init__.py +1 -1
  3. labmate/acquisition/acquisition_loop.py +11 -18
  4. labmate/acquisition/acquisition_manager.py +28 -48
  5. labmate/acquisition/analysis_data.py +15 -25
  6. labmate/acquisition/analysis_loop.py +9 -7
  7. labmate/acquisition/backend.py +2 -0
  8. labmate/acquisition/config_file.py +5 -3
  9. labmate/acquisition/custom_lint.py +2 -3
  10. labmate/acquisition_notebook/__init__.py +2 -2
  11. labmate/acquisition_notebook/acquisition_analysis_manager.py +24 -47
  12. labmate/acquisition_notebook/display_widget.py +9 -9
  13. labmate/attrdict/attrdict_class.py +4 -10
  14. labmate/display/__init__.py +2 -3
  15. labmate/display/buttons.py +1 -0
  16. labmate/display/links.py +2 -1
  17. labmate/display/main.py +3 -2
  18. labmate/display/platform_utils/__init__.py +3 -1
  19. labmate/display/platform_utils/windows_utils.py +3 -9
  20. labmate/parsing/__init__.py +3 -5
  21. labmate/parsing/parsed_value.py +30 -10
  22. labmate/parsing/saving.py +2 -6
  23. labmate/utils/async_utils.py +1 -0
  24. labmate/utils/autoreload.py +2 -0
  25. labmate/utils/file_read.py +12 -13
  26. labmate/utils/lint.py +9 -11
  27. labmate/utils/random_utils.py +1 -0
  28. labmate/utils/title_parsing.py +4 -14
  29. {labmate-0.10.5.dist-info → labmate-0.10.6.dist-info}/METADATA +1 -1
  30. labmate-0.10.6.dist-info/RECORD +41 -0
  31. {labmate-0.10.5.dist-info → labmate-0.10.6.dist-info}/WHEEL +1 -1
  32. labmate-0.10.5.dist-info/RECORD +0 -41
  33. {labmate-0.10.5.dist-info → labmate-0.10.6.dist-info}/licenses/LICENCE +0 -0
  34. {labmate-0.10.5.dist-info → labmate-0.10.6.dist-info}/top_level.txt +0 -0
@@ -19,10 +19,12 @@ from ..acquisition import AcquisitionManager, AnalysisData
19
19
  from ..logger import logger
20
20
  from . import display_widget
21
21
 
22
+
22
23
  if TYPE_CHECKING:
23
24
  from dh5.path import Path
24
- from ..acquisition.backend import AcquisitionBackend
25
+
25
26
  from ..acquisition import FigureProtocol
27
+ from ..acquisition.backend import AcquisitionBackend
26
28
  from ..acquisition.config_file import ConfigFile
27
29
 
28
30
  # from ..logger import Logger
@@ -65,7 +67,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
65
67
  _analysis_cell_str = None
66
68
  _is_old_data = False
67
69
  _last_fig_name = None
68
- _default_config_files: Tuple[str, ...] = tuple()
70
+ _default_config_files: Tuple[str, ...] = ()
69
71
  _acquisition_started = 0
70
72
  _linting_external_vars = None
71
73
  _analysis_cell_prerun_hook: Optional[Tuple[_CallableWithNoArgs, ...]] = None
@@ -83,9 +85,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
83
85
  save_on_edit_analysis: Optional[bool] = None,
84
86
  save_fig_inside_h5: bool = False,
85
87
  shell: Any = True,
86
- backend: Optional[
87
- Union["AcquisitionBackend", Iterable["AcquisitionBackend"]]
88
- ] = None,
88
+ backend: Optional[Union["AcquisitionBackend", Iterable["AcquisitionBackend"]]] = None,
89
89
  ):
90
90
  """
91
91
  AcquisitionAnalysisManager.
@@ -118,7 +118,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
118
118
  self.shell = shell
119
119
 
120
120
  if use_magic:
121
- from .acquisition_magic_class import load_ipython_extension
121
+ from .acquisition_magic_class import load_ipython_extension # pyright: ignore[reportMissingImports] # noqa: I001
122
122
 
123
123
  load_ipython_extension(aqm=self, shell=self.shell)
124
124
 
@@ -177,7 +177,8 @@ class AcquisitionAnalysisManager(AcquisitionManager):
177
177
  Args:
178
178
  fig (Figure, optional): Figure that should be saved. Figure could be any class with
179
179
  function save_fig implemented. By default gets plt.gcf().
180
- name (str, optional): Name of the fig. It's a suffix that will be added to the filename. Defaults to None.
180
+ name (str, optional): Name of the fig. It's a suffix that will be added to the filename.
181
+ Defaults to None.
181
182
  extensions(str, optional): Extensions of the file. Defaults to `pdf`.
182
183
  tight_layout(bool, optional): True to call fig.tight_layout(). Defaults to True.
183
184
 
@@ -256,15 +257,12 @@ class AcquisitionAnalysisManager(AcquisitionManager):
256
257
  acquisition_finished = time.time()
257
258
  if not self._once_saved:
258
259
  additional_info: Dict[str, Any] = {
259
- "acquisition_duration": acquisition_finished
260
- - self._acquisition_started,
260
+ "acquisition_duration": acquisition_finished - self._acquisition_started,
261
261
  "logs": self.logger.getvalue(),
262
262
  "prints": self.logger.get_stdout(),
263
263
  }
264
264
  if self._default_config_files:
265
- additional_info.update(
266
- {"default_config_files": self._default_config_files}
267
- )
265
+ additional_info.update({"default_config_files": self._default_config_files})
268
266
  kwds.update({"info": additional_info})
269
267
 
270
268
  super().save_acquisition(update_, file_suffix=file_suffix, **kwds)
@@ -300,9 +298,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
300
298
  - If default configuration files are provided, they are set in the loaded data.
301
299
  """
302
300
  filename = self._get_full_filename(filename)
303
- if not os.path.exists(
304
- filename if filename.endswith(".h5") else filename + ".h5"
305
- ):
301
+ if not os.path.exists(filename if filename.endswith(".h5") else filename + ".h5"): # noqa: PTH110
306
302
  raise ValueError(f"File {filename} cannot be found")
307
303
 
308
304
  data = AnalysisData(
@@ -394,9 +390,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
394
390
  display_warning("Old data analysis")
395
391
 
396
392
  filename = str(filepath or self._get_full_filename(filename)) # type: ignore
397
- filename = (
398
- (filename.rsplit(".h5", 1)[0]) if filename.endswith(".h5") else filename
399
- )
393
+ filename = (filename.rsplit(".h5", 1)[0]) if filename.endswith(".h5") else filename
400
394
 
401
395
  else:
402
396
  self._is_old_data = False
@@ -411,8 +405,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
411
405
  )
412
406
  or (
413
407
  acquisition_name[0] == r"^"
414
- and re.match(acquisition_name, self.current_experiment_name)
415
- is None
408
+ and re.match(acquisition_name, self.current_experiment_name) is None
416
409
  )
417
410
  ):
418
411
  raise ValueError(
@@ -421,7 +414,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
421
414
  )
422
415
 
423
416
  filename = str(self.current_filepath) # without h5
424
- self.logger.info(os.path.basename(filename))
417
+ self.logger.info(os.path.basename(filename)) # noqa: PTH119
425
418
 
426
419
  if (
427
420
  (not self._is_old_data)
@@ -436,7 +429,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
436
429
  "Check if everything is ok and executive again"
437
430
  )
438
431
 
439
- if os.path.exists(filename + ".h5"):
432
+ if os.path.exists(filename + ".h5"): # noqa: PTH110
440
433
  self._load_analysis_data(filename)
441
434
  else:
442
435
  if self._is_old_data:
@@ -446,9 +439,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
446
439
  if cell is not None:
447
440
  self.save_analysis_cell(cell=cell)
448
441
 
449
- if (self._analysis_cell_str is not None) and (
450
- self._linting_external_vars is not None
451
- ):
442
+ if (self._analysis_cell_str is not None) and (self._linting_external_vars is not None):
452
443
  from ..acquisition import custom_lint
453
444
  from ..utils import lint
454
445
 
@@ -461,9 +452,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
461
452
  run_on_call=custom_lint.on_call_functions,
462
453
  )
463
454
  for var in lint_result.external_vars:
464
- self.logger.warning(
465
- "External variable used inside the analysis code: %s", var
466
- )
455
+ self.logger.warning("External variable used inside the analysis code: %s", var)
467
456
  for error in lint_result.errors:
468
457
  self.logger.warning(error)
469
458
 
@@ -488,15 +477,13 @@ class AcquisitionAnalysisManager(AcquisitionManager):
488
477
 
489
478
  filepath = utils.get_path_from_filename(filename)
490
479
  if isinstance(filepath, tuple):
491
- return os.path.join(self.data_directory, *filepath)
480
+ return os.path.join(self.data_directory, *filepath) # noqa: PTH118
492
481
  return filepath
493
482
 
494
483
  def parse_config_file(self, config_file_name: str, /) -> "ConfigFile":
495
484
  return self.data.parse_config_file(config_file_name)
496
485
 
497
- def parse_config(
498
- self, config_files: Optional[Tuple[str, ...]] = None
499
- ) -> "ConfigFile":
486
+ def parse_config(self, config_files: Optional[Tuple[str, ...]] = None) -> "ConfigFile":
500
487
  return self.data.parse_config(config_files=config_files)
501
488
 
502
489
  @property
@@ -518,16 +505,12 @@ class AcquisitionAnalysisManager(AcquisitionManager):
518
505
  ):
519
506
  from ..utils import lint
520
507
 
521
- allowed_variables = (
522
- set() if allowed_variables is None else set(allowed_variables)
523
- )
508
+ allowed_variables = set() if allowed_variables is None else set(allowed_variables)
524
509
  if init_file is not None:
525
510
  allowed_variables.update(lint.find_variables_from_file(init_file)[0])
526
511
  self._linting_external_vars = allowed_variables
527
512
 
528
- def set_default_config_files(
529
- self, config_files: Union[str, Tuple[str, ...], List[str]], /
530
- ):
513
+ def set_default_config_files(self, config_files: Union[str, Tuple[str, ...], List[str]], /):
531
514
  self._default_config_files = (
532
515
  (config_files,) if isinstance(config_files, str) else tuple(config_files)
533
516
  )
@@ -574,7 +557,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
574
557
  if after_text is not None:
575
558
  if not isinstance(params, str):
576
559
  raise ValueError(
577
- "Cannot use after_text with multiple params"
560
+ "Cannot use after_text with multiple params. "
578
561
  "Use params=[(param, after_text), ...] instead."
579
562
  )
580
563
  return self.display_param_link(params=[(params, after_text)], title=title)
@@ -624,11 +607,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
624
607
  self.update_config_params_on_disk({param: value})
625
608
 
626
609
  buttons = (
627
- [
628
- display.buttons.create_button(
629
- update_value, param, value, name="Update"
630
- )
631
- ]
610
+ [display.buttons.create_button(update_value, param, value, name="Update")]
632
611
  if update_button
633
612
  else None
634
613
  )
@@ -661,9 +640,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
661
640
 
662
641
  def connect_default_widget(
663
642
  self,
664
- objs: Union[
665
- "display_widget.WidgetProtocol", List["display_widget.WidgetProtocol"]
666
- ],
643
+ objs: Union["display_widget.WidgetProtocol", List["display_widget.WidgetProtocol"]],
667
644
  ):
668
645
  if not isinstance(objs, (list, tuple)):
669
646
  objs = [objs]
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING, List, Optional, Protocol, TypeVar
4
4
  from .. import display as lm_display
5
5
  from ..display import platform_utils
6
6
 
7
+
7
8
  if TYPE_CHECKING:
8
9
  from labmate.acquisition_notebook import AcquisitionAnalysisManager
9
10
 
@@ -19,12 +20,11 @@ def _create_file_link(aqm: "AcquisitionAnalysisManager", level_up) -> str:
19
20
  filepath = _get_filepath(aqm)
20
21
  if filepath is None:
21
22
  return ""
22
- link_name = os.path.basename(filepath)
23
- link = "/".join(
24
- os.path.abspath(filepath).replace("\\", "/").split("/")[-level_up:]
25
- ).replace(" ", "%20")
26
- link = f"[{link_name}](//kyrylo-gr.github.io/h5viewer/open?url={link})"
27
- return link
23
+ link_name = os.path.basename(filepath) # noqa: PTH119
24
+ link = "/".join(os.path.abspath(filepath).replace("\\", "/").split("/")[-level_up:]).replace( # noqa: PTH100
25
+ " ", "%20"
26
+ )
27
+ return f"[{link_name}](//kyrylo-gr.github.io/h5viewer/open?url={link})"
28
28
 
29
29
 
30
30
  def display_widgets(objs: List["WidgetProtocol"], *args, **kwargs):
@@ -193,14 +193,14 @@ class OpenFinderButton(BaseWidget):
193
193
  import sys
194
194
 
195
195
  def open_finder():
196
- path = os.path.abspath(filepath) + ".h5"
196
+ path = os.path.abspath(filepath) + ".h5" # noqa: PTH100
197
197
  if sys.platform == "win32":
198
198
  path = path.replace("/", "\\")
199
199
  subprocess.run(["explorer", "/select,", path], shell=True)
200
200
  elif sys.platform == "darwin":
201
- subprocess.Popen(["open", "-R", os.path.dirname(path)])
201
+ subprocess.Popen(["open", "-R", os.path.dirname(path)]) # noqa: PTH120
202
202
  else:
203
- subprocess.Popen(["nautilus", "--select", os.path.dirname(path)])
203
+ subprocess.Popen(["nautilus", "--select", os.path.dirname(path)]) # noqa: PTH120
204
204
 
205
205
  self.widget = lm_display.buttons.create_button(open_finder, name="Open finder")
206
206
  return self.widget
@@ -92,21 +92,15 @@ class AttrDict(dict):
92
92
  keys_with_values = self.__get_value_for_output(keys)
93
93
  return utils_parse.format_title(keys_with_values, max_length=max_length)
94
94
 
95
- def __get_value_for_output(
96
- self, keys: List[str]
97
- ) -> List[utils_parse.ValueForPrint]:
98
- """Prepare the values for output. Returns list of ValueForPrint(key, value, unit, format))."""
95
+ def __get_value_for_output(self, keys: List[str]) -> List[utils_parse.ValueForPrint]:
96
+ """Prepare values for output. Returns list of ValueForPrint(key, value, unit, format)."""
99
97
  keys_with_values = []
100
98
  for key in keys:
101
99
  key_value, key_units, key_format = utils_parse.parse_get_format(key)
102
100
  if key_value in self:
103
101
  keys_with_values.append(
104
- utils_parse.ValueForPrint(
105
- key_value, self[key_value], key_units, key_format
106
- )
102
+ utils_parse.ValueForPrint(key_value, self[key_value], key_units, key_format)
107
103
  )
108
104
  else:
109
- raise ValueError(
110
- f"Cannot find key={key} inside {self.__class__.__name__}"
111
- )
105
+ raise ValueError(f"Cannot find key={key} inside {self.__class__.__name__}")
112
106
  return keys_with_values
@@ -10,6 +10,7 @@ from .main import (
10
10
  logger,
11
11
  )
12
12
 
13
+
13
14
  __all__ = ["links", "buttons", "logger", "html_output"]
14
15
 
15
16
 
@@ -20,9 +21,7 @@ class _LazyModule:
20
21
 
21
22
  def __getattr__(self, name):
22
23
  if self.__module is None:
23
- self.__module = importlib.import_module(
24
- f".{self.__name}", package=__package__
25
- )
24
+ self.__module = importlib.import_module(f".{self.__name}", package=__package__)
26
25
  return getattr(self.__module, name)
27
26
 
28
27
  # @property
@@ -4,6 +4,7 @@ from typing import TypeVar
4
4
 
5
5
  from .main import display, widgets
6
6
 
7
+
7
8
  # from functools import wraps
8
9
  # def add_display_method(func):
9
10
  # """If a function changes the data it should be saved.
labmate/display/links.py CHANGED
@@ -23,5 +23,6 @@ def create_link(
23
23
  after_text = after_text if after_text else ""
24
24
  return (
25
25
  f"<a href='{file}:{line_no}' target='_blank' style='margin: 0!; padding:0!;'>"
26
- f"{link_text}</a> {after_text}"
26
+ f"{link_text}"
27
+ f"</a> {after_text}"
27
28
  )
labmate/display/main.py CHANGED
@@ -4,6 +4,7 @@ import logging
4
4
  import sys
5
5
  from typing import Callable, List
6
6
 
7
+
7
8
  logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.WARNING)
8
9
  logger = logging.getLogger(__name__)
9
10
  handler = logging.StreamHandler()
@@ -28,13 +29,13 @@ except (ImportError, AttributeError):
28
29
  # For testing purposes every IPython function should have a simpler version.
29
30
  # pylint: disable=C0115, C0103, R0903
30
31
 
31
- def HTML(text): # noqa: D103
32
+ def HTML(text): # noqa: D103, N802
32
33
  return text
33
34
 
34
35
  def display(text): # noqa: D103
35
36
  logger.info(text)
36
37
 
37
- class widgets: # noqa: D101
38
+ class widgets: # noqa: D101, N801
38
39
  class Button: # noqa: D106
39
40
  func: str
40
41
  description: str
@@ -2,9 +2,11 @@
2
2
 
3
3
  The goal it to have a single interface for all such functions.
4
4
  """
5
+
5
6
  import os
6
- import sys
7
7
  import subprocess
8
+ import sys
9
+
8
10
 
9
11
  if os.name == "nt":
10
12
  from . import windows_utils as current_utils
@@ -1,9 +1,7 @@
1
1
  """This submodule contains functions that are specific for windows."""
2
2
 
3
3
 
4
- def copy_fig(
5
- fig=None, format_=None, text_to_copy=None, **kwargs
6
- ): # pragma: no cover <--
4
+ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no cover <--
7
5
  """Copy fig to the clipboard.
8
6
 
9
7
  Parameters
@@ -73,9 +71,7 @@ def copy_fig(
73
71
  im = Image.open(buf)
74
72
  with BytesIO() as output:
75
73
  im.convert("RGB").save(output, "BMP")
76
- data = output.getvalue()[
77
- 14:
78
- ] # The file header off-set of BMP is 14 bytes
74
+ data = output.getvalue()[14:] # The file header off-set of BMP is 14 bytes
79
75
  format_id = win32clipboard.CF_DIB # DIB = device independent bitmap
80
76
 
81
77
  except ImportError:
@@ -89,8 +85,6 @@ def copy_fig(
89
85
  win32clipboard.EmptyClipboard()
90
86
  win32clipboard.SetClipboardData(format_id, data)
91
87
  if text_to_copy:
92
- win32clipboard.SetClipboardData(
93
- win32clipboard.CF_TEXT, text_to_copy.encode("utf-8")
94
- )
88
+ win32clipboard.SetClipboardData(win32clipboard.CF_TEXT, text_to_copy.encode("utf-8"))
95
89
 
96
90
  win32clipboard.CloseClipboard()
@@ -10,10 +10,11 @@ Examples:
10
10
 
11
11
 
12
12
  """
13
+
13
14
  from typing import Dict
14
15
 
15
- from .parsed_value import ParsedValue
16
16
  from .brackets_score import BracketsScore
17
+ from .parsed_value import ParsedValue
17
18
 
18
19
 
19
20
  def parse_str(file: str, /) -> Dict[str, ParsedValue]:
@@ -36,10 +37,7 @@ def parse_str(file: str, /) -> Dict[str, ParsedValue]:
36
37
  if not brackets.is_zero():
37
38
  continue
38
39
 
39
- if "# value: " in value:
40
- value_eval = value[value.rfind("# value: ") + 9 :]
41
- else:
42
- value_eval = None
40
+ value_eval = value[value.rfind("# value: ") + 9 :] if ("# value: " in value) else None
43
41
 
44
42
  value = value.split("#")[0].strip()
45
43
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  from typing import Any, Union
4
4
 
5
+ import numpy as np
6
+
5
7
 
6
8
  def parse_value(value: str) -> Union[str, int, float]:
7
9
  """Convert str to int or float if possible."""
@@ -16,14 +18,14 @@ def parse_value(value: str) -> Union[str, int, float]:
16
18
  value_without_underscores[0] == "-" and value[1:].isdigit()
17
19
  ):
18
20
  return int(value)
19
- elif value_without_underscores.replace(".", "").isdigit() or (
20
- value[0] == "-" and value_without_underscores[1:].replace(".", "").isdigit()
21
- ):
22
- return float(value)
23
21
  elif (
24
- (value[0].isdigit() or (value[0] == "-" and value[1].isdigit()))
25
- and value[-1].isdigit()
26
- and "e" in value
22
+ value_without_underscores.replace(".", "").isdigit()
23
+ or (value[0] == "-" and value_without_underscores[1:].replace(".", "").isdigit())
24
+ or (
25
+ (value[0].isdigit() or (value[0] == "-" and value[1].isdigit()))
26
+ and value[-1].isdigit()
27
+ and "e" in value
28
+ )
27
29
  ):
28
30
  return float(value)
29
31
  except ValueError:
@@ -44,9 +46,11 @@ class ParsedValue:
44
46
 
45
47
  Examples:
46
48
  >>> v1 = ParsedValue("1", 1)
47
- >>> v2 = ParsedValue("2", 2)
49
+ >>> v2 = ParsedValue("6/3", 2)
48
50
  >>> v1 + v2
49
51
  3
52
+ >>> v2.unpack()
53
+ ('6/3', 2)
50
54
 
51
55
  """
52
56
 
@@ -63,8 +67,11 @@ class ParsedValue:
63
67
  self.original = parse_value(original)
64
68
  self.value = parse_value(value)
65
69
 
66
- def __iter__(self):
67
- return iter((self.original, self.value))
70
+ # def __iter__(self):
71
+ # return iter((self.original, self.value))
72
+
73
+ def unpack(self):
74
+ return self.original, self.value
68
75
 
69
76
  def __str__(self) -> str:
70
77
  return str(self.value)
@@ -81,9 +88,18 @@ class ParsedValue:
81
88
  def __abs__(self) -> float:
82
89
  return abs(self.value) # type: ignore
83
90
 
91
+ def __int__(self) -> int:
92
+ return int(self.value) # type: ignore
93
+
84
94
  def __float__(self) -> float:
85
95
  return float(self.value) # type: ignore
86
96
 
97
+ def __array__(self, dtype=None, **kwargs):
98
+ # So numpy/matplotlib can use it: np.asarray(obj) works
99
+ if dtype is not None:
100
+ return np.array(self.value, dtype=dtype, **kwargs)
101
+ return np.array(self.value, **kwargs)
102
+
87
103
  def __neg__(self) -> float:
88
104
  return -self.value # type: ignore
89
105
 
@@ -195,3 +211,7 @@ class ParsedValue:
195
211
  if isinstance(other, ParsedValue):
196
212
  return other.value
197
213
  return other
214
+
215
+ def __hash__(self) -> int:
216
+ return hash(self.value)
217
+ # return hash((self.original, self.value))
labmate/parsing/saving.py CHANGED
@@ -27,9 +27,7 @@ def append_values_from_modules_to_files(
27
27
  return configs
28
28
 
29
29
 
30
- def append_values_from_module_to_file(
31
- body: str, module, separator=" # value: "
32
- ) -> str:
30
+ def append_values_from_module_to_file(body: str, module, separator=" # value: ") -> str:
33
31
  """Add values from a module to a given file body.
34
32
 
35
33
  Args:
@@ -68,9 +66,7 @@ def append_values_from_module_to_file(
68
66
  for key, (val, _) in parse_str(line).items():
69
67
  real_val = variables.get(key, "")
70
68
  if (
71
- isinstance(val, str)
72
- and isinstance(real_val, str)
73
- and real_val != val.strip("\"'")
69
+ isinstance(val, str) and isinstance(real_val, str) and real_val != val.strip("\"'")
74
70
  ) or (
75
71
  isinstance(val, str)
76
72
  and isinstance(real_val, (float, int, complex))
@@ -1,4 +1,5 @@
1
1
  """Async utilities."""
2
+
2
3
  from dh5.utils.async_utils import ( # pylint: disable=unused-import # noqa: F401
3
4
  sleep,
4
5
  )
@@ -12,8 +12,10 @@ import labmate.utils.autoreload
12
12
  ```
13
13
 
14
14
  """
15
+
15
16
  from IPython.core.getipython import get_ipython
16
17
 
18
+
17
19
  shell = get_ipython()
18
20
  if shell:
19
21
  shell.run_cell("%load_ext autoreload")
@@ -1,8 +1,8 @@
1
1
  """Different method to read files."""
2
2
 
3
3
  import json
4
- import os
5
4
  import re
5
+ from pathlib import Path
6
6
  from typing import Any, Dict, List, Optional
7
7
 
8
8
  from ..parsing.brackets_score import BracketsScore
@@ -20,13 +20,13 @@ def read_file(file: str, /) -> str:
20
20
  Raises:
21
21
  ValueError: If the file does not exist or is not a file.
22
22
  """
23
- if not os.path.isfile(file):
23
+ if not Path(file).is_file():
24
24
  raise ValueError(
25
- "Cannot read a file if it doesn't exist or it's not a file."
26
- f"Path: {os.path.abspath(file)}"
25
+ "Cannot read a file if it doesn't exist or it's not a file. "
26
+ f"Path: {Path(file).absolute()}"
27
27
  )
28
28
 
29
- with open(file, "r", encoding="utf-8") as file_opened:
29
+ with open(file, encoding="utf-8") as file_opened:
30
30
  return file_opened.read()
31
31
 
32
32
 
@@ -40,15 +40,16 @@ def read_files(files: List[str], /) -> Dict[str, str]:
40
40
  A dictionary where the keys are the file names and the values are the contents of the files.
41
41
 
42
42
  Raises:
43
- ValueError: If some of the files have the same name, which would cause a key collision in the dictionary.
43
+ ValueError: If some of the files have the same name,
44
+ which would cause a key collision in the dict.
44
45
  """
45
46
  configs: Dict[str, str] = {}
46
47
  for config_file in files:
47
- config_file_name = os.path.basename(config_file)
48
+ config_file_name = Path(config_file).name
48
49
  if config_file_name in configs:
49
50
  raise ValueError(
50
- "Some of the files have the same name. So it cannot be pushed into dictionary to"
51
- " preserve unique key"
51
+ "Some of the files have the same name. "
52
+ "So it cannot be pushed into dict to preserve unique key"
52
53
  )
53
54
  configs[config_file_name] = read_file(config_file)
54
55
  return configs
@@ -62,7 +63,7 @@ def update_file_variable(file, params: Dict[str, Any]):
62
63
  file (str): The path to the file to update.
63
64
  params (Dict[str, Any]): The parameters to update the file with.
64
65
  """
65
- with open(file, "r", encoding="utf-8") as file_opened:
66
+ with open(file, encoding="utf-8") as file_opened:
66
67
  lines = file_opened.readlines()
67
68
  brackets = BracketsScore()
68
69
  current_param: Optional[str] = None
@@ -87,9 +88,7 @@ def update_file_variable(file, params: Dict[str, Any]):
87
88
  value_str = json.JSONEncoder().encode(params[current_param])
88
89
 
89
90
  print("value_str", value_str)
90
- if re.match(
91
- r"^['\"]?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?['\"]?$", value_str
92
- ):
91
+ if re.match(r"^['\"]?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?['\"]?$", value_str):
93
92
  value_str = value_str.replace('"', "")
94
93
 
95
94
  lines.insert(
labmate/utils/lint.py CHANGED
@@ -86,7 +86,7 @@ class NameVisitor(ast.NodeVisitor):
86
86
  external_vars (Set[str]): A set of external variable names.
87
87
  errors (List[str]): A list of errors encountered during traversal.
88
88
  run_on_call (Optional[Callable]): A function to run on each function call node.
89
- special_functions_db (Dict[str, Any]): A dictionary of special functions and their attributes.
89
+ special_functions_db (Dict[str, Any]): A dict of special functions and their attributes.
90
90
  """
91
91
 
92
92
  parent = None
@@ -107,9 +107,9 @@ class NameVisitor(ast.NodeVisitor):
107
107
  self.local_vars = ignore_var.copy() if ignore_var else set()
108
108
  self.builtins = set(__builtins__.keys())
109
109
  self.external_vars = set()
110
- self.errors = list()
110
+ self.errors = []
111
111
  self.run_on_call = kwargs.get("run_on_call")
112
- self.special_functions_db = dict()
112
+ self.special_functions_db = {}
113
113
  super().__init__()
114
114
 
115
115
  def visit(self, node, parent=None):
@@ -199,10 +199,9 @@ class LintResult(NamedTuple):
199
199
  errors: List[str]
200
200
 
201
201
 
202
- def find_variables_from_node(
203
- node, ignore_var: Optional[set] = None, **kwargs
204
- ) -> LintResult:
205
- """Walk through ast.node and find the variable that was never declared inside this node, but used.
202
+ def find_variables_from_node(node, ignore_var: Optional[set] = None, **kwargs) -> LintResult:
203
+ """
204
+ Walk through ast.node and find variables that were never declared inside the node, but are used.
206
205
 
207
206
  Variables from ingore_var set is allowed external variables to use.
208
207
  Returns (local_vars, external_vars)
@@ -246,8 +245,7 @@ def find_variables_from_code(
246
245
  f"Error at line {exception.lineno} in {exception.text}"
247
246
  ],
248
247
  )
249
- lint_results = find_variables_from_node(node, ignore_var, run_on_call=run_on_call)
250
- return lint_results
248
+ return find_variables_from_node(node, ignore_var, run_on_call=run_on_call)
251
249
 
252
250
 
253
251
  def find_variables_from_file(
@@ -260,12 +258,12 @@ def find_variables_from_file(
260
258
  Args:
261
259
  file: A string representing the path to the file to be analyzed.
262
260
  ignore_var: An optional set of variable names to ignore during analysis.
263
- run_on_call: An optional callable object to be run on each function call found during analysis.
261
+ run_on_call: An optional callable object to run on each function call found during analysis.
264
262
 
265
263
  Returns:
266
264
  A LintResult object containing the used and unused variables,
267
265
  and any errors encountered during analysis.
268
266
  """
269
- with open(file, "r", encoding="utf-8") as f:
267
+ with open(file, encoding="utf-8") as f:
270
268
  code = f.read()
271
269
  return find_variables_from_code(code, ignore_var, run_on_call=run_on_call)