pytest-dev/pytest
The pytest framework makes it easy to write small tests, yet scales to support complex functional testing
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ⚠Concentrated ownership — top contributor handles 52% of recent commits
- ✓In RepoPilot's curated trusted-corpus (29 projects)
- ✓Last commit today
- ✓23+ active contributors
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against dependency CVEs from deps.dev and OpenSSF Scorecard
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Want this for your own repo?
Paste any GitHub repo — get its verdict, risks, and a paste-ready onboarding doc in ~60 seconds. Free, no sign-up.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/pytest-dev/pytest)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card
This card auto-renders when someone shares https://repopilot.app/r/pytest-dev/pytest on X, Slack, or LinkedIn.
Ask AI about pytest-dev/pytest
Grounded in the actual source code. Pick a starter question or write your own.
Onboarding doc
Onboarding: pytest-dev/pytest
Generated by RepoPilot · 2026-06-27 · Source
🎯Verdict
GO — Healthy across the board
- In RepoPilot's curated trusted-corpus (29 projects)
- Last commit today
- 23+ active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 52% of recent commits
<sub>Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against dependency CVEs from deps.dev and OpenSSF Scorecard</sub>
⚡TL;DR
pytest is a mature Python testing framework that simplifies test authoring with plain assert statements and automatic test discovery, providing detailed assertion introspection and scaling from simple unit tests to complex functional testing suites. It's the de facto standard testing tool in the Python ecosystem, with ~3.6M lines of Python code distributed across plugins, fixtures, and assertion rewriting machinery. Monolithic single-package structure: src/ contains the core pytest engine (assertion rewriting, fixture system, plugin infrastructure), testing/ holds the test suite itself, doc/en/ contains full Sphinx documentation. The .github/workflows/ directory orchestrates multi-platform CI. Plugins and extensions hook into pytest's PEP 517 plugin architecture via entry points.
👥Who it's for
Python developers of all levels—from those writing single-file unit tests to teams building large integration test suites for applications and libraries. Contributors include core maintainers, plugin authors (pytest-cov, pytest-mock, etc.), and teams adopting pytest as their standardized test runner.
🌱Maturity & risk
Highly mature and production-ready. The repo shows active development (changelog and improvement tickets in changelog/ directory), comprehensive CI/CD via .github/workflows/test.yml, and institutional backing (Tidelift, OpenCollective sponsorship documented in repo root). This is a cornerstone project with millions of daily downloads and deep ecosystem integration.
Very low risk for adoption; pytest is battle-tested. Minor risks include: new features occasionally introduce subtle breaking changes (visible in CHANGELOG.rst and changelog/ entries like 14637.bugfix.rst), but these are rare and documented. Dependency surface is minimal (pluggy>=1.5.0 is the core external dep), and the single-maintainer risk is mitigated by active contributors and formalized governance visible in CODE_OF_CONDUCT.md and CONTRIBUTING.rst.
Active areas of work
Active maintenance with recent bugfix releases (entries like changelog/14637.bugfix.rst and changelog/14638.bugfix.rst). The workflows show continuous testing across Python versions, link validation in doc-check-links.yml, automated release preparation via prepare-release-pr.yml, and stale issue management. The pluggy>=1.5.0 dependency suggests ongoing plugin ecosystem work.
🚀Get running
Check README for instructions.
Daily commands:
Local test execution: pytest (runs pytest's own tests), pytest testing/test_main.py (specific test file), or pytest -v for verbose output. Benchmarking suite available: python bench/bench.py. Documentation: cd doc/en && make html (requires Sphinx dependencies listed in doc/en/_static/ references).
🗺️Map of the codebase
src/pytest/__init__.py— Main entry point exporting pytest's public API and version information.src/pytest/config.py— Core configuration parsing and session setup—all pytest runs flow through here.src/pytest/main.py— Primary test collection and execution orchestrator; handles CLI invocation and test discovery.src/pytest/nodes.py— Base node classes (Item, Collector, File) representing the test tree structure.src/pytest/runner.py— Test execution engine managing setup, teardown, and result reporting.src/pytest/hookspec.py— Plugin hook specifications defining the extension interface and contract.pyproject.toml— Project metadata, dependencies, and build configuration for pytest package.
🧩Components & responsibilities
- Config & PluginManager (pluggy, argparse, INI parsing) — Parses CLI args, loads plugins, and initializes session state.
- Failure mode: Plugin load error prevents any tests from running; config parsing errors halt startup.
- Collector (python.py, nodes.py) (Python AST, importlib, fs traversal) — Traverses filesystem and Python AST to discover test items and organize them hierarchically.
- Failure mode: Collection errors prevent those tests from running; discovery logic bugs cause tests to be missed.
- Runner (runner.py) (inspect, sys.exc_info, fixture resolution) — Executes test functions, manages fixture setup/teardown, and records outcomes.
- Failure mode: Fixture errors skip dependent tests; execution bugs produce false positives/negatives.
- Assertion Rewriter (assertion/rewrite.py) (AST, bytecode manipulation, importlib hooks) — Rewrites assert statements at import time to capture intermediate expression values.
- Failure mode: Rewrite errors corrupt bytecode; failures in rewrite logic hide assertion details.
- Capture (capture.py) (os.dup, file descriptors, context managers) — Intercepts and buffers stdout/stderr/stdin during test execution for assertion and reporting.
- Failure mode: Capture bugs cause output loss or deadlocks; broken captures leak sensitive data.
- Terminal Reporter (terminal.py) (VT100 ANSI codes, sys.stdout, formatting) — Formats and prints test progress, summaries, and failures to console.
- Failure mode: Reporter bugs produce garbled output or lose test metadata in CI environments.
🔀Data flow
CLI args→config.py— Command-line arguments parsed into Config object with options and rootdir.Config + plugins→Collector (python.py)— Initialized config passed to collection phase to discover test nodes.Test nodes→Runner (runner.py)— Collected items queued for execution with their metadata and dependency fixtures.Fixture definitions→Runner— Fixtures resolved at test time; injected as function arguments during execution.Test outcome + captured I/O→terminal.py— TestReport and CollectReport aggregated with captured stdout/stderr for console output.
🛠️How to make changes
Add a new pytest hook
- Define the hook specification in hookspec.py with docstring describing parameters and expected return type (
src/pytest/hookspec.py) - Call the hook at the appropriate point in main.py, config.py, runner.py, or other core modules using
config.hook.hook_name(...)(src/pytest/main.py) - Document the hook's behavior in doc/en/reference/reference_hooks.rst (
doc/en/reference/reference_hooks.rst)
Add a new command-line option
- Define the option in src/pytest/config.py using
parser.addoption()in a pytest_addoption hook (src/pytest/config.py) - Access the option value via
config.getoption('option_name')orrequest.config.getoption()in hooks or fixtures (src/pytest/fixtures.py) - Document the new option in doc/en/reference/reference_cli.rst (
doc/en/reference/reference_cli.rst)
Add a new built-in fixture
- Define the fixture function in src/pytest/fixtures.py or a dedicated module, using @pytest.fixture decorator (
src/pytest/fixtures.py) - Register the fixture in conftest.py at repo root or via pytest_plugins in init.py (
src/pytest/__init__.py) - Document scope, dependencies, and usage in doc/en/how-to/fixtures.rst (
doc/en/how-to/fixtures.rst)
Add support for a new test collection protocol
- Create a new Collector subclass in src/pytest/python.py or a new module inheriting from nodes.Collector (
src/pytest/python.py) - Implement
collect()method to yield Item or Collector instances representing discovered tests (src/pytest/nodes.py) - Register via pytest_collect_file hook in config.py to trigger collection for specific file types (
src/pytest/config.py)
🔧Why these technologies
- pluggy — Enables a clean, decoupled plugin system allowing third-party extensions without modifying core code.
- AST rewriting (assertion/rewrite.py) — Provides detailed assertion introspection to show intermediate values in failed assertions without manual decorators.
- Python standard library (unittest introspection, inspect, traceback) — Minimizes external dependencies while supporting both pytest-style and unittest-style test collection.
⚖️Trade-offs already made
-
Pluggy-based hook system over direct inheritance
- Why: Decouples plugins from core; allows multiple implementations of same hook to coexist.
- Consequence: Slight overhead in hook discovery/calling; requires plugins to understand hook specs rather than override base methods.
-
AST rewriting at import time
- Why: Provides accurate assertion details without runtime performance penalty during assertions.
- Consequence: Debugging pytest internals and assertion rewrites can be confusing; requires careful import hook management.
-
Single-threaded test execution by default
- Why: Avoids race conditions on fixtures and simplifies deterministic test ordering.
- Consequence: Sequential execution can be slow for large suites; parallel execution via pytest-xdist plugin adds complexity.
🚫Non-goals (don't propose these)
- Real-time test result streaming to remote servers
- Built-in distributed test execution (delegated to pytest-xdist plugin)
- Test result visualization UI (delegated to plugins and external tools)
- Language-agnostic test frameworks (pytest is Python-centric)
📊Code metrics
- Avg cyclomatic complexity: ~7 — Hook system, fixture resolution, and AST rewriting introduce cyclomatic complexity; core execution loop is straightforward but context-heavy.
- Largest file:
src/pytest/python.py(2,200 lines) - Estimated quality issues: ~12 — Global state in Config, implicit fixture binding, undefined hook ordering, and import-time side effects; well-tested but architectural debt around plugin isolation.
⚠️Anti-patterns to avoid
- Global mutable session state in config.py (Medium) —
src/pytest/config.py: The Config object and PluginManager accumulate state during a run; reusing them across sessions can leak fixture state or plugin cache. - Implicit fixture dependency resolution (Medium) —
src/pytest/fixtures.py: Fixture dependencies are resolved by name matching; typos or shadowing can silently bind wrong fixtures with no compile-time check. - Hook call ordering is not guaranteed (Medium) —
src/pytest/hookspec.py: Multiple plugins implementing the same hook have undefined execution order; can cause race-condition-like bugs in CI. - Assertion rewriter import-time side effects (Low) —
src/pytest/assertion/rewrite.py: AST rewriting happens on import, making it fragile to import-order changes and difficult to debug in nested test invocations.
🔥Performance hotspots
src/pytest/python.py (collect method)(CPU-bound collection phase) — Recursive filesystem and AST traversal for large test suites can be O(n) per file; no caching or parallelization.src/pytest/fixtures.py (fixture resolution)(CPU-bound fixture setup) — Fixture dependency graph resolution is re-computed for each test item; no memoization of fixture scopes or closure.src/pytest/runner.py (sequential test execution)(Wall-clock time for large suites) — Tests execute serially by default; parallel execution requires external pytest-xdist plugin.src/pytest/capture.py (I/O interception)(I/O overhead per test) — FD duplication and context switching on every test incurs OS syscall overhead; not optimized for high-volume output.
🪤Traps & gotchas
No required env vars, but be aware: (1) The test suite runs pytest on itself — editing core logic requires understanding recursion (e.g., testing/test_main.py imports from src/_pytest/). (2) Assertion rewriting is bytecode-level magic; changes to src/_pytest/assertion/rewrite.py require careful testing since they affect all test assertions globally. (3) The plugin hook system (via pluggy) uses string-based hook specs; misspelled hook names silently no-op (common gotcha when adding new hooks). (4) Documentation builds require Sphinx 9+ and several extensions (see .readthedocs.yaml for exact pins). (5) Changelog entries are required for most PRs (see changelog/README.rst)—missing them will fail CI checks.
🏗️Architecture
💡Concepts to learn
- AST-based assertion rewriting — pytest's assertion introspection (detailed failure messages from plain
assertstatements) works by rewriting Python bytecode at import time via AST manipulation—understanding this is crucial for debugging assertion-related issues or contributing tosrc/_pytest/assertion/ - Fixture dependency injection — pytest's fixtures system is a dependency-injection framework unique to pytest—deeply ingrained in the codebase and core to what makes pytest powerful, requires understanding how
FixtureLookupErrorpropagates and scope resolution works - Hook-based plugin architecture (PEP 302 / entry points) — pytest extends behavior entirely through the pluggy hook system—new contributors must understand how to register hooks (e.g.,
pytest_configure,pytest_collection_modifyitems) to add features without modifying core code - Parametrization and indirect fixture injection — pytest's
@pytest.mark.parametrizeand indirect parameter passing enable concise test matrices—this pattern is pervasive in pytest's own tests and critical for test clarity at scale - Item collection and Item/Node tree traversal — pytest models tests as a tree of Item nodes (File → Class → Function) with metadata; understanding collection phases and node traversal is essential for modifying discovery logic or adding custom item types
- Configuration loading precedence (pytest.ini, pyproject.toml, setup.cfg, ENV) — pytest resolves configuration from multiple sources with specific precedence rules (hard-coded in
src/_pytest/config/__init__.py)—misunderstanding this causes confusing 'why isn't my setting working' bugs - Scope-based fixture resolution and teardown ordering — Fixtures with function/class/session scope require careful lifetime management; scope mismatches are a common source of state leakage bugs—the implementation in
src/_pytest/fixtures.pyuses a sophisticated scope graph
🔗Related repos
pytest-dev/pluggy— Foundational plugin hook system that pytest depends on (pluggy>=1.5.0)—forked from pytest but now independentpytest-dev/py— Low-level Python library providing path manipulation, terminal output, and introspection—used by pytest internalspytest-dev/pytest-cov— Most popular pytest plugin for coverage reporting; canonical example of extending pytest with hookspallets/flask— Major upstream consumer—Flask's test suite heavily relies on pytest fixtures and parametrization patternspsf/cpython— pytest is used in CPython's test suite and influenced by lessons from its testing infrastructure
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive tests for pytest's internal plugin discovery and loading mechanism
The repo has a sophisticated plugin system (evidenced by pluggy>=1.5.0 dependency and .github/workflows/update-plugin-list.yml), but there's no dedicated test suite visible in the file structure for plugin discovery edge cases. This is critical for a framework that's heavily extensible. New contributors could write tests for plugin loading failures, version conflicts, and namespace package plugins.
- [ ] Create
src/pytest/tests/test_plugin_discovery.pywith tests for plugin loading edge cases - [ ] Add tests for conflicting plugin versions and namespace package plugins
- [ ] Test error handling when plugins fail to load or have incompatible signatures
- [ ] Run against existing plugin list in
.github/workflows/update-plugin-list.ymlto ensure compatibility
Implement missing integration tests for Sphinx documentation build pipeline
The repo has substantial Sphinx configuration (sphinx>=9, sphinxcontrib-trio, sphinx-removed-in, etc.) with a doc-check-links workflow, but there's no visible integration test suite for the documentation build itself. This prevents catching doc syntax errors, broken internal references, and missing autodoc stubs early. Contributors should add tests that build the full doc suite and validate output.
- [ ] Create
doc/test_doc_build.pywith integration tests that invoke Sphinx build - [ ] Add validation for all RST files in
doc/en/announce/rendering correctly - [ ] Test that all pytest public APIs are properly documented via autodoc
- [ ] Integrate test into
.github/workflows/test.ymlalongside the existing doc-check-links workflow
Add changelog entry validation and automated testing in CI
The repo has a changelog/ directory with a defined structure (README.rst, _template.rst, and numbered entries like 14637.bugfix.rst), but there's no visible validation that PR authors properly add changelog entries. This leads to missing release notes. A new contributor could implement a pre-commit hook and CI check to validate changelog entries follow the naming convention and template.
- [ ] Create
changelog/validate.pyto check changelog entries matchISSUE_NUMBER.TYPE.rstpattern - [ ] Add validation rules that entries reference valid issue numbers and use valid types (bugfix, feature, improvement, deprecation)
- [ ] Add a GitHub Actions job in
.github/workflows/test.ymlthat runs changelog validation on every PR - [ ] Add pre-commit hook configuration to
.pre-commit-config.yamlfor local validation
🌿Good first issues
- Add missing docstrings to public APIs in
src/_pytest/outcomes.py(skip, xfail, etc.)—these are heavily used but underdocumented, and stubs exist but lack examples. - Expand
testing/config/test coverage for edge cases insrc/_pytest/config/__init__.pywhen mixing pytest.ini with environment variables (currently sparse per file list). - Add performance benchmarks to
bench/for fixture resolution with deep dependency chains—no existing benchmark covers this common slow-test scenario despite it being a known pain point.
⭐Top contributors
Click to expand
Top contributors
- @bluetech — 52 commits
- @Pierre-Sassoulas — 10 commits
- @dependabot[bot] — 8 commits
- @pre-commit-ci[bot] — 5 commits
- @nicoddemus — 3 commits
📝Recent commits
Click to expand
Recent commits
3fa8d9b— Fix off-by-one in trailing assertion diff skipping (#14637) (#14639) (Aditya-Tripuraneni)e6d8374— docs: clarify recwarn resets warnings filter after tests (#14653) (itxsamad1)7660d7d— Error on top-level options in pytest.toml (#14646) (vismaytiwari)9db6646— assertion: add support fordict.keys()anddict.values()types in assertion explanations (as sets) (croc100)32e3ddb— Merge pull request #14647 from bluetech/approx-typing (bluetech)3cee4dd— approx: remove redundant__ne__implementation (bluetech)03da9f0— Renamepython_api.pytoapprox.py(bluetech)913e586— approx: exposepytest.Approxas the return type ofpytest.approx(bluetech)c95e8a7— approx: improve typing (bluetech)5085bb1— approx: inlineset_default(bluetech)
🔒Security observations
The pytest codebase demonstrates a reasonable security posture for a development-focused testing framework. No critical vulnerabilities were identified in the visible configuration. However, several medium-priority improvements could strengthen security: (1) tighten dependency version constraints to prevent uncontrolled upgrades, (2) resolve dependency constraint issues rather than working around them, and (3) implement more comprehensive automated security scanning in the CI/CD pipeline. The project appropriately acknowledges that as a development tool (not production), the attack surface is limited. Recommend focusing on dependency management and automated vulnerability scanning as next steps.
- Medium · Dependency Version Constraints Not Fully Specified —
Dependencies/Package file (sphinx>=9, pluggy>=1.5.0, etc.). The dependencies file uses loose version constraints (e.g., 'sphinx>=9', 'pluggy>=1.5.0') without upper bounds. This could allow installation of future major versions with breaking changes or security issues. The practice of using '-c broken-dep-constraints.txt' suggests known compatibility issues that are being worked around rather than properly resolved. Fix: Specify both lower and upper version bounds for dependencies (e.g., 'sphinx>=9,<10'). Review and resolve the 'broken-dep-constraints.txt' issues rather than suppressing them. Use lock files (poetry.lock, requirements.lock) for production deployments. - Low · Sphinx and Documentation Dependencies May Have Untracked Vulnerabilities —
Dependencies: sphinxcontrib-svg2pdfconverter, sphinx plugins. The codebase has multiple Sphinx-related dependencies (sphinx>=9, sphinxcontrib-trio, sphinxcontrib-svg2pdfconverter, etc.) that are used for documentation. While these are development dependencies, they could potentially introduce vulnerabilities if compromised. The svg2pdfconverter dependency is particularly concerning as it performs file format conversion. Fix: Regularly audit and update documentation dependencies. Consider using tools like 'pip audit' or 'safety' to check for known vulnerabilities. Isolate documentation build environment from production. Lock dependency versions for reproducible builds. - Low · No Explicit Security Policy for Dependency Updates —
SECURITY.md, .github/workflows/test.yml. While SECURITY.md exists and mentions security vulnerability reporting, there is no documented policy for proactive dependency updates, security scanning in CI/CD, or vulnerability response procedures visible in the provided files. Fix: Add explicit dependency scanning to CI/CD pipeline (e.g., 'pip audit' step). Document security response procedures. Enable Dependabot alerts and auto-merging for security patches. Consider adding a SBOM (Software Bill of Materials).
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/pytest-dev/pytest shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live pytest-dev/pytest
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/pytest-dev/pytest.
What it runs against: a local clone of pytest-dev/pytest — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in pytest-dev/pytest | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of pytest-dev/pytest. If you don't
# have one yet, run these first:
#
# git clone https://github.com/pytest-dev/pytest.git
# cd pytest
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of pytest-dev/pytest and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "pytest-dev/pytest(\\.git)?\\b" \\
&& ok "origin remote is pytest-dev/pytest" \\
|| miss "origin remote is not pytest-dev/pytest (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/pytest/__init__.py" \\
&& ok "src/pytest/__init__.py" \\
|| miss "missing critical file: src/pytest/__init__.py"
test -f "src/pytest/config.py" \\
&& ok "src/pytest/config.py" \\
|| miss "missing critical file: src/pytest/config.py"
test -f "src/pytest/main.py" \\
&& ok "src/pytest/main.py" \\
|| miss "missing critical file: src/pytest/main.py"
test -f "src/pytest/nodes.py" \\
&& ok "src/pytest/nodes.py" \\
|| miss "missing critical file: src/pytest/nodes.py"
test -f "src/pytest/runner.py" \\
&& ok "src/pytest/runner.py" \\
|| miss "missing critical file: src/pytest/runner.py"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/pytest-dev/pytest"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.
Similar Python repos
Other healthy-signal Python repos by stars.
Embed this chat in your README →
Drop this iframe anywhere — the widget runs against the same live analysis cache as the main app.
<iframe src="https://repopilot.app/embed/pytest-dev/pytest" width="100%" height="500" style="border:1px solid #d0d7de; border-radius:8px;" allow="microphone" loading="lazy" ></iframe>