Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 45 additions & 12 deletions docs/dev/contributing.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,61 @@
# Contributing

This is an open source project, and we are open to new contributors.

## Getting started
1. Make sure that you have [uv](https://docs.astral.sh/uv/) and [just](https://just.systems/) installed.

1. Install [uv](https://docs.astral.sh/uv/) and [just](https://just.systems/). modern-di supports
Python 3.11 and later.
2. Clone the project:
```
git clone git@github.com:modern-python/modern-di.git # or: git clone https://github.com/modern-python/modern-di.git
cd modern-di
```
3. Install dependencies by running `just install`

```bash
git clone https://github.com/modern-python/modern-di.git
cd modern-di
```

3. Run `just install`. It runs `uv lock --upgrade`, then syncs every extra and the lint group, so
you lint with the newest `ruff` and `ty`, as CI does. `uv.lock` is gitignored. Run it again in
every new checkout or worktree before `just lint`.

## Running linters
`Ruff` and `ty` do the static analysis.

Run all checks with `just lint`.
`ruff` and `ty` do the static analysis. Run all checks with `just lint`, which also applies
`ruff`'s fixes and formatting.

## Running tests

Run all tests with `just test`. Run a subset with `just test <PATH> -k <NAME>`.

CI runs the coverage-enforcing recipe `just test-ci` along with `just lint-ci`.
- `just test-ci` is the full run with coverage, and fails below 100% line and branch coverage of
`modern_di`.
- `just test-race` runs only the thread-race tests. CI repeats them on free-threaded Python builds.
- `just bench` runs the guard-tier benchmarks, and `just bench-compare` the cross-framework ones.

## Working on the docs

The site is built from `docs/` with MkDocs. Before you open a pull request that touches it:

- `just test-docs` runs every Python block under `docs/` as a test, with Sybil. The framework
pages under `docs/integrations/` are skipped there.
- `just test-docs-integrations` runs every page, the framework pages included, with each
integration's latest release installed. It builds a throwaway virtualenv.
- `just docs-build` is the strict MkDocs build. Any warning fails it.

The writing rules are in `docs/agents/docs-style.md`.

## What CI runs

Every pull request runs `just lint-ci` and `just adr-check`, `just test-ci` and `just test-docs` on
Python 3.11 to 3.14 (3.15 as a pre-release), `just test-race --count=50` on the free-threaded
builds, `just test-docs-integrations`, `just docs-build`, and an offline link check of every
Markdown file.

## Submitting changes

1. Fork the repo and branch off `main`.
2. Make your change with tests; keep **100% line and branch coverage** of `modern_di` (CI runs `just test-ci`, which fails below the `report.fail_under = 100` gate in `pyproject.toml`).
3. Run `just lint` and `just test` locally before pushing (CI runs the non-fixing variants `just lint-ci` / `just test-ci`).
4. For non-trivial changes, the PR body is the spec; the pull-request template walks you through it (why, design, non-goals, verification).
2. Make your change with tests, and keep 100% line and branch coverage of `modern_di`. The gate is
`report.fail_under = 100` in `pyproject.toml`.
3. Run `just lint` and `just test` locally before pushing.
4. For a non-trivial change, the pull-request body is the spec. The template has Summary, Changes
and Checklist sections.
5. Open a pull request upstream.
15 changes: 8 additions & 7 deletions docs/dev/performance-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ builds a container per test would pay that in every test.
[ADR 0001](https://github.com/modern-python/modern-di/blob/main/docs/adr/0001-resolver-hot-path-generated-source.md)
records the decision.

## After 3.5: the request path
## 3.6: the request path

Three smaller changes moved the per-request path:
Three smaller changes in 3.6.0 moved the per-request path:

- [#540](https://github.com/modern-python/modern-di/issues/540) inlined the cross-scope hop. The
generated resolver reads the container's ancestor map itself instead of calling
Expand Down Expand Up @@ -184,8 +184,9 @@ did not move then, because on G7 #585 measured −2.9% and #597 +4.6%.
so the change in that ratio is modern-di's.

The two publications after 4.0.0 (`ab327b3` and `8845e6a`) measured the 4.0.0 library plus
[#631](https://github.com/modern-python/modern-di/issues/631), which adds checks at provider
definition and runs nothing during a resolve, against that-depends 4.2.0 and wireup 2.12.1. Every
ratio stayed within 0.03 of 4.0.0 except dependency-injector's C2 (2.20 to 2.13, then 2.14) and,
at `8845e6a`, dishka's C4 (0.88 to 0.84). No cell crossed 1.0. modern-di's C4 fell from 1.85 to 1.80 µs at `ab327b3` and 1.74 µs at
`8845e6a`; #631 adds nothing to that path, and neither run explains the drop.
[#631](https://github.com/modern-python/modern-di/issues/631), which shipped in 4.1.0. It adds
checks at provider definition and runs nothing during a resolve. Both ran against that-depends 4.2.0
and wireup 2.12.1. Every ratio stayed within 0.03 of 4.0.0 except dependency-injector's C2 (2.20 to
2.13, then 2.14) and, at `8845e6a`, dishka's C4 (0.88 to 0.84). No cell crossed 1.0. modern-di's C4
fell from 1.85 to 1.80 µs at `ab327b3` and 1.74 µs at `8845e6a`; #631 adds nothing to that path, and
neither run explains the drop.
Loading
Loading