Skip to content

Deduplicate the optional FigureWidget import in graph_objects codegen - #5850

Open
DawnofGenX wants to merge 1 commit into
plotly:mainfrom
DawnofGenX:dedupe-figurewidget-codegen-5849
Open

DawnofGenX wants to merge 1 commit into
plotly:mainfrom
DawnofGenX:dedupe-figurewidget-codegen-5849

Conversation

@DawnofGenX

Copy link
Copy Markdown

Link to issue

Closes #5849

Description of change

The code generator wrote the optional FigureWidget import block (the try: import ... plus the missing_* fallback) into both plotly/graph_objs/__init__.py and plotly/graph_objects/__init__.py, leaving an identical block at the end of each generated file. graph_objects re-exports every other class from graph_objs — including Figure — and graph_objs already owns the optional import and the fallback, so the generator now emits the block only for graph_objs and adds ..graph_objs.FigureWidget to graph_objects' re-export list. The change is in codegen/__init__.py; plotly/graph_objects/__init__.py is regenerated (python commands.py codegen), not hand-edited.

Demo

N/A — no user-visible or visual change. Behaviour is unchanged: plotly.graph_objects.FigureWidget is the same object as plotly.graph_objs.FigureWidget, and still falls back to plotly.missing_anywidget.FigureWidget when ipywidgets is unavailable.

Testing strategy

Adds tests/test_core/test_figure_widget_backend/test_figurewidget_reexport.py, which asserts the three invariants: graph_objects.FigureWidget is graph_objs.FigureWidget, the forced-ipywidgets-failure fallback still resolves, and plotly/graph_objects/__init__.py contains no optional-ipywidgets import block of its own. The last assertion is the regression signal — it fails on unmodified main.

Additional information (optional)

Ran python commands.py codegen on the committed tree with the pinned ruff and it produces no diff, so the generated file and the generator agree.

Guidelines

The code generator emitted the optional FigureWidget import block
(try: import ipywidgets / missing_* fallback) into both
plotly/graph_objs/__init__.py and plotly/graph_objects/__init__.py,
producing an identical block at the end of each generated file.

graph_objects already re-exports every other class from graph_objs
(including Figure), and graph_objs owns the optional ipywidgets import
and the missing_* fallback. Emit the block only for graph_objs and
re-export FigureWidget from graph_objs in graph_objects like every
other class.

Behaviour is unchanged: plotly.graph_objects.FigureWidget still resolves
to the real class when ipywidgets is present and to the missing_*
fallback when it is absent.

Add a regression test proving the invariant (identity, forced-failure
fallback, and no duplicated ipywidgets block in graph_objects).

Fixes plotly#5849
@camdecoster camdecoster self-assigned this Oct 27, 2026

@camdecoster camdecoster left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the update. Could you please make these changes?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you please remove this test? It seems like overkill.

Comment thread CHANGELOG.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you please revert these changes? This is an internal update and doesn't need a changelog entry.

Comment thread codegen/__init__.py
Comment on lines 306 to +314
graph_objects_rel_classes = [
"..graph_objs." + rel_path.split(".")[-1]
for rel_path in datatype_rel_class_imports[()]
]
# FigureWidget is owned by graph_objs, which handles the optional
# ipywidgets import and the missing_* fallback. Re-export it from
# graph_objs like every other class instead of duplicating the optional
# import block in graph_objects.
graph_objects_rel_classes.append("..graph_objs.FigureWidget")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's simplify this a bit:

Suggested change
graph_objects_rel_classes.append("..graph_objs.FigureWidget")
graph_objects_rel_classes = [
*("..graph_objs." + rel_path.split(".")[-1] for rel_path in datatype_rel_class_imports[()]),
# graph_objs owns the optional ipywidgets import and the fallback
"..graph_objs.FigureWidget",
]

This branch has not been deployed

No deployments
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.

[BUG]: Duplicate FigureWidget import code in graph_objects and graph_objs

2 participants