Skip to content

Widen ty_python_semantic visibility to pub#1

Closed
knutwannheden wants to merge 261 commits intomainfrom
crisp-axolotl
Closed

Widen ty_python_semantic visibility to pub#1
knutwannheden wants to merge 261 commits intomainfrom
crisp-axolotl

Conversation

@knutwannheden
Copy link

Summary

  • Adds widen_ty_visibility.sh script that automates widening pub(crate) and pub(super) visibility modifiers to pub in ty_python_semantic
  • Runs the script to widen visibility across 107 files in the crate

This enables downstream consumers (like OpenRewrite) to access internal types from ty_python_semantic.

Test plan

  • cargo check -p ty_python_semantic passes (209 warnings, no errors)

dylwil3 and others added 30 commits February 19, 2026 16:15
…-sh#23431)

This changes the names of concurrency groups in most of our workflows to
use their hard-coded names instead of the name of the workflow that
triggered them (e.g. `build-wasm-...` and `build-binaries-...` instead
of `Release -...` for both). Hopefully this will reduce the number of
times the jobs butt heads.

I did not make this change for the CI workflow or for the Daily Fuzz
workflow since it didn't seem relevant for those, but let me know if I
should.
…al-sh#22205)

## Summary
This PR implements the `consider-swap-variables` rule from pylint.
Basically it tries to find code parts that swap two variables with each
other using a temporary variable.

Example code:
```py
temp = x
x = y
y = temp
```

can be simplified to

```py
x, y = y, x
```

related:
-
https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/consider-swap-variables.html
- astral-sh#970 

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
I've added new snapshots tests.

PS: Since this is my first contribution here and I'm not too familiar
with the codebase, suggestions are very welcome! The implementation
might also not be 100% memory-optimized yet, since we use `clone` a few
times.
…astral-sh#23406)

Closes astral-sh/uv#14874
Closes astral-sh#23402

uv has fairly extensive test coverage for this functionality but it
seems challenging to copy it over

My smoke test strategy was to ask an LLM to build the wheel and test all
of the cases

```
$ uv build --wheel
Building wheel...
Successfully built dist/ruff-0.15.1-py3-none-macosx_11_0_arm64.whl

$ WHEEL=dist/ruff-0.15.1-py3-none-macosx_11_0_arm64.whl

$ uv venv -q .smoke-venv && uv pip install -q --python .smoke-venv $WHEEL
$ .smoke-venv/bin/python -c "from ruff import find_ruff_bin; print(find_ruff_bin())"
/Users/zb/workspace/ruff/.smoke-venv/bin/ruff

$ .smoke-venv/bin/python -m ruff version
ruff 0.15.1+81 (1e42d4f 2026-02-18)

$ uv run --no-project --with $WHEEL -- python -c "from ruff import find_ruff_bin; print(find_ruff_bin())"
/Users/zb/.cache/uv/archive-v0/zf7_vNji2jmEGEDox-9Vj/bin/ruff

$ uv run --no-project --with $WHEEL -- python -m ruff version
ruff 0.15.1+81 (1e42d4f 2026-02-18)

$ uv pip install --target .smoke-target $WHEEL
$ PYTHONPATH=.smoke-target python3 -c "from ruff import find_ruff_bin; print(find_ruff_bin())"
/Users/zb/workspace/ruff/.smoke-target/bin/ruff

$ uv pip install --prefix .smoke-prefix $WHEEL
$ PYTHONPATH=.smoke-prefix/lib/python3.14/site-packages python3 -c "from ruff import find_ruff_bin; print(find_ruff_bin())"
/Users/zb/workspace/ruff/.smoke-prefix/bin/ruff

$ python3 -m pip install --user --break-system-packages $WHEEL                                                                                                                        
$ python3 -c "from ruff import find_ruff_bin; print(find_ruff_bin())"                                                                                                                                             
/Users/zb/Library/Python/3.13/bin/ruff                                                                                                                                                                            
                                                                                                                                                                                                                  
$ python3 -m ruff version                                                                                                                                                                                         
ruff 0.15.1+81 (1e42d4f 2026-02-18)   
```
…-sh#23437)

## Summary

When unpacking a "mixed tuple" like `tuple[I0, *tuple[I1, ...], I2]`
with a starred expression (e.g., `[a, b, *c] = x`), ty incorrectly
inferred `I1` for `b` instead of `I1 | I2`. The variable-length part can
materialize to 0 elements, causing `I2` to shift into the `b` position,
so the correct type is the union `I1 | I2`.

Closes: astral-sh/ty#947.
…sh#23444)

## Summary

What it says in the title

## Test Plan

New Markdown tests
…3440)

## Summary

