ruff/crates/ty_python_semantic/src
InSync 6d56ee803e
[ty] Add partial support for TypeIs (#18589)
## Summary

Part of [#117](https://github.com/astral-sh/ty/issues/117).

`TypeIs[]` is a special form that allows users to define their own
narrowing functions. Despite the syntax, `TypeIs` is not a generic and,
on its own, it is meaningless as a type.
[Officially](https://typing.python.org/en/latest/spec/narrowing.html#typeis),
a function annotated as returning a `TypeIs[T]` is a <i>type narrowing
function</i>, where `T` is called the <i>`TypeIs` return type</i>.

A `TypeIs[T]` may or may not be bound to a symbol. Only bound types have
narrowing effect:

```python
def f(v: object = object()) -> TypeIs[int]: ...

a: str = returns_str()

if reveal_type(f()):   # Unbound: TypeIs[int]
	reveal_type(a)     # str

if reveal_type(f(a)):  # Bound:   TypeIs[a, int]
	reveal_type(a)     # str & int
```

Delayed usages of a bound type has no effect, however:

```python
b = f(a)

if b:
	reveal_type(a)     # str
```

A `TypeIs[T]` type:

* Is fully static when `T` is fully static.
* Is a singleton/single-valued when it is bound.
* Has exactly two runtime inhabitants when it is unbound: `True` and
`False`.
  In other words, an unbound type have ambiguous truthiness.
It is possible to infer more precise truthiness for bound types;
however, that is not part of this change.

`TypeIs[T]` is a subtype of or otherwise assignable to `bool`. `TypeIs`
is invariant with respect to the `TypeIs` return type: `TypeIs[int]` is
neither a subtype nor a supertype of `TypeIs[bool]`. When ty sees a
function marked as returning `TypeIs[T]`, its `return`s will be checked
against `bool` instead. ty will also report such functions if they don't
accept a positional argument. Addtionally, a type narrowing function
call with no positional arguments (e.g., `f()` in the example above)
will be considered invalid.

## Test Plan

Markdown tests.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-06-13 15:27:45 -07:00
..
module_resolver [ty] Infer the Python version from --python=<system installation> on Unix (#18550) 2025-06-11 14:32:33 +00:00
semantic_index [ty] Delay computation of 'unbound' visibility for implicit instance attributes (#18669) 2025-06-13 12:50:57 -07:00
types [ty] Add partial support for TypeIs (#18589) 2025-06-13 15:27:45 -07:00
util [ty] Infer the Python version from --python=<system installation> on Unix (#18550) 2025-06-11 14:32:33 +00:00
ast_node_ref.rs [ty] AST garbage collection (#18482) 2025-06-13 08:40:11 -04:00
db.rs [ty] Infer the Python version from the environment if feasible (#18057) 2025-05-30 21:22:51 +00:00
dunder_all.rs [ty] Add infrastructure for AST garbage collection (#18445) 2025-06-05 11:43:18 -04:00
lib.rs [ty] Pull types on synthesized Python files created by mdtest (#18539) 2025-06-12 10:32:17 +01:00
lint.rs [ty] Ignore possibly-unresolved-reference by default (#17934) 2025-05-08 17:44:56 +02:00
list.rs Switch to Rust 2024 edition (#18129) 2025-05-16 13:25:28 +02:00
module_name.rs [ty] AST garbage collection (#18482) 2025-06-13 08:40:11 -04:00
node_key.rs [ty] AST garbage collection (#18482) 2025-06-13 08:40:11 -04:00
place.rs [ty] Add support for global __debug__ constant (#18540) 2025-06-10 06:48:59 +00:00
program.rs [ty] Infer the Python version from --python=<system installation> on Unix (#18550) 2025-06-11 14:32:33 +00:00
pull_types.rs [ty] Pull types on synthesized Python files created by mdtest (#18539) 2025-06-12 10:32:17 +01:00
python_platform.rs Switch to Rust 2024 edition (#18129) 2025-05-16 13:25:28 +02:00
semantic_index.rs [ty] Add infrastructure for AST garbage collection (#18445) 2025-06-05 11:43:18 -04:00
semantic_model.rs [ty] Add infrastructure for AST garbage collection (#18445) 2025-06-05 11:43:18 -04:00
site_packages.rs [ty] Track the origin of the environment.python setting for better error messages (#18483) 2025-06-06 13:36:41 +01:00
suppression.rs [ty] Add infrastructure for AST garbage collection (#18445) 2025-06-05 11:43:18 -04:00
types.rs [ty] Add partial support for TypeIs (#18589) 2025-06-13 15:27:45 -07:00
unpack.rs [ty] Add infrastructure for AST garbage collection (#18445) 2025-06-05 11:43:18 -04:00