-
Notifications
You must be signed in to change notification settings - Fork 253
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
Add CIBW_BEFORE_TEST to customize test environment #242
Conversation
Restarted the test (cfr. #243 (comment)). I still need to think about this and review this, but I don't have time, right now. I'll get a look somewhere next week or so. |
One additional remark. From PR #164 test are executed in separated environment. So |
@joerick Yes |
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.
See my discussion on use-cases, I'm a little confused on what actual real-world use of the option would look like!
docs/options.md
Outdated
A shell command to run after setup test environment. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to install non pip package, change values of environment variables | ||
or perform multi step pip installation (like install `scikit-build` or `cython` before install test package) |
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.
These reasons are a little curious, actually.
- Non-pip packages don't care about the virtualenv, so can be installed in BEFORE_BUILD.
- Changing environment variables won't work, since the command is run in a subshell
- Maybe I'm missing something, but I can't see the need to install anything before installing the wheel? Wheel installation is just an unzip and move, no code within the package is run. So why is there a need to install dependencies before that? It seems that TEST_REQUIRES would be sufficient for these cases.
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.
Example situation:
- PyQt5 from 5.14.0 has wheel with
manylinux2014
platform tag. Earlier are published withmanylinux1
.manylinux2014
needs pip in version 19.3. Example solution withBEFORE_BUILD
is to manually installPyQt5==5.13.2
- cmake package does not provide wheels for x86 python 3.8. So only option is to build it from source. But cmake package needs
scikit-build
for build and this dependency needs to be importable (installed in previous transatction). And package blosc does not provide wheel and need cmake package to be installed. And tests needblosc
package. - i do not have given example but it is possible to have similar story with
Cython
Also non pip package can care about virtualenv (location of python executable). Here example: https://github.com/LLNL/zfp
And change environment variable I think about ENV1=1 ENV2=7 command
docs/options.md
Outdated
CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt | ||
|
||
# chain commands using && | ||
CIBW_BEFORE_TEST: yum install -y libffi-dev && pip install . |
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.
pip install .
would be an anti-pattern, since it would build and install from code, rather than from the wheel.
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.
Agree. I copy it from CIBW_BEFORE_BUILD
documentation. Whole example is bad. Installig things system side during testis also bad idea. Maybe pip install scikit-build && pip install cmake
?
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 about this?
# chain commands using &&
CIBW_BEFORE_TEST : rm -rf ./data/cache && mkdir -p ./data/cache
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.
yes
docs/options.md
Outdated
#### Examples | ||
```yaml | ||
# install packages needed to build test dependencies | ||
CIBW_BEFORE_TEST: pip install cmake scikit-build |
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.
See above, I'm not sure why these aren't TEST_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.
As I mentioned before. Some dependencies need to be importable in setup.py
. And still some authors of packages does not provide wheels or it takes over month since release of python 3.8 to wheel for this python. And such things allow maintainer to have full test case without waiting on other persons.
From one of my build
File "/tmp/pip-install-f9rmc9hk/cmake/setup.py", line 7, in <module>
from skbuild import setup
ModuleNotFoundError: No module named 'skbuild'
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.
@joerick I know setup_requires
doesn't always work, for some reason. So that would be good.
But indeed, this might not be the perfect example to put in the docs, either?
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 see. Maybe it shouldn't be the first example. Could we move it so it's the last one, and change comment to # install python packages that are required to install test dependencies
CIBW_BEFORE_TEST: pip install cmake scikit-build | ||
|
||
# install test dependencies with overwritten environment variables. | ||
CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt |
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.
Curious - why would this be necessary?
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 case is that i want to build package with OMP support for MacOS. MacOS clang does not support this. So I need to use brew g++ for this. But one of test dependencies need to be compiled with system clang
. Otherwise I got such message:
python(53258,0x7fff9481d380) malloc: *** error for object 0x10f526c00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Other case which I can imagine is that my package is build against newest version of some library. And test dependency is build against older (system one). And I need to change LD_LIBRARY_PATH
etc to avoid collision.
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 confusion makes me wonder; wouldn't a different example be better for the docs, then?
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 think about
CFLAGS="-I ... -L ..." pip install package name
for custom library location?
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.
Huh, maybe. But .. that's again something where you'd ask the question where a user would ask why this is not CIBW_TEST_ENVIRONMENT
...
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.
Totally different example. Install non pip package like: https://github.com/LLNL/zfp
For this... (original example)
MacOS system clang does not support OpenMP. So if package needs OpenMP support then there is need to compile it with gcc/g++ (ex from brew).
For second. I meet problem when test for one package fail on Azure Pipeline but not fail on my computer. And this fail was connected with package used in test and build from source. And for me possibility to control compilation of single package is big profit.
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 think this one is okay as-is, the comment makes sense. (I agree about CIBW_TEST_ENVIRONMENT
@YannickJadoul, we can remove this example if that appears)
cibuildwheel/windows.py
Outdated
@@ -58,7 +58,7 @@ def get_python_configurations(build_selector): | |||
return python_configurations | |||
|
|||
|
|||
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment): | |||
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_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.
Ugh, these arguments are becoming a mess.
At any rate, I don't think before_test
should be alone at the end of the argument list. Can you put it maybe after test_command
or so?
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.
Agree. But there is question if use kwargs
or reorder arguments? @joerick ?
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'd say just reorder now such that it make +- logical sense. Refactoring this (maybe **kwargs
, but I don't know what the best solution is) is for another time/PR.
docs/options.md
Outdated
#### Examples | ||
```yaml | ||
# install packages needed to build test dependencies | ||
CIBW_BEFORE_TEST: pip install cmake scikit-build |
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 see. Maybe it shouldn't be the first example. Could we move it so it's the last one, and change comment to # install python packages that are required to install test dependencies
CIBW_BEFORE_TEST: pip install cmake scikit-build | ||
|
||
# install test dependencies with overwritten environment variables. | ||
CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt |
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 think this one is okay as-is, the comment makes sense. (I agree about CIBW_TEST_ENVIRONMENT
@YannickJadoul, we can remove this example if that appears)
docs/options.md
Outdated
CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt | ||
|
||
# chain commands using && | ||
CIBW_BEFORE_TEST: yum install -y libffi-dev && pip install . |
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 about this?
# chain commands using &&
CIBW_BEFORE_TEST : rm -rf ./data/cache && mkdir -p ./data/cache
test/10_before_test/setup.py
Outdated
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step | ||
# is the same one as is currently running. | ||
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' | ||
if os.path.exists(version_file): | ||
os.remove(version_file) | ||
|
||
# check that the executable also was written | ||
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' | ||
if os.path.exists(executable_file): | ||
os.remove(executable_file) |
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.
Just thinking- I'm not sure we need these delete steps here in setup.py
..?
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 agree. The reason these were in CIBW_BEFORE_BUILD
is probably because only setup.py
gets run here. Now there's a test suite that's run, so things should be checked there.
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.
In macos build cibuildwheel use symlink for choosing python versions. Then all python version has same executable path. So we need to delete this files to be sure that CIBW_BEFORE_BUILD
is executed properly.
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 an excellent point about pythonversion.txt
. I previously said that pythonversion.txt
should be removed in this test - I was wrong, for the symlink reason above, we should keep that. Apologies @Czaki!
However, I still think the setup.py
'remove files' step is unnecessary. Each test will overwrite the previous version.
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 revert this change and remove cleaning.
test/10_before_test/setup.py
Outdated
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step | ||
# is the same one as is currently running. | ||
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' | ||
if os.path.exists(version_file): | ||
os.remove(version_file) | ||
|
||
# check that the executable also was written | ||
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' | ||
if os.path.exists(executable_file): | ||
os.remove(executable_file) |
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 agree. The reason these were in CIBW_BEFORE_BUILD
is probably because only setup.py
gets run here. Now there's a test suite that's run, so things should be checked there.
9ccdc79
to
586cac8
Compare
I'm a little lost with comments to documentation. I try to apply all, but I'm not sure if I properly understand all suggestions. Could You check? |
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.
Looks good to me! @YannickJadoul any further comments/questions or are we good to merge?
Would be nice to get this into the next release - @Czaki could you merge/rebase please? @YannickJadoul did you have any further comments before it goes in? |
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.
Sorry, I'd missed reviewing the new version!
Found one more little thing, I think.
And the test probably needs a new number, because by now we already have a test nr. 10.
dbbb683
to
7852971
Compare
@YannickJadoul again pypy problem with virtualenv separation.
|
@Czaki Sigh :-( But this time on Windows? I'll have a look tomorrow, if I can. Could you meanwhile test if |
I think that Lest wait on result. |
@YannickJadoul Yes. Again problem with virtualenv. Travis is somehow buggy.
|
Args. Sorry, today I don't have time to look at it. Maybe tomorrow, I don't know. Is it also an issue on master, btw, or is it linked to these changes?
I restarted everything in the latest build that failed. |
There is no test in master that cover this case... I will think about this and maybe produce some test which maybe can be used as example. |
@YannickJadoul Done |
5191dc0
to
4ec06df
Compare
@joerick Ready for merge. appveyor queue is rely long. |
Not ready. Need to somehow fix this. What you think about compare folders instead of executable (pypy3.exe vs python.exe) |
what's the difference between the paths? is python.exe a symbolic link to pypy3.exe? |
ah, yes it is, cibuildwheel creates it when it installs pypy. this might help |
if that doesn't work, you could consider a hard link from |
It is not so easy. this executables are cleated by
|
Ah, I hadn't realised that it was virtualenv creating the executables! hmm. hmm! Of the 3 choices above, my preference would be to compare |
So ready. |
Hm. Using circleci and appveyor really slow testing PR :( |
I need this change to overwrite some environment variable (use
clang
compiler instead ofgcc
on MacOS)It allow also use much more elegant solution than
to perform multi step requirements installation (in this case it is needed because there is no wheel for python 3.8).
I think that it is better solution than #240 which is my first try to solve this problem.