Skip to content

Commit

Permalink
Merge pull request #386 from andlaus/misc_fixes
Browse files Browse the repository at this point in the history
Miscellaneous fixes
  • Loading branch information
andlaus authored Feb 20, 2025
2 parents 3b369b5 + a8edd4b commit 90b8b96
Show file tree
Hide file tree
Showing 30 changed files with 159 additions and 79 deletions.
12 changes: 9 additions & 3 deletions examples/somersaultecu.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ class SomersaultSID(IntEnum):
short_name="flip",
long_name="Flip",
description=None,
admin_data=None,
),
"session":
FunctionalClass(
Expand All @@ -268,6 +269,7 @@ class SomersaultSID(IntEnum):
short_name="session",
long_name="Session",
description=None,
admin_data=None,
),
}

Expand Down Expand Up @@ -1094,7 +1096,8 @@ class SomersaultSID(IntEnum):
oid=None,
odx_id=OdxLinkId("somersault.struct.recall.forward_flips_grudgingly_done", doc_frags),
parameters=somersault_positive_responses["forward_flips_grudgingly_done"].parameters,
byte_size=None),
byte_size=None,
is_visible_raw=None),
"forward_flips_happily_done":
Structure(
short_name="forward_flips_happily_done_recall",
Expand All @@ -1105,7 +1108,8 @@ class SomersaultSID(IntEnum):
oid=None,
odx_id=OdxLinkId("somersault.struct.recall.forward_flips_happily_done", doc_frags),
parameters=somersault_positive_responses["forward_flips_happily_done"].parameters,
byte_size=None),
byte_size=None,
is_visible_raw=None),
"backward_flips_grudgingly_done":
Structure(
short_name="backward_flips_grudgingly_done_recall",
Expand All @@ -1116,7 +1120,8 @@ class SomersaultSID(IntEnum):
oid=None,
odx_id=OdxLinkId("somersault.struct.recall.backward_flips_grudgingly_done", doc_frags),
parameters=somersault_positive_responses["backward_flips_grudgingly_done"].parameters,
byte_size=None),
byte_size=None,
is_visible_raw=None),
}

