Search code examples
pipsetuptoolssetup.pypython-packagingpython-wheel

Prevent pip from caching a package


Is there a way to tell pip never to create a wheel cache of my package?

Background

I wrote a package for in-house use that sets up some symbolic links when installed using cmdclass in the setup.py. These post-install and post-develop triggers run fine if I install the sdist, but if I compile the package to a wheel, they do not run. To counter this, I make sure to only upload the sdist to our internal PyPI.

Problem

According to the documentation, when pip installs from an sdist it compiles it to a wheel and caches it for next time. This means that the package installs right the first time, but subsequent installs are broken.

I know I could run pip with --no-cache-dir, but I want to be sure everyone on my team can get the package correctly without having to add flags like this. There is no situation where someone would want a wheel of this package.

Question

Is there a setting or config variable I can set in my package to tell pip never to cache it as a wheel?


Solution

  • There is no clean way of doing this that I know of. You can take your chances and play dirty.

    Inspired by this comment, you could try with a setup.py script that looks like this (only partially tested):

    #!/usr/bin/env python3
    
    import setuptools
    
    setuptools.setup(
        name='LookMaNoWheels',
        version='1.2.3',
        cmdclass={'bdist_wheel': None},
    )
    

    The idea is to force a failure when trying to build a wheel. When this happens, tools such as pip tend to recover from this by installing directly from whatever distribution is available instead (in your case a sdist).


    Update

    Something like this would help provide a more informative error message:

    #!/usr/bin/env python3
    
    import distutils.errors
    import setuptools
    
    bdist_wheel = None
    
    try:
        import wheel.bdist_wheel
        class bdist_wheel(wheel.bdist_wheel.bdist_wheel):
            def run(self, *args, **kwargs):
                raise distutils.errors.DistutilsClassError("No!")
    except ModuleNotFoundError:
        pass
    
    setuptools.setup(
        name='LookMaNoWheels',
        version='1.2.3',
        cmdclass={'bdist_wheel': bdist_wheel},
    )