Python setuptools symbolic links and custom installation extensions … here is a solution to the problem.
Python setuptools symbolic links and custom installation extensions
I want to implement the following two items for a Python package with setup.py and using setuptools:
- Allows installation of packages using symbolic links instead of copying
file - Allows custom code to run when used with “install”
Set the .py
First of all, I usually do pip like this:
pip install -e . --user
And it works well.
For the second one, I do in setup.py:
from __future__ import print_function
from setuptools import setup
from setuptools.command.install import install
import os
class CustomInstallCommand(install):
def run(self):
print ("Custom code here")
install.run(self)
setup(...,
packages=['package_name'],
package_dir={'package_name':'package_name'},
cmdclass={'install': CustomInstallCommand},
zip_safe=False)
However, I found:
- If I run pip like above, the custom code is never called
If I do this, the custom code runs:
python setup.py install –user
But I’m not sure how to use this command with the equivalent -e
option so that symbolic links are installed instead of a copy of the file. How can I achieve both?
Solution
That’s because install
won’t be called. There are two modes available:
- The “real” installation mode is called by
python setup.py install
and the source code will be copied - The “development” mode is called via
python setup.py develop
and only creates a symbolic link to the source.
So you have to override the develop
command as if you were already using install
:
from setuptools.command.develop import develop
...
class CustomDevInstallCommand(develop):
def run(self):
print('running custom develop command')
super(CustomDevInstallCommand, self).run()
setup(
...,
cmdclass={
'install': CustomInstallCommand,
'develop': CustomDevInstallCommand,
},
)
Generated by pip install --editable
$ pip install --editable . -v
Created temporary directory: /private/var/folders/_y/2qk6029j4c7bwv0ddk3p96r00000gn/T/pip-ephem-wheel-cache-1yw7baz2
...
Installing collected packages: spam
Running setup.py develop for spam
Running command python -c "import setuptools"
Running command /Users/hoefling/.virtualenvs/stackoverflow/bin/python -c "import setuptools, tokenize; __file__='/Users/hoefling/projects/private/stackoverflow/so-49326214/setup.py'; f=getattr(tokenize, 'open', open)(__file__); code=f.read().replace('\r\n', '\n'); f.close(); exec(compile(code, __file__, 'exec'))" develop --no-deps
running develop
<b>running custom develop command</b>
running egg_info
...
Successfully installed spam
Cleaning up...