Skip to content
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 support for environment markers in requirements lines for pip-sync #206

Closed
shimon opened this issue Sep 23, 2015 · 26 comments
Closed

add support for environment markers in requirements lines for pip-sync #206

shimon opened this issue Sep 23, 2015 · 26 comments
Labels
PR wanted Feature is discussed or bug is confirmed, PR needed

Comments

@shimon
Copy link

shimon commented Sep 23, 2015

Environment markers let you specify requirements that are conditional on the environment. They're particularly useful for OS-dependent modules. For instance, if I'm working on a django app from a Linux box, I'd like pyinotify installed. But my colleague who uses a mac won't be able to install it - the install will fail.

Pip handles these in its requirements specifiers as such:

SomeProject ==5.4 ; python_version < '2.7'
SomeProject; sys.platform == 'win32'

Unfortunately, this doesn't seem to be supported by pip-tools yet. If I put an environment marker into my requirements.in, that is stripped from the generated requirements.txt. I'm not sure if pip-sync respects an environment marker in an incoming requirement specifier, but it ought to also.

@ssbarnea
Copy link
Member

This missing feature makes the entire pip-tools kinda useless for me. pynotify is clearly a good example of library that is needed on specific platforms.

@shimon
Copy link
Author

shimon commented Feb 29, 2016

FWIW, we've worked around this gap by having a separate dev-linux-requirements.in file, and handling different bundles of requirements with make. It would still be nice to have this case handled by pip-tools, though (simply passing through to the generated requirements.txt file).

@jbg
Copy link

jbg commented Mar 15, 2016

FWIW, I’ve just observed that pip-sync ignores the environment markers in requirements.txt and tries to install packages that are marked for a different environment.

@tysonclugg
Copy link
Contributor

tysonclugg commented Jun 23, 2016

Bonus points for allowing pip-compile --environment '{"python_version": "2.7", "sys.platform": "darwin"}' --output-file requirements-2.7-darwin.txt requirements.in as a kind of "cross-compilation" support. But seriously, don't let this request get in the way of getting something good in now - perfect comes later.

@merwok
Copy link

merwok commented Jan 23, 2017

I checked today if pip-compile supported environment markers; the desired behaviour for me would be to get pinned versions with the environment markers copied in the output file. That way, I can still have just one requirement file, but cpython vs pypy could install the appropriate database driver (for CI tests).

That said, for now I have different files for local dev, testing, CI tools, and deployment, but I haven’t had a need yet for requirements specific to one of the deployment environments (e.g. debug tools on dev vs monitoring tools on staging and prod), so maybe later I’ll go down the road of splitting requirements more and handling the complexity in my pip-sync commands.

@barrywhart
Copy link
Contributor

Related need: Support environment markers for indirect dependencies.

Example: I have an application that uses jsonschema. In Python 2.7, jsonschema requires functools32. In Python 3.3, it does not.

In my requirements.in file, I'd like a way to specify an environment marker for functools32 without implying that this is an application dependency.

Proposed syntax -- leading question mark for modifying indirect dependencies:

? functools32; python_version=='2.7'

@barrywhart
Copy link
Contributor

Observation: pip-compile uses pip.req.parse_requirements to parse the requirements.in file, which does parse the environment markers, e.g.

> /home/vagrant/.pyenv/versions/2.7.10/envs/venv-2.7.10/lib/python2.7/site-packages/piptools/scripts/compile.py(183)cli()
(Pdb) constraints[6].markers
<Marker('python_version == "2.7"')>

This seems like good news because it's already doing part of what we want. I'll see if I can figure out a way to include these markers in the output requirements.txt file.

@adamchainz
Copy link
Contributor

@barrywhart your feature is quite different to the original issue of outputting the markers. I think you should make a new issue for it and avoid spamming everyone here subscribed to the original issue.

@davidovich davidovich added the PR wanted Feature is discussed or bug is confirmed, PR needed label Feb 28, 2017
@barrywhart
Copy link
Contributor

Good point. BTW, I am creating a PR for the original issue (not including my addition).

@barrywhart
Copy link
Contributor

The PR is up now. The existing and new tests are passing for me locally, but the Travis build is failing. For some reason, I am unable to view the Travis build log. Would appreciate any help getting unstuck here.

@adamchainz
Copy link
Contributor

PR: #459

@barrywhart
Copy link
Contributor

PR is passing Jenkins now.

@barrywhart
Copy link
Contributor

Replaced PR #459 with equivalent, squashed PR #460

