spectre-core 0.0.22__py3-none-any.whl → 0.0.23__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 (77) hide show
  1. spectre_core/_file_io/__init__.py +4 -4
  2. spectre_core/_file_io/file_handlers.py +60 -106
  3. spectre_core/batches/__init__.py +20 -3
  4. spectre_core/batches/_base.py +85 -134
  5. spectre_core/batches/_batches.py +55 -99
  6. spectre_core/batches/_factory.py +21 -20
  7. spectre_core/batches/_register.py +8 -8
  8. spectre_core/batches/plugins/_batch_keys.py +7 -6
  9. spectre_core/batches/plugins/_callisto.py +65 -97
  10. spectre_core/batches/plugins/_iq_stream.py +105 -169
  11. spectre_core/capture_configs/__init__.py +46 -17
  12. spectre_core/capture_configs/_capture_config.py +25 -52
  13. spectre_core/capture_configs/_capture_modes.py +8 -6
  14. spectre_core/capture_configs/_capture_templates.py +50 -110
  15. spectre_core/capture_configs/_parameters.py +37 -74
  16. spectre_core/capture_configs/_pconstraints.py +40 -40
  17. spectre_core/capture_configs/_pnames.py +36 -34
  18. spectre_core/capture_configs/_ptemplates.py +260 -347
  19. spectre_core/capture_configs/_pvalidators.py +99 -102
  20. spectre_core/config/__init__.py +13 -8
  21. spectre_core/config/_paths.py +18 -35
  22. spectre_core/config/_time_formats.py +6 -5
  23. spectre_core/exceptions.py +38 -0
  24. spectre_core/jobs/__init__.py +3 -6
  25. spectre_core/jobs/_duration.py +12 -0
  26. spectre_core/jobs/_jobs.py +72 -43
  27. spectre_core/jobs/_workers.py +55 -105
  28. spectre_core/logs/__init__.py +7 -2
  29. spectre_core/logs/_configure.py +13 -17
  30. spectre_core/logs/_decorators.py +6 -4
  31. spectre_core/logs/_logs.py +37 -89
  32. spectre_core/logs/_process_types.py +5 -3
  33. spectre_core/plotting/__init__.py +13 -3
  34. spectre_core/plotting/_base.py +64 -138
  35. spectre_core/plotting/_format.py +10 -8
  36. spectre_core/plotting/_panel_names.py +7 -5
  37. spectre_core/plotting/_panel_stack.py +82 -115
  38. spectre_core/plotting/_panels.py +120 -155
  39. spectre_core/post_processing/__init__.py +6 -3
  40. spectre_core/post_processing/_base.py +41 -55
  41. spectre_core/post_processing/_factory.py +14 -11
  42. spectre_core/post_processing/_post_processor.py +16 -12
  43. spectre_core/post_processing/_register.py +10 -7
  44. spectre_core/post_processing/plugins/_event_handler_keys.py +4 -3
  45. spectre_core/post_processing/plugins/_fixed_center_frequency.py +54 -47
  46. spectre_core/post_processing/plugins/_swept_center_frequency.py +199 -174
  47. spectre_core/receivers/__init__.py +9 -2
  48. spectre_core/receivers/_base.py +82 -148
  49. spectre_core/receivers/_factory.py +20 -30
  50. spectre_core/receivers/_register.py +7 -10
  51. spectre_core/receivers/_spec_names.py +17 -15
  52. spectre_core/receivers/plugins/_b200mini.py +47 -60
  53. spectre_core/receivers/plugins/_receiver_names.py +8 -6
  54. spectre_core/receivers/plugins/_rsp1a.py +44 -40
  55. spectre_core/receivers/plugins/_rspduo.py +59 -44
  56. spectre_core/receivers/plugins/_sdrplay_receiver.py +67 -83
  57. spectre_core/receivers/plugins/_test.py +136 -129
  58. spectre_core/receivers/plugins/_usrp.py +93 -85
  59. spectre_core/receivers/plugins/gr/__init__.py +1 -1
  60. spectre_core/receivers/plugins/gr/_base.py +14 -22
  61. spectre_core/receivers/plugins/gr/_rsp1a.py +53 -60
  62. spectre_core/receivers/plugins/gr/_rspduo.py +77 -89
  63. spectre_core/receivers/plugins/gr/_test.py +49 -57
  64. spectre_core/receivers/plugins/gr/_usrp.py +61 -59
  65. spectre_core/spectrograms/__init__.py +21 -13
  66. spectre_core/spectrograms/_analytical.py +108 -99
  67. spectre_core/spectrograms/_array_operations.py +39 -46
  68. spectre_core/spectrograms/_spectrogram.py +289 -322
  69. spectre_core/spectrograms/_transform.py +106 -73
  70. spectre_core/wgetting/__init__.py +1 -3
  71. spectre_core/wgetting/_callisto.py +87 -93
  72. {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/METADATA +9 -23
  73. spectre_core-0.0.23.dist-info/RECORD +79 -0
  74. {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/WHEEL +1 -1
  75. spectre_core-0.0.22.dist-info/RECORD +0 -78
  76. {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/licenses/LICENSE +0 -0
  77. {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/top_level.txt +0 -0
@@ -4,19 +4,21 @@
4
4
 
5
5
  from enum import Enum
6
6
 
7
+
7
8
  class CaptureMode(Enum):
8
9
  """A default capture mode for `spectre`.
9
-
10
- Each `CaptureMode` has an associated base capture template, which can be fetched using:
11
-
10
+
11
+ Each `CaptureMode` has an associated base capture template, which can be fetched using:
12
+
12
13
  `get_base_capture_template`
13
-
14
+
14
15
  All base capture templates must be registered by one of `CaptureMode`. To introduce a new
15
16
  base capture template, you need to create a new `CaptureMode` constant.
16
-
17
+
17
18
  :ivar FIXED_CENTER_FREQUENCY: Indicates data capture at a fixed center frequency.
18
19
  :ivar SWEPT_CENTER_FREQUENCY: Indicates data capture where the center frequency is continually sweeping
19
20
  in fixed increments.
20
21
  """
22
+
21
23
  FIXED_CENTER_FREQUENCY = "fixed_center_frequency"
22
- SWEPT_CENTER_FREQUENCY = "swept_center_frequency"
24
+ SWEPT_CENTER_FREQUENCY = "swept_center_frequency"
@@ -11,41 +11,29 @@ from ._pconstraints import BasePConstraint
11
11
  from ._ptemplates import PTemplate, get_base_ptemplate
12
12
  from ._ptemplates import PName
13
13
 
14
+
14
15
  class CaptureTemplate:
15
16
  """A managed collection of parameter templates. Strictly defines what parameters are required
16
17
  in a capture config, and the values each parameter can take.
17
18
  """
18
- def __init__(
19
- self
20
- ) -> None:
21
- """Initialise a `CaptureTemplate` instance.
22
- """
23
- self._ptemplates: dict[PName, PTemplate] = {}
24
19
 
20
+ def __init__(self) -> None:
21
+ """Initialise a `CaptureTemplate` instance."""
22
+ self._ptemplates: dict[PName, PTemplate] = {}
25
23
 
26
24
  @property
27
- def name_list(
28
- self
29
- ) -> list[PName]:
25
+ def name_list(self) -> list[PName]:
30
26
  """The names of all required parameters in the capture template."""
31
27
  return list(self._ptemplates.keys())
32
-
33
28
 
34
- def add_ptemplate(
35
- self,
36
- ptemplate: PTemplate
37
- ) -> None:
29
+ def add_ptemplate(self, ptemplate: PTemplate) -> None:
38
30
  """Add a parameter template to the capture template.
39
31
 
40
32
  :param ptemplate: Describes a required parameter for this capture template.
41
33
  """
42
34
  self._ptemplates[ptemplate.name] = ptemplate
43
35
 
44
-
45
- def get_ptemplate(
46
- self,
47
- parameter_name: PName
48
- ) -> PTemplate:
36
+ def get_ptemplate(self, parameter_name: PName) -> PTemplate:
49
37
  """Get the parameter template corresponding to the parameter with the name `parameter_name`.
50
38
 
51
39
  :param parameter_name: The name of the parameter.
@@ -53,37 +41,27 @@ class CaptureTemplate:
53
41
  :raises ValueError: If the parameter name is not found in the template.
54
42
  """
55
43
  if parameter_name not in self._ptemplates:
56
- raise ValueError(f"Parameter with name '{parameter_name}' is not found in the template. "
57
- f"Expected one of {self.name_list}")
44
+ raise ValueError(
45
+ f"Parameter with name '{parameter_name}' is not found in the template. "
46
+ f"Expected one of {self.name_list}"
47
+ )
58
48
  return self._ptemplates[parameter_name]
59
-
60
49
 
61
- def __apply_parameter_template(
62
- self,
63
- parameter: Parameter
64
- ) -> None:
50
+ def __apply_parameter_template(self, parameter: Parameter) -> None:
65
51
  """Apply the corresponding parameter template to the input parameter.
66
-
52
+
67
53
  As a side effect, the value of the input parameter will be type cast
68
54
  according to the template.
69
55
  """
70
56
  ptemplate = self.get_ptemplate(parameter.name)
71
57
  parameter.value = ptemplate.apply_template(parameter.value)
72
58
 
73
-
74
- def __apply_parameter_templates(
75
- self,
76
- parameters: Parameters
77
- ) -> None:
59
+ def __apply_parameter_templates(self, parameters: Parameters) -> None:
78
60
  """Apply the corresponding parameter template to each of the input parameters."""
79
61
  for parameter in parameters:
80
62
  self.__apply_parameter_template(parameter)
81
63
 
82
-
83
- def __fill_missing_with_defaults(
84
- self,
85
- parameters: Parameters
86
- ) -> None:
64
+ def __fill_missing_with_defaults(self, parameters: Parameters) -> None:
87
65
  """Add default parameters to `parameters` for any missing entries.
88
66
 
89
67
  Missing parameters are identified by comparing `parameters` against the
@@ -94,16 +72,11 @@ class CaptureTemplate:
94
72
  if ptemplate.name not in parameters.name_list:
95
73
  # no args for `make_parameter` implies the parameter with the default value will be used.
96
74
  parameter = ptemplate.make_parameter()
97
- parameters.add_parameter(parameter.name,
98
- parameter.value)
99
-
75
+ parameters.add_parameter(parameter.name, parameter.value)
100
76
 
101
- def apply_template(
102
- self,
103
- parameters: Parameters
104
- ) -> Parameters:
77
+ def apply_template(self, parameters: Parameters) -> Parameters:
105
78
  """Apply the capture template to the input parameters. This involves:
106
-
79
+
107
80
  - Adding default parameters if they are missing with respect to this template.
108
81
  - Type casting the value of each input parameter according to the corresponding parameter template.
109
82
  - Validating the value of each input parameter against any corresponding pconstraints.
@@ -115,19 +88,11 @@ class CaptureTemplate:
115
88
  self.__apply_parameter_templates(parameters)
116
89
  return parameters
117
90
 
118
-
119
- def __iter__(
120
- self
121
- ) -> Iterator[PTemplate]:
91
+ def __iter__(self) -> Iterator[PTemplate]:
122
92
  """Iterate over stored ptemplates."""
123
- yield from self._ptemplates.values()
93
+ yield from self._ptemplates.values()
124
94
 
125
-
126
- def set_default(
127
- self,
128
- parameter_name: PName,
129
- default: Any
130
- ) -> None:
95
+ def set_default(self, parameter_name: PName, default: Any) -> None:
131
96
  """Set the default of an existing parameter template.
132
97
 
133
98
  :param parameter_name: The name of the parameter template to be updated.
@@ -135,34 +100,22 @@ class CaptureTemplate:
135
100
  """
136
101
  self.get_ptemplate(parameter_name).default = default
137
102
 
138
-
139
- def set_defaults(
140
- self,
141
- *ptuples: tuple[PName, Any]
142
- ) -> None:
103
+ def set_defaults(self, *ptuples: tuple[PName, Any]) -> None:
143
104
  """Update the defaults of multiple parameter templates.
144
105
 
145
106
  :param ptuples: Tuples of the form (`parameter_name`, `new_default`) to update defaults.
146
107
  """
147
- for (parameter_name, default) in ptuples:
108
+ for parameter_name, default in ptuples:
148
109
  self.set_default(parameter_name, default)
149
110
 
150
-
151
- def enforce_default(
152
- self,
153
- parameter_name: PName
154
- ) -> None:
111
+ def enforce_default(self, parameter_name: PName) -> None:
155
112
  """Set the `enforce_default` attribute of an existing parameter template to True.
156
113
 
157
114
  :param parameter_name: The name of the parameter template to enforce its default value.
158
115
  """
159
116
  self.get_ptemplate(parameter_name).enforce_default = True
160
117
 
161
-
162
- def enforce_defaults(
163
- self,
164
- *parameter_names: PName
165
- ) -> None:
118
+ def enforce_defaults(self, *parameter_names: PName) -> None:
166
119
  """Set the `enforce_default` attribute of multiple existing parameter templates to True.
167
120
 
168
121
  :param parameter_names: The names of the parameter templates to enforce their default values.
@@ -170,11 +123,8 @@ class CaptureTemplate:
170
123
  for name in parameter_names:
171
124
  self.enforce_default(name)
172
125
 
173
-
174
126
  def add_pconstraint(
175
- self,
176
- parameter_name: PName,
177
- pconstraints: list[BasePConstraint]
127
+ self, parameter_name: PName, pconstraints: list[BasePConstraint]
178
128
  ) -> None:
179
129
  """Add one or more `PConstraint` instances to an existing parameter template.
180
130
 
@@ -184,22 +134,16 @@ class CaptureTemplate:
184
134
  for pconstraint in pconstraints:
185
135
  self.get_ptemplate(parameter_name).add_pconstraint(pconstraint)
186
136
 
187
-
188
- def to_dict(
189
- self
190
- ) -> dict[str, dict[str, str]]:
137
+ def to_dict(self) -> dict[str, dict[str, str]]:
191
138
  """Convert the current instance to a serialisable dictionary.
192
139
 
193
140
  :return: A dictionary representation of this capture template, where all values
194
141
  are formatted strings.
195
142
  """
196
143
  return {ptemplate.name.value: ptemplate.to_dict() for ptemplate in self}
197
-
198
-
199
144
 
200
- def make_base_capture_template(
201
- *pnames: PName
202
- ) -> CaptureTemplate:
145
+
146
+ def make_base_capture_template(*pnames: PName) -> CaptureTemplate:
203
147
  """Make a capture template composed entirely of base `PTemplate` instances.
204
148
 
205
149
  :param pnames: The names of parameters to include in the capture template.
@@ -207,12 +151,11 @@ def make_base_capture_template(
207
151
  """
208
152
  capture_template = CaptureTemplate()
209
153
  for pname in pnames:
210
- capture_template.add_ptemplate( get_base_ptemplate(pname) )
154
+ capture_template.add_ptemplate(get_base_ptemplate(pname))
211
155
  return capture_template
212
156
 
213
157
 
214
- def _make_fixed_frequency_capture_template(
215
- ) -> CaptureTemplate:
158
+ def _make_fixed_frequency_capture_template() -> CaptureTemplate:
216
159
  """The absolute minimum required parameters for any fixed frequency capture template."""
217
160
  capture_template = make_base_capture_template(
218
161
  PName.BATCH_SIZE,
@@ -236,19 +179,17 @@ def _make_fixed_frequency_capture_template(
236
179
  PName.WINDOW_TYPE,
237
180
  )
238
181
  capture_template.set_defaults(
239
- (PName.EVENT_HANDLER_KEY, "fixed_center_frequency"),
240
- (PName.BATCH_KEY, "iq_stream"),
241
- (PName.WATCH_EXTENSION, "bin")
182
+ (PName.EVENT_HANDLER_KEY, "fixed_center_frequency"),
183
+ (PName.BATCH_KEY, "iq_stream"),
184
+ (PName.WATCH_EXTENSION, "bin"),
242
185
  )
243
186
  capture_template.enforce_defaults(
244
- PName.EVENT_HANDLER_KEY,
245
- PName.BATCH_KEY,
246
- PName.WATCH_EXTENSION
187
+ PName.EVENT_HANDLER_KEY, PName.BATCH_KEY, PName.WATCH_EXTENSION
247
188
  )
248
189
  return capture_template
249
190
 
250
- def _make_swept_frequency_capture_template(
251
- ) -> CaptureTemplate:
191
+
192
+ def _make_swept_frequency_capture_template() -> CaptureTemplate:
252
193
  """The absolute minimum required parameters for any swept frequency capture template."""
253
194
  capture_template = make_base_capture_template(
254
195
  PName.BATCH_SIZE,
@@ -272,29 +213,26 @@ def _make_swept_frequency_capture_template(
272
213
  PName.WATCH_EXTENSION,
273
214
  PName.WINDOW_HOP,
274
215
  PName.WINDOW_SIZE,
275
- PName.WINDOW_TYPE)
216
+ PName.WINDOW_TYPE,
217
+ )
276
218
  capture_template.set_defaults(
277
- (PName.EVENT_HANDLER_KEY, "swept_center_frequency"),
278
- (PName.BATCH_KEY, "iq_stream"),
279
- (PName.WATCH_EXTENSION, "bin")
219
+ (PName.EVENT_HANDLER_KEY, "swept_center_frequency"),
220
+ (PName.BATCH_KEY, "iq_stream"),
221
+ (PName.WATCH_EXTENSION, "bin"),
280
222
  )
281
223
  capture_template.enforce_defaults(
282
- PName.EVENT_HANDLER_KEY,
283
- PName.BATCH_KEY,
284
- PName.WATCH_EXTENSION
224
+ PName.EVENT_HANDLER_KEY, PName.BATCH_KEY, PName.WATCH_EXTENSION
285
225
  )
286
226
  return capture_template
287
227
 
288
228
 
289
229
  _base_capture_templates: dict[CaptureMode, CaptureTemplate] = {
290
230
  CaptureMode.FIXED_CENTER_FREQUENCY: _make_fixed_frequency_capture_template(),
291
- CaptureMode.SWEPT_CENTER_FREQUENCY: _make_swept_frequency_capture_template()
231
+ CaptureMode.SWEPT_CENTER_FREQUENCY: _make_swept_frequency_capture_template(),
292
232
  }
293
233
 
294
234
 
295
- def get_base_capture_template(
296
- capture_mode: CaptureMode
297
- ) -> CaptureTemplate:
235
+ def get_base_capture_template(capture_mode: CaptureMode) -> CaptureTemplate:
298
236
  """Get a pre-defined capture template, to be configured according to the specific use-case.
299
237
 
300
238
  :param capture_mode: The mode used to retrieve the capture template.
@@ -302,6 +240,8 @@ def get_base_capture_template(
302
240
  :raises KeyError: If no capture template is found for the given mode.
303
241
  """
304
242
  if capture_mode not in _base_capture_templates:
305
- raise KeyError(f"No capture template found for the capture mode '{capture_mode}'. "
306
- f"Expected one of {list(_base_capture_templates.keys())}")
307
- return deepcopy( _base_capture_templates[capture_mode] )
243
+ raise KeyError(
244
+ f"No capture template found for the capture mode '{capture_mode}'. "
245
+ f"Expected one of {list(_base_capture_templates.keys())}"
246
+ )
247
+ return deepcopy(_base_capture_templates[capture_mode])
@@ -7,15 +7,13 @@ from typing import Any, Optional, TypeVar, Generic, Iterator, overload, cast
7
7
  from ._pnames import PName
8
8
 
9
9
  # value type
10
- VT = TypeVar('VT')
10
+ VT = TypeVar("VT")
11
+
11
12
 
12
13
  class Parameter(Generic[VT]):
13
14
  """A simple container for a named value."""
14
- def __init__(
15
- self,
16
- name: PName,
17
- value: Optional[VT] = None
18
- ) -> None:
15
+
16
+ def __init__(self, name: PName, value: Optional[VT] = None) -> None:
19
17
  """Initialise a `Parameter` instance.
20
18
 
21
19
  :param name: The name of the parameter.
@@ -24,28 +22,18 @@ class Parameter(Generic[VT]):
24
22
  self._name = name
25
23
  self._value: Optional[VT] = value
26
24
 
27
-
28
25
  @property
29
- def name(
30
- self
31
- ) -> PName:
26
+ def name(self) -> PName:
32
27
  """The parameter name."""
33
28
  return self._name
34
-
35
29
 
36
30
  @property
37
- def value(
38
- self
39
- ) -> Optional[VT]:
31
+ def value(self) -> Optional[VT]:
40
32
  """The parameter value."""
41
33
  return self._value
42
-
43
-
34
+
44
35
  @value.setter
45
- def value(
46
- self,
47
- v: Optional[VT]
48
- ) -> None:
36
+ def value(self, v: Optional[VT]) -> None:
49
37
  """Update the parameter value.
50
38
 
51
39
  :param v: The new value to set for the parameter.
@@ -55,26 +43,17 @@ class Parameter(Generic[VT]):
55
43
 
56
44
  class Parameters:
57
45
  """A managed collection of parameters."""
58
- def __init__(
59
- self
60
- ) -> None:
46
+
47
+ def __init__(self) -> None:
61
48
  """Initialise a `Parameters` instance."""
62
49
  self._parameters: dict[PName, Parameter] = {}
63
-
64
-
50
+
65
51
  @property
66
- def name_list(
67
- self
68
- ) -> list[PName]:
52
+ def name_list(self) -> list[PName]:
69
53
  """List the names of stored parameters."""
70
54
  return list(self._parameters.keys())
71
55
 
72
-
73
- def add_parameter(
74
- self,
75
- name: PName,
76
- value: Optional[VT]
77
- ) -> None:
56
+ def add_parameter(self, name: PName, value: Optional[VT]) -> None:
78
57
  """Add a `Parameter` instance to this `Parameters` instance with the input name and value.
79
58
 
80
59
  :param name: The name of the parameter.
@@ -82,15 +61,13 @@ class Parameters:
82
61
  :raises KeyError: If a parameter already exists under the input name.
83
62
  """
84
63
  if name in self._parameters:
85
- raise KeyError(f"Cannot add a parameter with name '{name}', "
86
- f"since a parameter already exists with that name. ")
64
+ raise KeyError(
65
+ f"Cannot add a parameter with name '{name}', "
66
+ f"since a parameter already exists with that name. "
67
+ )
87
68
  self._parameters[name] = Parameter(name, value)
88
69
 
89
-
90
- def get_parameter(
91
- self,
92
- name: PName
93
- ) -> Parameter:
70
+ def get_parameter(self, name: PName) -> Parameter:
94
71
  """Get the stored `Parameter` instance corresponding to the input name.
95
72
 
96
73
  :param name: The name of the parameter.
@@ -98,43 +75,33 @@ class Parameters:
98
75
  :return: A `Parameter` instance with the input name, if it exists.
99
76
  """
100
77
  if name not in self._parameters:
101
- raise KeyError(f"Parameter with name '{name}' does not exist. "
102
- f"Expected one of {self.name_list}")
78
+ raise KeyError(
79
+ f"Parameter with name '{name}' does not exist. "
80
+ f"Expected one of {self.name_list}"
81
+ )
103
82
  return self._parameters[name]
104
83
 
105
-
106
- def get_parameter_value(
107
- self,
108
- name: PName
109
- ) -> Optional[VT]:
84
+ def get_parameter_value(self, name: PName) -> Optional[VT]:
110
85
  """Get the value of the parameter with the corresponding name.
111
86
 
112
87
  :param name: The name of the parameter.
113
88
  :return: The value of the parameter with the input name.
114
89
  """
115
90
  return self.get_parameter(name).value
116
-
117
91
 
118
- def __iter__(
119
- self
120
- ) -> Iterator[Parameter]:
92
+ def __iter__(self) -> Iterator[Parameter]:
121
93
  """Iterate over stored parameters."""
122
- yield from self._parameters.values()
94
+ yield from self._parameters.values()
123
95
 
124
-
125
- def to_dict(
126
- self
127
- ) -> dict[str, Optional[Any]]:
96
+ def to_dict(self) -> dict[str, Optional[Any]]:
128
97
  """Convert the `Parameters` instance to a serialisable dictionary.
129
98
 
130
99
  :return: A dictionary representation of the stored parameters.
131
100
  """
132
101
  return {p.name.value: p.value for p in self}
133
-
134
102
 
135
- def _parse_string_parameter(
136
- string_parameter: str
137
- ) -> list[str]:
103
+
104
+ def _parse_string_parameter(string_parameter: str) -> list[str]:
138
105
  """Parse string of the form `a=b` into a list of the form `[a, b]`.
139
106
 
140
107
  :param string_parameter: A string representation of a capture config parameter.
@@ -142,18 +109,16 @@ def _parse_string_parameter(
142
109
  :return: The parsed components of the input string parameter, using the `=` character as a separator.
143
110
  The return list will always contain two elements.
144
111
  """
145
- if not string_parameter or '=' not in string_parameter:
112
+ if not string_parameter or "=" not in string_parameter:
146
113
  raise ValueError(f"Invalid format: '{string_parameter}'. Expected 'KEY=VALUE'.")
147
- if string_parameter.startswith('=') or string_parameter.endswith('='):
114
+ if string_parameter.startswith("=") or string_parameter.endswith("="):
148
115
  raise ValueError(f"Invalid format: '{string_parameter}'. Expected 'KEY=VALUE'.")
149
116
  # remove leading and trailing whitespace.
150
117
  string_parameter = string_parameter.strip()
151
- return string_parameter.split('=', 1)
152
-
153
-
154
- def parse_string_parameters(
155
- string_parameters: list[str]
156
- ) -> dict[str, str]:
118
+ return string_parameter.split("=", 1)
119
+
120
+
121
+ def parse_string_parameters(string_parameters: list[str]) -> dict[str, str]:
157
122
  """Parses a list of strings of the form `a=b` into a dictionary mapping each `a` to each `b`.
158
123
 
159
124
  :param string_parameters: A list of strings, where each element is of the form `a=b`.
@@ -164,11 +129,9 @@ def parse_string_parameters(
164
129
  k, v = _parse_string_parameter(string_parameter)
165
130
  d[k] = v
166
131
  return d
167
-
168
132
 
169
- def make_parameters(
170
- d: dict[str, Any]
171
- ) -> Parameters:
133
+
134
+ def make_parameters(d: dict[str, Any]) -> Parameters:
172
135
  """Create a `Parameters` instance from the given dictionary. Each key is interpreted as a valid `PName`.
173
136
 
174
137
  :param d: A dictionary where keys represent parameter names and values represent their corresponding values.
@@ -177,4 +140,4 @@ def make_parameters(
177
140
  parameters = Parameters()
178
141
  for k, v in d.items():
179
142
  parameters.add_parameter(PName(k), v)
180
- return parameters
143
+ return parameters