{"library":"setupmeta","title":"Simplify your setup.py","description":"setupmeta is a Python library designed to significantly reduce boilerplate in `setup.py` files by automatically inferring project metadata from common project conventions. It extracts information like long description from `README.rst`/`README.md`, version from `__version__.py` or Git tags, and dependencies from `requirements.txt`. It encourages a DRY (Don't Repeat Yourself) approach to Python packaging. The current version is 3.9.0, and it is actively maintained with a regular release cadence.","language":"python","status":"active","last_verified":"Sat May 16","install":{"commands":["pip install setupmeta"],"cli":null},"imports":["from setuptools import setup"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import os\nimport subprocess\n\n# Create a dummy project structure for demonstration\nproject_name = \"myproject_example\"\n\nos.makedirs(project_name, exist_ok=True)\nwith open(os.path.join(project_name, \"__init__.py\"), \"w\") as f:\n    f.write(\"__version__ = '0.0.1'\\n\")\n    f.write(\"__title__ = 'My Example Project'\\n\")\n\nwith open(os.path.join(project_name, \"../README.rst\"), \"w\") as f:\n    f.write(\"My Example Project\\n\")\n    f.write(\"===================\\n\\n\")\n    f.write(\"A simple project to demonstrate setupmeta.\")\n\nwith open(os.path.join(project_name, \"../requirements.txt\"), \"w\") as f:\n    f.write(\"click\\n\")\n    f.write(\"requests>=2.0.0\\n\")\n\n# Create a minimal setup.py\nsetup_py_content = \"\"\"\nfrom setuptools import setup\n\nsetup(\n    name=\"%s\",\n    versioning=\"distance\",  # Optional: activates tag-based versioning based on git\n    setup_requires=[\"setupmeta\"]  # This tells setuptools to use setupmeta\n)\n\"\"\" % project_name\n\nwith open(os.path.join(project_name, \"../setup.py\"), \"w\") as f:\n    f.write(setup_py_content)\n\nprint(f\"Project '{project_name}' and setup.py created. Now run: \")\nprint(f\"cd {os.path.dirname(os.path.abspath(__file__))}\")\nprint(f\"python setup.py explain # To see what setupmeta deduces\")\nprint(f\"python setup.py sdist bdist_wheel # To build distributions\")\n\n# Example of running the command programmatically (requires project setup from above)\n# try:\n#     # This command needs to be run from the directory containing setup.py\n#     # For this example, assume it's run in the parent directory of 'myproject_example'\n#     original_dir = os.getcwd()\n#     os.chdir(os.path.dirname(os.path.abspath(__file__)))\n#     subprocess.run([\"python\", \"setup.py\", \"explain\"], check=True)\n# finally:\n#     os.chdir(original_dir)\n","lang":"python","description":"setupmeta significantly shortens your `setup.py`. By placing `setup_requires=\"setupmeta\"` in your `setuptools.setup()` call, setupmeta will automatically deduce common project metadata from existing files (like `README.rst`, `__init__.py`, `requirements.txt`). The `python setup.py explain` command is invaluable for seeing exactly what metadata setupmeta has detected from your project's structure and files.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-16","installed_version":"3.9.0","pypi_latest":"3.9.0","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":2,"avg_import_s":0.66,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.78,"mem_mb":15.7,"disk_size":"19.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.8,"import_time_s":0.56,"mem_mb":15.7,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":1,"mem_mb":17.2,"disk_size":"21.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.8,"import_time_s":0.87,"mem_mb":17.2,"disk_size":"22M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.46,"mem_mb":17,"disk_size":"20.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.2,"import_time_s":0.5,"mem_mb":17,"disk_size":"21M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.46,"mem_mb":17.4,"disk_size":"20.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.3,"import_time_s":0.47,"mem_mb":17.4,"disk_size":"21M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.85,"mem_mb":15.3,"disk_size":"18.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"setupmeta","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.1,"import_time_s":0.69,"mem_mb":15.4,"disk_size":"19M"}]}}