-
Notifications
You must be signed in to change notification settings - Fork 216
Description
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
Lines 42 to 54 in e840449
| 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.