UPDATE: 5 mar 2019: Since pip version 19.03 you can omit setup.py for your packages and use pyproject.toml
and [build-system]
(not supporting installation in the editable mode (in this case you still need setup.py)
UPDATE: 12 jun 2018: One more similar tool https://github.com/takluyver/flit . There is a big future behind poetry
and flit
. Hope they will merge forces and we'll have all-in-one comfortable packages and app management, like, rust cargo
for example
UPDATE: 19 Apr 2018: There is a similar tool, which may handle all packaging management at once, without the need of setup.py. This is https://github.com/sdispater/poetry
UPDATE: 11 Apr 2018:
The author of Pipenv describes the problem here: http://pipenv.readthedocs.io/en/latest/advanced/#pipfile-vs-setup-py
If you run pipenv install -e .
in a package which has no setup.py, then you'll get:
$ pipenv install -e .
Directory '.' is not installable. File 'setup.py' not found.
So you need setup.py
anyway for such case.
It is important to understand the concept behind applications and packages. This information could be useful https://caremad.io/posts/2013/07/setup-vs-requirement/
If you're building an application, then pipenv
is the only thing you need.
However, if you're building a package, then you have to have setup.py
anyway, in order to allow pip or pipenv install of it (maybe in the editable mode as well).
The answer by the author of the pipenv
is here: https://github.com/pypa/pipenv/issues/1161#issuecomment-349972287
Thus, pipenv vs setup.py
is a wrong formulation. They can't be against each other. Rather support each other, or exclude each other.
We may have to find a way how to use them both, without duplicating things.
When you're building a package, you may still use pipenv, but this leads to duplicate things (requiremets in setup.py and Pipfile). I am using the following approach to address this:
import pathlib
import subprocess
from setuptools import setup, find_packages
from setuptools.command.install import install
from setuptools.command.develop import develop
__requires__ = ['pipenv']
packages = find_packages(exclude=['tests'])
base_dir = pathlib.Path(__file__).parent
pipenv_command = ['pipenv', 'install', '--deploy', '--system']
pipenv_command_dev = ['pipenv', 'install', '--dev', '--deploy', '--system']
class PostDevelopCommand(develop):
"""Post-installation for development mode."""
def run(self):
subprocess.check_call(pipenv_command_dev)
develop.run(self)
class PostInstallCommand(install):
"""Post-installation for installation mode."""
def run(self):
subprocess.check_call(pipenv_command)
install.run(self)
with open(base_dir / 'README.md', encoding='utf-8') as f:
long_description = f.read()
setup(
name='dll_api',
use_scm_version = True,
long_description='\n' + long_description,
packages=packages,
setup_requires=['setuptools_scm'],
cmdclass={
'develop': PostDevelopCommand,
'install': PostInstallCommand,
},
)
Now you have the following:
$ python setup.py install
running install
Installing dependencies from Pipfile.lock (e05404)…
Note pipenv
should be installed before!
This is not a clean way to solve the problem, however, do the job.