Skip to content

Conversation

@meawoppl
Copy link

@meawoppl meawoppl commented Jan 3, 2026

wxPython is kinda annoying/needy to install, and the way the imports are currently make it tough to use headless w/o installing a bunch of extra stuff. This PR uses an existing environment variable to gate the import of wx to areas of the code that actually use GUI elements.

Quick summary of changes:

  • Add get_wx() in compat.py to gate wx imports behind INTERACTIVE_HTML_BOM_NO_DISPLAY environment variable
  • Allows headless HTML BOM generation without wxPython installed
  • GUI features like --show-dialog still require wx

Usage

INTERACTIVE_HTML_BOM_NO_DISPLAY=1 python -m InteractiveHtmlBom.generate_interactive_bom board.kicad_pcb --no-browser

@meawoppl meawoppl force-pushed the meawoppl/optional-wx-dep branch 2 times, most recently from 64d3670 to 2d0397a Compare January 3, 2026 20:51
Copy link
Member

Choose a reason for hiding this comment

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

This change is not needed.

Copy link
Author

Choose a reason for hiding this comment

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

I am honestly a bit confused on how this line of code works now that I look at it. I am not sure how this imports resolves... regardless, it triggers import of the __init__ here I think:
https://github.com/openscopeproject/InteractiveHtmlBom/blob/master/InteractiveHtmlBom/__init__.py

Would you prefer I replace the imports there with the get_wx() singleton or move the import?

Copy link
Member

Choose a reason for hiding this comment

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

This file is not part of the package, it exists solely for convenience where you can just download the repo and drop it as a whole in kicad's plugin dir. KiCad's plugin system will run this init file and the import initializes kicad plugin, that's all it does. This file is irrelevant for cli use case so just leave it unchanged.

Copy link
Author

Choose a reason for hiding this comment

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

This makes sense wrt. to the existance of the plugin import, that said, that import will still trigger the __init__.py one folder up so would you prefer I replace the imports there with the get_wx() singleton we add here?

Copy link
Member

@qu1ck qu1ck Jan 6, 2026

Choose a reason for hiding this comment

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

It doesn't matter what it triggers, this code does not run when you use ibom in cli mode. Leave it unchanged.

one folder up

This is the topmost level init, there is no one folder up. When you run cli it only uses inner folder as a package, this top level folder may as well not exist.

@meawoppl meawoppl force-pushed the meawoppl/optional-wx-dep branch from 2d0397a to 7c796fe Compare January 4, 2026 22:15
app = wx.App()
if hasattr(wx, "APP_ASSERT_SUPPRESS"):
app.SetAssertMode(wx.APP_ASSERT_SUPPRESS)
elif hasattr(wx, "DisableAsserts"):
Copy link
Member

Choose a reason for hiding this comment

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

This should be kept.

Copy link
Author

Choose a reason for hiding this comment

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

This is a bit confusing as this would nominally only run if not creating a wx app, correct?

I feel like we shouldn't have to disable asserts if not even importing wx...

I can move it into the if create_wx_app block, but I think that would be a behavior change. What is this line of code really about?

Copy link
Member

Choose a reason for hiding this comment

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

Kicad's code sometimes throws GUI asserts requiring user input to close even when wx app is not created. This line suppresses that so that the app does not crash or get blocked without a desktop environment.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed

Add get_wx() in compat.py to gate wx imports behind
INTERACTIVE_HTML_BOM_NO_DISPLAY environment variable.
@meawoppl meawoppl force-pushed the meawoppl/optional-wx-dep branch from 7c796fe to db509db Compare January 8, 2026 02:57
@meawoppl
Copy link
Author

meawoppl commented Jan 8, 2026

I think I got everything, lmk if you want anything else changed/tweaked.

Copy link
Member

@qu1ck qu1ck left a comment

Choose a reason for hiding this comment

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

Tested it and it works fine except when wx is not available the error is cryptic.

from .compat import get_wx, should_create_wx_app
wx = get_wx()
create_wx_app = should_create_wx_app()

Copy link
Member

Choose a reason for hiding this comment

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

Add a check here if wx is None and create_wx_app is true then show an error "wxpython is required unless INTERACTIVE_HTML_BOM_NO_DISPLAY environment variable is set" and exit early.

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