How to use environment markers correctly to install conditional dependencies #1
Comments
I am having a problem regarding environment markers, Note that the syntax for the environment marker is correct and travis is running |
I tried downloading the PIDStore wheel package and look at the package info at it actually looks correct (environment marker is still there): ...
{
"environment": "python_version<\"3.4\"",
"requires": ["enum34 (>=1.0.4)"]
},
... I think the problem might be related with the |
Yep, just verified: (pidstore3) lnielsen-mbp:Downloads lnielsen$ pip install invenio-pidstore --pre
...
Successfully installed Babel-2.3.4 Flask-0.12 Flask-BabelEx-0.9.3 Jinja2-2.9.5 MarkupSafe-1.0 Werkzeug-0.12 click-6.7 invenio-pidstore-1.0.0b1 itsdangerous-0.24 pytz-2016.10 speaklater-1.3 No (pidstore3) lnielsen-mbp:Downloads lnielsen$ pip install invenio-pidstore[all] --pre
...
Collecting enum34>=1.0.4; extra == "all" (from invenio-pidstore[all])
Downloading enum34-1.1.6-py3-none-any.whl
.... So the problem is with these lines in extras_require['all'] = []
for name, reqs in extras_require.items():
if name in ('mysql', 'postgresql', 'sqlite'):
continue
extras_require['all'].extend(reqs) Not sure what a nice solution to this is. The quick fix for PIDStore is to change it into something like: extras_require['all'] = []
for name, reqs in extras_require.items():
if name in ('mysql', 'postgresql', 'sqlite') or name.startswith(':'):
continue
extras_require['all'].extend(reqs) But it won't work generically as you can also have something like this: extra_require = {
'test:python_version<"3.4"' : [
# ...
]
} |
Note that this is true for setuptools < 36.2.1; since then the marker is preserved correctly. However old versions of setuptools only support conditional dependencies in See HypothesisWorks/hypothesis#1091 for discussion. |
Hmm, I don't get it. What do you mean by this line:
Strip it off where & when? I have a library where I use what is described above as the "bad example", it has a dependency on
Here is the relevant line in setup.py. That generates correct line in pkg info like this, with environment marker intact:
And the wheel on PyPI has the correct metadata, the condition is even listed right there in the HTML on the landing page (ctrl+f for "Requires Distributions"). The above was .dist-info but I checked and
So, why exactly is bad example bad? Please help me understand.. |
"Bad example" is only bad if your packaging toolchain (pip, setuptools and wheel) are out of date. Your tools are up-to-date, and so it works! Unfortunately, your users might not be so diligent... |
But users install the .whl, they don't build .whl. And if you want to protect against out of date tools in executing It sounds like you trying to say there a version of pip/setuptools which will correctly read the conditional deps from an existing wheel if it was written like the "GOOD example" and it will incorrectly install the conditional deps when it was written like the "BAD example", correct me if that's wrong. It's written "wheel package will simply strip off the environment marker", but I don't see that, is there an old version of wheel where that happened? If so, could it be mentioned in the original post the version specifier where wheel has such a problem? |
@wimglenn This post stems from tons of failed Travis builds that we traced back to Wheel stripping of the environment marker when written as in the bad example above. At the time of the post (i.e March last year), I can confirm that wheel definitely was stripping off the environment marker when you built the package back. Unfortunately, I can tell you which version of Wheel it was except that it was the most recent version at the time of writing (March 2017). If Wheel has been fixed in the meantime, then that's just great and we might start using the bad example again - however that just wasn't the case in March 2017, hence this post to share the experience with our fellow Invenio developers. |
I am having issue while putting conditional dependency for importlib. I have below snippet in my setup.py |
Problem
You have a module which is only required on Python 2 and not on Python 3. Example functools32 is only needed on Python 2.
Solution
$ pip install pip setuptools wheel --upgrade
extras_require
insetup.py
:Why should I not use the method from the bad example?
The bad example is a valid method for specifying environment marker according to PEP508, so why not use it?
When you build a wheel using
python setup.py bdist_wheel
then wheel package will simply strip off the environment marker. Then, when you try to install the just built wheel package using pip or setuptools, the environment marker is not available, and pip/setuptools will consequently try to installfunctools32
on Python 3.The text was updated successfully, but these errors were encountered: