Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove build products

Is it possible to automatically remove build products that are generated by a setup.py script based on setuptools?

I've just started with a new Python project and it's the first time I'm using setuptools as a developer, so I may be getting something wrong. when I build the project using python setup.py bdist, three directories, build, dist and one ending in .egg-info are created. When I then run python setup.py clean it doesn't seem to be doing anything and just prints this:

running clean

I've tried adding --all to the clean command and while it does remove some files in the build directory, it doesn't remove the directory itself or any of the files in the other two directories.

I'm assuming that this should be possible very easily and that I'm just looking in the wrong place. I'm used to this functionality e.g. from virtually any project using make where make clean or make distclean will remove any build products.

like image 413
Feuermurmel Avatar asked Feb 01 '15 16:02

Feuermurmel


1 Answers

Standard approach:

distutils.command.clean

From Cleaning build directory in setup.py and the documentation:

This command removes the temporary files created by build and its subcommands, like intermediary compiled object files. With the --all option, the complete build directory will be removed.


Another way to do it:

This may not be the best solution:

It seems from the comment below this answer that python setup.py clean --all sometimes fails to remove everything (Numpy in the example in the comment).

It seems not all setup.py scripts support clean. Example: NumPy – kevinarpe Jun 15 '16 at 7:14


You could use the remove_tree() command in your setup script:

import glob
remove_tree(['dist', glob.glob('*.egg-info')[0],glob.glob('build/bdist.*')[0]]) 

Or in a setup script:

from setuptools import setup
from setuptools.command import install 

class PostInstallCommand(install):

    def run(self):
        import glob
        from distutils.dir_util import remove_tree
        remove_tree(['dist', glob.glob('*.egg-info')[0],glob.glob('build/bdist.*')[0]]) 


setup(name='Some Name',
      version='1.0',
      description='A cross platform library',
      author='Simon',
      platforms = ["windows", "mac", "linux"],
      py_modules = ['UsefulStuff', '__init__'],
      cmdclass = {'install':PostInstallCommand}
     )

Another way I solved it was to remove everything manually manually (using shutil and glob):

import shutil, glob
shutil.rmtree('dist')
shutil.rmtree(glob.glob('*.egg-info')[0])
shutil.rmtree(glob.glob('build/bdist.*')[0])

Adding it to the setup script was harder but using this answer, it should look something like this:

from setuptools import setup
from setuptools.command import install 

class PostInstallCommand(install):

    def run(self):
        import shutil, glob
        shutil.rmtree('dist')
        shutil.rmtree(glob.glob('*.egg-info')[0])
        shutil.rmtree(glob.glob('build/bdist.*')[0])
        install.run(self)



setup(name='Some Name',
      version='1.0',
      description='A cross platform library',
      author='Simon',
      platforms = ["windows", "mac", "linux"],
      py_modules = ['UsefulStuff', '__init__'],
      cmdclass = {'install':PostInstallCommand}
     )

cmdclass = {'install'} allows this class to run after the installation. See this answer for more details.

What gave me the idea to use shutil?

The idea to use shutil came from the old documentation:

Some of this could be replaced with the shutil module?

like image 121
Xantium Avatar answered Oct 17 '22 12:10

Xantium