Skip to content
Back to skills

1599 Setuptools Compatibility 32509397

ASecurity

Reference documentation on hatchling's compatibility with the setuptools ecosystem. Use this when helping users understand how hatchling interoperates with setuptools and the broader Python packaging ecosystem.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
testingpythongobashflasktestingfrontendbackenddocumentation

Works with

  • cli

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1599-setuptools-compatibility_32509397 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1599 Setuptools Compatibility 32509397?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1599 Setuptools Compatibility 32509397
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1599-setuptools-compatibility-32509397/badge)](https://www.skillsdirectory.com/skills/tools-only-1599-setuptools-compatibility-32509397)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
category: integration
topics: [setuptools, compatibility, interoperability, ecosystem, migration]
related: [./legacy-setup-py.md, ./pep-standards.md]
---

# Setuptools Compatibility

Reference documentation on hatchling's compatibility with the setuptools ecosystem. Use this when helping users understand how hatchling interoperates with setuptools and the broader Python packaging ecosystem.

## Ecosystem Interoperability

### Setuptools Not Required

Hatchling is a standalone build backend. You do **not** need setuptools installed to:

- Build wheels and sdists
- Install packages
- Use virtual environments
- Run tests

However, some tools may recommend or depend on setuptools. That's fine - they can coexist.

### When Setuptools Still Appears

Even with hatchling, you might see setuptools because:

1. **Transitive dependency**: Some packages list setuptools as a build requirement
2. **pip requirements**: Older pip versions recommend setuptools
3. **Tool ecosystem**: Some development tools assume setuptools

This is normal and doesn't interfere with hatchling.

---

## Configuration Equivalence

### Setuptools setup.py → Hatchling pyproject.toml

| Setuptools Pattern          | Hatchling Equivalent                             | Notes                            |
| --------------------------- | ------------------------------------------------ | -------------------------------- |
| `packages=find_packages()`  | Auto-discovery                                   | Works with std/src layout        |
| `package_dir={"": "src"}`   | `packages = ["src/pkg"]`                         | Explicit configuration           |
| `install_requires=[...]`    | `dependencies = [...]`                           | PEP 508 format                   |
| `extras_require={...}`      | `[project.optional-dependencies]`                | Same structure                   |
| `entry_points={...}`        | `[project.scripts]` / `[project.entry-points.*]` | PEP 621 standard                 |
| `include_package_data=True` | Default behavior                                 | VCS files included automatically |
| `package_data={...}`        | `force-include`                                  | More explicit control            |
| `data_files=[(...)`         | `[tool.hatch.build.targets.wheel]`               | Wheel-specific placement         |
| `zip_safe=False`            | Default                                          | Wheels never zipped              |
| `setup_requires=[...]`      | `[build-system] requires`                        | Isolated at build time           |

---

## Build Artifact Compatibility

### Wheels (Platform Independent)

Hatchling-built wheels are **100% compatible** with wheels built by setuptools:

```bash
# Both produce identical wheels in structure
pip install mypackage-1.0.0-py3-none-any.whl
```

Wheel format defined by [PEP 427](https://peps.python.org/pep-0427/) - format agnostic to builder.

### Source Distributions

Hatchling sdists follow the standard format:

```text
mypackage-1.0.0.tar.gz
└── mypackage-1.0.0/
    ├── pyproject.toml
    ├── PKG-INFO
    ├── README.md
    ├── LICENSE
    └── src/mypackage/
        ├── __init__.py
        └── module.py
```

**Critical**: Each sdist contains `pyproject.toml` with build instructions. Frontends (pip) use this to build wheels.

---

## Dependency Resolution

### PEP 508 Compliance

Both setuptools and hatchling use PEP 508 for dependency specifications:

```toml
# Identical dependencies, regardless of builder
dependencies = [
    "requests>=2.28.0",
    "click>=8.0,<9.0",
    'pathlib2; python_version<"3.4"',
]
```

Dependency resolution happens in the frontend (pip), not the builder. Both builders produce identical results.

### Optional Dependencies (Extras)

```toml
[project.optional-dependencies]
# PEP 621 standard - both builders support equally
dev = ["pytest>=7.0", "black"]
docs = ["sphinx", "sphinx-rtd-theme"]

# Installation
pip install mypackage[dev,docs]
```

---

## Metadata Compatibility

### Core Metadata Format

Both builders generate standardized [Core Metadata](https://packaging.python.org/specifications/core-metadata/) in wheels:

```text
mypackage-1.0.0.dist-info/
├── WHEEL           # Wheel format metadata
├── METADATA        # Distribution metadata
├── RECORD          # File hashes
├── entry_points.txt
└── top_level.txt
```

This metadata is **identical in format** regardless of builder choice.

### Metadata Inspection

```bash
# Works identically for wheels from either builder
pip show mypackage
python -c "import importlib.metadata; print(importlib.metadata.version('mypackage'))"
importlib_metadata.entry_points()
```

---

## Plugin & Extension Compatibility

### Entry Points System

Both builders support the standardized entry points system:

```toml
[project.entry-points."flask.commands"]
my-command = "myapp.commands:cli"

[project.entry-points."console_scripts"]
myapp = "myapp.cli:main"
```

Entry point discovery works identically:

```python
from importlib.metadata import entry_points

# Works the same regardless of builder
eps = entry_points(group="flask.commands")
```

### Plugin Distribution

Plugins built with either system are interchangeable:

```bash
# Plugin built with hatchling works in app built with setuptools
pip install hatchling-plugin setuptools-app
```

---

## Testing & Validation

### Test Infrastructure Compatibility

Standard testing tools work identically:

```bash
# These work the same regardless of builder
pytest
python -m unittest
tox

# Package in editable mode
pip install -e .
```

### Distribution Validation

```bash
# twine works with hatchling-built packages
pip install twine
twine check dist/*
twine upload dist/*

# PyPI accepts wheels/sdists from any PEP 517 backend
```

---

## Known Incompatibilities (Rare)

### Setuptools-Specific Features Not Supported

These setuptools extensions are **not** needed with hatchling:

| Feature                      | Status        | Alternative                 |
| ---------------------------- | ------------- | --------------------------- |
| Custom commands (`cmdclass`) | Not supported | Build hooks                 |
| `setup.py` scripts           | Not supported | Entry points or scripts     |
| Distutils-specific behavior  | Not supported | Use only standard behaviors |
| `setup.py test`              | Deprecated    | Use pytest, tox             |

### When You Might Need Setuptools

- **Legacy projects**: Pre-2020 projects may require it
- **Custom build logic**: Uncommon setups with `setup.py` scripts
- **Distutils dependencies**: Very rare; most moved to setuptools
- **C extension modules**: Use `scikit-build-core` with hatchling instead

---

## Migration Recommendations

### Why Switch from Setuptools

✓ **Modern standards** (PEP 517, 621, 660) ✓ **Simpler configuration** (TOML vs Python code) ✓ **Smaller** (hatchling ~10kb vs setuptools ~500kb) ✓ **Faster builds** (optimized for common cases) ✓ **Better defaults** (sensible out-of-box behavior) ✓ **Active development** (setuptools is maintenance-focused)

### When to Keep Setuptools

- Project has complex custom build logic
- Team/organization standardized on setuptools
- Requires setuptools-specific plugins
- Building C extensions (though scikit-build-core is better)

---

## Coexistence Patterns

### Hybrid Approach (Not Recommended)

```toml
[build-system]
# Using hatchling as primary backend
requires = ["hatchling", "setuptools"]
build-backend = "hatchling.build"
```

**Why not**: Confusing, no benefit, increases complexity.

### Clean Transition Path

**Phase 1**: Add hatchling

```toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```

**Phase 2**: Remove setup.py (if present)

```bash
rm setup.py setup.cfg
```

**Phase 3**: Verify everything works

```bash
pip install -e .
python -m build
pip install .
```

---

## Cross-Builder Packages

### Packages Depend on Builder, Not Each Other

A package installed from a wheel doesn't care how it was built:

```python
# This package was built with hatchling
import requests  # Works regardless of how requests was built

# This works whether requests was built with:
# - hatchling
# - setuptools
# - poetry
# - flit
```

**Key principle**: Builder choice is private implementation detail.

---

## Verification Commands

```bash
# Check what builder was used to build a package
# (Usually not visible, but you can inspect the wheel)

# Extract WHEEL metadata
unzip -p mypackage-1.0.0-py3-none-any.whl mypackage-1.0.0.dist-info/WHEEL

# For installed packages, metadata is already in site-packages
python -c "import importlib.metadata; print(importlib.metadata.version('mypackage'))"

# Test that all standard operations work
pip install .
pip install -e .
pip install .[dev]
python -m pytest
```

---

## Resources

- [Setuptools Documentation](https://setuptools.pypa.io/)
- [Hatchling Documentation](https://hatch.pypa.io/)
- [PEP 517 Build Systems](https://peps.python.org/pep-0517/)
- [PyPA Packaging Specifications](https://packaging.python.org/en/latest/specifications/)

**Key Takeaway**: Hatchling is a drop-in replacement for setuptools that implements standard PEPs. The ecosystem is builder-agnostic at runtime.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.