# this is a hack to get around a catch-22: we need to specify the
Expand Down Expand Up @@ -2292,6 +2297,7 @@ class SomersaultSID(IntEnum):
[x for x in somersault_dops.values() if x.short_name != "schroedinger_dop"] +
[somersault_dops["schroedinger_base"]]),
unit_spec=UnitSpec(
admin_data=None,
unit_groups=NamedItemList(somersault_unit_groups.values()),
units=NamedItemList(somersault_units.values()),
physical_dimensions=NamedItemList(somersault_physical_dimensions.values()),
Expand Down
2 changes: 1 addition & 1 deletion odxtools/companyrevisioninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def from_et(et_element: ElementTree.Element,

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

return CompanyRevisionInfo(
Expand Down
7 changes: 1 addition & 6 deletions odxtools/comparaminstance.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,4 @@ def get_subvalue(self, subparam_name: str) -> Optional[str]:

@property
def short_name(self) -> str:
if self.spec:
return self.spec.short_name

# ODXLINK IDs allow dots and hyphens, but short names do not.
# (This should not happen anyway in a correct PDX...)
return self.spec_ref.ref_id.replace(".", "__").replace("-", "_")
return self.spec.short_name
8 changes: 4 additions & 4 deletions odxtools/diagcomm.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
from dataclasses import dataclass
from enum import Enum
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from xml.etree import ElementTree

from .admindata import AdminData
Expand Down Expand Up @@ -61,8 +61,8 @@ class DiagComm(IdentifiableElement):
audience: Optional[Audience]
protocol_snrefs: List[str]
related_diag_comm_refs: List[RelatedDiagCommRef]
pre_condition_state_refs: Iterable[OdxLinkRef]
state_transition_refs: Iterable[OdxLinkRef]
pre_condition_state_refs: List[OdxLinkRef]
state_transition_refs: List[OdxLinkRef]

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

is_mandatory_raw = odxstr_to_bool(et_element.get("IS-MANDATORY"))
is_executable_raw = odxstr_to_bool(et_element.get("IS-MANDATORY"))
is_executable_raw = odxstr_to_bool(et_element.get("IS-EXECUTABLE"))
is_final_raw = odxstr_to_bool(et_element.get("IS-FINAL"))

return DiagComm(
Expand Down
2 changes: 2 additions & 0 deletions odxtools/diaglayers/hierarchyelement.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,15 @@ def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> Non
unit_groups=NamedItemList(unit_groups),
units=NamedItemList([]),
physical_dimensions=NamedItemList([]),
admin_data=None,
sdgs=[])
else:
# locally defined unit spec and inherited unit groups
unit_spec = UnitSpec(
unit_groups=NamedItemList(unit_groups),
units=local_unit_spec.units,
physical_dimensions=local_unit_spec.physical_dimensions,
admin_data=None,
sdgs=[])
############

Expand Down
12 changes: 4 additions & 8 deletions odxtools/diagnostictroublecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@dataclass
class DiagnosticTroubleCode(IdentifiableElement):
trouble_code: int
text: Optional[str]
text: str
display_trouble_code: Optional[str]
level: Optional[int]
is_temporary_raw: Optional[bool]
Expand All @@ -29,15 +29,11 @@ def is_temporary(self) -> bool:
def from_et(et_element: ElementTree.Element,
doc_frags: List[OdxDocFragment]) -> "DiagnosticTroubleCode":
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
if et_element.find("DISPLAY-TROUBLE-CODE") is not None:
display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
else:
display_trouble_code = None
display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")

level = None
if (level_str := et_element.findtext("LEVEL")) is not None:
level = int(level_str)
else:
level = None

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

return DiagnosticTroubleCode(
trouble_code=int(odxrequire(et_element.findtext("TROUBLE-CODE"))),
text=et_element.findtext("TEXT"),
text=odxrequire(et_element.findtext("TEXT")),
display_trouble_code=display_trouble_code,
level=level,
is_temporary_raw=is_temporary_raw,
Expand Down
4 changes: 2 additions & 2 deletions odxtools/encodestate.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def emplace_atomic_value(
odxraise(f"Illegal encoding ({base_type_encoding}) specified for "
f"{base_data_type.value}")

internal_value = raw_value
raw_value = internal_value

# ... unsigned integers, ...
elif base_data_type == DataType.A_UINT32:
Expand Down Expand Up @@ -189,7 +189,7 @@ def emplace_atomic_value(
odxraise(f"Illegal encoding ({base_type_encoding}) specified for "
f"{base_data_type.value}")

internal_value = raw_value
raw_value = internal_value

# ... and others (floating point values)
else:
Expand Down
9 changes: 7 additions & 2 deletions odxtools/functionalclass.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# SPDX-License-Identifier: MIT
from dataclasses import dataclass
from typing import Any, Dict, List
from typing import Any, Dict, List, Optional
from xml.etree import ElementTree

from .admindata import AdminData
from .element import IdentifiableElement
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
from .snrefcontext import SnRefContext
Expand All @@ -15,13 +16,17 @@ class FunctionalClass(IdentifiableElement):
Corresponds to FUNCT-CLASS.
"""

admin_data: Optional[AdminData]

@staticmethod
def from_et(et_element: ElementTree.Element,
doc_frags: List[OdxDocFragment]) -> "FunctionalClass":

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

return FunctionalClass(**kwargs)
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)

return FunctionalClass(admin_data=admin_data, **kwargs)

def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
return {self.odx_id: self}
Expand Down
12 changes: 9 additions & 3 deletions odxtools/inputparam.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import Any, Dict, List, Optional
from xml.etree import ElementTree

from deprecation import deprecated

from .dopbase import DopBase
from .element import NamedElement
from .exceptions import odxrequire
Expand Down Expand Up @@ -38,12 +40,16 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
return {}

def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
self._dop_base = odxlinks.resolve(self.dop_base_ref, DopBase)
self._dop = odxlinks.resolve(self.dop_base_ref, DopBase)

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

@property
def dop_base(self) -> DopBase:
def dop(self) -> DopBase:
"""The data object property describing this parameter."""
return self._dop_base
return self._dop

@deprecated(details="use .dop") # type: ignore[misc]
def dop_base(self) -> DopBase:
return self._dop
5 changes: 3 additions & 2 deletions odxtools/modification.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
from typing import Any, Dict, List, Optional
from xml.etree import ElementTree

from .exceptions import odxrequire
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
from .snrefcontext import SnRefContext


@dataclass
class Modification:
change: Optional[str]
change: str
reason: Optional[str]

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

return Modification(change=change, reason=reason)
Expand Down
4 changes: 4 additions & 0 deletions odxtools/odxlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ class OdxLinkRef:
#: The document fragments to which the `ref_id` refers to (in reverse order)
ref_docs: List[OdxDocFragment]

# TODO: this is difficult because OdxLinkRef is derived from and
# we do not want having to specify it mandatorily
#revision: Optional[str] = None

@overload
@staticmethod
def from_et(et: None, source_doc_frags: List[OdxDocFragment]) -> None:
Expand Down
11 changes: 8 additions & 3 deletions odxtools/outputparam.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import Any, Dict, List, Optional
from xml.etree import ElementTree

from deprecation import deprecated

from .dopbase import DopBase
from .element import IdentifiableElement
from .exceptions import odxrequire
Expand All @@ -29,12 +31,15 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
return {}

def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
self._dop_base = odxlinks.resolve(self.dop_base_ref, DopBase)
self._dop = odxlinks.resolve(self.dop_base_ref, DopBase)

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

@property
def dop(self) -> DopBase:
return self._dop

@deprecated(details="use .dop") # type: ignore[misc]
def dop_base(self) -> DopBase:
"""The data object property describing this parameter."""
return self._dop_base
return self._dop
1 change: 1 addition & 0 deletions odxtools/parameters/physicalconstantparameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def _resolve_snrefs(self, context: SnRefContext) -> None:
dop = odxrequire(self.dop)
if not isinstance(dop, DataObjectProperty):
odxraise("The type of PHYS-CONST parameters must be a simple DOP")
return
base_data_type = dop.physical_type.base_data_type
self._physical_constant_value = base_data_type.from_string(self.physical_constant_value_raw)

Expand Down
37 changes: 20 additions & 17 deletions odxtools/parameters/tablekeyparameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@
class TableKeyParameter(Parameter):

odx_id: OdxLinkId

# the spec mandates that exactly one of the two attributes must
# be non-None
table_ref: Optional[OdxLinkRef]
table_snref: Optional[str]
table_row_snref: Optional[str]

# the spec mandates that exactly one of the two attributes must
# be non-None
table_row_ref: Optional[OdxLinkRef]
table_row_snref: Optional[str]

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

@property
@override
Expand All @@ -86,17 +89,20 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
else:
self._table = odxlinks.resolve(self.table_ref)

if self.table_row_ref is not None:
elif self.table_row_ref is not None:
if TYPE_CHECKING:
self._table_row = odxlinks.resolve(self.table_row_ref, TableRow)
else:
self._table_row = odxlinks.resolve(self.table_row_ref)

if self.table_ref is None and self.table_snref is None:
if TYPE_CHECKING:
self._table = odxlinks.resolve(self._table_row.table_ref, Table)
else:
self._table = odxlinks.resolve(self._table_row.table_ref)
# be aware that we cannot simply use
# `self._table_row.table` here because the table object
# might not have resolved its references yet because the
# order of reference resolution is undefined
if TYPE_CHECKING:
self._table = odxlinks.resolve(self._table_row.table_ref, Table)
else:
self._table = odxlinks.resolve(self._table_row.table_ref)

@override
def _resolve_snrefs(self, context: SnRefContext) -> None:
Expand All @@ -108,16 +114,13 @@ def _resolve_snrefs(self, context: SnRefContext) -> None:
self._table = resolve_snref(self.table_snref, tables, Table)
else:
self._table = resolve_snref(self.table_snref, tables)

if self.table_row_snref is not None:
# make sure that we know the table to which the table row
# SNREF is relative to.
table = odxrequire(
self._table, "If a table row is referenced via short name, a table must "
"be referenced as well")
if TYPE_CHECKING:
self._table_row = resolve_snref(self.table_row_snref, table.table_rows, TableRow)
self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows,
TableRow)
else:
self._table_row = resolve_snref(self.table_row_snref, table.table_rows)
self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows)

@property
def table(self) -> "Table":
Expand Down
8 changes: 4 additions & 4 deletions odxtools/scaleconstr.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class ScaleConstr:

short_label: Optional[str]
description: Optional[Description]
lower_limit: Optional[Limit]
upper_limit: Optional[Limit]
lower_limit: Limit
upper_limit: Limit
validity: ValidType
value_type: DataType

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

lower_limit = Limit.limit_from_et(
et_element.find("LOWER-LIMIT"), doc_frags, value_type=value_type)
odxrequire(et_element.find("LOWER-LIMIT")), doc_frags, value_type=value_type)
upper_limit = Limit.limit_from_et(
et_element.find("UPPER-LIMIT"), doc_frags, value_type=value_type)
odxrequire(et_element.find("UPPER-LIMIT")), doc_frags, value_type=value_type)

validity_str = odxrequire(et_element.get("VALIDITY"))
try:
Expand Down
Loading

0 comments on commit 90b8b96

Please sign in to comment.