Skip to content

Fix arg-type, return-value, and assignment mypy errors#651

Open
bizfsc wants to merge 2 commits intocanopen-python:masterfrom
bizfsc:fix/mypy-type-fixes
Open

Fix arg-type, return-value, and assignment mypy errors#651
bizfsc wants to merge 2 commits intocanopen-python:masterfrom
bizfsc:fix/mypy-type-fixes

Conversation

@bizfsc
Copy link
Copy Markdown
Collaborator

@bizfsc bizfsc commented Apr 29, 2026

Fix arg-type, return-value, assignment, return, index, and operator mypy errors across the codebase.

Changes

canopen/nmt.py

  • Use bytes() instead of list[int] for send_message() and send_periodic() calls.
  • Use b'' instead of None for node guarding remote frame data.

canopen/emcy.py

  • Fix wait() return type: Optional[EmcyError] (was EmcyError, but returns None on timeout).

canopen/network.py

  • Fix add_node() return type to Union[RemoteNode, LocalNode] (accepts both).
  • Fix create_node() parameter type to Union[int, LocalNode].
  • Add assert node.id is not None for index safety.
  • Add type: ignore[arg-type] for node construction where OD may be None.

canopen/variable.py

  • Add raise ValueError at end of read() to satisfy missing return.
  • Annotate Bits.raw with proper type.
  • Add isinstance check for value_descriptions dict access.
  • Add type: ignore for dynamically typed operations (decode_phys, decode_desc, encode_bits).

canopen/sdo/base.py

  • Add explicit return None in get_variable().
  • Add type: ignore[return-value] for SdoArray.__len__().

canopen/objectdictionary/__init__.py

  • Fix __getitem__ dot-notation access with isinstance check for indexability.
  • Add explicit return None in get_variable().
  • Annotate ODVariable.parent and ODArray.parent with proper Union types.
  • Fix decode_phys() return type to Union[int, float].
  • Rewrite encode_phys() without intermediate division.
  • Add type: ignore for encode_raw string operations and min/max comparisons.
  • Add type: ignore for dest.close() and source.name in file handling.

Impact

Reduces mypy error count from 95 to 51 (standalone), and combined with PRs #647, #649, #650 will bring the count down significantly further.",
false

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

❌ Patch coverage is 88.23529% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
canopen/objectdictionary/__init__.py 88.88% 1 Missing and 1 partial ⚠️
canopen/variable.py 71.42% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

- nmt.py: Use bytes() instead of list[int] for send_message/send_periodic
- emcy.py: Fix wait() return type to Optional[EmcyError]
- network.py: Fix add_node/create_node return types and type narrowing
- variable.py: Fix missing return in read(), annotate Bits.raw, add
  type: ignore for inherently dynamic type operations
- sdo/base.py: Fix missing return in get_variable(), add type: ignore
  for SdoArray.__len__
- objectdictionary/__init__.py: Fix __getitem__ indexability, add
  missing return in get_variable(), annotate ODVariable.parent,
  fix decode_phys/encode_phys types, add type: ignore for dynamic
  encode_raw operations
Copy link
Copy Markdown
Member

@acolomb acolomb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some good stuff in here, but also questionable decisions. Especially the # type: ignore stuff makes me want to fix the underlying problem instead of hiding the error. Some of the assertions may already be remedied by #657, and we need to find an overall strategy for handling the general type flexibility inherent in the API (where #652 does give a good overview).

I think we'll pick some of the uncontroversial changes from this, but not all changes here align with my vision of a "good solution". Need a bit more time to pick them apart, though.

return self[idx][sub]
parent = self[idx]
if not isinstance(parent, (ODRecord, ODArray)):
raise KeyError(f"{pretty_index(index)} was not found in Object Dictionary")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really better than a TypeError? I think it's pretty clear to see "not indexable" in a message where a sub-element of some object was requested via dot notation.

@acolomb
Copy link
Copy Markdown
Member

acolomb commented May 6, 2026

  • Fix decode_phys() return type to Union[int, float].

This method must be questioned at a deeper level. The .phys property docstring mentions "Non integers will be passed as is."

So it is in fact desirable to allow passing back unmodified non-numeric values. On the other hand, why should the factor only be applied to integer types, but not if the underlying variable is already a float?

As for typing, would generics help us here? If an integer or float is passed, the result is definitely numeric (depending on the factor), otherwise it's the same as the argument type. This could probably be expressed via @overload annotations, which I just learned more about.

  • Rewrite encode_phys() without intermediate division.

This overlaps with #648. Regarding type checks, an assertion after the .data_type check would be a good compromise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants