How to List Pre-commit Hooks from YAML Config in Python

Parse a .pre-commit-config.yaml file with PyYAML and print every hook ID paired with its source repository.

Easy Python 3.9+ Aug 9, 2026 Modern tooling 15 views 0 copies

Requires third-party packages — install first
pip install pyyaml

Python code

28 lines
Python 3.9+
import yaml

pre_commit_config = """
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
  - repo: https://github.com/psf/black
    rev: 23.11.0
    hooks:
      - id: black
"""

def list_hooks(config_text):
    config = yaml.safe_load(config_text)
    hooks = []
    for repo in config.get("repos", []):
        repo_url = repo.get("repo", "unknown")
        for hook in repo.get("hooks", []):
            hooks.append((hook.get("id", "unknown"), repo_url))
    return hooks

if __name__ == "__main__":
    for hook_id, repo_url in list_hooks(pre_commit_config):
        print(f"{hook_id}  <-  {repo_url}")

Output

stdout
trailing-whitespace  <-  https://github.com/pre-commit/pre-commit-hooks
end-of-file-fixer  <-  https://github.com/pre-commit/pre-commit-hooks
check-yaml  <-  https://github.com/pre-commit/pre-commit-hooks
black  <-  https://github.com/psf/black

How it works

yaml.safe_load converts the YAML text into nested Python dictionaries and lists, making it trivial to walk the repo/hook structure. The get("repos", []) pattern safely handles a missing top-level key so the loop doesn't crash. Nested loops iterate each repository and then each hook inside it, collecting (hook_id, repo_url) tuples. The built-in __name__ == "__main__" guard keeps the print statement from running when the script is imported elsewhere.

Common mistakes

  • Using `yaml.load` instead of `yaml.safe_load`, which can execute arbitrary code
  • Assuming the `repos` key always exists without using `.get('repos', [])`
  • Forgetting that `hook.get('id')` may return None for malformed entries

Variations

  1. Use `with open('.pre-commit-config.yaml') as f:` then `yaml.safe_load(f)` to read directly from a file instead of a string
  2. Return a list of only hook IDs (without repo URLs) if you just need names for a quick check

Real-world use cases

  • Auditing which hooks a repository has enabled before merging a new contributor's PR.
  • Building a CI script that verifies every hook in the config is implemented and up to date.
  • Generating documentation that lists all linting and formatting checks for a project.

Sponsored

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Modern tooling

Related tutorials and quizzes for this topic.