Python setuptools symbolic links and custom installation extensions

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:

  1. Allows installation of packages using symbolic links instead of copying
    file
  2. 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:

  1. If I run pip like above, the custom code is never called
  2. 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...

Related Problems and Solutions