Checks Reference

pycmdcheck includes 66 built-in checks organized into 10 groups. Each check has a unique ID, name, severity level, and documentation.

Check Groups

Structure

Checks for essential package structure files:

ID Name Severity Description
ST001 HasReadme ERROR Check that README file exists
ST002 HasLicense ERROR Check that LICENSE file exists
ST003 HasPyprojectToml ERROR Check that pyproject.toml exists
ST004 NoSetupPy WARNING Check that setup.py is not present
ST005 HasSrcLayout NOTE Check for src/ directory layout
ST006 HasPyTyped NOTE Check for py.typed marker (PEP 561)
ST007 HasGitignore NOTE Check that .gitignore exists
ST008 ExportConsistencyCheck WARNING Check all exports are consistent
ST009 HasContributing WARNING Check for CONTRIBUTING file
ST010 HasCodeOfConduct WARNING Check for CODE_OF_CONDUCT file
ST011 HasPreCommitConfig NOTE Check for pre-commit configuration
ST012 HasCIConfig WARNING Check for CI configuration

Metadata

Checks for pyproject.toml metadata fields:

ID Name Severity Description
MT001 HasProjectName ERROR Check that project name is defined
MT002 HasProjectVersion ERROR Check that project version is defined
MT003 HasProjectDescription ERROR Check that project description is defined
MT004 HasRequiresPython ERROR Check that requires-python is defined
MT005 HasKeywords NOTE Check that keywords are defined
MT006 HasClassifiers WARNING Check that classifiers are defined
MT007 HasHomepage WARNING Check that homepage URL is defined
MT008 HasReadmeField WARNING Check that readme field is defined
MT009 ValidLicenseIdentifier NOTE Check that license is a valid SPDX identifier
MT010 LicenseCompatibilityCheck WARNING Check license compatibility
MT011 OSIApprovedLicense WARNING Check license is OSI-approved
MT012 AuthorEmail NOTE Check that author/maintainer email is defined

Tests

Checks for test infrastructure:

ID Name Severity Description
TS001 HasTestsDirectory WARNING Check that tests directory exists
TS002 TestsRun ERROR Check that tests run and pass
TS003 TestCoverage WARNING Check that test coverage meets threshold
TS004 TestNamingConvention NOTE Check test files follow naming conventions
TS005 TestDiscoverability NOTE Check all test files are discoverable by pytest

Documentation

Checks for documentation presence:

ID Name Severity Description
DC001 HasDocstrings WARNING Check that package has module docstring
DC002 HasDocsDirectory NOTE Check that docs directory exists
DC003 HasExamples NOTE Check for examples directory or code
DC004 HasAPIReference NOTE Check for API documentation setup
DC005 BrokenLinksCheck WARNING Check for broken URLs in documentation
DC006 ReadmeStructure WARNING Check README has install/usage sections
DC007 ReadmeBadges NOTE Check README has status badges

Code Quality

Checks for code quality and standards:

ID Name Severity Description
CQ001 RuffCheck WARNING Check that code passes ruff linting
CQ002 HasTypeHints NOTE Check for py.typed marker (PEP 561)
CQ003 NoTODOsInCode NOTE Check for TODO/FIXME comments
CQ004 MypyCheck WARNING Check that code passes mypy type checking
CQ005 ComplexityCheck WARNING Check code cyclomatic complexity
CQ006 DeadCodeCheck NOTE Check for unused code with vulture
CQ007 DoctestCheck WARNING Check that doctests pass
CQ008 DocstringCoverage NOTE Check docstring coverage percentage
CQ009 TypeHintCoverage NOTE Check type hint coverage percentage

Dependencies

Checks for dependency management:

ID Name Severity Description
DP001 NoPinnedDependencies WARNING Check that deps aren’t overly pinned
DP002 HasLockfile NOTE Check that a lockfile exists
DP003 DependencyFreshnessCheck NOTE Check for outdated dependencies
DP004 CircularImportCheck ERROR Check for circular imports
DP005 UnusedDependencyCheck WARNING Check for unused declared dependencies

Security

Checks for security issues:

ID Name Severity Description
SC001 NoHardcodedSecrets ERROR Check for hardcoded API keys, passwords, and secrets
SC002 NoInsecureFunctions WARNING Check for eval(), exec(), pickle, subprocess shell=True
SC003 NoDependencyVulnerabilities WARNING Check for known vulnerabilities in dependencies
SC004 DependencyAudit WARNING Audit dependencies for security issues
SC005 NoHardcodedSecretsV2 NOTE Enhanced check for hardcoded secrets
SC006 DeprecatedAPIs WARNING Check for deprecated Python stdlib usage

Build

Checks for build and distribution:

ID Name Severity Description
BD001 BuildSucceeds ERROR Check that package builds successfully
BD002 WheelBuilds ERROR Check that wheel can be built
BD003 InstallSucceeds ERROR Check that package installs correctly
BD004 ImportSucceeds ERROR Check that package imports without errors

Release

Checks for release readiness:

ID Name Severity Description
RL001 HasChangelog WARNING Check that changelog exists
RL002 ValidVersion ERROR Check that version follows semver
RL003 ChangelogFormatCheck WARNING Check that changelog follows standard format
RL004 HasCitation NOTE Check for CITATION.cff file
RL005 PyPIPublished NOTE Check package is on PyPI

Governance

Checks for license and governance compliance:

ID Name Severity Description
GV001 LicenseCompatibility WARNING Check license compatibility with dependencies

Severity Levels

Severity Exit Code Description
ERROR 1 Critical issue that should block release
WARNING 2 Important issue that should be addressed
NOTE 0 Informational, non-blocking issue

Filtering Checks

Skip specific checks

pycmdcheck --skip ST001 --skip MT003

Skip entire groups

pycmdcheck --skip-group metadata --skip-group documentation

Only run specific checks

pycmdcheck --only ST001 --only ST002

Only run specific groups

pycmdcheck --only-group structure --only-group release

Creating Custom Checks

You can create custom checks by implementing the check protocol and registering via entry points.

Check Protocol

from typing import ClassVar
from pycmdcheck import CheckResult, CheckStatus, Severity

class MyCustomCheck:
    id: ClassVar[str] = "CU001"
    group: ClassVar[str] = "custom"
    name: ClassVar[str] = "MyCustomCheck"
    description: ClassVar[str] = "Description of what this check does"
    severity: ClassVar[Severity] = Severity.WARNING
    requires: ClassVar[set[str]] = {"root", "pyproject"}
    doc_url: ClassVar[str] = "https://example.com/checks/CU001.html"

    @classmethod
    def check(cls, root, pyproject) -> CheckResult:
        # Perform check logic
        if some_condition:
            return CheckResult.passed(
                check_id=cls.id,
                check_name=cls.name,
                message="Check passed",
                url=cls.doc_url,
            )
        return CheckResult.failed(
            check_id=cls.id,
            check_name=cls.name,
            severity=cls.severity,
            message="Check failed",
            hint="How to fix this issue",
            url=cls.doc_url,
        )

Register via Entry Points

In your package’s pyproject.toml:

[project.entry-points."pycmdcheck.checks"]
my_checks = "my_package.checks:register"

The register function:

def register(registry):
    registry.add(MyCustomCheck)