Fix a small typo in the description of a rule

## Test Plan

n/a
…23300)

## Summary          

Closes astral-sh#13141
  
Adds a new rule `unnecessary-assign-before-yield` (`RUF070`) that
detects variable assignments immediately followed by a `yield` (or
`yield from`) of that variable, where the variable is not referenced
anywhere else. This is the `yield` equivalent of `RET504`
(`unnecessary-assign`).

  ```python
  # Before
  def gen():
      x = 1
      yield x

  # After
  def gen():
      yield 1
```

 Unlike return, yield does not exit the function, so the rule only triggers when the binding has exactly one reference (the yielditself). The fix is marked as unsafe for the same reason.

## Test Plan

cargo nextest run -p ruff_linter -- RUF070

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
…h#22149)

**Summary:**

Fixes UP032 autofix incorrectly converting raw strings with `\N{...}` to
f-strings, which changes semantics and causes runtime errors.

Fixes astral-sh#22060 

## Test Plan

- Added test case for raw strings with \N{...}
- Regular strings with \N{...} still autofix correctly
- All 119 pyupgrade tests pass

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
)

## Summary
Stop raising return-in-generator with pytest hook wrappers
(@hookimpl(wrapper=True)). They are specifically designed to use this
pattern:
https://docs.pytest.org/en/stable/how-to/writing_hook_functions.html#hook-wrappers-executing-around-other-hooks

Before: return-in-generator reports would surface with pytest hook
wrappers

After: specifically check for pytest hook wrappers before reporting
return-in-generator

Testing:
Wrote some tests to cover different cases

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
…nal file

This happened whenever:

* Diagnostic mode was set to `openFilesOnly`
* One opened and then closed an external file (or caused the
  LSP client to send notifications that a file was closed, which
  may happen even when the end user doesn't actually open or close
  a file)

When this happened, the entire open file set was cleared. This in turn
resulted in `should_check_file` returning `false` for any file
previously in the open file set. And thus, we'd never get any
diagnostics.

Looking at our revision history, it seems like this bug has been
present for a long time? I'm not sure. However, this bug doesn't apply
when the diagnostic mode is set to `workspace`, which might explain
why it defied reproduction.

I've also included a regression test and some extra TRACE level logs
that might help diagnose these sorts of problems in the future.

Fixes astral-sh/ty-vscode#342
## Summary

If a generic function's return type depends on a type variable, and the
argument passed resolves that type variable to `Never`, the call should
still be treated as terminal:

```py
def identity[T](x: T) -> T:
    return x

def f() -> Never:
    identity(exit())  # should be detected as terminal
```

