Commit Graph

1289 Commits

Author SHA1 Message Date
Ibraheem Ahmed
fba4ac1dc6 improve literal promotion tests 2026-01-09 16:36:14 -05:00
Ibraheem Ahmed
d6d0b44fdb preserve bounds and constraints on synthetic type variables 2026-01-09 16:36:12 -05:00
Ibraheem Ahmed
5ed810a5d9 avoid creating invalid type mappings during synthetic inference 2026-01-09 16:35:49 -05:00
Ibraheem Ahmed
4812707fd7 avoid marking synthesized type variables as inferable unnecessarily 2026-01-09 16:35:48 -05:00
Ibraheem Ahmed
540593587d inform literal promotion with variance of inferred argument types 2026-01-09 16:34:53 -05:00
Alex Waygood
dc61104726 [ty] Derive Default in a few more places in place.rs (#22481) 2026-01-09 18:37:36 +00:00
Andrew Gallant
e9cc2f6f42 [ty] Refactor completion construction to use a builder
I want to be able to attach extra data to each `Completion`, but not
burden callers with the need to construct it. This commit helps get us
to that point by requiring callers to use a `CompletionBuilder` for
construction instead of a `Completion` itself.

I think this will also help in the future if it proves to be the case
that we can improve performance by delaying work until we actually build
a `Completion`, which might only happen if we know we won't throw it
out. But we aren't quite there yet.

This also lets us tighten things up a little bit and makes completion
construction less noisy. The downside is that callers no longer need to
consider "every" completion field.

There should not be any behavior changes here.
2026-01-09 09:55:32 -05:00
Micha Reiser
e61657ff3c [ty] Enable unused-type-ignore-comment by default (#22474) 2026-01-09 10:58:43 +00:00
Micha Reiser
ba5dd5837c [ty] Pass slice to specialize (#22421) 2026-01-09 09:45:39 +01:00
Carl Meyer
f9f7a6901b Complete minor TODO in ty_python_semantic crate (#22468)
This TODO is very old -- we have long since recorded this definition.
Updating the test to actually assert the declaration requires a new
helper method for declarations, to complement the existing
`first_public_binding` helper.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-08 16:04:34 -08:00
Douglas Creager
701f5134ab [ty] Only consider fully static pivots when deriving transitive constraints (#22444)
When working with constraint sets, we track transitive relationships
between the constraints in the set. For instance, in `S ≤ int ∧ int ≤
T`, we can infer that `S ≤ T`. However, we should only consider fully
static types when looking for a "pivot" for this kind of transitive
relationship. The same pattern does not hold for `S ≤ Any ∧ Any ≤ T`;
because the two `Any`s can materialize to different types, we cannot
infer that `S ≤ T`.

Fixes https://github.com/astral-sh/ty/issues/2371
2026-01-08 09:31:55 -05:00
Alex Waygood
eeac2bd3ee [ty] Optimize union building for unions with many enum-literal members (#22363) 2026-01-08 10:50:04 +00:00
Charlie Marsh
68a2f6c57d [ty] Fix super() with TypeVar-annotated self and cls parameter (#22208)
## Summary

This PR fixes `super()` handling when the first parameter (`self` or
`cls`) is annotated with a TypeVar, like `Self`.

Previously, `super()` would incorrectly resolve TypeVars to their bounds
before creating the `BoundSuperType`. So if you had `self: Self` where
`Self` is bounded by `Parent`, we'd process `Parent` as a
`NominalInstance` and end up with `SuperOwnerKind::Instance(Parent)`.

As a result:

```python
class Parent:
    @classmethod
    def create(cls) -> Self:
        return cls()

class Child(Parent):
    @classmethod
    def create(cls) -> Self:
        return super().create()  # Error: Argument type `Self@create` does not satisfy upper bound `Parent`
```

We now track two additional variants on `SuperOwnerKind` for TypeVar
owners:

- `InstanceTypeVar`: for instance methods where self is a TypeVar (e.g.,
`self: Self`).
- `ClassTypeVar`: for classmethods where `cls` is a `TypeVar` wrapped in
`type[...]` (e.g., `cls: type[Self]`).

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

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2026-01-07 19:56:09 -05:00
Alex Waygood
abaa735e1d [ty] Improve UnionBuilder performance by changing Type::is_subtype_of calls to Type::is_redundant_with (#22337) 2026-01-07 22:17:44 +00:00
Carl Meyer
30902497db [ty] Make signature return and parameter types non-optional (#22425)
## Summary

Fixes https://github.com/astral-sh/ty/issues/2363
Fixes https://github.com/astral-sh/ty/issues/2013

And several other bugs with the same root cause. And makes any similar
bugs impossible by construction.

Previously we distinguished "no annotation" (Rust `None`) from
"explicitly annotated with something of type `Unknown`" (which is not an
error, and results in the annotation being of Rust type
`Some(Type::DynamicType(Unknown))`), even though semantically these
should be treated the same.

This was a bit of a bug magnet, because it was easy to forget to make
this `None` -> `Unknown` translation everywhere we needed to. And in
fact we did fail to do it in the case of materializing a callable,
leading to a top-materialized callable still having (rust) `None` return
type, which should have instead materialized to `object`.

This also fixes several other bugs related to not handling un-annotated
return types correctly:
1. We previously considered the return type of an unannotated `async
def` to be `Unknown`, where it should be `CoroutineType[Any, Any,
Unknown]`.
2. We previously failed to infer a ParamSpec if the return type of the
callable we are inferring against was not annotated.
3. We previously wrongly returned `Unknown` from `some_dict.get("key",
None)` if the value type of `some_dict` included a callable type with
un-annotated return type.

We now make signature return types and annotated parameter types
required, and we eagerly insert `Unknown` if there's no annotation. Most
of the diff is just a bunch of mechanical code changes where we
construct these types, and simplifications where we use them.

One exception is type display: when a callable type has un-annotated
parameters, we want to display them as un-annotated, but if it has a
parameter explicitly annotated with something of `Unknown` type, we want
to display that parameter as `x: Unknown` (it would be confusing if it
looked like your annotation just disappeared entirely).

Fortunately, we already have a mechanism in place for handling this: the
`inferred_annotation` flag, which suppresses display of an annotation.
Previously we used it only for `self` and `cls` parameters with an
inferred annotated type -- but we now also set it for any un-annotated
parameter, for which we infer `Unknown` type.

We also need to normalize `inferred_annotation`, since it's display-only
and shouldn't impact type equivalence. (This is technically a
previously-existing bug, it just never came up when it only affected
self types -- now it comes up because we have tests asserting that `def
f(x)` and `def g(x: Unknown)` are equivalent.)

## Test Plan

Added mdtests.
2026-01-07 09:18:39 -08:00
Alex Waygood
3ad99fb1f4 [ty] Fix an mdtest title (#22439) 2026-01-07 16:34:56 +00:00
Andrew Gallant
952193e0c6 [ty] Offer completions for T when a value has type Unknown | T
Fixes astral-sh/ty#2197
2026-01-07 10:15:36 -05:00
Alex Waygood
4cba2e8f91 [ty] Generalize len() narrowing somewhat (#22330) 2026-01-07 13:57:50 +00:00
Alex Waygood
1a7f53022a [ty] Link to Callable __name__ FAQ directly from unresolved-attribute diagnostic (#22437) 2026-01-07 13:22:53 +00:00
Micha Reiser
93039d055d [ty] Add --add-ignore CLI option (#21696) 2026-01-07 11:17:05 +01:00
Alex Waygood
5933cc0101 [ty] Optimize and simplify some object-related code (#22366)
## Summary

I wondered if this might improve performance a little. It doesn't seem
to, but it's a net reduction in LOC and I think the changes make sense.
I think it's worth it anyway just in terms of simplifying the code.

## Test Plan

Our existing tests all pass and the primer report is clean (aside from
our usual flakes).
2026-01-07 08:35:26 +00:00
Dhruv Manilawala
2190fcebe0 [ty] Substitute ParamSpec in overloaded functions (#22416)
## Summary

fixes: https://github.com/astral-sh/ty/issues/2027

This PR fixes a bug where the type mapping for a `ParamSpec` was not
being applied in an overloaded function.

This PR also fixes https://github.com/astral-sh/ty/issues/2081 and
reveals new diagnostics which doesn't look related to the bug:

```py
from prefect import flow, task

@task
def task_get() -> int:
    """Task get integer."""
    return 42

@task
def task_add(x: int, y: int) -> int:
    """Task add two integers."""
    print(f"Adding {x} and {y}")
    return x + y

@flow
def my_flow():
    """My flow."""
    x = 23
    future_y = task_get.submit()

	# error: [no-matching-overload]
    task_add(future_y, future_y)
	# error: [no-matching-overload]
    task_add(x, future_y)
```

The reason is that the type of `future_y` is `PrefectFuture[int]` while
the type of `task_add` is `Task[(x: int, y: int), int]` which means that
the assignment between `int` and `PrefectFuture[int]` fails which
results in no overload matching. Pyright also raises the invalid
argument type error on all three usages of `future_y` in those two
calls.

## Test Plan

Add regression mdtest from the linked issue.
2026-01-07 13:30:34 +05:30
Douglas Creager
df9d6886d4 [ty] Remove redundant apply_specialization type mappings (#22422)
@dhruvmanila encountered this in #22416 — there are two different
`TypeMapping` variants for apply a specialization to a type. One
operates on a full `Specialization` instance, the other on a partially
constructed one. If we move this enum-ness "down a level" it reduces
some copy/paste in places where we are operating on a `TypeMapping`.
2026-01-07 13:10:26 +05:30
Carl Meyer
f97da18267 [ty] improve typevar solving from constraint sets (#22411)
## Summary

Fixes https://github.com/astral-sh/ty/issues/2292

When solving a bounded typevar, we preferred the upper bound over the
actual type seen in the call. This change fixes that.

## Test Plan

Added mdtest, existing tests pass.
2026-01-06 13:10:51 -08:00
Alex Waygood
bc191f59b9 Convert more ty snapshots to the new format (#22424) 2026-01-06 20:01:41 +00:00
Alex Waygood
2ec29b7418 [ty] Optimize Type::negate() (#22402) 2026-01-06 19:17:59 +00:00
Jack O'Connor
ab1ac254d9 [ty] fix comparisons and arithmetic with NewTypes of float (#22105)
Fixes https://github.com/astral-sh/ty/issues/2077.
2026-01-06 09:32:22 -08:00
Charlie Marsh
01de8bef3e [ty] Add named fields for Place enum (#22172)
## Summary

Mechanical refactor to migrate this enum to named fields. No functional
changes.

See:
https://github.com/astral-sh/ruff/pull/22093#discussion_r2636050127.

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 17:24:51 +00:00
Charlie Marsh
b59f6eb5e9 [ty] Support comparisons between variable-length tuples (#21824)
## Summary

Closes https://github.com/astral-sh/ty/issues/1741.
2026-01-06 12:09:40 -05:00
Charlie Marsh
d65542c05e [ty] Make tuple intersection a fallible operation (#22094)
## Summary

This PR attempts to address a TODO in
https://github.com/astral-sh/ruff/pull/21965#discussion_r2635378498.
2026-01-06 10:47:04 -05:00
Charlie Marsh
8b8b174e4f [ty] Add a diagnostic for @functools.total_ordering without a defined comparison method (#22183)
## Summary

This raises a `ValueError` at runtime:

```python
from functools import total_ordering

@total_ordering
class NoOrdering:
    def __eq__(self, other: object) -> bool:
        return True
```

Specifically:

```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/functools.py", line 193, in total_ordering
    raise ValueError('must define at least one ordering operation: < > <= >=')
ValueError: must define at least one ordering operation: < > <= >=
```

See: https://github.com/astral-sh/ty/issues/1202.
2026-01-06 04:14:06 +00:00
Charlie Marsh
28fa02129b [ty] Add support for @total_ordering (#22181)
## Summary

We have some suppressions in the pyx codebase related to this, so wanted
to resolve.

Closes https://github.com/astral-sh/ty/issues/1202.
2026-01-05 22:47:03 -05:00
Jack O'Connor
922d964bcb [ty] emit diagnostics for method definitions and other invalid statements in TypedDict class bodies (#22351)
Fixes https://github.com/astral-sh/ty/issues/2277.
2026-01-05 11:28:04 -08:00
Jack O'Connor
4712503c6d [ty] cargo insta test --force-update-snapshots (#22313)
Snapshot tests recently started reporting this warning:

> Snapshot test passes but the existing value is in a legacy format.
> Please run cargo insta test --force-update-snapshots to update to a
> newer format.

This PR is the result of that forced update.

One file (crates/ruff_db/src/diagnostic/render/full.rs) seems to get
corrupted, because it contains strings with unprintable characters that
trigger some bug in cargo-insta. I've manually reverted that file, and
also manually reverted the `input_file:` lines, which we like.
2026-01-05 07:55:47 -08:00
Alex Waygood
f3dea6e5c9 [ty] Optimize IntersectionType for the common case of a single negated element (#22344)
Co-authored-by: Micha Reiser <micha@reiser.io>
2026-01-05 13:41:50 +00:00
Micha Reiser
24dd149e03 [ty] Extract relation module from types.rs (#22232) 2026-01-05 13:16:49 +00:00
Alex Waygood
b8d527ff46 [ty] Optimize and simplify UnionElement::try_reduce (#22339) 2026-01-05 12:54:44 +00:00
Charlie Marsh
92a2f2c992 [ty] Apply class decorators via try_call() (#22375)
## Summary

Decorators are now called with the class as an argument, and the return
type becomes the class's type. This mirrors how function decorators
already work.

Closes https://github.com/astral-sh/ty/issues/2313.
2026-01-04 17:11:00 -05:00
Micha Reiser
b85c0190c5 [ty] Use upstream GetSize implementation for OrderMap and OrderSet (#22374) 2026-01-04 19:54:03 +00:00
Micha Reiser
46a4bfc478 [ty] Use default HashSet for TypeCollector (#22368) 2026-01-04 18:58:30 +00:00
Alex Waygood
e1439beab2 [ty] Use UnionType helper methods more consistently (#22357) 2026-01-03 14:19:06 +00:00
Felix Scherz
fd86e699b5 [ty] narrow TypedDict unions with not in (#22349)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2026-01-03 13:12:57 +00:00
Alex Waygood
10a417aaf6 [ty] Specify heap_size for SynthesizedTypedDictType (#22345) 2026-01-02 20:09:35 +00:00
Matthew Mckee
a2e0ff57c3 Run cargo sort (#22310) 2026-01-02 19:58:15 +00:00
Alex Waygood
26230b1ed3 [ty] Use IntersectionType::from_elements more (#22329) 2026-01-01 15:01:00 +00:00
github-actions[bot]
8e45bac3c1 [ty] Sync vendored typeshed stubs (#22321)
Co-authored-by: typeshedbot <>
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2026-01-01 01:29:12 +00:00
Charlie Marsh
f619783066 [ty] Treat __setattr__ as fallback-only (#22014)
## Summary

Closes https://github.com/astral-sh/ty/issues/1460.
2025-12-30 19:01:10 -05:00
Ibraheem Ahmed
ff05428ce6 [ty] Subtyping for bidirectional inference (#21930)
## Summary

Supersedes https://github.com/astral-sh/ruff/pull/21747. This version
uses the constraint solver directly, which means we should benefit from
constraint solver improvements for free.

Resolves https://github.com/astral-sh/ty/issues/1576.
2025-12-30 17:03:20 -05:00
Charlie Marsh
12dd27da52 [ty] Support narrowing for tuple matches with literal elements (#22303)
## Summary

See:
https://github.com/astral-sh/ruff/pull/22299#issuecomment-3699913849.
2025-12-30 13:45:07 -05:00
github-actions[bot]
7173c7ea3f [ty] Sync vendored typeshed stubs (#22302)
Co-authored-by: typeshedbot <>
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2025-12-30 17:24:13 +00:00