-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dop_snref Temporary plan #283
Conversation
…object_properties here do not define the entire content, which may lead to errors. The change here temporarily solves this problem (skipping using dop_snref that references other files)
To be honest, I don't really get what the issue is here: Shouldn't the on a different note: the semantics of short name references are pretty awful because the objects these references point to depend on the calling object, i.e., the only way to implement them "correctly" would be do do short name lookups each and every time an object referenced like this is accessed. since this is slow, and hopefully not very common, odxtools currently does pre-lookups and relies some hacks to bend the whole database towards the ECU of interest if this is an issue, cf. #200. |
You are correct that modifying The temporary changes I have submitted can allow me to temporarily bypass this issue and address the practical problems I have encountered in my current work, which perhaps others have encountered as well. I have confirmed in my local code that such changes are feasible. |
Even after reading section 7.3.5.2, I still don't get it: is the issue that your files use IMPORT-REF in addition to PARENT-REF to define the hierarchy of ECUs? (IMPORT-REF is currently not implemented, but I can have a look.) |
My understanding of : |
I have two ideas to solve the problem: |
I'm pretty sure that all ODX files that are contained within PDX archive files are already loaded. maybe there are some bugs, but IMO these should be fixed then. The only thing which I can come up with that could be wrong in your case is your files using the IMPORT-REF mechanism (which is a massive pain, because if I understood this correctly it is not a "normal" inheritance mechanism but only imports those objects from the base layer that get referenced by the derived layer...). Would be nice if you could check this... |
… another instance;add __contains__ magic methods for use <in>
… dop_snref.section 7.3.2.5 'Importing and referencing of cobjects'
Apart from changes to the coding standard and test cases,my local test have already passed.Please help me check if it is feasible. @andlaus |
my main issue with this PR is that I cannot see how it is connected to what's described in the ODX specification, in particular that you do a lot of stuff concerned with SNREFs, while the spec explicitly diallows this (cf. section 7.2.3.5, bullet point 2: |
Okay, I will try it out soon, thank you. |
The solution you provided was not successful. @andlaus |
I recommend my solution again: |
your problem actually is completely unrelated to the IMPORT-REF mechanism: As the exception says, your file tries to specify a table key for a table struct parameter via a short name reference. I will have a look, in the meantime you can probably use the non-strict mode as long as you do not try to en- or decode a request or response which contains that parameter... |
File A references file B through the IMPORT-REF method, and then using the short name from file B in file A will cause problems. |
doc_type = next(iter(imp.ref_docs)).doc_type | ||
# Delete the “DLC_” name prefix | ||
if doc_type == 'CONTAINER': | ||
doc_name = doc_name[4:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the DLC_
prefix in short names of diag layer containers is a convention of the PDX files you are interested in. we cannot hard-code this here...
@@ -55,6 +55,19 @@ def append(self, item: T) -> None: | |||
|
|||
super().append(item) | |||
|
|||
def append_list(self, item_list) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the difference of this and the .extend()
method?! Also, there's no type annotation for item_list
.
@@ -66,7 +66,10 @@ def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: | |||
|
|||
if self.dop_snref: | |||
ddds = diag_layer.diag_data_dictionary_spec | |||
self._dop = odxrequire(ddds.all_data_object_properties.get(self.dop_snref)) | |||
if snref_shortname := ddds.all_data_object_properties.get(self.dop_snref): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That if
statment is equivalent to simply
self._dop = ddds.all_data_object_properties.get(self.dop_snref)
that said, I think the odxrequire()
should stay because the reference to the DOP must be resolved. If it isn't (most probably because the referenced DOP is not yet implemented, e.g., DYNAMIC-ENDMARKER-FIELD
, one should use the non-strict mode for now. This is because quite a bit of code assumes that ParameterWithDop
objects provide a DOP...)
@@ -152,6 +165,9 @@ def __getattr__(self, key: str) -> T: | |||
|
|||
return self._item_dict[key] | |||
|
|||
def __contains__(self, key) -> bool: | |||
return key in self._item_dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method should be unnecessary: ItemAttributeList
is a list
, so the x
in x in my_named_item_list
should be an item. maybe this function can be renamed to .contains_name()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if x in my_named_item_list: print("x in my_named_item_list") else: print("x not in my_named_item_list")
This method returns a Boolean value (True or False), indicating whether the key exists in the _item_dict dictionary, not the item.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all code:return True if key in self._item_dict else False
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. the point is that this class primarily is a list, not a dict, and lists check for the item values, not the keys like dictionaries...
@@ -591,6 +594,27 @@ def not_inherited_fn(parent_ref: ParentRef) -> List[str]: | |||
|
|||
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn) | |||
|
|||
def _add_import_ref(self, ecu_shared_datas) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that after #285, the IMPORT-REF mechanism is implemented. What can/should be added to Database
and DiagLayerContainer
though, are wrapper attributes for the different kinds of DiagLayers
(analogos to .ecus
or .protocols
)
|
||
@property | ||
def odxlinks(self) -> OdxLinkDatabase: | ||
"""A map from odx_id to object""" | ||
return self._odxlinks | ||
|
||
@property | ||
def ecu_shared_datas(self) -> OdxLinkDatabase: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that should return NamedItemList[DiagLayer]
like the .ecus
and .protocols
properties. (on line 95 you define self._ecu_shared_data
this way...)
@@ -125,13 +128,20 @@ def refresh(self) -> None: | |||
# let the diaglayers sort out the inherited objects and the | |||
# short name references | |||
for dlc in self.diag_layer_containers: | |||
dlc._finalize_init(self._odxlinks) | |||
dlc._finalize_init(self._odxlinks, self._ecu_shared_datas) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you need to add such an argument, make it a Database
object, i.e., this line should become dlc._finalize_init(self._odxlinks, self)
. I somehow doubt that this is necessary, though...
for ecu_shared_data in self.ecu_shared_datas: | ||
ecu_shared_data._finalize_init(odxlinks) | ||
ecu_shared_data._finalize_init(odxlinks, ecu_shared_datas) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned above, it is better pass the whole Database
object here (if this is really necessary.)
at least as far as described by the specification, this should work: only DIAG-COMM-PROXY, DTC-PROXY, DIAG-VARIABLE-PROXY, and ROW-WRAPPER elements can be imported via this mechanism. DIAG-VARIABLEs are not yet implemented and the ODXLINK references of the remaining proxy objects should be resolved before short names are dealt with. (modulo bugs.) The exception message which you posted in #285 also points into a different direction, cf. #288 ... |
@QWander: can you please check if your issue still exists with the latest version of odxtools? |
okay, I'll close this now: I'm pretty sure this issue goes away if all files belonging to your database are loaded (e.g., using something like db = odxtools.load_files("protocols.odx-d", "base_variants.odx-d", "ecu_variants.odx-d", "comparams.odx-cs") ) and even if not, the non-strict mode will probably fix it. |
In section 7.3.2.5 "Importing and referencing of cobjects",the ability to cross-reference shortnames using "dop_snref" is
odefined.
dop_snref can reference the content of other files, but the all_data_object_properties here do not define the entire content, which may lead to errors.
The change here temporarily solves this problem (skipping the use of dop_snref that references other files). This is necessary, otherwise it will trigger odxraise.
Long term change direction: I tend to add the content of the import file when generating all_data_object_properties, rather than processing it in the resolve_snrefs section.