Description
I'm working on PyInstaller user-contributed hooks so that Plotly, Dash, and related packages work "out of the box" (pyinstaller-hooks-contrib/pull/103)
The one thing I'm running into is how to inform PyInstaller of all of the optional imports that were added in #2368 (which btw is awesome, the speedup was fast enough that I noticed plotly was faster as an end user!). My initial solution is to build, see what is missing, add an unused import, repeat. Which leaves you with something like this:
> # From my test project: https://github.com/KyleKing/Poetry-EdgeCaseTesting (branch: dev/pyinstaller)
> poetry run pyinstaller main.py --noconfirm; ./dist/main/main
...
Traceback (most recent call last):
File "main.py", line 3, in <module>
from package_name import app
File "PyInstaller/loader/pyimod03_importers.py", line 531, in exec_module
File "package_name/__init__.py", line 43, in <module>
fig = px.scatter(df, x="sepal_width", y="sepal_length")
File "plotly/express/_chart_types.py", line 64, in scatter
File "plotly/express/_core.py", line 2088, in make_figure
File "plotly/basedatatypes.py", line 1403, in update_layout
File "plotly/basedatatypes.py", line 5067, in update
File "plotly/basedatatypes.py", line 3876, in _perform_update
File "plotly/basedatatypes.py", line 5806, in __setitem__
File "plotly/basedatatypes.py", line 4796, in __setitem__
File "plotly/basedatatypes.py", line 5207, in _set_compound_prop
File "_plotly_utils/basevalidators.py", line 2743, in validate_coerce
File "_plotly_utils/basevalidators.py", line 2454, in validate_coerce
File "plotly/graph_objs/layout/_template.py", line 319, in __init__
File "plotly/basedatatypes.py", line 4796, in __setitem__
File "plotly/basedatatypes.py", line 5207, in _set_compound_prop
File "_plotly_utils/basevalidators.py", line 2450, in validate_coerce
File "plotly/graph_objs/layout/template/_data.py", line 1541, in __init__
File "plotly/basedatatypes.py", line 4800, in __setitem__
File "plotly/basedatatypes.py", line 5281, in _set_array_prop
File "_plotly_utils/basevalidators.py", line 2542, in validate_coerce
File "plotly/graph_objs/_bar.py", line 2901, in __init__
File "plotly/basedatatypes.py", line 4792, in __setitem__
File "plotly/basedatatypes.py", line 4274, in _get_validator
File "plotly/validator_cache.py", line 29, in get_validator
File "importlib/__init__.py", line 127, in import_module
ModuleNotFoundError: No module named 'plotly.validators.bar'
[53889] Failed to execute script main
import plotly.validators.layout.colorscale
import plotly.validators.layout.template.data
import plotly.validators.layout.xaxis
import plotly.validators.layout.title
import plotly.validators.layout.legend
import plotly.validators.layout.yaxis
import plotly.validators.scatter.marker
import plotly.validators.layout.margin
import plotly.validators.barpolar.marker.line
import plotly.validators.bar.marker.line
import plotly.validators.bar.error_x
import plotly.validators.bar.error_y
import plotly.validators.carpet.aaxis
import plotly.validators.carpet.baxis
import plotly.validators.choropleth
# ...
import plotly.express as px
df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length")
(Which is a little dramatic 😄, I could have compressed with: from plotly.validators.layout import xaxis, title, ...
)
Anyway, I couldn't find this type of issue documented elsewhere and while writing it up, I figured out the PyInstaller-way of discover lazy imports by globbing all Python files (datas = collect_data_files('plotly', include_py_files=True, includes=['**/*.py', 'package_data/**/*.*'])
) (PyInstaller #5117) (Update: don't glob Python files. See changes implemented in the PR, particularly: hiddenimports = collect_submodules('plotly.validators')
)
Hopefully, if merged into PyInstaller-Hooks-Contrib, then the PR will magically fix errors like these for all PyInstaller users! If you run into new errors, see if the stdhooks can be further updated