如何让setuptools的sdist仅生成未压缩的源分发文件夹?
Great question! Let's break this down clearly.
First, the short answer: There’s no built-in option in setuptools/distutils’ sdist command to directly output an uncompressed source folder instead of a compressed archive (like .tar.gz or .zip). The sdist tool is explicitly designed to create packaged archives for distribution, which is why you won’t find this functionality in official docs or the setuptools source code.
That said, there are practical workarounds to get the uncompressed source structure without manually unzipping every time:
1. Retain the temporary build directory with --keep-temp
When you run python setup.py sdist, the command first assembles all your source files into a temporary directory before compressing it into an archive. By default, this temp folder gets deleted after the archive is created—but you can keep it with the --keep-temp flag:
python setup.py sdist --keep-temp
The uncompressed source structure will live in a subfolder under build/ (usually something like build/sdist/your-package-0.1.0/), which you can copy or use directly.
2. Manually uncompress the generated archive
This is the most straightforward method for one-off needs. After generating the archive with:
python setup.py sdist
Use standard tools to extract it:
- For
.tar.gzarchives:tar xzf dist/your-package-0.1.0.tar.gz - For
.ziparchives:unzip dist/your-package-0.1.0.zip
3. Create a custom command for automation
If you need this functionality regularly, you can define a custom command that extends sdist but skips the archiving step. Add this to your setup.py:
from setuptools import setup from distutils.command.sdist import sdist as _sdist import shutil import os class uncompressed_sdist(_sdist): def run(self): # Let sdist assemble all the source files first super().run() # Copy the temp source folder to a permanent location source_folder = os.path.basename(self.archive_files[0]).replace('.tar.gz', '').replace('.zip', '') temp_source_path = os.path.join(self.dist_dir, source_folder) target_path = os.path.join(os.getcwd(), 'uncompressed_dist') if os.path.exists(target_path): shutil.rmtree(target_path) shutil.copytree(temp_source_path, target_path) print(f"Uncompressed source dist created at: {target_path}") setup( name="your-package", version="0.1.0", packages=["your_package"], cmdclass={'uncompressed_sdist': uncompressed_sdist}, )
Run it with:
python setup.py uncompressed_sdist
This will generate an uncompressed_dist/ folder with your source files alongside the standard compressed archive.
In summary, while there’s no direct native way to output an uncompressed folder via sdist, these workarounds cover most use cases. The --keep-temp flag is perfect for one-off needs, while a custom command works best for repeated automation.
内容的提问来源于stack exchange,提问作者John Go-Soco

