Skip to content

tweak easybuild.easyblocks package declaration to better support custom easyblocks repo#617

Merged
boegel merged 3 commits intoeasybuilders:developfrom
boegel:properly_support_custom_easyblocks_repo
Jun 22, 2015
Merged

tweak easybuild.easyblocks package declaration to better support custom easyblocks repo#617
boegel merged 3 commits intoeasybuilders:developfrom
boegel:properly_support_custom_easyblocks_repo

Conversation

@boegel
Copy link
Copy Markdown
Member

@boegel boegel commented May 28, 2015

Using extend_path to 'flatten' the easyblocks namespace results in better support for custom easyblocks repos, i.e. easyblocks that override existing easyblocks can be put in place easily.

This does require adding an (empty) __init__.py file in each letter-subdir.

There's one special case: because the R easyblock clashes with the easybuild.easyblocks.r, an icky from ... import * needs to be put in place in the r/__init__.py file...

For custom easyblock repos, including the following in the easybuild/easyblocks/__init__.py file should suffice with this in place:

subdirs = [chr(l) for l in range(ord('a'), ord('z') + 1)] + ['0']
for subdir in subdirs:
    __path__ = extend_path(__path__, '%s.%s' % (__name__, subdir))

 __path__ = extend_path(__path__, __name__)

Although a custom easyblocks repo may not include letter-subdirs, the extend_path loop still needs to be there, because only the first __init__.py there appears in the Python search path is actually executed.

