ST004: NoSetupPy

Overview

Property Value
ID ST004
Name NoSetupPy
Group structure
Severity WARNING

Description

Checks that a setup.py file does not exist in the package root directory.

Modern Python packages should use pyproject.toml exclusively for configuration. The presence of setup.py indicates a legacy build configuration that should be migrated.

What it checks

The check verifies that setup.py does not exist in the package root directory.

Why it matters

  • Standardization - pyproject.toml is the modern standard defined by PEP 517/518/621
  • Simplicity - Declarative configuration is easier to maintain than executable code
  • Security - setup.py can execute arbitrary code during installation
  • Consistency - Having both setup.py and pyproject.toml can lead to confusion

How to fix

Migrate your package configuration from setup.py to pyproject.toml.

Step 1: Create or update pyproject.toml

Convert your setup.py configuration to pyproject.toml:

[project]
name = "my-package"
version = "0.1.0"
description = "A brief description"
readme = "README.md"
license = "MIT"
requires-python = ">=3.11"
authors = [
    { name = "Your Name", email = "you@example.com" }
]
dependencies = [
    "requests>=2.28.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0.0",
]

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

Step 2: Remove setup.py

Once your pyproject.toml is configured correctly:

rm setup.py

Step 3: Remove setup.cfg (if present)

If you also have a setup.cfg, migrate its contents to pyproject.toml and remove it:

rm setup.cfg

Common migrations

setup.py pyproject.toml
name="pkg" [project] name = "pkg"
version="1.0" [project] version = "1.0"
install_requires=[...] [project] dependencies = [...]
extras_require={...} [project.optional-dependencies]
entry_points={...} [project.scripts] or [project.gui-scripts]

Configuration

Skip this check

[tool.pycmdcheck]
skip = ["ST004"]

CLI

pycmdcheck --skip ST004