Commit Graph

67 Commits

Author SHA1 Message Date
Hugo van Kemenade 09e6af16c8
[ruff+ty] Add colour to `--help` (#21337) 2025-11-08 17:17:14 +01:00
Micha Reiser 7569b09bdd
[ty] Add `ty_server::Db` trait (#21241) 2025-11-05 13:40:07 +00:00
Micha Reiser eb8c0ad87c
[ty] Add `--no-progress` option (#21063) 2025-10-24 18:00:00 +02:00
Micha Reiser f36fa7d6c1
[ty] Fix missing newline before first diagnostic (#21058) 2025-10-24 17:35:23 +02:00
Micha Reiser 9393279f65
[ty] Limit shown import paths to at most 5 unless ty runs with `-v` (#20912) 2025-10-16 13:18:09 +02:00
Micha Reiser 373fe8a39c
[ty] Remove 'pre-release software' warning (#20817) 2025-10-13 19:50:19 +02:00
David Peter 1f1542db51
[ty] Use 3.14 as the default version (#20759)
## Summary

Bump the latest supported Python version of ty to 3.14 and updates some
references from 3.13 to 3.14.

This also fixes a bug with `dataclasses.field` on 3.14 (which adds a new
keyword-only parameter to that function, breaking our previously naive
matching on the parameter structure of that function).

## Test Plan

A `ty check` on a file with template strings (without any further
configuration) doesn't raise errors anymore.
2025-10-08 11:38:47 +02:00
Brent Westbrook 88c0ce3e38
Update default and latest Python versions for 3.14 (#20725)
Summary
--

Closes #19467 and also removes the warning about using Python 3.14
without
preview enabled.

I also bumped `PythonVersion::default` to 3.9 because it reaches EOL
this month,
but we could also defer that for now if we wanted.

The first three commits are related to the `latest` bump to 3.14; the
fourth commit
bumps the default to 3.10.

Note that this PR also bumps the default Python version for ty to 3.10
because
there was a test asserting that it stays in sync with
`ast::PythonVersion`.

Test Plan
--

Existing tests

I spot-checked the ecosystem report, and I believe these are all
expected. Inbits doesn't specify a target Python version, so I guess
we're applying the default. UP007, UP035, and UP045 all use the new
default value to emit new diagnostics.
2025-10-07 12:23:11 -04:00
Alex Waygood 42b297bf44
[ty] Improve documentation for `extra-paths` and `python` config settings (#20717)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-10-06 12:20:00 +00:00
Alex Waygood 80b337669f
[ty] Add `--venv` as an alias to `--python` (#20718) 2025-10-06 13:03:05 +01:00
Micha Reiser c256c7943c
[ty] Update salsa to fix hang when cycle head panics (#20577) 2025-09-25 17:13:07 +02:00
Brent Westbrook ac5488086f
[ty] Add GitHub output format (#20358)
## Summary

This PR wires up the GitHub output format moved to `ruff_db` in #20320
to the ty CLI.

It's a bit smaller than the GitLab version (#20155) because some of the
helpers were already in place, but I did factor out a few
`DisplayDiagnosticConfig` constructor calls in Ruff. I also exposed the
`GithubRenderer` and a wrapper `DisplayGithubDiagnostics` type because
we needed a way to configure the program name displayed in the GitHub
diagnostics. This was previously hard-coded to `Ruff`:

<img width="675" height="247" alt="image"
src="https://github.com/user-attachments/assets/592da860-d2f5-4abd-bc5a-66071d742509"
/>

Another option would be to drop the program name in the output format,
but I think it can be helpful in workflows with multiple programs
emitting annotations (such as Ruff and ty!)

## Test Plan

New CLI test, and a manual test with `--config 'terminal.output-format =
"github"'`
2025-09-17 09:50:25 -04:00
Brent Westbrook aee9350df1
[ty] Add GitLab output format (#20155)
## Summary

This wires up the GitLab output format moved into `ruff_db` in
https://github.com/astral-sh/ruff/pull/20117 to the ty CLI.

While I was here, I made one unrelated change to the CLI docs. Clap was
rendering the escapes around the `\[default\]` brackets for the `full`
output, so I just switched those to parentheses:

```
--output-format <OUTPUT_FORMAT>
    The format to use for printing diagnostic messages

    Possible values:
    - full:    Print diagnostics verbosely, with context and helpful hints \[default\]
    - concise: Print diagnostics concisely, one per line
    - gitlab:  Print diagnostics in the JSON format expected by GitLab Code Quality reports
```

## Test Plan

New CLI test, and a manual test with `--config 'terminal.output-format =
"gitlab"'` to make sure this works as a configuration option too. I also
tried piping the output through jq to make sure it's at least valid JSON
2025-09-03 09:08:12 -04:00
David Peter 10301f6190
[ty] Enable virtual terminal on Windows (#19984)
## Summary

Should hopefully fix https://github.com/astral-sh/ty/issues/1045
2025-08-19 09:13:03 +00:00
Micha Reiser b96aa4605b
[ty] Reduce size of member table (#19572) 2025-08-07 11:16:04 +02:00
Dhruv Manilawala 1f29a04e9a
[ty] Support LSP client settings (#19614)
## Summary

This PR implements support for providing LSP client settings.

The complementary PR in the ty VS Code extension:
astral-sh/ty-vscode#106.

Notes for the previous iteration of this PR is in
https://github.com/astral-sh/ruff/pull/19614#issuecomment-3136477864
(click on "Details").

Specifically, this PR splits the client settings into 3 distinct groups.
Keep in mind that these groups are not visible to the user, they're
merely an implementation detail. The groups are:
1. `GlobalOptions` - these are the options that are global to the
language server and will be the same for all the workspaces that are
handled by the server
2. `WorkspaceOptions` - these are the options that are specific to a
workspace and will be applied only when running any logic for that
workspace
3. `InitializationOptions` - these are the options that can be specified
during initialization

The initialization options are a superset that contains both the global
and workspace options flattened into a 1-dimensional structure. This
means that the user can specify any and all fields present in
`GlobalOptions` and `WorkspaceOptions` in the initialization options in
addition to the fields that are _specific_ to initialization options.

From the current set of available settings, following are only available
during initialization because they are required at that time, are static
during the runtime of the server and changing their values require a
restart to take effect:
- `logLevel`
- `logFile`

And, following are available under `GlobalOptions`:
- `diagnosticMode`

And, following under `WorkspaceOptions`:
- `disableLanguageServices`
- `pythonExtension` (Python environment information that is populated by
the ty VS Code extension)

### `workspace/configuration`

This request allows server to ask the client for configuration to a
specific workspace. But, this is only supported by the client that has
the `workspace.configuration` client capability set to `true`. What to
do for clients that don't support pulling configurations?

In that case, the settings needs to be provided in the initialization
options and updating the values of those settings can only be done by
restarting the server. With the way this is implemented, this means that
if the client does not support pulling workspace configuration then
there's no way to specify settings specific to a workspace. Earlier,
this would've been possible by providing an array of client options with
an additional field which specifies which workspace the options belong
to but that adds complexity and clients that actually do not support
`workspace/configuration` would usually not support multiple workspaces
either.

Now, for the clients that do support this, the server will initiate the
request to get the configuration for all the workspaces at the start of
the server. Once the server receives these options, it will resolve them
for each workspace as follows:
1. Combine the client options sent during initialization with the
options specific to the workspace creating the final client options
that's specific to this workspace
2. Create a global options by combining the global options from (1) for
all workspaces which in turn will also combine the global options sent
during initialization

The global options are resolved into the global settings and are
available on the `Session` which is initialized with the default global
settings. The workspace options are resolved into the workspace settings
and are available on the respective `Workspace`.

The `SessionSnapshot` contains the global settings while the document
snapshot contains the workspace settings. We could add the global
settings to the document snapshot but that's currently not needed.

### Document diagnostic dynamic registration

Currently, the document diagnostic server capability is created based on
the `diagnosticMode` sent during initialization. But, that wouldn't
provide us with the complete picture. This means the server needs to
defer registering the document diagnostic capability at a later point
once the settings have been resolved.

This is done using dynamic registration for clients that support it. For
clients that do not support dynamic registration for document diagnostic
capability, the server advertises itself as always supporting workspace
diagnostics and work done progress token.

This dynamic registration now allows us to change the server capability
for workspace diagnostics based on the resolved `diagnosticMode` value.
In the future, once `workspace/didChangeConfiguration` is supported, we
can avoid the server restart when users have changed any client
settings.

## Test Plan

Add integration tests and recorded videos on the user experience in
various editors:

### VS Code

For VS Code users, the settings experience is unchanged because the
extension defines it's own interface on how the user can specify the
server setting. This means everything is under the `ty.*` namespace as
usual.


https://github.com/user-attachments/assets/c2e5ba5c-7617-406e-a09d-e397ce9c3b93

### Zed

For Zed, the settings experience has changed. Users can specify settings
during initialization:

```json
{
  "lsp": {
    "ty": {
      "initialization_options": {
        "logLevel": "debug",
        "logFile": "~/.cache/ty.log",
        "diagnosticMode": "workspace",
        "disableLanguageServices": true
      }
    },
  }
}
```

Or, can specify the options under the `settings` key:

```json
{
  "lsp": {
    "ty": {
      "settings": {
        "ty": {
          "diagnosticMode": "openFilesOnly",
          "disableLanguageServices": true
        }
      },
      "initialization_options": {
        "logLevel": "debug",
        "logFile": "~/.cache/ty.log"
      }
    },
  }
}
```

The `logLevel` and `logFile` setting still needs to go under the
initialization options because they're required by the server during
initialization.

We can remove the nesting of the settings under the "ty" namespace by
updating the return type of
db9ea0cdfd/src/tychecker.rs (L45-L49)
to be wrapped inside `ty` directly so that users can avoid doing the
double nesting.

There's one issue here which is that if the `diagnosticMode` is
specified in both the initialization option and settings key, then the
resolution is a bit different - if either of them is set to be
`workspace`, then it wins which means that in the following
configuration, the diagnostic mode is `workspace`:

```json
{
  "lsp": {
    "ty": {
      "settings": {
        "ty": {
          "diagnosticMode": "openFilesOnly"
        }
      },
      "initialization_options": {
        "diagnosticMode": "workspace"
      }
    },
  }
}
```

This behavior is mainly a result of combining global options from
various workspace configuration results. Users should not be able to
provide global options in multiple workspaces but that restriction
cannot be done on the server side. The ty VS Code extension restricts
these global settings to only be set in the user settings and not in
workspace settings but we do not control extensions in other editors.


https://github.com/user-attachments/assets/8e2d6c09-18e6-49e5-ab78-6cf942fe1255

### Neovim

Same as in Zed.

### Other

Other editors that do not support `workspace/configuration`, the users
would need to provide the server settings during initialization.
2025-08-06 18:37:21 +05:30
Leandro Braga de77b29798
[ty] clear the terminal screen in watch mode (#19712)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-08-04 13:45:37 +02:00
Micha Reiser 808c94d509
[ty] Implement streaming for workspace diagnostics (#19657) 2025-08-04 09:34:29 +00:00
Micha Reiser 6516db7835
[ty] Add progress bar to watch (#19729) 2025-08-04 09:31:13 +02:00
Micha Reiser 6bd413df6c
[ty] Update salsa (#19710) 2025-08-03 09:18:10 +00:00
Micha Reiser 5cace28c3e
[ty] Add warning for unknown `TY_MEMORY_REPORT` value (#19465) 2025-07-21 14:29:24 +00:00
Zanie Blue 78dfc8af0f
[ty] Allow `-qq` for silent output mode (#19366)
This matches uv's behavior.

Briefly discussed at
https://github.com/astral-sh/ruff/pull/19233#discussion_r2197930360

I think the most useful case is to avoid piping to `/dev/null` which
hard to do properly in a cross-platform script.
2025-07-15 17:08:19 +00:00
Zanie Blue 0c84652cc5
[ty] Allow `-q` short alias for `--quiet` (#19364) 2025-07-15 12:00:07 -05:00
Micha Reiser 90026047f9
[ty] Use python version and path from Python extension (#19012) 2025-07-14 09:47:27 +00:00
Micha Reiser 3da8b51dc1
[ty] Fix server version (#19284) 2025-07-14 09:06:34 +02:00
Brent Westbrook b5c5f710fc
Render Azure, JSON, and JSON lines output with the new diagnostics (#19133)
## Summary

This was originally stacked on #19129, but some of the changes I made
for JSON also impacted the Azure format, so I went ahead and combined
them. The main changes here are:

- Implementing `FileResolver` for Ruff's `EmitterContext`
- Adding `FileResolver::notebook_index` and `FileResolver::is_notebook`
methods
- Adding a `DisplayDiagnostics` (with an "s") type for rendering a group
of diagnostics at once
- Adding `Azure`, `Json`, and `JsonLines` as new `DiagnosticFormat`s

I tried a couple of alternatives to the `FileResolver::notebook` methods
like passing down the `NotebookIndex` separately and trying to reparse a
`Notebook` from Ruff's `SourceFile`. The latter seemed promising, but
the `SourceFile` only stores the concatenated plain text of the
notebook, not the re-parsable JSON. I guess the current version is just
a variation on passing the `NotebookIndex`, but at least we can reuse
the existing `resolver` argument. I think a lot of this can be cleaned
up once Ruff has its own actual file resolver.

As suggested, I also tried deleting the corresponding `Emitter` files in
`ruff_linter`, but it doesn't look like git was able to follow this as a
rename. It did, however, track that the tests were moved, so the
snapshots should be easy to review.

## Test Plan

Existing Ruff tests ported to tests in `ruff_db`. I think some other
existing ruff tests also cover parts of this refactor.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-07-11 15:04:46 -04:00
Zanie Blue 965f415212
[ty] Add a `--quiet` mode (#19233)
Adds a `--quiet` flag which silences diagnostic, warning logs, and
messages like "all checks passed" while retaining summary messages that
indicate problems, e.g., the number of diagnostics.

I'm a bit on the fence regarding filtering out warning logs, because it
can omit important details, e.g., the message that a fatal diagnostic
was encountered. Let's discuss that in
https://github.com/astral-sh/ruff/pull/19233#discussion_r2195408693

The implementation recycles the `Printer` abstraction used in uv, which
is intended to replace all direct usage of `std::io::stdout`. See
https://github.com/astral-sh/ruff/pull/19233#discussion_r2195140197

I ended up futzing with the progress bar more than I probably should
have to ensure it was also using the printer, but it doesn't seem like a
big deal. See
https://github.com/astral-sh/ruff/pull/19233#discussion_r2195330467

Closes https://github.com/astral-sh/ty/issues/772
2025-07-10 09:40:47 -05:00
Micha Reiser 492f5bf2aa
[ty] Remove countme from salsa-structs (#19257) 2025-07-10 11:45:09 +00:00
Charlie Marsh 3ee3434187
Auto-generate environment variable references for ty (#19205)
## Summary

This PR mirrors the environment variable implementation we have in uv:
efc361223c/crates/uv-static/src/env_vars.rs (L6-L7).

See: https://github.com/astral-sh/ty/issues/773.
2025-07-08 10:48:31 -04:00
Ibraheem Ahmed cd848986d7
[ty] Add separate CI job for memory usage stats (#19134)
## Summary

As discussed in https://github.com/astral-sh/ruff/pull/19059.
2025-07-07 12:17:02 -04:00
Ibraheem Ahmed 9218bf72ad
[ty] Print salsa memory usage totals in mypy primer CI runs (#18973)
## Summary

Print the [new salsa memory usage
dumps](https://github.com/astral-sh/ruff/pull/18928) in mypy primer CI
runs to help us catch memory regressions. The numbers are rounded to the
nearest power of 1.1 (about a 5% threshold between buckets) to avoid overly sensitive diffs.
2025-06-28 15:09:50 -04:00
Micha Reiser 29927f2b59
Update Rust toolchain to 1.88 and MSRV to 1.86 (#19011) 2025-06-28 20:24:00 +02:00
Ibraheem Ahmed 6f7b1c9bb3
[ty] Add environment variable to dump Salsa memory usage stats (#18928)
## Summary

Setting `TY_MEMORY_REPORT=full` will generate and print a memory usage
report to the CLI after a `ty check` run:

```
=======SALSA STRUCTS=======
`Definition`                                       metadata=7.24MB   fields=17.38MB  count=181062
`Expression`                                       metadata=4.45MB   fields=5.94MB   count=92804
`member_lookup_with_policy_::interned_arguments`   metadata=1.97MB   fields=2.25MB   count=35176
...
=======SALSA QUERIES=======
`File -> ty_python_semantic::semantic_index::SemanticIndex`
    metadata=11.46MB  fields=88.86MB  count=1638
`Definition -> ty_python_semantic::types::infer::TypeInference`
    metadata=24.52MB  fields=86.68MB  count=146018
`File -> ruff_db::parsed::ParsedModule`
    metadata=0.12MB   fields=69.06MB  count=1642
...
=======SALSA SUMMARY=======
TOTAL MEMORY USAGE: 577.61MB
    struct metadata = 29.00MB
    struct fields = 35.68MB
    memo metadata = 103.87MB
    memo fields = 409.06MB
```

Eventually, we should integrate these numbers into CI in some form. The
one limitation currently is that heap allocations in salsa structs (e.g.
interned values) are not tracked, but memoized values should have full
coverage. We may also want a peak memory usage counter (that accounts
for non-salsa memory), but that is relatively simple to profile manually
(e.g. `time -v ty check`) and would require a compile-time option to
avoid runtime overhead.
2025-06-26 21:27:51 +00:00
Micha Reiser 0194452928
[ty] Rename `src.root` setting to `environment.root` (#18760)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-06-24 14:40:44 +02:00
Micha Reiser 37fdece72f
[ty] Anchor all exclude patterns (#18685)
Co-authored-by: Andrew Gallant <andrew@astral.sh>
2025-06-18 08:57:36 +00:00
Micha Reiser 3a430fa6da
[ty] Allow overriding rules for specific files (#18648) 2025-06-15 14:27:39 +01:00
Micha Reiser 1f27d53fd5
[ty] File inclusion and exclusion (#18498) 2025-06-12 19:07:31 +02:00
Alex Waygood e84406d8be
[ty] Infer the Python version from `--python=<system installation>` on Unix (#18550) 2025-06-11 14:32:33 +00:00
Charlie Marsh 0232e422b2
Add `CONDA_PREFIX` to `--python` documentation (#18574)
## Summary

Noticed this while working on https://github.com/astral-sh/ty/pull/612.
2025-06-08 20:20:35 -04:00
Ibraheem Ahmed 8531f4b3ca
[ty] Add infrastructure for AST garbage collection (#18445)
## Summary

https://github.com/astral-sh/ty/issues/214 will require a couple
invasive changes that I would like to get merged even before garbage
collection is fully implemented (to avoid rebasing):
- `ParsedModule` can no longer be dereferenced directly. Instead you
need to load a `ParsedModuleRef` to access the AST, which requires a
reference to the salsa database (as it may require re-parsing the AST if
it was collected).
- `AstNodeRef` can only be dereferenced with the `node` method, which
takes a reference to the `ParsedModuleRef`. This allows us to encode the
fact that ASTs do not live as long as the database and may be collected
as soon a given instance of a `ParsedModuleRef` is dropped. There are a
number of places where we currently merge the `'db` and `'ast`
lifetimes, so this requires giving some types/functions two separate
lifetime parameters.
2025-06-05 11:43:18 -04:00
Alex Waygood b390b3cb8e
[ty] Update docs for Python version inference (#18397) 2025-05-30 22:45:28 +01:00
justin 8d5655a7ba
[ty] Add --config-file CLI arg (#18083) 2025-05-27 08:00:38 +02:00
Micha Reiser 62ef96f51e
[ty] Move `respect-ignore-files` under `src` section (#18322) 2025-05-26 18:45:48 +01:00
Micha Reiser d8216fa328
[ty] Gracefully handle salsa cancellations and panics in background request handlers (#18254) 2025-05-26 13:37:49 +01:00
Jo 83a036960b
[ty] Add long help for `--config` argument (#18285) 2025-05-25 13:09:02 +02:00
Sumana Harihareswara 029085fa72
[ty] Clarify `ty check` output default in documentation. (#18246)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-05-22 15:24:58 +02:00
Micha Reiser 9ae698fe30
Switch to Rust 2024 edition (#18129) 2025-05-16 13:25:28 +02:00
Micha Reiser b6b7caa023
[ty] Change layout of extra verbose output and respect `--color` for verbose output (#18089) 2025-05-15 09:57:59 +02:00
Zanie Blue a97e72fb5e
Update reference documentation for `--python-version` (#18056)
Adding more detail here
2025-05-12 22:31:04 +00:00
Zanie Blue 6b64630635
Update `--python` to accept paths to executables in virtual environments (#17954)
## Summary

Updates the `--python` flag to accept Python executables in virtual
environments. Notably, we do not query the executable and it _must_ be
in a canonical location in a virtual environment. This is pretty naive,
but solves for the trivial case of `ty check --python .venv/bin/python3`
which will be a common mistake (and `ty check --python $(which python)`)

I explored this while trying to understand Python discovery in ty in
service of https://github.com/astral-sh/ty/issues/272, I'm not attached
to it, but figure it's worth sharing.

As an alternative, we can add more variants to the
`SearchPathValidationError` and just improve the _error_ message, i.e.,
by hinting that this looks like a virtual environment and suggesting the
concrete alternative path they should provide. We'll probably want to do
that for some other cases anyway (e.g., `3.13` as described in the
linked issue)

This functionality is also briefly mentioned in
https://github.com/astral-sh/ty/issues/193

Closes https://github.com/astral-sh/ty/issues/318

## Test Plan

e.g.,

```
uv run ty check --python .venv/bin/python3
```

needs test coverage still
2025-05-12 15:39:04 -05:00