This is a tiny win for correctness, but unfortunately a small drop in
performance and slight increase in memory usage, because we need to
infer more call expressions upfront. If we think it's not important
enough, I'm also okay to change this to a test-only PR that documents
this as a known limitation. If we merge it, I might follow up with an
idea to simplify the code in a [slightly larger refactoring
PR](astral-sh#23378).

## Memory usage

Insignificant changes on some large internal projects, a 2% *decrease*
in memory usage when running on home-assistant/core.

## Ecosystem

No ecosystem changes, as far as I can tell.

## Test Plan

New Markdown tests
## Summary

This PR implements the following paragraph in the typing spec:

> Type checkers should infer a final attribute that is initialized in a
class body as being a class variable, except in the case of
[Dataclasses](https://typing.python.org/en/latest/spec/dataclasses.html),
where `x: Final[int] = 3` creates a dataclass field and instance-level
final attribute `x` with default value `3`; `x: ClassVar[Final[int]] =
3` is necessary to create a final class variable with value `3`. In
non-dataclasses, combining `ClassVar` and `Final` is redundant, and type
checkers may choose to warn or error on the redundancy.
>
>
https://typing.python.org/en/latest/spec/qualifiers.html#semantics-and-examples

## Test Plan

New Markdown tests
## Summary

Pulls in two recent changes that we made to the conformance test suite.

## Test Plan

Checked that this [improves
conformance](https://shark.fish/typing-conformance-report/) :-)
…stral-sh#23346)

## Summary

* The first commit modernizes the `LiteralString` test suite.
* The second commit adds more precise type inference for
`f"{literal_str_a} {literal_str_b}"` to make a conformance test pass.


## Test Plan

Updated and new Markdown tests
…ral-sh#23453)

Closes astral-sh#23452 

## Summary

Adds `DiagnosticTag::Unnecessary` to B007 diagnostics only when
certainty is Certain, so editors can dim definitely-unused loop control
variables without dimming uncertain cases.

## Test Plan

Added new test and manually tested in VSCode.

<img width="485" height="227" alt="image"
src="https://github.com/user-attachments/assets/b41c85f1-0a2e-4e6d-987c-0cb62ec96513"
/>
AlexWaygood and others added 23 commits March 7, 2026 15:47
## Summary

For now, we keep our sections as-is, but within each section, we show
all the eager imports followed by all the lazy imports, e.g.:

```python
import json
import os
import subprocess
from collections import defaultdict
from pathlib import Path
from typing import Final
lazy import ast
lazy import shutil
lazy from dataclasses import dataclass
```

We may change this behavior later; it shouldn't be considered stable.

See: astral-sh#21305.
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[actions/download-artifact](https://redirect.github.com/actions/download-artifact)
| action | major | `v7.0.0` → `v8.0.0` |
|
[actions/upload-artifact](https://redirect.github.com/actions/upload-artifact)
| action | major | `v6.0.0` → `v7.0.0` |

---

### Release Notes

<details>
<summary>actions/download-artifact (actions/download-artifact)</summary>

###
[`v8.0.0`](https://redirect.github.com/actions/download-artifact/releases/tag/v8.0.0)

[Compare
Source](https://redirect.github.com/actions/download-artifact/compare/v7.0.0...v8.0.0)

##### v8 - What's new

##### Direct downloads

To support direct uploads in `actions/upload-artifact`, the action will
no longer attempt to unzip all downloaded files. Instead, the action
checks the `Content-Type` header ahead of unzipping and skips non-zipped
files. Callers wishing to download a zipped file as-is can also set the
new `skip-decompress` parameter to `false`.

##### Enforced checks (breaking)

A previous release introduced digest checks on the download. If a
download hash didn't match the expected hash from the server, the action
would log a warning. Callers can now configure the behavior on mismatch
with the `digest-mismatch` parameter. To be secure by default, we are
now defaulting the behavior to `error` which will fail the workflow run.

##### ESM

To support new versions of the @&astral-sh#8203;actions/\* packages, we've
upgraded the package to ESM.

##### What's Changed

- Don't attempt to un-zip non-zipped downloads by
[@&astral-sh#8203;danwkennedy](https://redirect.github.com/danwkennedy) in
[#&astral-sh#8203;460](https://redirect.github.com/actions/download-artifact/pull/460)
- Add a setting to specify what to do on hash mismatch and default it to
`error` by
[@&astral-sh#8203;danwkennedy](https://redirect.github.com/danwkennedy) in
[#&astral-sh#8203;461](https://redirect.github.com/actions/download-artifact/pull/461)

**Full Changelog**:
<actions/download-artifact@v7...v8.0.0>

</details>

<details>
<summary>actions/upload-artifact (actions/upload-artifact)</summary>

###
[`v7.0.0`](https://redirect.github.com/actions/upload-artifact/releases/tag/v7.0.0)

[Compare
Source](https://redirect.github.com/actions/upload-artifact/compare/v6.0.0...v7.0.0)

#### v7 What's new

##### Direct Uploads

Adds support for uploading single files directly (unzipped). Callers can
set the new `archive` parameter to `false` to skip zipping the file
during upload. Right now, we only support single files. The action will
fail if the glob passed resolves to multiple files. The `name` parameter
is also ignored with this setting. Instead, the name of the artifact
will be the name of the uploaded file.

##### ESM

To support new versions of the `@actions/*` packages, we've upgraded the
package to ESM.

#### What's Changed

- Add proxy integration test by
[@&astral-sh#8203;Link-](https://redirect.github.com/Link-) in
[#&astral-sh#8203;754](https://redirect.github.com/actions/upload-artifact/pull/754)
- Upgrade the module to ESM and bump dependencies by
[@&astral-sh#8203;danwkennedy](https://redirect.github.com/danwkennedy) in
[#&astral-sh#8203;762](https://redirect.github.com/actions/upload-artifact/pull/762)
- Support direct file uploads by
[@&astral-sh#8203;danwkennedy](https://redirect.github.com/danwkennedy) in
[#&astral-sh#8203;764](https://redirect.github.com/actions/upload-artifact/pull/764)

#### New Contributors

- [@&astral-sh#8203;Link-](https://redirect.github.com/Link-) made their first
contribution in
[#&astral-sh#8203;754](https://redirect.github.com/actions/upload-artifact/pull/754)

**Full Changelog**:
<actions/upload-artifact@v6...v7.0.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/ruff).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW50ZXJuYWwiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This branch (ty-types-2) is a fork of astral-sh/ruff that widens
visibility in ty_python_semantic from pub(crate)/pub(super) to pub
for consumption by OpenRewrite.

To sync with upstream:  scripts/widen_ty_visibility.sh
To sync and run tests:  scripts/widen_ty_visibility.sh --test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.