SG-45110 Skip Qt binding members in autodoc to fix PySide6 doc builds - #84
julien-lang wants to merge 13 commits into
Conversation
tk-framework-qtwidgets documents QWidget subclasses with :inherited-members:. With PySide2, nested Qt enums aren't real Python classes so autodoc never walked into them. With PySide6 they are real classes, so :inherited-members: pulls them in per widget, and Sphinx flags the repeated Qt-native class as a duplicate object description, aborting the build under -W. Skip autodoc members whose __module__ belongs to the Qt binding itself (PySide2/PySide6/PyQt4/PyQt5), since those are already covered via intersphinx_mapping. No documented content is lost: PySide2 never generated standalone pages for these nested enums either, only inline signature references.
There was a problem hiding this comment.
🟡 Changes recommended
Limit filtering to mapped bindings or add PyQt inventories to avoid losing undocumented replacement content.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates shared Sphinx autodoc configuration to prevent duplicate Qt-binding documentation during PySide6 builds.
Changes:
- Adds and registers a hook to skip Qt-binding members.
- Filters inherited Qt members from autodoc output.
File summaries
| File | Summary | Review finding |
|---|---|---|
tk_toolchain/cmd_line_tools/tk_docs_generation/sphinx_data/conf.py |
Filters Qt-binding members during documentation generation. | Moderate: PyQt4/PyQt5 members are skipped without corresponding intersphinx inventories; 2 votes. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #84 +/- ##
==========================================
+ Coverage 48.95% 49.72% +0.76%
==========================================
Files 19 19
Lines 721 732 +11
==========================================
+ Hits 353 364 +11
Misses 368 368
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ust __dict__ access
Overriding __eq__/__ne__ on _QtStubMeta broke class identity comparisons for real bundle classes subclassing the stub (metaclasses propagate to subclasses), making Sphinx's inherited-member filter treat every subclass as equal to its base, which duplicated base-class members (e.g. ViewItemDelegate.Padding) across subclass docs.
Useful for diagnosing QtImporter failures (and other tank-level issues) directly from the Rundeck build log instead of hitting confusing errors deep inside autodoc with no visibility into the real cause.
There was a problem hiding this comment.
🟡 Changes recommended
The Qt-member filter must cover all supported binding prefixes, not only PySide6.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
Problem
Building documentation for
tk-framework-qtwidgetswith PySide6 fails under-Wwithsphinx.errors.SphinxWarning: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in activity_stream, use :noindex: for one of them.tk-framework-qtwidgetsdocuments realQWidgetsubclasses (ActivityStreamWidget,ReplyListWidget, etc.) using:inherited-members:. With PySide2, nested Qt enums (e.g.QPaintDevice.PaintDeviceMetric) aren't real Python classes, so autodoc never walked into them. With PySide6 they are real classes, so:inherited-members:pulls them in as documented members of every widget that inherits them, and Sphinx registers the same Qt-native class multiple times across different modules, which it flags as a duplicate object description and aborts the build.tk-coreand other bundles that use:inherited-members:document plain Python classes (Engine,Application,Sgtk, etc.), never Qt classes, so they never hit this. Anytk-*bundle documenting real Qt widget subclasses would hit the same issue once built with PySide6.Fix
Added an
autodoc-skip-memberhook in the sharedconf.py(used by alltk-*doc builds) that skips any member whose__module__belongs to the Qt binding itself (PySide2/PySide6/PyQt4/PyQt5), since those are already covered viaintersphinx_mapping.No documented content is lost: PySide2 docs never generated standalone pages for these nested enums either, they only ever appeared as inline type references in method signatures.
Also stream Toolkit's debug logs to stdout during the doc build, since they were otherwise silently swallowed and made it hard to diagnose
QtImporterfailures while investigating this issue. Also fixed anUnboundLocalErrorcaused by a redundant nestedimport sysshadowing the module-level import.Testing
Verified locally with a PySide6 venv (
tk-framework-qtwidgets/pyenv-build-doc) usingtk-docs-preview --build-only.Before the fix: build fails with 25 duplicate object description warnings across 9 Qt enum/flag classes.
After the fix:
tk-framework-qtwidgetsandtk-coredocs both build successfully under-W, with no regression in previously-documented content (spot-checkedActivityStreamWidget.acceptDrops,allow_screenshots,attachments_filter, etc.).Also validated end-to-end on Rundeck against tk-internal's release pipeline.
Related: SG-45110, SG-44795