Skip to content

Commit 099cd8d

Browse files
authored
Merge pull request #14 from harp-tech/gl-dev
Read common register schema using importlib
2 parents f619cc9 + 9b58487 commit 099cd8d

5 files changed

Lines changed: 90 additions & 16 deletions

File tree

harp/__init__.py

Whitespace-only changes.

harp/io.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def read(
8484
time = micros * _SECONDS_PER_TICK + seconds
8585
payloadtype = payloadtype & ~0x10
8686
if epoch is not None:
87-
time = epoch + pd.to_timedelta(time, "s") # type: ignore
87+
time = epoch + pd.to_timedelta(time, "s") # type: ignore
8888
index = pd.Series(time)
8989
index.name = "time"
9090

@@ -111,6 +111,6 @@ def read(
111111
msgtype = np.ndarray(
112112
nrows, dtype=np.uint8, buffer=data, offset=0, strides=stride
113113
)
114-
msgtype = pd.Categorical.from_codes(msgtype, categories=_messagetypes) # type: ignore
114+
msgtype = pd.Categorical.from_codes(msgtype, categories=_messagetypes) # type: ignore
115115
result["type"] = msgtype
116116
return result

harp/schema.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
11
from os import PathLike
2-
from pathlib import Path
32
from typing import TextIO, Union
43
from harp.model import Model, Registers
54
from pydantic_yaml import parse_yaml_raw_as
5+
from importlib import resources
66

7-
_common_yaml_path = Path(__file__).absolute().parent.joinpath("common.yml")
87

9-
10-
def _read_common_registers(file: Union[str, PathLike, TextIO]) -> Registers:
11-
if isinstance(file, TextIO):
12-
return parse_yaml_raw_as(Registers, file.read())
13-
else:
14-
with open(file) as fileIO:
15-
return _read_common_registers(fileIO)
8+
def _read_common_registers() -> Registers:
9+
file = resources.files(__package__) / "common.yml"
10+
with file.open("rt") as fileIO:
11+
return parse_yaml_raw_as(Registers, fileIO.read())
1612

1713

1814
def read_schema(
1915
file: Union[str, PathLike, TextIO], include_common_registers: bool = True
2016
) -> Model:
21-
if isinstance(file, TextIO):
17+
if isinstance(file, (str, PathLike)):
18+
with open(file) as fileIO:
19+
return read_schema(fileIO)
20+
else:
2221
schema = parse_yaml_raw_as(Model, file.read())
2322
if not "WhoAmI" in schema.registers and include_common_registers:
24-
common = _read_common_registers(_common_yaml_path)
23+
common = _read_common_registers()
2524
schema.registers = dict(common.registers, **schema.registers)
2625
if schema.bitMasks is not None and common.bitMasks is not None:
2726
schema.bitMasks = dict(common.bitMasks, **schema.bitMasks)
2827
if schema.groupMasks is not None and common.groupMasks is not None:
2928
schema.groupMasks = dict(common.groupMasks, **schema.groupMasks)
3029
return schema
31-
else:
32-
with open(file) as fileIO:
33-
return read_schema(fileIO, include_common_registers)

tests/data/device.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
%YAML 1.1
2+
---
3+
# yaml-language-server: $schema=https://raw.githubusercontent.com/harp-tech/reflex-generator/main/schema/device.json
4+
device: TestDevice
5+
whoAmI: 0000
6+
firmwareVersion: "0.1"
7+
hardwareTargets: "0.1"
8+
registers:
9+
DigitalInputState:
10+
address: 32
11+
access: Event
12+
type: U8
13+
maskType: DigitalInputs
14+
description: Reports the state of the digital input lines.
15+
DigitalInputMode:
16+
address: 33
17+
access: Write
18+
type: U8
19+
maskType: DigitalInputs
20+
description: Reports the state of the digital input lines.
21+
bitMasks:
22+
DigitalInputs:
23+
description: Specifies the state of the digital input lines.
24+
bits:
25+
DI0: 0x1
26+
DI1: 0x2
27+
DI2: 0x4
28+
DI3: 0x8
29+
groupMasks:
30+
InputMode:
31+
description: Specifies when the device reports the state of digital input lines.
32+
values:
33+
Rising: 0
34+
Falling: 1
35+
Both: 2

tests/test_schema.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import pytest
2+
from os import PathLike
3+
from typing import Iterable, Optional, Type, Union
4+
from pytest import mark
5+
from pathlib import Path
6+
from dataclasses import dataclass
7+
from harp.schema import read_schema
8+
9+
datapath = Path(__file__).parent
10+
11+
12+
@dataclass
13+
class DeviceSchemaParam:
14+
path: Union[str, PathLike]
15+
expected_whoAmI: int
16+
expected_device: Optional[int] = None
17+
expected_registers: Optional[Iterable[str]] = None
18+
expected_error: Optional[Type[BaseException]] = None
19+
20+
def __post_init__(self):
21+
self.path = datapath / self.path
22+
23+
24+
testdata = [
25+
DeviceSchemaParam(
26+
path="data/device.yml",
27+
expected_whoAmI=0,
28+
expected_registers=["DigitalInputMode"],
29+
)
30+
]
31+
32+
33+
@mark.parametrize("schemaFile", testdata)
34+
def test_read_schema(schemaFile: DeviceSchemaParam):
35+
schema = read_schema(schemaFile.path)
36+
assert schema.whoAmI == schemaFile.expected_whoAmI
37+
if schemaFile.expected_registers:
38+
for register in schemaFile.expected_registers:
39+
assert register in schema.registers
40+
41+
42+
if __name__ == "__main__":
43+
pytest.main()

0 commit comments

Comments
 (0)