Skip to content

Fix Python type errors - #32

Merged
awolverp merged 3 commits into
awolverp:masterfrom
andersk:python-type-checking
Oct 7, 2026
Merged

awolverp merged 3 commits into
awolverp:masterfrom
andersk:python-type-checking

Conversation

@andersk

@andersk andersk commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

With a complete _rustlib stub, mypy and pyright reported these errors:

  • _ConfigNode's invalid_ordering is a tuple of any length.
  • BaseNode._SUBCLASS_WRAP needs a ClassVar annotation.
  • TreeDom.__eq__ must accept any object, as object.__eq__ does.
  • create_element accepts a QualName name, as the Rust constructor does.
  • AttrsList's (key, value) pairs are typed as such, rather than as any tuple, which could have supplied the start argument when unpacked.
  • AttrsList.get's default of None conflicted with its type; give it overloads. _find_by_key's default argument was never passed.
  • AttrsList.extend and __setitem__ reassigned variables with values of different types.
  • The iterators' _BASECLASS is called with a raw node, not a BaseNode.
  • Traverse yields EdgeTraverse rather than nodes, so it shouldn't inherit the other iterators' __next__.

BaseNode._raw was untyped, so everything read from the raw node was Any, and type checkers couldn't catch mistakes in using it.

mypy --strict and pyright now report no errors in the package.

andersk and others added 3 commits October 6, 2026 03:33
With a complete _rustlib stub, mypy and pyright reported these errors:

- _ConfigNode's invalid_ordering is a tuple of any length.
- BaseNode._SUBCLASS_WRAP needs a ClassVar annotation.
- TreeDom.__eq__ must accept any object, as object.__eq__ does.
- create_element accepts a QualName name, as the Rust constructor does.
- AttrsList's (key, value) pairs are typed as such, rather than as any
  tuple, which could have supplied the start argument when unpacked.
- AttrsList.get's default of None conflicted with its type; give it
  overloads.  _find_by_key's default argument was never passed.
- AttrsList.extend and __setitem__ reassigned variables with values of
  different types.
- The iterators' _BASECLASS is called with a raw node, not a BaseNode.
- Traverse yields EdgeTraverse rather than nodes, so it shouldn't
  inherit the other iterators' __next__.

mypy and pyright now report no errors in the package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
BaseNode._raw was untyped, so everything read from the raw node was
Any, and type checkers couldn't catch mistakes in using it.

Make BaseNode generic over the type of its raw node, with each node
type a subclass of BaseNode[the corresponding _rustlib type].  Make it
covariant, so that attach() and the iterators can accept any node as a
BaseNode[_Node], and make _raw a read-only property so that's sound.
Add a Node type alias for any node, which is what the navigation
properties, the iterators, and TreeDom.__iter__ return, so that callers
can narrow it with isinstance() to use a node type's attributes.

Replace the registry of node classes that BaseNode._wrap() looked up,
whose types couldn't be checked, with isinstance() checks.

The raw nodes don't support ordering comparisons, so remove BaseNode's,
which compared the raw nodes.  Without them, comparing nodes raises
TypeError as before, and Comment and Text, which compare their content
with strings, return NotImplemented rather than deferring to them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Annotate the remaining functions, and QualName's constructor in the
_rustlib stub, so that the package passes mypy --strict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
@awolverp
awolverp merged commit 5d2a174 into awolverp:master Oct 7, 2026
12 checks passed
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