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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With