Fix graphviz_draw return type annotation and docstring (PIL.Image -> PIL.Image.Image) - #1637
Conversation
graphviz_draw was annotated and documented as returning the PIL.Image module instead of the PIL.Image.Image class. Because graphviz.py does `from PIL import Image`, `Image` is the module, so `-> Image | None` annotated the return with a module rather than the image class. Correct the runtime annotation to `Image.Image | None` and the `:returns:`/`:rtype:` docstring to `PIL.Image.Image`. The stub (graphviz.pyi) already imported the class and was correct, so it is left unchanged. Add tests/visualization/test_graphviz_typing.py with two guards: - a runtime check (get_type_hints + docstring) for the implementation, which is what actually regressed here since the stub shadows the implementation for static type checkers; and - a static assert_type check for every stub overload, wired into the `stubs` nox session via mypy. Fixes Qiskit#1357
Coverage Report for CI Build 29712307288Coverage remained the same at 94.694%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
|
Listen, the fix for the type annotations is correct and it will be merged. With that being said, the tests were so bad I had to revert them. I had to make the decision to test things manually rather than relying on that token waste. The repository does not have an AI contribution policy yet, but your PR is closer to #1587 (comment) than to let's say #1594. If the fix wasn't that simple, this would have been rejected with no further discussion. If you ask any LLM to perform an "adversarial review", it will highlight that the test you contributed is "weird". It's the only type checking test besides I already noticed in #1638 that you ignored comments from the original issue on how to fix things i.e. using |
|
Tick the box to add this pull request to the merge queue (same as
|
|
Thank you for the honest feedback — you're right, and I appreciate you taking the time instead of just closing this. The core mistake was mine: I didn't supervise the AI-generated code properly. I sent a test file I hadn't reviewed carefully enough against the repo's existing conventions, and reverting it was the right call. Same with #1638 — the issue clearly pointed at I do care about this project and want to keep learning from it. Going forward I won't open a PR with code I can't explain myself, and I'll follow what's already discussed in the issue before writing anything. Sorry for the extra review work, and thanks for the fix. |
Summary
graphviz_drawwas annotated and documented as returning thePIL.Imagemodule instead of thePIL.Image.Imageclass. This fixes the runtime annotation and the docstring, and adds regression tests.Fixes #1357.
Root cause
rustworkx/visualization/graphviz.pydoesfrom PIL import Image, so within that moduleImageis the modulePIL.Image, not the image class. The return annotation was therefore:which annotates the return value with a module. The docstring had the matching mistake (
:rtype: PIL.Image). This PR changes them toImage.Image | Noneand:rtype: PIL.Image.Image.Why the stub (
graphviz.pyi) is intentionally left untouchedThis is the non-obvious part, and the reason the fix touches
graphviz.pyand not the stub:from PIL.Image import Image(the class) and returnsImage, so it was already correct —git logshows it has imported the class since before enhance visualization func type hint #1443..pyistub exists, static type checkers use the stub and ignore the.pyimplementation. So the wrong annotation ingraphviz.pyis invisible to mypy/pyright at call sites, andpyright --verifytypes(the tool cited in graphviz typing error #1357) reads the already-correct stub.In other words, the specific
--verifytypessymptom from the original report (filed against 0.15.1) is no longer reproducible onmainat the stub level — but the implementation annotation and the rendered docstring were still wrong, which is what this PR fixes.How this was found
While adding a regression test, a negative control (reverting the fix and re-running the checks) surfaced the stub-vs-implementation split above: a
typing.assert_typetest kept passing even with the bug reintroduced, because it validates the stub. The bug only manifests when something reads the implementation's own annotation:After the fix,
get_type_hints(graphviz_draw)["return"]correctly resolves toPIL.Image.Image | None.Tests
tests/visualization/test_graphviz_typing.pyguards both fronts so neither can regress:get_type_hints+ docstring) over the implementation — this is what actually catches graphviz typing error #1357. Verified it fails without the fix (TypeErroron the annotation;AssertionErroron the:rtype:docstring) and passes with it.assert_typeunderTYPE_CHECKING) over every stub overload —filename=None → Image,filename=str → None, withimage_typeas both aLiteraland an arbitrarystr. Wired into the existingstubsnox session viamypyso CI enforces it.Verified locally against a fresh build (rustworkx
main, Pillow 12.3, mypy 1.17.1, pyright 1.1.411): runtime tests pass,mypy/pyrightclean on the typing test, andstubteststill passes.How this helps the project
.pydocstring, so the API reference forgraphviz_drawshowedPIL.Image(a module) as the return type. Users now see the correctPIL.Image.Image.typing.get_type_hints/inspect.signatureongraphviz_drawno longer crashes withTypeErrorand gets the right type.🤖 Generated with Claude Code