.. | ||
reference | ||
README.md |
ty
Getting started
For a quick guide on getting started, see the top-level README.
Installation
Adding ty to your project
Use uv (or your project manager of choice) to add ty as a development dependency:
uv add --dev ty
Adding ty as a dependency ensures that all developers on the project are using the same version of ty.
Then, use uv run
to invoke ty:
uv run ty
Installing globally
Install ty globally with uv:
uv tool install ty@latest
Or, pipx:
pipx install ty
Installing with pip
Install ty into your current Python environment with pip:
pip install ty
Module discovery
First-party modules
First-party modules are Python files that are part of your own project’s codebase, unlike modules from the standard library modules or third-party packages installed via a package manager like uv or pip. By default, ty searches for first-party modules in the project's root folder or the src
folder (if present). If your project uses a different layout, configure the project's src.root
in your pyproject.toml
. For example, if your project's code is in the app
directory, like so:
example-pkg
├── README.md
├── pyproject.toml
└── app
└── example_pkg
└── __init__.py
then set src.root
in your pyproject.toml
to ./app
:
[tool.ty.src]
root = "./app"
Third-party modules
Third-party modules are external Python packages that are not part of the standard library or your own project’s code. These are typically installed using a package manager like uv or pip and include libraries such as requests
, numpy
, or django
.
ty searches third-party modules in your project's virtual environment. By default, it looks for a virtual environment in a .venv
folder located at the project root. If the VIRTUAL_ENV
environment variable is set, ty will use the path specified there instead. If your project uses a different location for your virtual environment, specify the location by setting the environment.python
configuration or --python
CLI option.
Python version
The supported Python syntax and standard library functions differ between Python versions. For example, Python 3.10 introduced support for match
statements and the sys.stdlib_module_names
symbol. While these features enhance the language, using them in a project targeting an older Python version can lead to compatibility issues.
ty helps you avoid such compatibility issues by checking your code against the Python version your project targets, and flagging any use of features or standard library symbols not available in that version.
ty determines the project's target Python version from:
- The
python-version
value in your configuration or the--python-version
command line option. - The lower bound of the project's
requires-python
field in yourpyproject.toml
. - If neither is specified, ty defaults to the latest stable Python version it supports (Python 3.13)
Excluding files
ty ignores files listed in an .ignore
or .gitignore
file unless respect-ignore-files
is set to false
.
Alternatively, you can explicitly pass the paths that ty should check, like so: ty check src scripts/benchmark.py
. We plan on adding dedicated options for including and excluding files in an upcoming release.
Editor integration
ty can be integrated with various editors and IDEs to provide a seamless development experience. This section provides instructions on how to set up ty with your editor and configure it to your liking.
VS Code
Install the ty extension from the VS Code Marketplace.
For more documentation on the ty extension, refer to the extension's README.
Other editors
ty can be used with any editor that supports the language server protocol. To start the language server, run ty server
. Refer to your editor's documentation
to learn how to connect to an LSP server.
Rules
Rules are individual type checks that detect common issues in your code—such as incompatible assignments, missing imports, or invalid type annotations. Each rule focuses on a specific pattern and can be turned on or off depending on your project’s needs. See [rules] for a reference of all supported rules.
Rule level
Each rule has a configurable level:
error
: violations are reported as errors and ty exits with an exit code of 1 if there's any.warn
: violations are reported as warnings. Depending on your configuration, ty exits with an exit code of 0 if there are only warning violations (default) or 1 when using--error-on-warning
.ignore
: the rule is turned off
Configuring rules on the command line
You can configure the lint level for each rule on the command line using --warn
, --error
, and --ignore
.
ty check --warn unused-ignore-comment --ignore redundant-cast --error possibly-unbound-attribute --error possibly-unbound-import
This command:
- enables
unused-ignore-comment
and sets its level to warnings - disables
redundant-cast
- changes the lint level for
possibly-unbound-attribute
andpossibly-unbound-import
from warning to error
The options can be repeated and options coming later take precedence over earlier options.
Configuring rules in a configuration file
You can turn rules on or of or change their level in your configuration's rules
section.
[tool.ty.rules]
unused-ignore-comment = "warn"
redundant-cast = "warn"
possibly-unbound-attribute = "error"
possibly-unbound-import = "error"
This configuration:
- enables
unused-ignore-comment
and sets its level to warnings - disables
redundant-cast
- changes the lint level for
possibly-unbound-attribute
andpossibly-unbound-import
from warning to error
Suppressions
Line-level suppression comments
Suppression comments allow you to silence specific instances of ty violations in your code, be they false positives or permissible violations.
Note
To disable a rule entirely, set its severity to
ignore
in yourty.toml
orpyproject.toml
or disable it using the--ignore
CLI argument.
To suppress a violation inline add a # ty: ignore[rule]
comment at the end of the line:
a = 10 + "test" # ty: ignore[unsupported-operator]
Multiline violations can be suppressed by adding the comment at the end of the violation's first or last line:
def add_three(a: int, b: int, c: int): ...
add_three( # ty: ignore[missing-argument]
3,
2
)
or when adding the suppression to the last line:
add_three(
3,
2
) # ty: ignore[missing-argument]
To suppress multiple violations on the same line, list all rule names and separate them with a comma:
add_three("one", 5) # ty: ignore[missing-argument, invalid-argument-type]
The comma separated list of rule names ([rule1, rule2]
) is optional. We recommend to always suppress specific error codes to avoid accidental suppression of other errors.
ty supports the type: ignore
comment format introduced with PEP 484. ty handles them similarly to ty: ignore
comments, but it suppresses all violations on that line, even when using type: ignore[code]
.
# Ignore all typing errors on the next line
add_three("one", 5) # type: ignore
ty reports unused ty: ignore
and type: ignore
comments if the rule unused-ignore-comment
is enabled. unused-ignore-comment
violations
can only be suppressed using ty: ignore[unused-ignore-comment]
. They can't be suppressed using ty: ignore
(without a rule code) or a type: ignore
comment.
@no_type_check
directive
ty supports the @no_type_check
decorator to suppress all violations inside a function.
from typing import no_type_check
def add_three(a: int, b: int, c: int):
a + b + c
@no_type_check
def main():
add_three(3, 4)
Decorating a class with @no_type_check
isn't supported.
Configuration
Configuration files
ty supports persistent configuration files at both the project- and user-level.
Specifically, ty will search for a pyproject.toml
or ty.toml
file in the current directory, or in the nearest parent directory.
If a pyproject.toml
file is found, ty will read configuration from the [tool.ty]
table. For example, to ignore the index-out-of-bounds
rule, add the following to a pyproject.toml
:
pyproject.toml
:
[tool.ty.rules]
index-out-of-bounds = "ignore"
(If there is no tool.ty
table, the pyproject.toml
file will be ignored, and ty will continue searching in the directory hierarchy.)
ty will also search for ty.toml
files, which follow an identical structure, but omit the [tool.ty]
prefix. For example:
ty.toml
:
[rules]
index-out-of-bounds = "ignore"
Note
ty.toml
files take precedence overpyproject.toml
files, so if bothty.toml
andpyproject.toml
files are present in a directory, configuration will be read fromty.toml
, and the[tool.ty]
section in the accompanyingpyproject.toml
will be ignored.
ty will also discover user-level configuration at ~/.config/ty/ty.toml
(or $XDG_CONFIG_HOME/ty/ty.toml
) on macOS and Linux, or %APPDATA%\ty\ty.toml
on Windows. User-level configuration must use the ty.toml
format, rather than the pyproject.toml
format, as a pyproject.toml
is intended to define a Python project.
If project- and user-level configuration files are found, the settings will be merged, with project-level configuration taking precedence over the user-level configuration.
For example, if a string, number, or boolean is present in both the project- and user-level configuration tables, the project-level value will be used, and the user-level value will be ignored. If an array is present in both tables, the arrays will be merged, with the project-level settings appearing later in the merged array.
Settings provided via command line take precedence over persistent configuration.
See the configuration reference for an enumeration of the available settings.
Exit codes
0
if no violations with severityerror
or higher were found.1
if any violations with severityerror
were found.2
if ty terminates abnormally due to invalid CLI options.101
if ty terminates abnormally due to an internal error.
ty supports two command line arguments that change how exit codes work:
--exit-zero
: ty will exit with0
even if violations were found.--error-on-warning
: ty will exit with1
if it finds any violations with severitywarning
or higher.
Reference
For more details, see the reference documentation: