-
-
Notifications
You must be signed in to change notification settings - Fork 573
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
Changes from 16 commits
b9228cf
c3ebb25
17004e1
1f4d945
fbb7a63
bf4da06
9924d42
6497950
56d76e8
b7e2022
081351d
9099bbd
e6d6991
5f8da30
93a1c4f
9221125
555e993
cfb5c9f
e4716a6
2ac7896
288e46c
d0085e0
b936a28
5be57b2
c1a0288
8b92179
eadc990
21580e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from PyInstaller.utils.hooks import collect_data_files, collect_entry_point, collect_submodules, copy_metadata | ||
|
||
datas, hiddenimports = collect_entry_point("pytest11") | ||
|
||
datas += collect_data_files("sunpy") | ||
datas += collect_data_files("dask") | ||
datas += collect_data_files("drms") | ||
datas += copy_metadata("sunpy") | ||
|
||
hiddenimports += collect_submodules('sunpy') | ||
hiddenimports += collect_submodules('numpy.distutils') | ||
hiddenimports += collect_submodules('distutils') | ||
hiddenimports += ['skimage.filters.rank.core_cy_3d'] | ||
hiddenimports += ['sunpy.data.data_manager.tests.mocks'] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import os | ||
import sys | ||
import shutil | ||
|
||
import pytest | ||
|
||
# Skipping these tests that take check the name of the current module (which ends up starting with | ||
# sunpy_tests rather than sunpy). | ||
# asdf path issue with PyInstaller as well. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this an asdf issue or a sunpy issue? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An issue specifically with asdf and PyInstaller, works fine when used without. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this just the tests, or will asdf fail to find the schemas and break when running user code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just these tests from what I've noticed. I haven't checked it thoroughly though, is there any way we can? |
||
|
||
if getattr(sys, 'frozen', False): | ||
# Running in a bundle | ||
bundle_dir = sys._MEIPASS | ||
|
||
SKIP_TESTS = [ | ||
'test_saveframe', | ||
'test_saveframe_arr', | ||
'test_genericmap_basic', | ||
'test_genericmap_mask', | ||
'test_attr_metamagic', | ||
'test_main_nonexisting_module', | ||
'test_main_stdlib_module', | ||
'test_origin', | ||
'test_find_dependencies', | ||
'test_missing_dependencies_by_extra', | ||
'test_hgc_100', | ||
'test_missing_dependencies_by_extra', | ||
'test_basic', | ||
'test_data_manager', | ||
'test_file_tampered', | ||
'test_download_cache', | ||
'test_skip_all', | ||
'test_override_file', | ||
'test_same_file_id_different_module'] | ||
Comment on lines
+16
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can any of these be removed now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the script, these tests either use current directory's file name which is 'sunpy_tests' instead of 'sunpy' which resutls in an assertion error. |
||
|
||
sys.exit(pytest.main(['sunpy_tests', | ||
'-k ' + ' and '.join('not ' + test for test in SKIP_TESTS)])) | ||
else: | ||
ROOT = os.path.join(os.path.dirname(__file__), '../') | ||
|
||
for root, dirnames, files in os.walk(os.path.join(ROOT, 'sunpy')): | ||
for dirname in dirnames: | ||
final_dir = os.path.relpath( | ||
os.path.join( | ||
root.replace( | ||
'sunpy', | ||
'sunpy_tests'), | ||
dirname), | ||
ROOT) | ||
# We only copy over 'tests' directories, but not sunpy/tests (only | ||
# sunpy/tests/tests) since that is not just a directory with tests. | ||
if dirname == 'tests' and not root.endswith('sunpy'): | ||
shutil.copytree(os.path.join(root, dirname), final_dir, dirs_exist_ok=True) | ||
else: | ||
# Create empty __init__.py files so that 'sunpy_tests' still | ||
# behaves like a single package, otherwise pytest gets confused | ||
# by the different conftest.py files. | ||
init_filename = os.path.join(final_dir, '__init__.py') | ||
if not os.path.exists(os.path.join(final_dir, '__init__.py')): | ||
os.makedirs(final_dir, exist_ok=True) | ||
with open(os.path.join(final_dir, '__init__.py'), 'w') as f: | ||
f.write("#") | ||
# Copy over all conftest.py files | ||
for file in files: | ||
if file == 'conftest.py': | ||
final_file = os.path.relpath( | ||
os.path.join( | ||
root.replace( | ||
'sunpy', | ||
'sunpy_tests'), | ||
file), | ||
ROOT) | ||
shutil.copy2(os.path.join(root, file), final_file) | ||
|
||
# Add the top-level __init__.py file | ||
with open(os.path.join('sunpy_tests', '__init__.py'), 'w') as f: | ||
f.write("#") | ||
|
||
# Copy the top-level conftest.py | ||
shutil.copy2(os.path.join(ROOT, 'sunpy', 'conftest.py'), | ||
os.path.join('sunpy_tests', 'conftest.py')) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Added hook file and tests for using PyInstaller with SunPy. | ||
jeffreypaul15 marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -179,3 +179,24 @@ install_command = pip install --no-deps {opts} {packages} | |
commands = | ||
conda list | ||
{env:PYTEST_COMMAND} {posargs} | ||
|
||
[testenv:pyinstaller] | ||
nabobalis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
description = check that sunpy can be included in a pyinstaller bundle | ||
changedir = .pyinstaller | ||
deps = | ||
pyinstaller | ||
extras = | ||
tests | ||
net | ||
all | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe 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 commentThe 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 commentThe 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 commentThe 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 |
||
commands = | ||
./python3 run_sunpy_tests.py | ||
pyinstaller --onefile run_sunpy_tests.py \ | ||
--distpath . \ | ||
Cadair marked this conversation as resolved.
Show resolved
Hide resolved
|
||
--additional-hooks-dir hooks \ | ||
--exclude-module tkinter \ | ||
--hidden-import pytest \ | ||
--hidden-import sunpy \ | ||
--hidden-import pytest_mpl.plugin | ||
|
||
./run_sunpy_tests | ||
Cadair marked this conversation as resolved.
Show resolved
Hide resolved
|
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.
Say what now? Why is this here?
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.
I encountered these missing imports when running the SunPy's tests for PyInstaller, adding them fixed 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.
I am curious as to how we got here in the import stack, I didn't realise we had even an optional transitive dependency on skimage.
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.
sunpy/sunpy/image/coalignment.py
Line 24 in f1c45df
Which leads to the
__init__
offilters
being executed fromskimage
https://github.com/scikit-image/scikit-image/blob/178e05f17855859d6661ebb6e04d8ddcb50c1cc5/skimage/filters./rank/generic_cy.pyx#L11
Because of the relative import, falls under hidden import category.
This isn't our issue as of now and a PR has just been merged over at pyinstaller/pyinstaller-hooks-contrib#107
PyInstaller combines these hooks on a monthly basis so I'm not sure how long it'd take for that to be sorted.
I've left it here for the time being, I suppose this is essential and I don't think we need it just for the tests.