Check Manifest
check-manifest is a command-line tool designed to verify the completeness of the `MANIFEST.in` file in Python source packages, helping developers avoid accidentally omitting files from source distributions. It does this by comparing files under version control with those included in a generated source distribution. The current version is 0.51, and the project maintains an active release cadence, often aligning updates with new Python version support and essential bug fixes.
Warnings
- breaking check-manifest version 0.51 dropped support for Python 3.7. Earlier versions (e.g., 0.45) also dropped Python 3.5 support. Ensure your development environment uses Python 3.8 or newer for compatibility.
- gotcha Users have reported significant performance degradation, particularly starting from version 0.41 and continuing in later releases. This can lead to slower CI/CD pipelines or local checks, especially in larger projects.
- gotcha check-manifest relies on the state of your Version Control System (VCS), like Git. Uncommitted changes, particularly deleted files, can cause `check-manifest` to report them as 'missing from sdist' until these changes are committed to your VCS.
Install
-
pip install check-manifest
Quickstart
import subprocess
import os
import shutil
# Create a dummy project structure for demonstration
project_dir = "my_package_to_check"
os.makedirs(f"{project_dir}/my_package", exist_ok=True)
with open(f"{project_dir}/setup.py", "w") as f:
f.write("from setuptools import setup\nsetup(name='my_package', version='0.1.0')\n")
with open(f"{project_dir}/my_package/__init__.py", "w") as f:
f.write("import os\n
__version__ = '0.1.0'\n")
with open(f"{project_dir}/README.md", "w") as f:
f.write("# My Package")
print(f"Created dummy project in {project_dir}/")
# Simulate initial git init and add/commit for check-manifest to work
# check-manifest needs a VCS to compare against.
subprocess.run(["git", "init", "-b", "main"], cwd=project_dir, capture_output=True, text=True)
subprocess.run(["git", "add", "."], cwd=project_dir, capture_output=True, text=True)
subprocess.run(["git", "commit", "-m", "Initial commit"], cwd=project_dir, capture_output=True, text=True)
print("\n--- Running check-manifest (expecting no MANIFEST.in, so it will suggest one) ---")
# Run check-manifest without updating initially
result = subprocess.run(
["check-manifest"],
cwd=project_dir,
capture_output=True,
text=True,
check=False
)
print(result.stdout)
print(result.stderr)
if result.returncode != 0:
print("check-manifest detected issues (as expected without MANIFEST.in).")
print("\n--- Running check-manifest with -u to update MANIFEST.in ---")
result_update = subprocess.run(
["check-manifest", "-u"],
cwd=project_dir,
capture_output=True,
text=True,
check=False
)
print(result_update.stdout)
print(result_update.stderr)
if result_update.returncode == 0:
print("check-manifest -u successfully created/updated MANIFEST.in.")
with open(f"{project_dir}/MANIFEST.in", "r") as f:
print("\n--- Generated MANIFEST.in content ---")
print(f.read())
else:
print("check-manifest -u failed.")
# Cleanup
shutil.rmtree(project_dir)
print(f"\nCleaned up dummy project directory: {project_dir}")