Preliminary testing shows this works as intended (see below). A unit test will be added to confirm this (and make sure we don't break it).

$ find /tmp/easybuild -type f              
/tmp/easybuild/__init__.py
/tmp/easybuild/easyblocks/__init__.py
/tmp/easybuild/easyblocks/icc.py

$ PYTHONPATH=/tmp:$PYTHONPATH python -c "from easybuild.easyblocks import VERSION; print VERSION"
2.2.0dev

$ PYTHONPATH=/tmp:$PYTHONPATH python -c "import easybuild.easyblocks; import easybuild.easyblocks.icc; print easybuild.easyblocks.icc; from easybuild.easyblocks.icc import EB_icc; print EB_icc.__module__; import easybuild.easyblocks.ifort; print easybuild.easyblocks.ifort"
<module 'easybuild.easyblocks.icc' from '/tmp/easybuild/easyblocks/icc.py'>
easybuild.easyblocks.icc
<module 'easybuild.easyblocks.ifort' from '/Users/kehoste/work/easybuild-easyblocks/easybuild/easyblocks/i/ifort.pyc'>

The reason this works is because extend_path basically scans sys.path, and thus considers all easybuild/easyblocks package directories that are included in the Python search path...

@JensTimmerman: please review?

@hpcugentbot
Copy link
Copy Markdown

Refer to this link for build results (access rights to CI server needed):
https://jenkins1.ugent.be/job/easybuild-easyblocks-pr-builder/980/
Easyblocks unit test suite PASSed (see https://jenkins1.ugent.be/job/easybuild-easyblocks-pr-builder/980/console for more details).

This pull request is now ready for review/testing.

Please try and find someone who can tackle this; contact @boegel if you're not sure what to do.

@JensTimmerman
Copy link
Copy Markdown

Does this also deal with the case where a custom easyblock repository has a custom r.py package?

@boegel
Copy link
Copy Markdown
Member Author

boegel commented May 29, 2015

In that case, there's no problem, since the path to the custom easyblock repo will be first in the Python search path anyway:

$ find /tmp/easybuild -name '*.py'
/tmp/easybuild/__init__.py
/tmp/easybuild/easyblocks/__init__.py
/tmp/easybuild/easyblocks/icc.py
/tmp/easybuild/easyblocks/r.py

$ PYTHONPATH=/tmp:$PYTHONPATH python -c "import easybuild.easyblocks.r; print easybuild.easyblocks.r.__file__"
/tmp/easybuild/easyblocks/r.pyc

@JensTimmerman
Copy link
Copy Markdown

ok, yes, this works because you use
from easybuild.easyblocks.r.r import * and not from .r.r import *

@JensTimmerman
Copy link
Copy Markdown

please add some kind of integration test for this.

@hpcugentbot
Copy link
Copy Markdown

Refer to this link for build results (access rights to CI server needed):
https://jenkins1.ugent.be/job/easybuild-easyblocks-pr-builder/981/
Easyblocks unit test suite FAILed.

See https://jenkins1.ugent.be/job/easybuild-easyblocks-pr-builder/981/console for more details.

Please fix the reported issues by pushing additional commits to the branch corresponding with this pull request; contact @boegel if you're not sure what to do.

@boegel
Copy link
Copy Markdown
Member Author

boegel commented May 30, 2015

Current implementation of the test doesn't work when an easybuild-easyblocks repo that was installed with easy_install, and hence which is included in an easy-install.pth available through $PYTHONPATH, is around (as is the case on Jenkins).

The problem is that that repo gets precedence over whichever repo is listed first through $PYTHONPATH...

@hpcugentbot
Copy link
Copy Markdown

Refer to this link for build results (access rights to CI server needed):
https://jenkins1.ugent.be/job/easybuild-easyblocks-pr-builder/982/
Easyblocks unit test suite PASSed (see https://jenkins1.ugent.be/job/easybuild-easyblocks-pr-builder/982/console for more details).

This pull request is now ready for review/testing.

Please try and find someone who can tackle this; contact @boegel if you're not sure what to do.

@boegel
Copy link
Copy Markdown
Member Author

boegel commented May 30, 2015

Worked around possible complications from easy-install.pth by reconstructing only the required parts of the Python search path (i.e. easybuild-framework and vsc-base) into $PYTHONPATH.

Since the easy-install.pth trickery may make it very hard for people not intimately familiar with Python to set up a custom easyblocks repo such that theur easyblocs are preferred over the ones part of the EasyBuild installation, I'll look into adding support for a dedicated configuration option in the EasyBuild framework to specify the location of own easyblocks (and also toolchains, toolchain components and module naming schemes, while I'm at it). Cfr. easybuilders/easybuild-framework#1010.

@JensTimmerman
Copy link
Copy Markdown

You've only fixed this in the tests, so, in real world situations this issue will still pop up?

@boegel
Copy link
Copy Markdown
Member Author

boegel commented Jun 1, 2015

In real world situations, we need something like eb --my-easyblocks=/foo/*.py, which just injects a location for a custom easyblocks repo straight into sys.path. We can also take care of the magic that needs to be included in easybuild/easyblocks/__init__.py, in that case.

Setting this up via $PYTHONPATH is clearly not going to work out in practice, there are too many possible complications.

The changes here are orthogonal to that though, and are still required to make things work as expected.

@JensTimmerman
Copy link
Copy Markdown

So the first 'untweaked' testcase is also broken in master?

@boegel
Copy link
Copy Markdown
Member Author

boegel commented Jun 1, 2015

@JensTimmerman: not sure what you mean here... If you use $PYTHONPATH now to make eb consider extra easyblocks, it'll work, the trouble with easy-install.pth is only relevant w.r.t. giving own easyblocks priority over existing ones (which doesn't work with current master due to the way we flatten the easyblocks namespace in __init__.py).

@JensTimmerman
Copy link
Copy Markdown

My question is: if you take the unittest before you tweaked it to actually work with a workaround, does that also fail on the current master branch of easybuild?
Just making sure you're not breaking anything that used to work.

@boegel
Copy link
Copy Markdown
Member Author

boegel commented Jun 1, 2015

The unit test tests whether custom easyblocks can overrule an existing easyblock, so yes, it would fail on master. Making that possible is exactly the point of this PR.

@boegel
Copy link
Copy Markdown
Member Author

boegel commented Jun 1, 2015

BTW, the workaround for the failing test is in the test itself (I basically avoid running into an easy-install.pth for the easybuild.framework and vsc namespaces by composing $PYTHONPATH myself.

@JensTimmerman
Copy link
Copy Markdown

Can you then please add a test that also tests the current behaviour? Where you can just add an easyblock to the path, and see that it's picked up?

@boegel
Copy link
Copy Markdown
Member Author

boegel commented Jun 1, 2015

@JensTimmerman
Copy link
Copy Markdown

I guess it's fine then

@boegel
Copy link
Copy Markdown
Member Author

boegel commented Jun 22, 2015

documentation will be updated along with easybuilders/easybuild-framework#1301

Thanks for the review @JensTimmerman!

boegel added a commit that referenced this pull request Jun 22, 2015
…s_repo

tweak easybuild.easyblocks package declaration to better support custom easyblocks repo
@boegel boegel merged commit 737ea25 into easybuilders:develop Jun 22, 2015
@boegel boegel deleted the properly_support_custom_easyblocks_repo branch June 22, 2015 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants