Skip to content

Commit 94cdcc7

Browse files
committed
Fix __contains__ and __eq__ override signatures
Change method signatures to accept 'object' as required by the Liskov substitution principle (Mapping/Container/object supertypes). For __eq__, return NotImplemented for incompatible types instead of raising AttributeError. For __contains__ in SdoArray, add isinstance check to handle non-int arguments gracefully.
1 parent 4e789fe commit 94cdcc7

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

canopen/objectdictionary/__init__.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def __iter__(self) -> Iterator[int]:
160160
def __len__(self) -> int:
161161
return len(self.indices)
162162

163-
def __contains__(self, index: Union[int, str]):
163+
def __contains__(self, index: object) -> bool:
164164
return index in self.names or index in self.indices
165165

166166
def add_object(self, obj: Union[ODArray, ODRecord, ODVariable]) -> None:
@@ -234,10 +234,12 @@ def __len__(self) -> int:
234234
def __iter__(self) -> Iterator[int]:
235235
return iter(sorted(self.subindices))
236236

237-
def __contains__(self, subindex: Union[int, str]) -> bool:
237+
def __contains__(self, subindex: object) -> bool:
238238
return subindex in self.names or subindex in self.subindices
239239

240-
def __eq__(self, other: ODRecord) -> bool:
240+
def __eq__(self, other: object) -> bool:
241+
if not isinstance(other, ODRecord):
242+
return NotImplemented
241243
return self.index == other.index
242244

243245
def add_member(self, variable: ODVariable) -> None:
@@ -298,7 +300,9 @@ def __len__(self) -> int:
298300
def __iter__(self) -> Iterator[int]:
299301
return iter(sorted(self.subindices))
300302

301-
def __eq__(self, other: ODArray) -> bool:
303+
def __eq__(self, other: object) -> bool:
304+
if not isinstance(other, ODArray):
305+
return NotImplemented
302306
return self.index == other.index
303307

304308
def add_member(self, variable: ODVariable) -> None:
@@ -387,7 +391,9 @@ def qualname(self) -> str:
387391
return f"{self.parent.name}.{self.name}"
388392
return self.name
389393

390-
def __eq__(self, other: ODVariable) -> bool:
394+
def __eq__(self, other: object) -> bool:
395+
if not isinstance(other, ODVariable):
396+
return NotImplemented
391397
return (self.index == other.index and
392398
self.subindex == other.subindex)
393399

canopen/sdo/base.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def __iter__(self) -> Iterator[int]:
6464
def __len__(self) -> int:
6565
return len(self.od)
6666

67-
def __contains__(self, key: Union[int, str]) -> bool:
67+
def __contains__(self, key: object) -> bool:
6868
return key in self.od
6969

7070
def get_variable(
@@ -113,7 +113,7 @@ def __len__(self) -> int:
113113
# Skip the "highest subindex" entry, which is not part of the data
114114
return len(self.od) - int(0 in self.od)
115115

116-
def __contains__(self, subindex: Union[int, str]) -> bool:
116+
def __contains__(self, subindex: object) -> bool:
117117
return subindex in self.od
118118

119119

@@ -136,7 +136,9 @@ def __iter__(self) -> Iterator[int]:
136136
def __len__(self) -> int:
137137
return self[0].raw
138138

139-
def __contains__(self, subindex: int) -> bool:
139+
def __contains__(self, subindex: object) -> bool:
140+
if not isinstance(subindex, int):
141+
return False
140142
return 0 <= subindex <= len(self)
141143

142144

0 commit comments

Comments
 (0)