4

As the title states -- can I use setup.py with pipenv with pyenv to manage my environments, versions, and dependencies?

I have a python package in the form of a directory structure with a setup.py file.

I love using pipenv as my project environment manager -- I use pyenv for managing my multiple python version.

So what I'm trying to do is:

  1. Use pyenv to get a project specifc python version: pyenv version 3.8.5
  2. run the setupfile using python setup.py install -- say this package is called foobar -- this installs the package in ~/.pyenv/versions/3.8.5/lib/python3.8/foobar (the real name is not foobar -- just using that here to illustrate the point)
  3. Now when I go to my_project and run pipenv install foobar -- I get the following:
pipenv install foobar
Installing foobar…
Error:  An error occurred while installing foobar!
Error text:
ERROR: Could not find a version that satisfies the requirement foobar (from -r /var/folders/2d/f68m9g153v9cywvjn16hs6nc0000gn/T/pipenv-4uv_ikyt-requirements/pipenv-asuqkc7y-requirement.txt (line 1)) (from versions: none)
ERROR: No matching distribution found for foobar (from -r /var/folders/2d/f68m9g153v9cywvjn16hs6nc0000gn/T/pipenv-4uv_ikyt-requirements/pipenv-asuqkc7y-requirement.txt (line 1))

✘ Installation Failed 

At a loss.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
user1172468
  • 5,306
  • 6
  • 35
  • 62

1 Answers1

9

I don't use pyenv but the principle is the same: you have a locally installable package (using setup.py), and Pipenv does support those with its install command, and it calls them editable dependencies.

You can tell Pipenv to install a path as editable — often this is useful for the current working directory when working on packages:

$ pipenv install --dev -e .  
  
$ cat Pipfile  
...  
[dev-packages]  
"e1839a8" = {path = ".", editable = true}
...  

Let's take your foobar from a libraries folder:

libraries$ tree
.
├── foobar
│   └── __init__.py
└── setup.py

To install that to some other virtual environment with pipenv:

myapp$ pipenv install -e /path/to/libraries
...
Installing -e /path/to/libraries...
Adding foobar to Pipfile's [packages]...
✔ Installation Succeeded 
myapp$ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
foobar = {editable = true, path = "/path/to/libraries"}

[dev-packages]

[requires]
python_version = "3.9"
myapp$ pipenv shell
(myapp) myapp$ python
>>> import foobar
>>> foobar.add(1,2)
3

Notice that you don't need the step of installing your package with python setup.py install or pip install .. The nice thing here is if you now edit foobar codes, it gets reflected in that other environment without needing for repeated pipenv install.

Installing it to lib/python3.8/site-packages (or wherever pyenv installs packages) by running

python setup.py install

will not work, because that's not the correct flow. You prepare your foobar for distribution, and then install it from a distribution, not from site-packages, which is already the installed version (does not have setup.py). You could probably work it around by copying the entire foobar package to your pyenv's site-packages folder (including setup.py), then tell pipenv to install it from there.... but that's just not the correct flow.

An alternative to pipenv install -e, if you want to test your actual source distribution, is to actually build your source distribution of foobar, then pipenv install from that.

libraries$ python3.8 setup.py sdist
...
Creating tar archive
...

libraries$ tree
.
...
├── dist
│   ├── foobar-0.1.0-py3.8.egg
│   └── foobar-0.1.0.tar.gz
├── foobar
│   └── __init__.py
├── ...
└── setup.py
(myapp) myapp$ pipenv install /path/to/libraries/dist/foobar-0.1.0.tar.gz
Installing /path/to/libraries/dist/foobar-0.1.0.tar.gz...
(myapp) myapp$ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
foobar = {path = "/path/to/libraries/dist/foobar-0.1.0.tar.gz"}

[dev-packages]

[requires]
python_version = "3.9"

But installing from sdist loses the convenience of quickly seeing the updates to foobar when you use it on your other apps. I don't know what your workflow is, but I prefer having a common directory (libraries) instead where I store all locally-editable packages, then pipenv install-ing from there.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135