Hacker News new | ask | show | jobs
by abhishekjha 2891 days ago
What's wrong with pipenv? I am genuinely curious.

On local :

    mkdir my_project_directory
    cd my_project_directory
    export PIPENV_VENV_IN_PROJECT=1 (To make the virtual environment folder determininstic(.venv/) otherwise you will get a hash based directory(my_project_directory-some-hash-value) which might not be suitable for automatic deployments in applications like docker. I don't know why this is not default.)
    pipenv --python 3.6 (or any particular version number)
    pipenv install numpy scipy pandas matplotlib requests
    pipenv graph (Gives me a dependency graph)
    git add .
    git commit -a -S -m "init" 
    git push
On remote :

    git clone url/my_project_directory
    cd my_project_directory
    export PIPENV_VENV_IN_PROJECT=1
    pipenv install
    pipenv shell
    pipenv graph

Is this workflow not enough? I have recently started using pipenv after a lot of struggle. The only issue I have is, Pycharm doesn't allow native pipenv initialisation. I always end up creating an environment manually and then importing the project. Pycharm does detect the environment though.
13 comments

A lot of people seem to run into bugs and some hit a brick wall when they report them:

https://www.reddit.com/r/Python/comments/8elkqe/pipenv_a_gui...

Personally I think poetry doesn't get enough visibility. It's not as hyped as pipenv but it feels a bit nicer:

https://poetry.eustace.io/

It really serves a different audience/purpose.

Poetry replaces setup.py which is mostly used for building libraries. You still need to create your own virtualenv.

Pipenv replaces requirements.txt and handles the virtualenv for you. It can’t be used for packaging libs, but it’s primary purpose is to make developing on apps easier.

Lore seems to be much closer to pipenv than poetry.

pyproject.toml and pyproject.lock are analogous to Pipfile and Pipfile.lock

Both attempt to replace requirements.txt, both have dependency resolvers and both are workflow tools.

Yet poetry does not manage the virtualenv for you which is what these other tools do. I think poetry would find a lot more love outside of packaging where people are now using pipenv if it managed the virtualenv too.

The integration pipenv has with pyenv is also very nice.

Many people want less tools, which is the primary reason pipenv took off IMO. Creating and activating virtualenvs? mkvirtualenv? Minor python version changes and the venv is toast? Different ways of structuring requirements files? It’s a mess for juniors especially.

People that are packaging libs probably aren’t having the same difficulty with virtualenvs that junior devs are when starting at a company deving on new code bases, learning new processes and tools. But packaging and releasing python libs is challenging, so tooling to help with that is awesome.

A single tool that can do packaging, dependency management, and venv management would be embraced. If poetry doesn’t add venv management, then pipenv should add packaging management.

>Yet poetry does not manage the virtualenv for you which is what these other tools do.

That's not correct:

https://poetry.eustace.io/docs/basic-usage/#poetry-and-virtu...

>A single tool that can do packaging, dependency management, and venv management would be embraced.

It does all of those.

My apologies! I checked the wrong place in the docs before commenting, you are right.

Can you direct it to use a python other than the one linked to poetry? I don’t have CLI access at the moment.

Poetry looks nice - that dev has authored some other really nice looking libs.

After skimming the docs and tinkering with poetry a bit, I'm not sure what my workflow with it would be for containerized python apps, though - where you generally don't want virtual environments at all. Pipenv handles that case pretty well.

I might reach for it though if I were developing open-source libraries that would be distributed on pypi

You don't need to but there's also no harm in creating a virtualenv in a container.
After having used both, I'm not yet sure which is better of `pipenv` or `pip install --require-hashes` + `python -m venv`. For example, `pipenv sync` doesn't uninstall packages which were previously in the same Pipfile{,.lock}, making the sharing of Pipfile{,.lock} via version control kinda pointless. `PIPENV_VENV_IN_PROJECT` not being the default is also annoying for development.
`pipenv clean` uninstalls all packages not specified in the lock file
Pycharm just released 2018.2 with support for pipenv :) https://www.jetbrains.com/pycharm/whatsnew/#v2018-2-python
So I went ahead and tried it. To not have `export PIPENV_VENV_IN_PROJECT=1` while creating an environment is giving me an environment with the hash value. This is not good. Looks like I am gonna have to keep creating pipenv environments manually and then import projects into pycharm.
There doesn't seem to be really fast way to check if everything is up to date or not:

  $ pipenv install numpy scipy pandas matplotlib requests
  ....
  ....installs everything
  ....
  $ time pipenv sync
  Installing dependencies from Pipfile.lock (3f6ae1)…
        15/15 — 00:00:05
  All dependencies are now up-to-date!

  real	0m7.219s
  user	0m15.645s
  sys	0m1.406s
Why does it take so long just to check a bunch of hashes? Is there a better command?
Last time I tried, it also required that the target Python version be installed somewhere on the path. If pipenv used venv instead of virtualenv, something like pyenv to retrieve/install Python versions, and was distributed as a full executable (rather than requiring a bootstrapped Python) I would actually it.
Install pyenv and add a .python-version file to your project. pipenv will use it the pyenv installed python, and prompt to install it via pyenv if it's missing
pipenv will do automatic python installation if you have pyenv installed [1]. Pyenv isn't bundled in the base install, but I've been using them both and have been happy switching between environments with different Python versions.

[1]: https://docs.pipenv.org/advanced/#automatic-python-installat...

`pipenv install --python ~/.pyenv/versions/3.6.5/bin/python` works for me, and that directory is not on my path. Did you try the more explicit `--python` flag?
It uses virtualenv, rather than venv.

After discovering PYTHONUSERBASE, I no longer need any of the plethora of wrappers around venv/virtualenv.

>After discovering PYTHONUSERBASE, I no longer need any of the plethora of wrappers around venv/virtualenv.

Is there any walkthrough available? Pipenv has one deficiency is that it can be slow at times, particularly when you want to quickly install a dependency and run. Would love to know the alternative.

https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUS...

Set the environment variable to a different directory for each project, and `python3 -m pip install whatever` will go into that directory.

How do you use PYTHONUSERBASE?

    $ export PYTHONUSERBASE=/path/to/project-specific-python-user-base
    $ python3 -m pip install --user whatever
Everything now goes into that directory. Different projects on the same machine have different directories and so can't affect one another.
Up till not long ago pipenv was not ready - for example it could not install packages like gevent. That bug is fixed now I believe.
I think you are supposed to use `pipenv sync` on the remote to get the pinned versions from the lock file
That's honestly my biggest gripe with pipenv: which command is best for a CI run?

My current magic is:

    pipenv sync $(pipenv --venv > /dev/null || echo '--python 3.6') --dev
The reason is that (magically) adding --python 3.6 will always create a new virtual environment, and I'd rather not do that if the cache is up to date, but running sync by itself won't.

And I think I also want to run `install --deploy`, to check if my Pipfile / lock are in sync or broken.

None of them are huge gripes, more the frustration that it almost works out of the box, but it always seems no one writing these tools ever uses them in prod...

I use `pipenv install --deploy --system`. Doesn't create a virtualenv and verifies the lock file.

Of course, I definitely understand where you're coming from. It took quite a while for me to figure that out, because --deploy is not well documented.

I'm not sure I want to use --system in CI, just to avoid differences with development machines if possible. That does simplify baking a Docker image, though.
pipenv has a huge issue that they refuse to fix: no init command. That means you can only run pipenv commands from the root directory of your project. If you accidentally run pipenv install X in a subdirectory, guess what? You just created a new Pipfile and virtualenv!

npm actually got this right, init helps, and it makes sense to traverse up directories to find a package.json.

I agree searching up would be helpful, though, honestly, build tools and other engineers assume you're doing build actions in the project root, and as some of them fail mysteriously if you're not, I often write scripts to fail fast if they're run elsewhere.

Regarding "init", are you complaining that many commands will create a new virtualenv when really only one ought to? Automagically creating the virtualenv definitely seemed cool and modern to me... for about 3 minutes.

They may have changed that behavior recently. I was trying out pipenv last week and running `pipenv run script.py` in a subdirectory printed a message along the lines of "Courtesy notice: no pipfile found in this directory. Using pipfile in [project_root]. Behavior can be customized by specifying a pipfile with [some_flag]". I'm fairly sure, but not positive, that I also was able to install modules from subdirectories into the project venv like you want.

On mobile; I may be misremembering some details. Would encourage you to check new version behavior if you're interested.

Wow thank you so much! It's crazy how much this project is changing[1], especially and more and more users/companies/projects are starting to depend on it.

[1] https://github.com/pypa/pipenv/blob/77110ed5da89823fa5954e47...

As far as I can tell, the main difference is that this also uses pyenv to manage python versions separate from system python packages. There was an article a couple of weeks ago about combining pyenv + pipenv, and this doesn't really seem to add anything over that combination except an opinionated wrapper script.
Pipenv is certainly better than npm. Although, that may be a result of the js ecosystem but still...
Pipenv is probably the best tool to keep clean the dependency workflow
Also, for now, pipenv handles badly custom pipy with authentication