Skip to content

Commit 90b8b96

Browse files
authored
Merge pull request #386 from andlaus/misc_fixes
Miscellaneous fixes
2 parents 3b369b5 + a8edd4b commit 90b8b96

30 files changed

+159
-79
lines changed

examples/somersaultecu.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ class SomersaultSID(IntEnum):
260260
short_name="flip",
261261
long_name="Flip",
262262
description=None,
263+
admin_data=None,
263264
),
264265
"session":
265266
FunctionalClass(
@@ -268,6 +269,7 @@ class SomersaultSID(IntEnum):
268269
short_name="session",
269270
long_name="Session",
270271
description=None,
272+
admin_data=None,
271273
),
272274
}
273275

@@ -1094,7 +1096,8 @@ class SomersaultSID(IntEnum):
10941096
oid=None,
10951097
odx_id=OdxLinkId("somersault.struct.recall.forward_flips_grudgingly_done", doc_frags),
10961098
parameters=somersault_positive_responses["forward_flips_grudgingly_done"].parameters,
1097-
byte_size=None),
1099+
byte_size=None,
1100+
is_visible_raw=None),
10981101
"forward_flips_happily_done":
10991102
Structure(
11001103
short_name="forward_flips_happily_done_recall",
@@ -1105,7 +1108,8 @@ class SomersaultSID(IntEnum):
11051108
oid=None,
11061109
odx_id=OdxLinkId("somersault.struct.recall.forward_flips_happily_done", doc_frags),
11071110
parameters=somersault_positive_responses["forward_flips_happily_done"].parameters,
1108-
byte_size=None),
1111+
byte_size=None,
1112+
is_visible_raw=None),
11091113
"backward_flips_grudgingly_done":
11101114
Structure(
11111115
short_name="backward_flips_grudgingly_done_recall",
@@ -1116,7 +1120,8 @@ class SomersaultSID(IntEnum):
11161120
oid=None,
11171121
odx_id=OdxLinkId("somersault.struct.recall.backward_flips_grudgingly_done", doc_frags),
11181122
parameters=somersault_positive_responses["backward_flips_grudgingly_done"].parameters,
1119-
byte_size=None),
1123+
byte_size=None,
1124+
is_visible_raw=None),
11201125
}
11211126

