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
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions