Skip to content

Remove numpy distutils#161

Merged
rgommers merged 26 commits intoPyWavelets:masterfrom
kwohlfahrt:setuptools
Jul 6, 2016
Merged

Remove numpy distutils#161
rgommers merged 26 commits intoPyWavelets:masterfrom
kwohlfahrt:setuptools

Conversation

@kwohlfahrt
Copy link
Member

This removes the last of the .src templating. This means we no longer need to use numpy's distutils, which somewhat simplifies the CI process, especially on windows. This replaces #159 and closes #160.

The first build takes ~20 minutes (numpy is built from source), but afterwards the wheels are cached and subsequent builds take <2 minutes.

The main disadvantage at the moment is it requires Cython and numpy to be installed before running setup.py. There are numerous work-arounds including custom build_ext classes so this shouldn't be a deal-breaker.

TODO:

  • Make nosetests pick up doctests
    • runtests.py --doctests and runtests.py both run 992 tests on master, so it doesn't seem to be working there either
  • Use coverage/coveralls (coverage works, just not used for anything)

@grlee77
Copy link
Contributor

grlee77 commented Feb 29, 2016

The templating changes all look good to me. I am not an expert on distutils or Appveyor, but I agree that the proposed changes seem to have reduced total LOC substantially which may ease future maintenance.

@kwohlfahrt kwohlfahrt force-pushed the setuptools branch 2 times, most recently from 6c38b2c to daccc98 Compare February 29, 2016 23:41
@kwohlfahrt
Copy link
Member Author

Disabling binaries is necessary for the Python-2.6/numpy-1.7 build. Otherwise matplotlib fails with an error that it was linked against the wrong numpy version. However, this prevents caching of the wheel which makes the build take much longer.

I think this means either the test against old numpy versions, or the matplotlib doctests need to go.

EDIT: Nevermind. pip doesn't order installations by dependency, so specifying numpy before matplotlib manually fixed it.

@kwohlfahrt
Copy link
Member Author

Everything is passing now, but the caching on appveyor seems to be broken. It's working on my own CI environment, just not the PyWavelets one.

EDIT: According to http://help.appveyor.com/discussions/problems/4048-build-cache-not-restored build caches are not kept on PR builds (but PR builds will use a cache from master).

@kwohlfahrt kwohlfahrt force-pushed the setuptools branch 2 times, most recently from 908a1b0 to 255974f Compare March 1, 2016 13:53
@kwohlfahrt
Copy link
Member Author

@grlee77 I've been using ./setup.py nosetests, which runs in the source directory.

This is admittedly less nice than it being contained in build/testenv, I think the issue test discovery as tests are not installed with the rest of the package.

I've sort of got out of tree tests working:

nosetests --where build/lib.linux-x86_64-2.7/ ../../pywt/tests/

This requires including the pywt.data package and files in the install - we may want to do this anyway?

It also doesn't seem to play nicely with doctest or coverage, but in-tree builds seem to be the norm for python testing as far as I can tell.

@rgommers rgommers mentioned this pull request Mar 1, 2016
@rgommers
Copy link
Member

rgommers commented Mar 1, 2016

Removal of .c.src templating is quite nice. When I introduced it it was a 1:1 translation of some homegrown templating method - with almost zero test coverage I didn't dare do anything more than that. But should be pretty risk-free now.

@rgommers
Copy link
Member

rgommers commented Mar 1, 2016

This requires including the pywt.data package and files in the install - we may want to do this anyway?

Yes. Tests pass now for installed pywt, so this must be done already.

I don't quite see why you'd need the --where argument to nosetests? pywt is either on sys.path or it isn't I'd say.

@kwohlfahrt
Copy link
Member Author

I think this commit is going to give subtle problems. IIRC Cython and setuptools incompatibly monkeypatch Extension, and using cython as a script is much more robust.

Do you mean setuptools and Cython.cythonize not working together? I hadn't heard of any problems from this, and it's one less script to maintain. Cython.cythonize didn't work with the numpy distutils, but I think that was more from it not knowing how to deal with the Configuration object.

Also, it looks like this requires Cython as a build-time dependency for released builds, which is not the case now. Or maybe that's fixed in a later commit (I'm reviewing commits one by one)?

No, but it should be straightforward to fix: http://docs.cython.org/src/reference/compilation.html#distributing-cython-modules

And the hashing to prevent rebuilds as well?

Cython.cythonize does this internally. It also picks up if the installed version of Cython has changed and rebuilds (just noticed this now, neat).

./setup.py build
kai@laptop ~/D/c/pywt> ./setup.py build
Compiling pywt/_extensions/_pywt.pyx because it changed.
Compiling pywt/_extensions/_dwt.pyx because it changed.
Compiling pywt/_extensions/_swt.pyx because it changed.
[1/3] Cythonizing pywt/_extensions/_dwt.pyx
[2/3] Cythonizing pywt/_extensions/_pywt.pyx
[3/3] Cythonizing pywt/_extensions/_swt.pyx
running build
running build_py
<LOTS MORE COMPILING>
kai@laptop ~/D/c/pywt> ./setup.py build
running build
running build_py
copying pywt/version.py -> build/lib.linux-x86_64-3.4/pywt
running build_ext
kai@laptop ~/D/c/pywt> 

I don't quite see why you'd need the --where argument to nosetests? pywt is either on sys.path or it isn't I'd say.

If I'm in the working directory (next to setup.py), and I run ./setup.py build, nosetests fails because the compiled extensions aren't in the working directory (and build/lib-linux-whatever isn't on sys.path). I need to run ./setup.py build_ext --inplace, but it's a little irritating because it puts a bunch of .so files in my working directory. Though I guess Cython already does this with .c files so it's not a big deal. The above was an attempt to get nosetests to run in the build/lib-linux-... directory so the source tree stays as clean as possible.

@kwohlfahrt
Copy link
Member Author

The fact that tests were passing without the data files is a problem. Let me know if anybody has a solution.

On that note, it should be possible to trigger CI on tags right? So the sdist build, test and upload can be done in an automated fashion?

@kwohlfahrt
Copy link
Member Author

This was referenced Mar 3, 2016
@kwohlfahrt kwohlfahrt force-pushed the setuptools branch 2 times, most recently from 73ef296 to a1dfc5b Compare March 7, 2016 12:10
@grlee77
Copy link
Contributor

grlee77 commented Jun 21, 2016

@kwohlfahrt
I am +1 on merging this

It has been a while since I looked at this, but I see you added the ability to install without Cython present.

I checked out this branch and verified that a local development installation via
pip install -e .
is working fine. I also tried an alternative way of running tests via py.test pywt and that also works.

Is there anything else still in progress here or do you think it is ready?

@kwohlfahrt
Copy link
Member Author

Been a while since I have looked as well, but I think I left it fine. It also lets us merge my other PR for code coverage (yay!) after a rebase.

@grlee77
Copy link
Contributor

grlee77 commented Jun 30, 2016

@rgommers @aaren
Do either of you have any objections or other feedback related to this build/CI refactoring?

@rgommers
Copy link
Member

It's been a while, I'll have a look now.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Those instructions look outdated, in particular they are missing that the MSVC version to build Python 3.5 changed. The link above the table does use MSVC Express instead of the GRMSDKK.. thing. So I'm not sure that the simplifications below are OK.

Copy link
Member Author

Choose a reason for hiding this comment

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

Found my source! Really should have linked this instead, either I copy/pasted the wrong thing or that used to be in the article at the link too - https://packaging.python.org/appveyor/

At the bottom. Will update the link if you're happy with the current solution?

Copy link
Member

Choose a reason for hiding this comment

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

Nice, wasn't aware of those docs. I see now that Python 3.5 doesn't use that same SDK, switched via DISTUTILS_USE_SDK. So looks good to me.

@rgommers
Copy link
Member

With the doctesting added, a missing matplotlib will result in 4 test failures. I'm not sure if there's a good way to mark those tests as skipped though - doctest tends to be inflexible. Any preferences on how to handle that?

Kai Wohlfahrt and others added 17 commits July 2, 2016 11:40
Cache pip install on travis-ci as well.
According to the article linked in the header, python3.3 and 3.4 need a
special flag to make sure the build environment is set up correctly.

This works together with util/appveyor/build.cmd.
This makes the build process a little more consistent (same packages updated
and installed on both platforms). Also removes the dependency of the appveyor
cache on appveyor.yml, which was preventing me from properly testing it.

Caching on Travis doesn't seem to be working, but we'll see if this helps.
Numpy build was failing, this might be the reason.
This commit enables doctests and coverage reports. Also fixes the absurdly
long logs (nosetests is more compact than test).

Note matplotlib is required for data/_readers.py, use a non-interactive
backend for travis.
Update tox.ini to install matplotlib for new doctests, and don't change out
of source directory.

Coverage isn't quite right, it includes lots of other modules not part of
pywt (dateutil, etc)
No longer used.
Apparently setup.py nosetests already specifies --where, so using that
gives a warning that it'll be deprecated in future. Use ignore-files
instead.

Install coverage on appveyor.
Shape returns e.g. (512L, 512L) on python2 appveyor. Check for equality
instead.
Other packages (notably matplotlib) link against numpy, so they must be
installed in the correct order.
Don't specify a numpy version so pip doesn't insist on upgrading it with
pywt.

Cython is treated as a compiler and not required after distribution, so
don't require it.
This allows the import of Cython to fail, and attempts to use pre-built C
sources if it does.
Tests before didn't pick up problems with the distribution (e.g. missing
data files) that were present in the source tree. This should be fixed in
CI now, developers should probably use:

./setup.py build
nosetests build/lib.xyz/ --tests pywt/tests
nosetests wasn't added to $PATH on windows, so specify full location.
Old link was broken/the wrong link in the first place.
@rgommers
Copy link
Member

rgommers commented Jul 5, 2016

I propose to keep it simple for now and document that matplotlib is needed to run all tests. Then we can get this PR merged.

For reference, this is what scipy does: https://github.com/scipy/scipy/blob/master/tools/refguide_check.py. It checks that docstrings run, but doesn't actually do the full doctesting. That allows skipping tests (possibly conditionally), not having to add doctest markup crap, etc. Doctests really aren't usable on a larger project, too many limitations.

@kwohlfahrt
Copy link
Member Author

Can we use tests_require in setup.py, or is that deprecated? I can never work out what the current state of setuptools is.

@kwohlfahrt kwohlfahrt mentioned this pull request Jul 5, 2016
@rgommers
Copy link
Member

rgommers commented Jul 5, 2016

Can we use tests_require in setup.py, or is that deprecated?

This is only used when you do python setup.py test, which is not a good way to run tests. I think adding the requirement to the docs as you did is fine. I suggest to remove the last commit, and then we can press the green button here.

I can never work out what the current state of setuptools is.

That makes two of us:)

@kwohlfahrt
Copy link
Member Author

OK, updated. Feel free to merge (and then pull in #181 as well).

@rgommers rgommers merged commit 3e4657c into PyWavelets:master Jul 6, 2016
@rgommers rgommers added this to the v0.5.0 milestone Jul 6, 2016
@rgommers
Copy link
Member

rgommers commented Jul 6, 2016

Merging. Thanks Kai!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Appveyor failing on recent PRs

3 participants