11221127
# this is a hack to get around a catch-22: we need to specify the
@@ -2292,6 +2297,7 @@ class SomersaultSID(IntEnum):
22922297
[x for x in somersault_dops.values() if x.short_name != "schroedinger_dop"] +
22932298
[somersault_dops["schroedinger_base"]]),
22942299
unit_spec=UnitSpec(
2300+
admin_data=None,
22952301
unit_groups=NamedItemList(somersault_unit_groups.values()),
22962302
units=NamedItemList(somersault_units.values()),
22972303
physical_dimensions=NamedItemList(somersault_physical_dimensions.values()),

odxtools/companyrevisioninfo.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def from_et(et_element: ElementTree.Element,
2525

2626
company_data_ref = odxrequire(
2727
OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
28-
revision_label = et_element.findtext("REVISION_LABEL")
28+
revision_label = et_element.findtext("REVISION-LABEL")
2929
state = et_element.findtext("STATE")
3030

3131
return CompanyRevisionInfo(

odxtools/comparaminstance.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,4 @@ def get_subvalue(self, subparam_name: str) -> Optional[str]:
138138

139139
@property
140140
def short_name(self) -> str:
141-
if self.spec:
142-
return self.spec.short_name
143-
144-
# ODXLINK IDs allow dots and hyphens, but short names do not.
145-
# (This should not happen anyway in a correct PDX...)
146-
return self.spec_ref.ref_id.replace(".", "__").replace("-", "_")
141+
return self.spec.short_name

odxtools/diagcomm.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: MIT
22
from dataclasses import dataclass
33
from enum import Enum
4-
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional
4+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
55
from xml.etree import ElementTree
66

77
from .admindata import AdminData
@@ -61,8 +61,8 @@ class DiagComm(IdentifiableElement):
6161
audience: Optional[Audience]
6262
protocol_snrefs: List[str]
6363
related_diag_comm_refs: List[RelatedDiagCommRef]
64-
pre_condition_state_refs: Iterable[OdxLinkRef]
65-
state_transition_refs: Iterable[OdxLinkRef]
64+
pre_condition_state_refs: List[OdxLinkRef]
65+
state_transition_refs: List[OdxLinkRef]
6666

6767
# attributes
6868
semantic: Optional[str]
@@ -119,7 +119,7 @@ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) ->
119119
odxraise(f"Encountered unknown diagnostic class type '{diagnostic_class_str}'")
120120

121121
is_mandatory_raw = odxstr_to_bool(et_element.get("IS-MANDATORY"))
122-
is_executable_raw = odxstr_to_bool(et_element.get("IS-MANDATORY"))
122+
is_executable_raw = odxstr_to_bool(et_element.get("IS-EXECUTABLE"))
123123
is_final_raw = odxstr_to_bool(et_element.get("IS-FINAL"))
124124

125125
return DiagComm(

odxtools/diaglayers/hierarchyelement.py

+2
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,15 @@ def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> Non
137137
unit_groups=NamedItemList(unit_groups),
138138
units=NamedItemList([]),
139139
physical_dimensions=NamedItemList([]),
140+
admin_data=None,
140141
sdgs=[])
141142
else:
142143
# locally defined unit spec and inherited unit groups
143144
unit_spec = UnitSpec(
144145
unit_groups=NamedItemList(unit_groups),
145146
units=local_unit_spec.units,
146147
physical_dimensions=local_unit_spec.physical_dimensions,
148+
admin_data=None,
147149
sdgs=[])
148150
############
149151

odxtools/diagnostictroublecode.py

+4-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
@dataclass
1616
class DiagnosticTroubleCode(IdentifiableElement):
1717
trouble_code: int
18-
text: Optional[str]
18+
text: str
1919
display_trouble_code: Optional[str]
2020
level: Optional[int]
2121
is_temporary_raw: Optional[bool]
@@ -29,15 +29,11 @@ def is_temporary(self) -> bool:
2929
def from_et(et_element: ElementTree.Element,
3030
doc_frags: List[OdxDocFragment]) -> "DiagnosticTroubleCode":
3131
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
32-
if et_element.find("DISPLAY-TROUBLE-CODE") is not None:
33-
display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
34-
else:
35-
display_trouble_code = None
32+
display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
3633

34+
level = None
3735
if (level_str := et_element.findtext("LEVEL")) is not None:
3836
level = int(level_str)
39-
else:
40-
level = None
4137

4238
is_temporary_raw = odxstr_to_bool(et_element.get("IS-TEMPORARY"))
4339
sdgs = [
@@ -46,7 +42,7 @@ def from_et(et_element: ElementTree.Element,
4642

4743
return DiagnosticTroubleCode(
4844
trouble_code=int(odxrequire(et_element.findtext("TROUBLE-CODE"))),
49-
text=et_element.findtext("TEXT"),
45+
text=odxrequire(et_element.findtext("TEXT")),
5046
display_trouble_code=display_trouble_code,
5147
level=level,
5248
is_temporary_raw=is_temporary_raw,

odxtools/encodestate.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def emplace_atomic_value(
157157
odxraise(f"Illegal encoding ({base_type_encoding}) specified for "
158158
f"{base_data_type.value}")
159159

160-
internal_value = raw_value
160+
raw_value = internal_value
161161

162162
# ... unsigned integers, ...
163163
elif base_data_type == DataType.A_UINT32:
@@ -189,7 +189,7 @@ def emplace_atomic_value(
189189
odxraise(f"Illegal encoding ({base_type_encoding}) specified for "
190190
f"{base_data_type.value}")
191191

192-
internal_value = raw_value
192+
raw_value = internal_value
193193

194194
# ... and others (floating point values)
195195
else:

odxtools/functionalclass.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# SPDX-License-Identifier: MIT
22
from dataclasses import dataclass
3-
from typing import Any, Dict, List
3+
from typing import Any, Dict, List, Optional
44
from xml.etree import ElementTree
55

6+
from .admindata import AdminData
67
from .element import IdentifiableElement
78
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
89
from .snrefcontext import SnRefContext
@@ -15,13 +16,17 @@ class FunctionalClass(IdentifiableElement):
1516
Corresponds to FUNCT-CLASS.
1617
"""
1718

19+
admin_data: Optional[AdminData]
20+
1821
@staticmethod
1922
def from_et(et_element: ElementTree.Element,
2023
doc_frags: List[OdxDocFragment]) -> "FunctionalClass":
2124

2225
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
2326

24-
return FunctionalClass(**kwargs)
27+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
28+
29+
return FunctionalClass(admin_data=admin_data, **kwargs)
2530

2631
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
2732
return {self.odx_id: self}

odxtools/inputparam.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from typing import Any, Dict, List, Optional
44
from xml.etree import ElementTree
55

6+
from deprecation import deprecated
7+
68
from .dopbase import DopBase
79
from .element import NamedElement
810
from .exceptions import odxrequire
@@ -38,12 +40,16 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
3840
return {}
3941

4042
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
41-
self._dop_base = odxlinks.resolve(self.dop_base_ref, DopBase)
43+
self._dop = odxlinks.resolve(self.dop_base_ref, DopBase)
4244

4345
def _resolve_snrefs(self, context: SnRefContext) -> None:
4446
pass
4547

4648
@property
47-
def dop_base(self) -> DopBase:
49+
def dop(self) -> DopBase:
4850
"""The data object property describing this parameter."""
49-
return self._dop_base
51+
return self._dop
52+
53+
@deprecated(details="use .dop") # type: ignore[misc]
54+
def dop_base(self) -> DopBase:
55+
return self._dop

odxtools/modification.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
from typing import Any, Dict, List, Optional
44
from xml.etree import ElementTree
55

6+
from .exceptions import odxrequire
67
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
78
from .snrefcontext import SnRefContext
89

910

1011
@dataclass
1112
class Modification:
12-
change: Optional[str]
13+
change: str
1314
reason: Optional[str]
1415

1516
@staticmethod
1617
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Modification":
17-
change = et_element.findtext("CHANGE")
18+
change = odxrequire(et_element.findtext("CHANGE"))
1819
reason = et_element.findtext("REASON")
1920

2021
return Modification(change=change, reason=reason)

odxtools/odxlink.py

+4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ class OdxLinkRef:
9696
#: The document fragments to which the `ref_id` refers to (in reverse order)
9797
ref_docs: List[OdxDocFragment]
9898

99+
# TODO: this is difficult because OdxLinkRef is derived from and
100+
# we do not want having to specify it mandatorily
101+
#revision: Optional[str] = None
102+
99103
@overload
100104
@staticmethod
101105
def from_et(et: None, source_doc_frags: List[OdxDocFragment]) -> None:

odxtools/outputparam.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from typing import Any, Dict, List, Optional
44
from xml.etree import ElementTree
55

6+
from deprecation import deprecated
7+
68
from .dopbase import DopBase
79
from .element import IdentifiableElement
810
from .exceptions import odxrequire
@@ -29,12 +31,15 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
2931
return {}
3032

3133
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
32-
self._dop_base = odxlinks.resolve(self.dop_base_ref, DopBase)
34+
self._dop = odxlinks.resolve(self.dop_base_ref, DopBase)
3335

3436
def _resolve_snrefs(self, context: SnRefContext) -> None:
3537
pass
3638

3739
@property
40+
def dop(self) -> DopBase:
41+
return self._dop
42+
43+
@deprecated(details="use .dop") # type: ignore[misc]
3844
def dop_base(self) -> DopBase:
39-
"""The data object property describing this parameter."""
40-
return self._dop_base
45+
return self._dop

odxtools/parameters/physicalconstantparameter.py

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def _resolve_snrefs(self, context: SnRefContext) -> None:
5454
dop = odxrequire(self.dop)
5555
if not isinstance(dop, DataObjectProperty):
5656
odxraise("The type of PHYS-CONST parameters must be a simple DOP")
57+
return
5758
base_data_type = dop.physical_type.base_data_type
5859
self._physical_constant_value = base_data_type.from_string(self.physical_constant_value_raw)
5960

odxtools/parameters/tablekeyparameter.py

+20-17
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@
2323
class TableKeyParameter(Parameter):
2424

2525
odx_id: OdxLinkId
26+
27+
# the spec mandates that exactly one of the two attributes must
28+
# be non-None
2629
table_ref: Optional[OdxLinkRef]
2730
table_snref: Optional[str]
28-
table_row_snref: Optional[str]
31+
32+
# the spec mandates that exactly one of the two attributes must
33+
# be non-None
2934
table_row_ref: Optional[OdxLinkRef]
35+
table_row_snref: Optional[str]
3036

3137
@staticmethod
3238
@override
@@ -58,9 +64,6 @@ def from_et(et_element: ElementTree.Element,
5864
def __post_init__(self) -> None:
5965
self._table: Table
6066
self._table_row: Optional[TableRow] = None
61-
if self.table_ref is None and self.table_snref is None and \
62-
self.table_row_ref is None and self.table_row_snref is None:
63-
odxraise("Either a table or a table row must be defined.")
6467

6568
@property
6669
@override
@@ -86,17 +89,20 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
8689
else:
8790
self._table = odxlinks.resolve(self.table_ref)
8891

89-
if self.table_row_ref is not None:
92+
elif self.table_row_ref is not None:
9093
if TYPE_CHECKING:
9194
self._table_row = odxlinks.resolve(self.table_row_ref, TableRow)
9295
else:
9396
self._table_row = odxlinks.resolve(self.table_row_ref)
9497

95-
if self.table_ref is None and self.table_snref is None:
96-
if TYPE_CHECKING:
97-
self._table = odxlinks.resolve(self._table_row.table_ref, Table)
98-
else:
99-
self._table = odxlinks.resolve(self._table_row.table_ref)
98+
# be aware that we cannot simply use
99+
# `self._table_row.table` here because the table object
100+
# might not have resolved its references yet because the
101+
# order of reference resolution is undefined
102+
if TYPE_CHECKING:
103+
self._table = odxlinks.resolve(self._table_row.table_ref, Table)
104+
else:
105+
self._table = odxlinks.resolve(self._table_row.table_ref)
100106

101107
@override
102108
def _resolve_snrefs(self, context: SnRefContext) -> None:
@@ -108,16 +114,13 @@ def _resolve_snrefs(self, context: SnRefContext) -> None:
108114
self._table = resolve_snref(self.table_snref, tables, Table)
109115
else:
110116
self._table = resolve_snref(self.table_snref, tables)
117+
111118
if self.table_row_snref is not None:
112-
# make sure that we know the table to which the table row
113-
# SNREF is relative to.
114-
table = odxrequire(
115-
self._table, "If a table row is referenced via short name, a table must "
116-
"be referenced as well")
117119
if TYPE_CHECKING:
118-
self._table_row = resolve_snref(self.table_row_snref, table.table_rows, TableRow)
120+
self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows,
121+
TableRow)
119122
else:
120-
self._table_row = resolve_snref(self.table_row_snref, table.table_rows)
123+
self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows)
121124

122125
@property
123126
def table(self) -> "Table":

odxtools/scaleconstr.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ class ScaleConstr:
2525

2626
short_label: Optional[str]
2727
description: Optional[Description]
28-
lower_limit: Optional[Limit]
29-
upper_limit: Optional[Limit]
28+
lower_limit: Limit
29+
upper_limit: Limit
3030
validity: ValidType
3131
value_type: DataType
3232

@@ -37,9 +37,9 @@ def scale_constr_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDoc
3737
description = Description.from_et(et_element.find("DESC"), doc_frags)
3838

3939
lower_limit = Limit.limit_from_et(
40-
et_element.find("LOWER-LIMIT"), doc_frags, value_type=value_type)
40+
odxrequire(et_element.find("LOWER-LIMIT")), doc_frags, value_type=value_type)
4141
upper_limit = Limit.limit_from_et(
42-
et_element.find("UPPER-LIMIT"), doc_frags, value_type=value_type)
42+
odxrequire(et_element.find("UPPER-LIMIT")), doc_frags, value_type=value_type)
4343

4444
validity_str = odxrequire(et_element.get("VALIDITY"))
4545
try:

0 commit comments

Comments
 (0)