|
| 1 | +# Contributing to ty |
| 2 | + |
| 3 | +Welcome! We're happy to have you here. Thank you in advance for your contribution to ty. |
| 4 | + |
| 5 | +> [!NOTE] |
| 6 | +> |
| 7 | +> This guide is for ty. If you're looking to contribute to Ruff, please see |
| 8 | +> [the Ruff contributing guide](../../CONTRIBUTING.md). |
| 9 | +
|
| 10 | +## The Basics |
| 11 | + |
| 12 | +We welcome contributions in the form of pull requests. |
| 13 | + |
| 14 | +For small changes (e.g., bug fixes), feel free to submit a PR. |
| 15 | + |
| 16 | +For larger changes (e.g. new diagnostics, new functionality, new configuration options), consider |
| 17 | +creating an [**issue**](https://github.com/astral-sh/ty/issues) outlining your proposed change. |
| 18 | +You can also join us on [Discord](https://discord.com/invite/astral-sh) to discuss your idea with the |
| 19 | +community. We've labeled [beginner-friendly tasks](https://github.com/astral-sh/ty/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) |
| 20 | +in the issue tracker, along with [bugs](https://github.com/astral-sh/ty/issues?q=is%3Aissue+is%3Aopen+label%3Abug) |
| 21 | +that are ready for contributions. |
| 22 | + |
| 23 | +### Prerequisites |
| 24 | + |
| 25 | +ty is written in Rust. You'll need to install the |
| 26 | +[Rust toolchain](https://www.rust-lang.org/tools/install) for development. |
| 27 | + |
| 28 | +You'll need [uv](https://docs.astral.sh/uv/getting-started/installation/) (or `pipx` and `pip`) to |
| 29 | +run Python utility commands. |
| 30 | + |
| 31 | +You can optionally install pre-commit hooks to automatically run the validation checks |
| 32 | +when making a commit: |
| 33 | + |
| 34 | +```shell |
| 35 | +uv tool install pre-commit |
| 36 | +pre-commit install |
| 37 | +``` |
| 38 | + |
| 39 | +We recommend [nextest](https://nexte.st/) to run ty's test suite (via `cargo nextest run`), |
| 40 | +though it's not strictly necessary: |
| 41 | + |
| 42 | +```shell |
| 43 | +cargo install cargo-nextest --locked |
| 44 | +``` |
| 45 | + |
| 46 | +Throughout this guide, any usages of `cargo test` can be replaced with `cargo nextest run`, |
| 47 | +if you choose to install `nextest`. |
| 48 | + |
| 49 | +### Development |
| 50 | + |
| 51 | +After cloning the repository, run ty locally from the repository root with: |
| 52 | + |
| 53 | +```shell |
| 54 | +cargo run --bin ty -- check --project /path/to/project/ |
| 55 | +``` |
| 56 | + |
| 57 | +Prior to opening a pull request, ensure that your code has been auto-formatted, |
| 58 | +and that it passes both the lint and test validation checks: |
| 59 | + |
| 60 | +```shell |
| 61 | +cargo clippy --workspace --all-targets --all-features -- -D warnings # Rust linting |
| 62 | +cargo test # Rust testing |
| 63 | +uvx pre-commit run --all-files --show-diff-on-failure # Rust and Python formatting, Markdown and Python linting, etc. |
| 64 | +``` |
| 65 | + |
| 66 | +These checks will run on GitHub Actions when you open your pull request, but running them locally |
| 67 | +will save you time and expedite the merge process. |
| 68 | + |
| 69 | +If you're using VS Code, you can also install the recommended [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) extension to get these checks while editing. |
| 70 | + |
| 71 | +Include the text `[ty]` at the beginning of your pull request title, to distinguish ty pull requests |
| 72 | +from Ruff ones. |
| 73 | + |
| 74 | +Your pull request will be reviewed by a maintainer, which may involve a few rounds of iteration |
| 75 | +prior to merging. |
| 76 | + |
| 77 | +### Debugging ty |
| 78 | + |
| 79 | +ty can optionally emit extensive tracing output, which can be very useful in understanding its |
| 80 | +operation and debugging issues; see [`crates/ty/docs/tracing.md`](./docs/tracing.md) for details. |
| 81 | + |
| 82 | +### Project Structure |
| 83 | + |
| 84 | +The codebase is structured as a monorepo with a [flat crate structure](https://matklad.github.io/2021/08/22/large-rust-workspaces.html), |
| 85 | +such that all crates are contained in a flat `crates` directory. |
| 86 | + |
| 87 | +The vast majority of ty's code lives in the `ty_python_semantic` crate (located at |
| 88 | +`crates/ty_python_semantic`). As a contributor, that's the crate that'll probably be most relevant |
| 89 | +to you. |
| 90 | + |
| 91 | +At the time of writing, the repository includes the following ty-specific crates (in addition to |
| 92 | +crates shared with Ruff, such as `ruff_db`, `ruff_python_ast`, and `ruff_python_parser`): |
| 93 | + |
| 94 | +- `ty_python_semantic`: The core type checker, which includes the type inference engine and |
| 95 | + semantic analysis. |
| 96 | +- `ty_test`: The Markdown-based test framework for ty, "mdtest". |
| 97 | +- `ty`: The command-line interface. |
| 98 | +- `ty_ide`: IDE features (hover, go-to-definition, autocomplete) for the language server. |
| 99 | +- `ty_project`: Discovery and representation of a Python project to be checked by ty. |
| 100 | +- `ty_server`: The ty language server. |
| 101 | +- `ty_vendored`: A vendored copy of [typeshed](https://github.com/python/typeshed), which holds type |
| 102 | + annotations for the Python standard library. |
| 103 | +- `ty_wasm`: library crate for exposing ty as a WebAssembly module. Powers the |
| 104 | + [ty Playground](https://play.ty.dev/). |
| 105 | + |
| 106 | +## Writing tests |
| 107 | + |
| 108 | +Core type checking tests are written as Markdown code blocks. |
| 109 | +They can be found in [`crates/ty_python_semantic/resources/mdtest`][resources-mdtest]. |
| 110 | +See [`crates/ty_test/README.md`][mdtest-readme] for more information |
| 111 | +on the test framework itself. |
| 112 | + |
| 113 | +Any ty pull request to improve ty's type inference or type checking logic should include mdtests |
| 114 | +demonstrating the effect of the change. |
| 115 | + |
| 116 | +We write mdtests in a "literate" style, with prose explaining the motivation of each test, and any |
| 117 | +context necessary to understand the feature being demonstrated. |
| 118 | + |
| 119 | +### Property tests |
| 120 | + |
| 121 | +ty uses property-based testing to test the core type relations. These tests are located in |
| 122 | +[`crates/ty_python_semantic/src/types/property_tests.rs`](../ty_python_semantic/src/types/property_tests.rs). |
| 123 | + |
| 124 | +The property tests do not run in CI on every PR, just once daily. It is advisable to run them |
| 125 | +locally after modifying core type relation methods (`is_subtype_of`, `is_equivalent_to`, etc.) to |
| 126 | +ensure that the changes do not break any of the properties. |
| 127 | + |
| 128 | +## Ecosystem CI (mypy-primer) |
| 129 | + |
| 130 | +GitHub Actions will run your changes against a number of real-world projects from GitHub and |
| 131 | +report on any linter or formatter differences. See [`crates/ty/docs/mypy_primer.md`](./docs/mypy_primer.md) |
| 132 | +for instructions on running these checks locally. |
| 133 | + |
| 134 | +## Coding guidelines |
| 135 | + |
| 136 | +We use the [Salsa](https:://github.com/salsa-rs/salsa) library for incremental computation. Many |
| 137 | +methods take a Salsa database (usually `db: &'db dyn Db`) as an argument. This should always be the |
| 138 | +first argument (or second after `self`). |
| 139 | + |
| 140 | +[mdtest-readme]: ../ty_test/README.md |
| 141 | +[resources-mdtest]: ../ty_python_semantic/resources/mdtest |
0 commit comments