plesty-lib 0.2.4__tar.gz → 0.2.6__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.
- plesty_lib-0.2.6/.gitlab-ci.yml +24 -0
- plesty_lib-0.2.6/CHANGELOG.md +7 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/PKG-INFO +2 -1
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/README.md +1 -0
- plesty_lib-0.2.6/gl-secret-detection-report.json +50 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/data/array.py +16 -25
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/data/ctype_manager.py +6 -7
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/data/table.py +2 -1
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/data/types.py +6 -10
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/data/units.py +5 -7
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/async_wrapper.py +4 -3
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/base_device_sync.py +91 -57
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/base_tcp_scpi_device.py +32 -24
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/base_visa_scpi_device.py +25 -18
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/composite_device.py +7 -9
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/device_utils.py +11 -15
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/funcs.py +129 -131
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/params.py +22 -47
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/service/__init__.py +10 -7
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/service/resource_manager.py +6 -12
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/service/tcp_ip_client.py +12 -15
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/service/tcp_ip_server.py +8 -18
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/sim/data_generator.py +26 -30
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/solver/iceblock.py +4 -3
- plesty_lib-0.2.6/plesty/lib/solver/scpi.py +158 -0
- plesty_lib-0.2.6/plesty/lib/test/__init__.py +7 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/test/device_func_system.py +5 -5
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/test/device_param_system.py +7 -11
- plesty_lib-0.2.6/plesty/lib/test/device_pipeline.py +512 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/test/grouped_param_keys.py +3 -3
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/test/resource_allocation.py +10 -12
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/test/schema_params.py +5 -6
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/traffic/__init__.py +5 -11
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/traffic/serial.py +14 -28
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/traffic/tcp_ip.py +6 -16
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/traffic/usb_utils.py +3 -6
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/traffic/utils.py +2 -3
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/traffic/visa.py +4 -4
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/utils/error_utils.py +7 -1
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/utils/logger.py +4 -4
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/utils/registry.py +4 -3
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plestylib/__init__.py +1 -1
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/pyproject.toml +9 -2
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/tests/test_data_array.py +1 -3
- plesty_lib-0.2.6/tests/test_data_types.py +253 -0
- plesty_lib-0.2.6/tests/test_device_base.py +252 -0
- plesty_lib-0.2.6/tests/test_device_funcs.py +269 -0
- plesty_lib-0.2.6/tests/test_device_params.py +297 -0
- plesty_lib-0.2.6/tests/test_device_pipeline.py +781 -0
- plesty_lib-0.2.6/tests/test_device_scpi.py +278 -0
- plesty_lib-0.2.6/tests/test_misc.py +180 -0
- plesty_lib-0.2.6/tests/test_service_manager.py +120 -0
- plesty_lib-0.2.6/tests/test_sim.py +241 -0
- plesty_lib-0.2.6/tests/test_solver.py +177 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/tests/test_tcp_ip_resources.py +4 -12
- plesty_lib-0.2.6/tests/test_traffic_drivers.py +201 -0
- plesty_lib-0.2.6/tests/test_traffic_utils.py +173 -0
- plesty_lib-0.2.6/tests/test_utils.py +139 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/uv.lock +660 -125
- plesty_lib-0.2.4/.gitlab-ci.yml +0 -44
- plesty_lib-0.2.4/plesty/lib/solver/scpi.py +0 -108
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/.gitignore +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/COPYING +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/LICENSE +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/LICENSES/GPL-3.0-or-later.txt +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/api_reference.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/contributing.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/base_device.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/cmd_solver.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/error_handling.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/func_system.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/index.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/logging_system.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/param_system.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/test_helper.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/device/traffic_manager.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/imgs/device_layers.png +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/imgs/device_standard.png +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/imgs/plesty_framework.png +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/index.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/quickstart.md +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/docs/toc.yaml +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/__init__.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/data/__init__.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/device/__init__.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/sim/__init__.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/solver/__init__.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/utils/__init__.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/plesty/lib/utils/dll_utils.py +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/spdx.tmpl +0 -0
- {plesty_lib-0.2.4 → plesty_lib-0.2.6}/tests/test_schema_params.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
workflow:
|
|
2
|
+
rules:
|
|
3
|
+
# Create pipelines for merge requests
|
|
4
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
5
|
+
# Create branch pipelines for main and exp
|
|
6
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
7
|
+
- if: $CI_COMMIT_BRANCH == "exp"
|
|
8
|
+
# Create pipelines for tags (dev and stable releases)
|
|
9
|
+
- if: $CI_COMMIT_TAG
|
|
10
|
+
# Otherwise do not create a pipeline
|
|
11
|
+
- when: never
|
|
12
|
+
|
|
13
|
+
stages:
|
|
14
|
+
- check
|
|
15
|
+
- security
|
|
16
|
+
- deploy
|
|
17
|
+
- release
|
|
18
|
+
|
|
19
|
+
include:
|
|
20
|
+
- component: $CI_SERVER_FQDN/plesty/plesty-ci/plesty-standard-ci@exp
|
|
21
|
+
inputs:
|
|
22
|
+
standard: quantum
|
|
23
|
+
extra_branch: exp
|
|
24
|
+
access_token: $CI_BOT_TOKEN
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plesty-lib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: A library for the Plesty ecosystem.
|
|
5
5
|
Author-email: Yunshuang Yuan <yunshuang.yuan@fkp.uni-hannover.de>
|
|
6
6
|
Maintainer-email: Plesty Development Team <yunshuang.yuan@fkp.uni-hannover.de>
|
|
@@ -69,6 +69,7 @@ class PowermeterDevice(BaseVisaScpiDevice):
|
|
|
69
69
|
### 2. Use the device
|
|
70
70
|
|
|
71
71
|
```python
|
|
72
|
+
# replace the serial number P0000001 with that of your own device
|
|
72
73
|
address = "USB0::0x1313::0x8078::P0000001::INSTR"
|
|
73
74
|
|
|
74
75
|
with PowermeterDevice(address) as dev:
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scan": {
|
|
3
|
+
"analyzer": {
|
|
4
|
+
"id": "secrets",
|
|
5
|
+
"name": "secrets",
|
|
6
|
+
"url": "https://gitlab.com/gitlab-org/security-products/analyzers/secrets",
|
|
7
|
+
"vendor": {
|
|
8
|
+
"name": "GitLab"
|
|
9
|
+
},
|
|
10
|
+
"version": "7.37.0"
|
|
11
|
+
},
|
|
12
|
+
"scanner": {
|
|
13
|
+
"id": "gitleaks",
|
|
14
|
+
"name": "Gitleaks",
|
|
15
|
+
"url": "https://github.com/gitleaks/gitleaks",
|
|
16
|
+
"vendor": {
|
|
17
|
+
"name": "GitLab"
|
|
18
|
+
},
|
|
19
|
+
"version": "8.30.1"
|
|
20
|
+
},
|
|
21
|
+
"type": "secret_detection",
|
|
22
|
+
"start_time": "2026-06-26T14:45:00",
|
|
23
|
+
"end_time": "2026-06-26T14:45:01",
|
|
24
|
+
"status": "success",
|
|
25
|
+
"observability": {
|
|
26
|
+
"events": [
|
|
27
|
+
{
|
|
28
|
+
"event": "collect_secrets_analyzer_scan_metrics_from_pipeline",
|
|
29
|
+
"time_s": 0.483231567,
|
|
30
|
+
"exit_code": 0,
|
|
31
|
+
"git_strategy": "FetchShallow",
|
|
32
|
+
"repo_size_kb": 1260,
|
|
33
|
+
"commit_count": 1,
|
|
34
|
+
"bytes_scanned": 23,
|
|
35
|
+
"pipeline_type": "Tag"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"event": "collect_secrets_analyzer_ruleset_adoption_metrics_from_pipeline",
|
|
39
|
+
"custom_ruleset": false,
|
|
40
|
+
"passthrough_types": null,
|
|
41
|
+
"passthrough_count": 0,
|
|
42
|
+
"passthrough_auth_used": false,
|
|
43
|
+
"rules_version": "0.24.3"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"version": "15.2.4",
|
|
49
|
+
"vulnerabilities": []
|
|
50
|
+
}
|
|
@@ -16,7 +16,7 @@ from typing import List, Dict, Any, Tuple, Optional
|
|
|
16
16
|
from .units import Units
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class _PlestyArrayMeta(type(np.ndarray)):
|
|
19
|
+
class _PlestyArrayMeta(type(np.ndarray)): # type: ignore[misc]
|
|
20
20
|
"""Forward NumPy top-level callables as class methods for PlestyArray.
|
|
21
21
|
|
|
22
22
|
Example:
|
|
@@ -81,7 +81,13 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
81
81
|
_META_KEYS = {"name", "range", "options", "unit", "description"}
|
|
82
82
|
__array_priority__ = 1000
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
name: Optional[str]
|
|
85
|
+
range: Optional[Tuple[float, float] | Tuple[int, int]]
|
|
86
|
+
options: Optional[List[Any]]
|
|
87
|
+
unit: Optional[str]
|
|
88
|
+
description: Optional[str]
|
|
89
|
+
|
|
90
|
+
def update_meta(self, **kwargs) -> None:
|
|
85
91
|
"""Update meta information for the PlestyArray.
|
|
86
92
|
|
|
87
93
|
Example:
|
|
@@ -141,12 +147,8 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
141
147
|
}
|
|
142
148
|
|
|
143
149
|
@classmethod
|
|
144
|
-
def _split_meta_kwargs(
|
|
145
|
-
|
|
146
|
-
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
|
147
|
-
meta_kwargs = {
|
|
148
|
-
k: kwargs.pop(k) for k in list(kwargs.keys()) if k in cls._META_KEYS
|
|
149
|
-
}
|
|
150
|
+
def _split_meta_kwargs(cls, kwargs: Dict[str, Any]) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
|
151
|
+
meta_kwargs = {k: kwargs.pop(k) for k in list(kwargs.keys()) if k in cls._META_KEYS}
|
|
150
152
|
return kwargs, meta_kwargs
|
|
151
153
|
|
|
152
154
|
@classmethod
|
|
@@ -176,7 +178,7 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
176
178
|
description: Optional[str] = None,
|
|
177
179
|
):
|
|
178
180
|
"""Create a new PlestyArray instance with optional metadata."""
|
|
179
|
-
obj = np.asarray(input_array).view(cls)
|
|
181
|
+
obj: "PlestyArray" = np.asarray(input_array).view(cls) # type: ignore[assignment]
|
|
180
182
|
obj.name = name
|
|
181
183
|
obj.range = range
|
|
182
184
|
obj.options = options
|
|
@@ -205,9 +207,7 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
205
207
|
x.view(np.ndarray) if isinstance(x, PlestyArray) else x for x in out
|
|
206
208
|
)
|
|
207
209
|
|
|
208
|
-
np_inputs = tuple(
|
|
209
|
-
x.view(np.ndarray) if isinstance(x, PlestyArray) else x for x in inputs
|
|
210
|
-
)
|
|
210
|
+
np_inputs = tuple(x.view(np.ndarray) if isinstance(x, PlestyArray) else x for x in inputs)
|
|
211
211
|
|
|
212
212
|
result = getattr(ufunc, method)(*np_inputs, **kwargs)
|
|
213
213
|
|
|
@@ -246,9 +246,7 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
246
246
|
right_scale = right_expr.conversion_scale_to(left_expr)
|
|
247
247
|
np_inputs_scaled = list(np_inputs)
|
|
248
248
|
np_inputs_scaled[1] = np_inputs_scaled[1] * right_scale
|
|
249
|
-
result = getattr(ufunc, method)(
|
|
250
|
-
*tuple(np_inputs_scaled), **kwargs
|
|
251
|
-
)
|
|
249
|
+
result = getattr(ufunc, method)(*tuple(np_inputs_scaled), **kwargs)
|
|
252
250
|
meta["unit"] = Units.standardize(left.unit)
|
|
253
251
|
else:
|
|
254
252
|
lu = left.unit or "-"
|
|
@@ -286,11 +284,7 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
286
284
|
meta["unit"] = f"({lu})^({ru})"
|
|
287
285
|
else:
|
|
288
286
|
lu = left.unit or "-"
|
|
289
|
-
ru = (
|
|
290
|
-
right.unit
|
|
291
|
-
if isinstance(right, PlestyArray) and right.unit
|
|
292
|
-
else "-"
|
|
293
|
-
)
|
|
287
|
+
ru = right.unit if isinstance(right, PlestyArray) and right.unit else "-"
|
|
294
288
|
meta["unit"] = f"({lu})^({ru})"
|
|
295
289
|
|
|
296
290
|
elif isinstance(left, PlestyArray) and np.isscalar(right):
|
|
@@ -313,12 +307,9 @@ class PlestyArray(np.ndarray, metaclass=_PlestyArrayMeta):
|
|
|
313
307
|
if source is None:
|
|
314
308
|
source = self._find_meta_source(kwargs.values()) if kwargs else None
|
|
315
309
|
|
|
316
|
-
np_args = tuple(
|
|
317
|
-
a.view(np.ndarray) if isinstance(a, PlestyArray) else a for a in args
|
|
318
|
-
)
|
|
310
|
+
np_args = tuple(a.view(np.ndarray) if isinstance(a, PlestyArray) else a for a in args)
|
|
319
311
|
np_kwargs = {
|
|
320
|
-
k: (v.view(np.ndarray) if isinstance(v, PlestyArray) else v)
|
|
321
|
-
for k, v in kwargs.items()
|
|
312
|
+
k: (v.view(np.ndarray) if isinstance(v, PlestyArray) else v) for k, v in kwargs.items()
|
|
322
313
|
}
|
|
323
314
|
|
|
324
315
|
result = func(*np_args, **np_kwargs)
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import ctypes as ct
|
|
10
10
|
from ctypes import POINTER
|
|
11
|
+
from typing import Any
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class CtypeParam:
|
|
@@ -20,7 +21,7 @@ class CtypeParam:
|
|
|
20
21
|
self.ptype = self.get_pytype(ctype_str) if ptype is None else ptype
|
|
21
22
|
self.ctype = self.get_ctype(ctype_str)
|
|
22
23
|
|
|
23
|
-
def get_pytype(self, ctype_str):
|
|
24
|
+
def get_pytype(self, ctype_str: str) -> type:
|
|
24
25
|
"""Map a string representation of a C type to an actual ctypes type."""
|
|
25
26
|
self.pytype_mapping = {
|
|
26
27
|
"c_int": int,
|
|
@@ -35,15 +36,13 @@ class CtypeParam:
|
|
|
35
36
|
"c_unsigned char": int,
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
clean_ctype_str = (
|
|
39
|
-
ctype_str.replace("*", "").replace("ref", "").replace("ptr", "").strip()
|
|
40
|
-
)
|
|
39
|
+
clean_ctype_str = ctype_str.replace("*", "").replace("ref", "").replace("ptr", "").strip()
|
|
41
40
|
if clean_ctype_str in self.pytype_mapping:
|
|
42
41
|
return self.pytype_mapping[clean_ctype_str]
|
|
43
42
|
else:
|
|
44
43
|
raise ValueError(f"Unsupported C type for Python mapping: {ctype_str}")
|
|
45
44
|
|
|
46
|
-
def get_ctype(self, ctype_str):
|
|
45
|
+
def get_ctype(self, ctype_str: str) -> Any:
|
|
47
46
|
"""Map a string representation of a C type to an actual ctypes type."""
|
|
48
47
|
ctype_mapping = {
|
|
49
48
|
"c_int": ct.c_int,
|
|
@@ -70,13 +69,13 @@ class CtypeParam:
|
|
|
70
69
|
else:
|
|
71
70
|
raise ValueError(f"Unsupported C type: {ctype_str}")
|
|
72
71
|
|
|
73
|
-
def to_pytype(self):
|
|
72
|
+
def to_pytype(self) -> Any:
|
|
74
73
|
"""Convert the C type value to its corresponding Python type."""
|
|
75
74
|
if self.ptype is None:
|
|
76
75
|
raise ValueError("Python type mapping is not defined for this C type.")
|
|
77
76
|
return self.ptype(self.value)
|
|
78
77
|
|
|
79
|
-
def to_ctype(self):
|
|
78
|
+
def to_ctype(self) -> Any:
|
|
80
79
|
"""Convert the Python value to its corresponding C type."""
|
|
81
80
|
if self.ctype is None:
|
|
82
81
|
raise ValueError("C type mapping is not defined for this value.")
|
|
@@ -10,6 +10,7 @@ in a structured way.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from dataclasses import dataclass
|
|
13
|
+
from typing import Any
|
|
13
14
|
from .array import PlestyArray
|
|
14
15
|
|
|
15
16
|
|
|
@@ -18,7 +19,7 @@ class TableHeader:
|
|
|
18
19
|
"""Represents the header of a PlestyTable, defining column names and types."""
|
|
19
20
|
|
|
20
21
|
name: str
|
|
21
|
-
dtype:
|
|
22
|
+
dtype: Any = None
|
|
22
23
|
unit: str | None = None
|
|
23
24
|
description: str | None = None
|
|
24
25
|
|
|
@@ -16,7 +16,7 @@ from .table import PlestyTable2D
|
|
|
16
16
|
from .ctype_manager import CtypeParam
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def resolve_dtype(dtype: Any) -> type | None:
|
|
19
|
+
def resolve_dtype(dtype: Any) -> type[Any] | CtypeParam | None:
|
|
20
20
|
"""Resolve schema dtype strings into Python types.
|
|
21
21
|
|
|
22
22
|
Supports scalar aliases and array types in the form array_<numpy_dtype>,
|
|
@@ -26,7 +26,7 @@ def resolve_dtype(dtype: Any) -> type | None:
|
|
|
26
26
|
return dtype
|
|
27
27
|
|
|
28
28
|
dtype_str = str(dtype).strip().lower()
|
|
29
|
-
aliases = {
|
|
29
|
+
aliases: dict[str, type[Any]] = {
|
|
30
30
|
"str": str,
|
|
31
31
|
"string": str,
|
|
32
32
|
"int": int,
|
|
@@ -58,9 +58,7 @@ def resolve_dtype(dtype: Any) -> type | None:
|
|
|
58
58
|
np.dtype(item_token)
|
|
59
59
|
return PlestyArray
|
|
60
60
|
except TypeError as exc:
|
|
61
|
-
raise ValueError(
|
|
62
|
-
f"Unsupported numpy dtype token in array type: {dtype!r}"
|
|
63
|
-
) from exc
|
|
61
|
+
raise ValueError(f"Unsupported numpy dtype token in array type: {dtype!r}") from exc
|
|
64
62
|
|
|
65
63
|
raise ValueError(f"Unsupported dtype in schema: {dtype!r}")
|
|
66
64
|
|
|
@@ -88,7 +86,7 @@ def normalize_shape(shape: Any) -> tuple[Any, ...] | None:
|
|
|
88
86
|
return tuple(shape)
|
|
89
87
|
|
|
90
88
|
|
|
91
|
-
def istype(value, dtype):
|
|
89
|
+
def istype(value: Any, dtype: Any) -> bool:
|
|
92
90
|
"""Check if a value is of a specified data type, including basic and iterable types."""
|
|
93
91
|
if dtype in [int, float, str, bool]:
|
|
94
92
|
return isinstance(value, dtype)
|
|
@@ -103,11 +101,9 @@ def istype(value, dtype):
|
|
|
103
101
|
return False
|
|
104
102
|
|
|
105
103
|
|
|
106
|
-
def cast_basic_type(value, dtype):
|
|
104
|
+
def cast_basic_type(value: Any, dtype: Any) -> Any:
|
|
107
105
|
"""Cast a value to the given basic type, raising ValueError on failure."""
|
|
108
106
|
try:
|
|
109
107
|
return dtype(value)
|
|
110
108
|
except Exception as e:
|
|
111
|
-
raise ValueError(
|
|
112
|
-
f"Value {value} cannot be cast to expected type {dtype.__name__}: {e}"
|
|
113
|
-
)
|
|
109
|
+
raise ValueError(f"Value {value} cannot be cast to expected type {dtype.__name__}: {e}")
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"""Unit parsing, composition, and conversion utilities for Plesty."""
|
|
8
8
|
|
|
9
9
|
import re
|
|
10
|
-
from typing import Dict, Optional
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class Units:
|
|
@@ -18,7 +18,7 @@ class Units:
|
|
|
18
18
|
- ``factor``: numeric scaling factor to SI base units
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
SYMBOLS = {
|
|
21
|
+
SYMBOLS: dict[str, dict[str, Any]] = {
|
|
22
22
|
# length
|
|
23
23
|
"km": {"dim": "L", "factor": 1.0e3},
|
|
24
24
|
"m": {"dim": "L", "factor": 1.0},
|
|
@@ -92,12 +92,12 @@ class Units:
|
|
|
92
92
|
i += 2
|
|
93
93
|
|
|
94
94
|
applied_exp = sign * exponent
|
|
95
|
-
dim = entry["dim"]
|
|
95
|
+
dim: str = str(entry["dim"])
|
|
96
96
|
dims[dim] = dims.get(dim, 0) + applied_exp
|
|
97
97
|
if dims[dim] == 0:
|
|
98
98
|
dims.pop(dim)
|
|
99
99
|
|
|
100
|
-
factor *= entry["factor"] ** applied_exp
|
|
100
|
+
factor *= float(entry["factor"]) ** applied_exp
|
|
101
101
|
sign = 1
|
|
102
102
|
i += 1
|
|
103
103
|
|
|
@@ -167,9 +167,7 @@ class Units:
|
|
|
167
167
|
numerator.append(symbol if power == 1 else f"{symbol}^{power}")
|
|
168
168
|
else:
|
|
169
169
|
pos_power = -power
|
|
170
|
-
denominator.append(
|
|
171
|
-
symbol if pos_power == 1 else f"{symbol}^{pos_power}"
|
|
172
|
-
)
|
|
170
|
+
denominator.append(symbol if pos_power == 1 else f"{symbol}^{pos_power}")
|
|
173
171
|
|
|
174
172
|
num_text = "*".join(numerator) if numerator else "1"
|
|
175
173
|
if not denominator:
|
|
@@ -11,6 +11,7 @@ import threading
|
|
|
11
11
|
import weakref
|
|
12
12
|
from queue import Queue
|
|
13
13
|
from functools import wraps
|
|
14
|
+
from typing import Any
|
|
14
15
|
import inspect
|
|
15
16
|
|
|
16
17
|
|
|
@@ -28,7 +29,7 @@ class AsyncWrapperBase:
|
|
|
28
29
|
``async def _call(self, func, *args, **kwargs)``
|
|
29
30
|
"""
|
|
30
31
|
|
|
31
|
-
_registry = weakref.WeakKeyDictionary()
|
|
32
|
+
_registry: weakref.WeakKeyDictionary[Any, Any] = weakref.WeakKeyDictionary()
|
|
32
33
|
|
|
33
34
|
def __new__(cls, obj):
|
|
34
35
|
"""Return the existing wrapper for obj if one exists, otherwise create a new one."""
|
|
@@ -66,7 +67,7 @@ class AsyncWrapperBase:
|
|
|
66
67
|
return attr # already async
|
|
67
68
|
|
|
68
69
|
@wraps(attr)
|
|
69
|
-
async def async_method(*args, timeout=None, **kwargs):
|
|
70
|
+
async def async_method(*args: Any, timeout: Any = None, **kwargs: Any) -> Any:
|
|
70
71
|
coro = self._call(attr, *args, **kwargs)
|
|
71
72
|
if timeout is not None:
|
|
72
73
|
return await asyncio.wait_for(coro, timeout)
|
|
@@ -240,7 +241,7 @@ class AsyncDeviceThread:
|
|
|
240
241
|
- When the underlying API is already fully asynchronous.
|
|
241
242
|
"""
|
|
242
243
|
|
|
243
|
-
_registry = weakref.WeakKeyDictionary()
|
|
244
|
+
_registry: weakref.WeakKeyDictionary[Any, Any] = weakref.WeakKeyDictionary()
|
|
244
245
|
|
|
245
246
|
def __new__(cls, device):
|
|
246
247
|
"""Return the existing wrapper for device if one exists, otherwise create a new one."""
|