New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PyInstaller Support for SunPy #5224
Conversation
Hello @jeffreypaul15! Thanks for updating this PR. There are currently no PEP 8 issues detected in this Pull Request. Cheers! Comment last updated at 2021-06-20 13:23:21 UTC |
What needs to be added upstream? |
The Hook support has to be added to PyInstaller directly |
Would that change this PR? Will you be doing that? |
It would remove the hook file from here as it would be added to PyInstaller directly. If this PR is implemented correctly, sure I would love to make the PR over at PyInstaller. |
So this PR adds support but in theory we could move that support upstream and not need this PR? Or we would still need something here? |
We would still need the test script that is implemented in this PR and the tox environment for it, only |
tox.ini
Outdated
[testenv:pyinstaller] | ||
# Check that astropy can be included in a PyInstaller bundle without any issues. This | ||
# also serves as a test that tests do not import anything from outside the tests | ||
# directories with relative imports, since we copy the tests out to a separate directory | ||
# to run them. | ||
description = check that astropy can be included in a pyinstaller bundle | ||
changedir = .pyinstaller | ||
deps = | ||
# The developer version of PyInstaller doesn't work yet because it | ||
# requires https://github.com/pyinstaller/pyinstaller/pull/4888 - | ||
# so for now we pin to the latest working commit. | ||
git+https://github.com/pyinstaller/pyinstaller.git@c111ec5c#egg=PyInstaller | ||
# PyInstaller is not yet compatible with Matplotlib 3.3 so we pin | ||
# Matplotlib to an older version for now - see the following issue | ||
# for more details: https://github.com/pyinstaller/pyinstaller/issues/5004 | ||
matplotlib<3.3 | ||
extras = | ||
tests | ||
net | ||
all | ||
commands = | ||
pyinstaller --onefile run_sunpy_tests.py \ | ||
--distpath . \ | ||
--additional-hooks-dir hooks \ | ||
--exclude-module tkinter \ | ||
--hidden-import pytest \ | ||
--hidden-import pytest_doctestplus.plugin \ | ||
--hidden-import pytest_mpl.plugin | ||
|
||
./run_sunpy_tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much of this do we need?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? I suppose the comments are required right? These issues still persist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each command, the mpl version, the pyinstaller version etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The matplotlib issue still persists with PyInstaller so that is required.
Do we need to test pyinstaller with the dev version? Why not just use the latest working commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The matplotlib 3.3 incompatibility should have been cleared up in pyinstaller/pyinstaller#5006 and then 3.4 compatibility in pyinstaller/pyinstaller#5568 which is included in PyInstaller 4.3 (which released a few days ago). If you're still seeing breakages then that's quite worrying...
Astropy runs the PyInstaller tests on their github daily workflow, would we need to do that as well? |
Yes, we need to make sure this works on our CI somehow. |
tox.ini
Outdated
description = check that sunpy can be included in a pyinstaller bundle | ||
changedir = .pyinstaller | ||
deps = | ||
# The developer version of PyInstaller doesn't work yet because it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this copied out of astropy? Is this still true for us, this PR linked here is pretty old.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I've taken AstroPy as a reference, I think this wouldn't be a problem for Sunpy though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally if we can test with a released version that would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah sorry I undid these changes accidentally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this @jeffreypaul15
tox.ini
Outdated
--hidden-import pytest \ | ||
--hidden-import pytest_doctestplus.plugin \ | ||
--hidden-import pytest_mpl.plugin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these just here to make it possible to run the tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to create the executable file
tox.ini
Outdated
extras = | ||
tests | ||
net | ||
all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need these here do we? All we are running from tox is pyinstaller? or does pyinstaller copy from your current env?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tox needs these to ensure that the tests run fine by itself, PyInstaller then copies the current environment (tox) and creates the executable based on the environment it was running on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need all of these now?
all, encompasess net. can we get away with just all and test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All doesn't seem to load Beautiful Soup which is part of net, this gave me an error locally I might need to check what else is required from tests and add them individually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should, I wonder what the cause is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My apologies, must've been some local issue, we don't need net
If we could get the hook added upstream first, then we can deal with this PR? |
|
Sure. |
@bwoodsend in pyinstaller/pyinstaller-hooks-contrib#112 (comment)_ makes a valid point with the hook, but the all the tests and the script revolves around having the dependencies and optional dependencies. I'm not sure if doing it the way AstroPy has is a good idea then. |
.pyinstaller/run_sunpy_tests.py
Outdated
import os | ||
import sys | ||
|
||
sys.exit(os.system('pytest -p no:warnings --doctest-rst -m "not mpl_image_compare" --pyargs sunpy')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No no no! This will just run regular unfrozen pytest so it's not testing anything except os.system()
! Use pytest.main()
instead.
sys.exit(os.system('pytest -p no:warnings --doctest-rst -m "not mpl_image_compare" --pyargs sunpy')) | |
import pytest | |
# Set some default args. | |
args = ['-p', 'no:warnings', '--doctest-rst', '-m', | |
'not mpl_image_compare. '--pyargs sunpy'] | |
# And allow additional arguments to be supplied at runtime. | |
args += sys.argv[1:] | |
pytest.main(args) |
However, without an import sunpy
in there, PyInstaller will have no reason to think that sunpy
is a dependency so it won't collect it (or run the hook) unless you force it to with a --hiddenimport=sunpy
or put import sunpy
in the script.
That's still probably not the end of the story though - it depends: Does import sunpy
load everything so that you can access any public corner without additional import statements or are you expected to use from sunpy.foo.bar import xyz
to pull the bits you need out? If it's the latter then PyInstaller will consider sunpy.foo.bar
to be unneeded unless you add it as a hiddenimport
or an explicit reference in run_sunpy_tests.py
too. (Note, this won't apply if you opt to keep the collect_submodules("sunpy")
in the hook. Using collect_submodules("sunpy")
does simplify testing - at the expense of making builds huge.)
It's quite likely that you'll have to have more than one test script, each importing and testing a different corner of sunpy
, and each using only the optional dependencies that that corner requires.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your help on this @bwoodsend.
I've uncovered another issue with PyInstaller and SunPy : from pkg_resources import get_distribution
get_distribution('sunpy') Doesn't work with PyInstaller, The 0df8534#diff-0c2fc003b7a8d4cda00792118c87f10505af98697c012a80656f63cb926c88a6 update to sysinfo.py probably uncovered an issue with pyinstaller and Although, PyInstaller can be used with any current stable version of SunPy just before from |
Oh, that one is quite an easy one. from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata("sunpy") Of course, as you already have a datas += copy_metadata("sunpy") |
Thanks for this. |
@nabobalis what would we want to do here? We can either skip the tests dependencies while making the hook, but this complicates testing, or we could have a separate internal hook within the repository for testing and have the main hook present upstream without the original test dependencies. |
Whatever makes it easier to setup and to ensure that hook works and the offline tests pass. |
Offline tests require certain imports like |
Won't the next stable release be the dev version and then have the same issue? |
I'm assuming that they'd fix it before the release, should I report it to them? I can't seem to find the change that caused it. |
I suspect that this asdf issue is in part due to pyinstaller/pyinstaller#5774. asdf makes use of
although we (PyInstaller) will want to stream line it into something more sane. I'm adding a recursive option to copy metadata to deal with |
Where did we get with this again? I forgot. |
Last I checked, I think the asdf issue still persists, we would be able to use sunpy without asdf as of this current PR |
Will need a rebase due to the file conflict. |
On it. |
What will getting pyinstaller/pyinstaller-hooks-contrib#112 merged in do for this PR or will it change nothing? |
@Cadair |
It won't really do much, since I'm going to open another PR which only contains the required files for sunpy to run without tests. |
Another PR here or upstream? |
Upstream |
Why another one? Is the one you opened not enough? |
I closed that one, thought it would be better to create a new one instead. |
So outside of that and asdf, this PR is good to go? Can you open an issue on the asdf repo about pyinstaller please? |
It should be.
Sure |
Co-authored-by: Nabil Freij <nabil.freij@gmail.com>
Fixes #5207
Based on AstroPy's hook and testing script : https://github.com/astropy/astropy/blob/main/.pyinstaller/run_astropy_tests.py
I've written a similar hook for SunPy, although the testing script is quite different from the one over at AstroPy.
The hook is at
sunpy/.pyinstaller/hooks/hook-sunpy.py
which can be loaded by--additional-hooks-dir
while running PyInstaller.Instead of having to create a separate 'sunpy_tests' directory locally (astropy's version),
the
executable
created from PyInstaller runs :pytest -p no:warnings --doctest-rst -m "not mpl_image_compare" --pyargs sunpy
which runs all the tests by default through the executable.
Support will have to be added upstream to pyinstaller-hooks-contrib