Add support for configuring knot in pyproject.toml files (#15493)

## Summary

This PR adds support for configuring Red Knot in the `tool.knot` section
of the project's
`pyproject.toml` section. Options specified on the CLI precede the
options in the configuration file.

This PR only supports the `environment` and the `src.root` options for
now.
Other options will be added as separate PRs.

There are also a few concerns that I intentionally ignored as part of
this PR:

* Handling of relative paths: We need to anchor paths relative to the
current working directory (CLI), or the project (`pyproject.toml` or
`knot.toml`)
* Tracking the source of a value. Diagnostics would benefit from knowing
from which configuration a value comes so that we can point the user to
the right configuration file (or CLI) if the configuration is invalid.
* Schema generation and there's a lot more; see
https://github.com/astral-sh/ruff/issues/15491

This PR changes the default for first party codes: Our existing default
was to only add the project root. Now, Red Knot adds the project root
and `src` (if such a directory exists).

Theoretically, we'd have to add a file watcher event that changes the
first-party search paths if a user later creates a `src` directory. I
think this is pretty uncommon, which is why I ignored the complexity for
now but I can be persuaded to handle it if it's considered important.

Part of https://github.com/astral-sh/ruff/issues/15491

## Test Plan

Existing tests, new file watching test demonstrating that changing the
python version and platform is correctly reflected.
This commit is contained in:
Micha Reiser 2025-01-17 09:41:06 +01:00 committed by GitHub
parent 9ed67ba33e
commit eb47a6634d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 820 additions and 413 deletions

View file

@ -3,7 +3,7 @@
use rayon::ThreadPoolBuilder;
use red_knot_python_semantic::PythonVersion;
use red_knot_workspace::db::{Db, ProjectDatabase};
use red_knot_workspace::project::settings::Configuration;
use red_knot_workspace::project::options::{EnvironmentOptions, Options};
use red_knot_workspace::project::ProjectMetadata;
use red_knot_workspace::watch::{ChangeEvent, ChangedKind};
use ruff_benchmark::criterion::{criterion_group, criterion_main, BatchSize, Criterion};
@ -74,15 +74,14 @@ fn setup_case() -> Case {
.unwrap();
let src_root = SystemPath::new("/src");
let metadata = ProjectMetadata::discover(
src_root,
&system,
Some(&Configuration {
let mut metadata = ProjectMetadata::discover(src_root, &system).unwrap();
metadata.apply_cli_options(Options {
environment: Some(EnvironmentOptions {
python_version: Some(PythonVersion::PY312),
..Configuration::default()
..EnvironmentOptions::default()
}),
)
.unwrap();
..Options::default()
});
let mut db = ProjectDatabase::new(metadata, system).unwrap();