Skip to content

Make type dispatch and interface modeling statically safer in tlbparser and codegenerator. - #975

Merged
junkmd merged 6 commits into
enthought:mainfrom
junkmd:remove_E721_from_codegenerator
Oct 23, 2026
Merged

junkmd merged 6 commits into
enthought:mainfrom
junkmd:remove_E721_from_codegenerator

Conversation

@junkmd

@junkmd junkmd commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Clarify CodeGenerator type annotations and centralize explicit dispatch
  • Mark applicable type-description classes as final
  • Replace exact type comparisons with isinstance
  • Model IUnknown and IDispatch as simplified ComInterface definitions in tlbparser
  • Remove the Typedef[None] alias and related special handling

Background and purpose

CodeGenerator previously obtained type names dynamically and invoked generation methods through getattr. As a result, the types accepted as input and their corresponding handlers were not clearly visible to the type system.
By explicitly annotating the types accepted by generate and dispatching supported types explicitly, invalid type handling can be detected earlier.

The dispatch logic was also duplicated across multiple paths, including interface generation.
Centralizing it ensures that the same type is handled consistently regardless of the path used, making the code-generation flow easier to follow and reducing the risk of missing updates when types are added or changed.

The existing type(...) is ... comparisons triggered E721 violations in static analysis. Replacing them directly with isinstance would potentially allow subclasses and change the intended behavior.
Marking the concrete types produced by tlbparser and handled by CodeGenerator as final preserves the original intent of accepting only the supported concrete types while allowing isinstance to be used safely.

tlbparser previously represented IUnknown and IDispatch as empty typedefs. This did not reflect the interfaces used by the generated type descriptions.
Defining simplified ComInterface models with the practical COM members required by their use cases makes the mapping more accurate without attempting to reproduce every detail from stdole.
Because Typedef no longer contains None, the Typedef[None] alias and its related special handling also be removed.

Verification points

  • Each type produced by tlbparser is dispatched to the correct generation method
  • Unsupported types are reported as TypeError instead of being invoked implicitly
  • Existing code-generation results remain unchanged for interfaces, structures, pointers, and related types
  • IUnknown and IDispatch are mapped to the expected practical interface definitions
  • Typedef no longer requires support for None
  • Static-analysis issues, including E721, are resolved

…erate`.

Use type narrowing after `generate` receives an item so `name` can be
retrieved safely without relying on `getattr`.
Use explicit type checks for types and container element types that
`tlbparser` can produce instead of dynamically retrieving type names and
calling methods via `getattr`, improving type safety. Confirm that paths
reaching an error without calling any method are inferred as `Never`.
Share the type-based dispatch logic between `generate` and
`_define_interface` so all supported type descriptions use the same
generation path.
Replace exact `type(...)` comparisons in `CodeGenerator` with `isinstance`
checks. All `typedesc` produced by `tlbparser` and used by `CodeGenerator`
are marked with `typing.final`, so the accepted concrete types cannot have
subclasses.
This preserves the previous exact-type guarantee while allowing `isinstance`
to avoid E721 violations.

Types that `tlbparser` does not produce, including skipped
function-definition types, are intentionally not marked `final`.
Define `IUnknown` and `IDispatch` with the practical COM interface members
needed by their use cases, while keeping the models intentionally simplified
instead of reproducing every detail from `stdole`.

Remove the `Typedef[None]` alias and related special handling now that
`Typedef` no longer contains `None`.
@junkmd junkmd added enhancement New feature or request typing related to Python static typing system labels Oct 23, 2026
@codecov-commenter

codecov-commenter commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.84211% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.61%. Comparing base (b8e3b31) to head (3cf2e3c).

Files with missing lines Patch % Lines
comtypes/tools/codegenerator/codegenerator.py 95.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #975      +/-   ##
==========================================
+ Coverage   89.57%   89.61%   +0.04%     
==========================================
  Files         143      143              
  Lines       14175    14247      +72     
==========================================
+ Hits        12697    12768      +71     
- Misses       1478     1479       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@junkmd
junkmd merged commit 273f5b2 into enthought:main Oct 23, 2026
148 of 151 checks passed
@junkmd
junkmd deleted the remove_E721_from_codegenerator branch October 23, 2026 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request typing related to Python static typing system

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants