Skip to content

PDO getitem unexpected returns PdoVariable on value 0 #581

@sveinse

Description

@sveinse

Reading PDO maps from a node is a 1-indexed value. However, if the user use index 0 (which is a common expectation for many indexes), __getitem__ returns a PdoVariable instead of the expected PdoMap.

node = network.create_node(42, "mynode.eds")
node.rpdo.aread(from_od=False)

# Use correct 1 index
rpdo = node.rpdo[1]    # Type returned is `PdoMap`

# Use incorrect 0 index
rpdo = node.rpdo[0]    # Type returned is a `PdoVariable`

The source is due to the else in this code

def __getitem__(self, key):
if isinstance(key, int) and (0x1A00 <= key <= 0x1BFF or # By TPDO ID (512)
0x1600 <= key <= 0x17FF or # By RPDO ID (512)
0 < key <= 512): # By PDO Index
return self.map[key]
else:
for pdo_map in self.map.values():
try:
return pdo_map[key]
except KeyError:
# ignore if one specific PDO does not have the key and try the next one
continue
raise KeyError(f"PDO: {key} was not found in any map")

We just spent an hour trying to debug why the PDO didn't work before we realized the obvious mistake. I think using 0 index is such a common expectation, that I think we should give an error or clearly warn the user.

What is the intent of the the else section in L48-L53? When is this used? I could not find any tests showing how this is used. Because of the else rpdo[0] as shown above will fetch the first PdoVariable from the first PDO, but rpdo[1] will not fetch the second PdoVariable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions