Hacker News new | ask | show | jobs
by JulianWasTaken 3745 days ago
This is a nice idea in theory, but setup.py and requirements.txt are not the same, and you cannot particularly generate one from the other:

https://caremad.io/2013/07/setup-vs-requirement/

Also, unfortunately pip's parser for requirements.txt isn't public, like much of its internals at the moment, which means AIUI it's likely that the parsing code here is going to be brittle if it uses it, or miss edge cases if it doesn't. (I haven't read this carefully yet though).

2 comments

As somebody who deploys a lot of business-critical Python apps at $EMPLOYER, I don't even write a requirements.txt.

During development and integration testing, I want to get the latest version of my dependencies that I should be compatible with, so I use SemVer matching (somepackage~=1.2.3) in setup.py.

For deployment, I want to use the exact dependency packages that the code was tested against. So after automated testing is complete, it runs "pip wheel" to build wheels of my package and all its dependencies and put them into a directory, then that is the artefact I use to recreate the package in production. Much more reliable than requirement.txt, since it doesn't assume that PyPI or internet access is available, and it doesn't care if upstream authors silently update packages without changing the version number.

The last scenario is unit-testing, because sometimes tests have extra dependencies the rest of the code doesn't share, like a mock library or other test helper. In theory, these extra things could be put in setup.py's "tests_require" option, but then they'd only be installed if you run tests with "python setup.py test", and they'd also be installed with "easy_install", which is terrible. I'm thinking maybe I should use setuptools' "feature" syntax, so you only get the test dependencies if you install with the [test] feature.

Another way to do this, that you or someone may be interested in, is by using pip-tools.

You write a requirements.in text file where you list libraries by just their name, and then run "pip-compile requirements.in" and it will output a requirements.txt.

It also has a function called "pip-sync" which will then install/update everything in the requirements.txt file.

https://github.com/nvie/pip-tools

ds' article has been referenced many times and I have had multiple discussions on #python myself and trust me, no one agree on a single approach.

> Also, unfortunately pip's parser for requirements.txt isn't public

I am not sure what you mean by "isn't public." The API is "private" or the parser is proprietary? or the API is not isolated to its own (like Ansible's command line parser is stuck inside a giant function). If the second I would be super surprise.

But I am with the repo author. I think we just need one format, one way to do things. The implementation however, needs to be discussed as the example code is pretty redundant in the effort, would be much nicer if we can just provide the path in setup.py and pip reads off setup.py and consume requirements.txt. For god sake this is dependency declaration, ain't package management.

pip is not meant to be used as an API, and there is no backward compatibility guarantee, AFAIK.

There is an ongoing effort to extract all its logic into separated packages [1], thought.

[1] https://github.com/pypa/packaging