barrywhart added a commit to barrywhart/pip-tools that referenced this issue Mar 2, 2017
barrywhart added a commit to barrywhart/pip-tools that referenced this issue Mar 22, 2017
davidovich added a commit that referenced this issue Mar 30, 2017
#206: Preserve environment markers from requirements.in
@davidovich
Copy link
Contributor

closed by #460

@nirvana-msu
Copy link

I may be missing something obvious, but it's still not working for me. I have this following line in compiled requirements.txt:

hashpumpy==1.2; sys_platform=="linux"

This line comes from the same line in requirements.in (environment marker is simply copied).

If I try to run pip install -r requirements.txt on Windows, it correctly ignores the package. However if I try to run pip-sync requirements.txt, it tries to install the package (which fails because these binaries are not meant to be compiled under windows - only on linux).

@vphilippon
Copy link
Member

vphilippon commented Oct 6, 2017

You're right: pip-sync doesn't respect environment markers.

@vphilippon vphilippon reopened this Oct 6, 2017
@barrywhart
Copy link
Contributor

This ticket should be updated. It says that "pip-tools" does not support environment markers. Now that pip-compile supports them, the ticket only applies to pip-sync. Halfway there!

@vphilippon vphilippon changed the title add support for environment markers in requirements lines add support for environment markers in requirements lines for pip-sync Oct 10, 2017
@vphilippon
Copy link
Member

Fixed by #600

@lbolla
Copy link

lbolla commented Nov 26, 2018

Is this supposed to work if, instead of requirements.in I use setup.py to declare dependencies?
Because, it does not seem to work for me using setup.py.

@barrywhart
Copy link
Contributor

Are you asking about the pip-compile tool in general, or environment markers specifically? If the first, then the answer is no. The tool takes a requirement.in file as input. You may find it useful to create a one-line requirements.in file, listing the name of your library, then run that through pip-compile.

In general, I would say pip-compile, requirements.in, and requirements.txt are intended for use by Python applications, and setup.py is intended for use by Python libraries. This is not a hard rule, but there are some occasional quirks if you use them in a way they were not intended.

@lbolla
Copy link

lbolla commented Nov 26, 2018

I meant in general. My use case is that my application currently uses requirements.in to declare dependencies: all used to be good, but now we are trying to pull the app to do some integration tests and doing pip install my-app is not enough, because dependencies are not declared in setup.py.

I guess these kind of use-cases will become less frequent, with Docker and docker-compose kind of workflows.

@barrywhart
Copy link
Contributor

Yeah, we've gone through something similar. I created setup.py for our apps, and now wish I hadn't. Could you leave setup.py as it is, then create a requirements.in/requirements.txt with your dependencies, then do pip install -r requirements.txt instead? I think that's the ideal workflow for most applications.

@merwok
Copy link

merwok commented Nov 26, 2018

pip-compile does support transforming setup.py to requirements.txt, and setup.py supports environment markers:

install_requires = [
    "requests",
    "importlib; python_version == '2.6',
]

but I do not know if pip-compile setup.py will preserve the markers.

@lbolla
Copy link

lbolla commented Nov 26, 2018

@merwok it does not, from my experience.
@barrywhart the problem with that approach is that setup.py and requirements.in end up declaring the same dependencies, duplicating effort. I guess I would workaround by parsing requirements.in to figure out what dependencies to declare in setup.py, but it feels backwards to me.

@barrywhart
Copy link
Contributor

If I have a requirements.in, I would try and avoid putting requirements in setup.py. It's not "wrong" or anything, but as you say, it seems backwards and may not be buying you much. AFAIK, requirements in setup.py don't buy you much unless it's a library where applications that use it need to know what to install.

@AndydeCleyre
Copy link
Contributor

This still does not work for pip-sync from 4.1.0, as far as I can tell. Here's an example dev-requirements.txt from the plumbum project:

pytest
pytest-cov
pytest-mock
idna<2.8 ; python_version < '2.7'
pycparser<2.18 ; python_version < '2.7'
paramiko<2.4 ; python_version < '2.7'
paramiko ; python_version >= '2.7'
setuptools
wheel ; python_version >= '2.7'
psutil
pip-sync dev-requirements.txt

Identical output whether in a Python 3.7.4 or 2.7.16 env:

Incompatible requirements found: paramiko (from -r dev-requirements.txt (line 7)) and paramiko<2.4 (from -r dev-requirements.txt (line 6))

No packages end up installed aside from pip-tools and its deps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR wanted Feature is discussed or bug is confirmed, PR needed
Projects
None yet
Development

No branches or pull requests