101 Commits
Author SHA1 Message Date
astral-automations-bot[bot]andBrent Westbrook ba65abf8ba Bump version to 0.17.3 (#29745)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2026-10-26 20:14:27 -04:00
astral-automations-bot[bot]andBrent Westbrook 30516b42ab Bump version to 0.17.2 (#29637)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2026-10-22 13:54:24 -04:00
astral-automations-bot[bot] 4683270c69 Bump version to 0.17.1 (#29420)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
2026-10-15 10:56:41 -04:00
Shantanu Pradhan 523d83c941 Treat more collections and weakref containers as mutable (#29213)
## Summary

Closes #25173

This PR changes behavior of flake8-bugbear in regard to
`weakref.WeakKeyDictionary`, `weakref.WeakValueDictionary`,
`weakref.WeakSet`, `collections.ChainMap`, `collections.UserDict`,
`collections.UserList`, and `collections.UserString`, so that instead of
reporting the error B008 ("function call in argument defaults"), it
reports B006 ("mutable data structures for argument defaults"). These
types are similar to `dict` and `list` in terms of being containers and
are considered to be mutable, and therefore are suitable for B006,
allowing for fixing the code via replacing a default value with `None`
and making the object construction inside the body of the function.

### Implementation details

In this PR, those seven types are added to `is_mutable_return_type` in
`crates/ruff_python_stdlib/src/typing.rs` file along with other types
like `dict`, `list`, `set`, `Counter`, `OrderedDict`, `defaultdict`, and
`deque`. As B008 purposefully skips objects matching
`is_mutable_return_type` condition, this solves the categorization
mistake while avoiding duplicates.

As discussed with maintainers, this change doesn't use `--preview`
option. Because `is_mutable_return_type` is a shared helper, another
side effect of this PR is that B039, RUF008, RUF012, RUF024, and PLW2901
rules will also treat those seven types as mutable data structures.
According to the review comments, `collections.UserList` and
`collections.UserString` are also included; even though `str` is
immutable, a `UserString` instance is mutable due to `.data` attribute
being reassignable.

## Test Plan

A new mdtest was added at
`crates/ruff_linter/resources/mdtest/flake8-bugbear/mutable-argument-default.md`.

The new mdtest is set up to generate results for B006 and B008 and to
include a single import case per type. The purpose of the test is to
verify that B006 is triggered and that B008 ignores all those seven
types strictly.

No `ruff_linter` snapshot changes in the existing tests. Ecosystem check
results come from CI.
2026-10-14 15:38:11 +00:00
astral-automations-bot[bot]andBrent Westbrook 5b27c1ccfa Bump version to 0.17.0 (#29259)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2026-10-09 13:45:29 -04:00
astral-automations-bot[bot]andBrent Westbrook 3265ed1f94 Bump version to 0.16.10 (#29055)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2026-10-01 13:40:09 -04:00
astral-automations-bot[bot]andBrent Westbrook 0be08a206f Bump version to 0.16.9 (#28882)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2026-09-24 16:21:50 -04:00
astral-automations-bot[bot]andBrent Westbrook 62914c4b9b Bump version to 0.16.8 (#28648)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2026-09-16 11:31:02 -04:00
Brent Westbrook 652bfea146 Recognize quoted types in typing.TypeForm (#28507)
Summary
--

`typing.TypeForm` was introduced in Python 3.15 and [PEP
747](https://peps.python.org/pep-0747/) as
a way to annotate the passing of type objects like `int | str`,
`list[int]`, or `MyTypeAlias`. It
can be used either as a subscripted generic, as in this example from the
PEP:

```py
from typing import TypeForm

def trycast[T](typx: TypeForm[T], value: object) -> T | None: ...
```

or as a callable, which returns its argument unchanged:

```py
from typing import TypeForm

TypeForm("list[int]")
```

This PR recognizes `typing.TypeForm` as a standard-library generic and
as a known `typing` callable
and visits its argument or subscript as a type definition.

While I was reading the [typing docs], I realized that a couple of
nearby types were also not
listed, so I've attempted to sneak them in here but could split them off
if needed. We already had
coverage for `typing.TypeGuard` but not `typing_extensions.TypeGuard`
(added in 3.10), and we were
missing both variants of `TypeIs` (added in 3.13). These are only valid
in the subscript form, so
they don't need new `Callable` entries.

[typing docs]:
https://docs.python.org/3.15/library/typing.html#typing.TypeForm

Test Plan
--

New mdtests, using `unused-import` (`F401`) to demonstrate that visiting
these arguments as type
definitions marks them as used, but other rules will be affected as
well.
2026-09-11 14:12:38 +00:00
astral-automations-bot[bot]andBrent Westbrook b5dba861cc Bump version to 0.16.7 (#28496)
Co-authored-by: astral-automations-bot[bot] <305554984+astral-automations-bot[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2026-09-10 13:47:30 -04:00
Brent Westbrook 609e184aa3 Stop defining __cached__ for Python 3.15 (#28476)
Summary
--

This moves `__cached__` from the main list of `MAGIC_GLOBALS` to a
version-specific list because it will be
[removed](https://docs.python.org/3/reference/datamodel.html#module.__cached__)
in 3.15.

Test Plan
--

A new mdtest for `undefined-name` (`F821`), which is just one of the
rules affected but the easiest to test.
2026-09-10 09:10:00 -04:00
Brent WestbrookandAlex Waygood a02a6b8821 Recognize slice and frozendict generics (#28477)
Summary
--

This PR updates our standard library generic recognition to include
`frozendict` and `slice`. `F401`
is just an example of an affected rule because we visit the subscript
arguments of known stdlib
generics as type expressions:


https://github.com/astral-sh/ruff/blob/275e6112e4c5d383179efaa424c8d774acf9fe58/crates/ruff_linter/src/checkers/ast/mod.rs#L2177-L2181

Test Plan
--

mdtests including `F401` to exercise the new behavior

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2026-09-09 22:19:53 +00:00
Gore Williams 118c14fc4e [pylint] Gate ImportCycleError on Python 3.15 (PLW0133) (#28310)
Fix PLW0133's Python version gating for `ImportCycleError`.

`ImportCycleError` was added in Python 3.15, but Ruff currently treats
it as available starting in Python 3.13.

This updates the builtin exception classification so that:

- `PythonFinalizationError` remains available for Python 3.13+
- `ImportCycleError` is only considered available for Python 3.15+

Also adds regression coverage for the behavior across target Python
versions.

Closes part of #28206.
2026-09-04 15:53:58 -04:00
Brent Westbrook 22f65a2ab5 Bump 0.16.6 (#28280) 2026-09-03 12:36:42 -04:00
Brent Westbrook 9e4938c4a6 Bump 0.16.5 (#28110) 2026-08-27 12:09:07 -04:00
Brent Westbrook 11c76bf48f Bump 0.16.4 (#27937) 2026-08-20 13:14:29 -04:00
Ross Titmarsh 4d813d53cd Fix broken link to Python docs (#27757)
Fixed a link to `frozen.discard` in the Python docs this was a valid
link in older Python docs but has been broken.

While I was there I noticed a few other uncanonical links so replaced
them with more canonical versions and removed some links to specific
Python versions that are unnecessary.
2026-08-14 16:08:37 +00:00
Brent Westbrook b0e47022cf Bump 0.16.3 (#27723) 2026-08-13 09:39:16 -04:00
Alex Waygood c0824de94a Enable rustfmt on more files (#27630) 2026-08-10 15:30:41 +01:00
Brent Westbrook 5b48a04097 Bump 0.16.2 (#27555) 2026-08-07 09:12:50 -04:00
Charlie Marsh 103168bd42 Remove unused APIs from ruff_python_stdlib (#27390)
## Summary

This PR removes an unused API from ruff_python_stdlib identified by Hawk
0.1.11. It is split from #27339 so the removal can be reviewed
independently at the crate boundary.

- 6 net lines removed
- 6 deletions
- 1 file changed
2026-08-01 02:32:19 +00:00
Charlie Marsh 6cfeb8aa07 Narrow internal visibility with Hawk (#27339)
## Summary

This PR uses Hawk 0.1.11 to narrow internal declarations to the
visibility they actually need.

Here, I've intentionally _only_ made visibility changes; unused API
removals are split into follow-up PRs. In total, 1,201 declaration
visibility modifiers are narrowed. Public generated formatter APIs and
other declarations whose narrower visibility would activate dead-code or
API-shape lints remain unchanged.
2026-07-31 22:08:13 -04:00
Brent Westbrook 80790b348b Bump 0.16.1 (#27330) 2026-07-30 13:54:42 -04:00
Brent Westbrook 154d1c10ad [flake8-bugbear] Mark range as immutable (B008) (#27247)
Summary
--

Fixes #27245.

Test Plan
--

Updated existing snapshots. These were previously emitting both B006 on
the outer comprehensions and
B008 on the inner `range` call, but now the inner diagnostic is omitted
because `range` is
immutable.
2026-07-28 12:15:12 -04:00
Brent Westbrook a2635fd8f3 Bump 0.16.0 (#27136) 2026-07-23 14:37:34 -04:00
Brent Westbrook 0177a7e0d2 Bump 0.15.22 (#26884) 2026-07-16 10:54:43 -04:00
Brent Westbrook 3e1f636451 Bump 0.15.21 (#26676) 2026-07-09 15:42:27 -04:00
Brent Westbrook f82a36b6ba Bump 0.15.20 (#26376) 2026-06-25 10:00:55 -07:00
Charlie Marsh 7f0436561d Bump version to 0.15.19 (#26291) 2026-06-23 20:42:26 -04:00
Charlie Marsh dff016b7a4 Publish Ruff crates to crates.io (#26271)
## Summary

Publish Ruff's production Rust crates to crates.io as part of the
existing release workflow. This follows uv's setup: workspace
dependencies carry registry-compatible version pins, internal crates
receive generated READMEs and an explicit versioning policy, CI dry-runs
the full workspace publish, and release jobs publish missing crate
versions idempotently through crates.io trusted publishing.

The publishing set contains 32 packages: Ruff's CLI, WASM package,
server, linter, formatter, parser, and the internal Ruff component
crates required by them. It also includes `ty_module_resolver`,
`ty_site_packages`, and `ty_static`, because those three crates are part
of Ruff's normal dependency closure.

The publishing set deliberately excludes:

- Test-only crates: `mdtest`, `ruff_mdtest`,
`ruff_python_ast_integration_tests`, and
`ruff_python_trivia_integration_tests`.
- Benchmark and development crates: `ruff_benchmark` and `ruff_dev`.
- All remaining `ty_*` crates.

These packages retain `publish = false`, so bootstrap, version bumping,
README generation, CI dry-runs, and release publishing skip them through
Cargo metadata instead of a separate hard-coded allowlist.

The crates.io job is intentionally independent of release announcement,
so a crates.io outage cannot block the existing binary, PyPI, npm, or
GitHub release outputs. A bootstrap script reserves new crate names,
configures the release workflow as each crate's trusted publisher,
enables trusted-publishing-only releases, and records configured crates
for idempotent reruns.

The full workspace publish dry-run packages and verifies all 32 selected
crates.

Closes https://github.com/astral-sh/ruff/issues/43.
2026-06-23 12:49:23 -04:00
Alex Waygood bd2d6f6353 Update/regenerate various ruff_python_stdlib APIs (#25273)
## Summary

1. Manually update various functions in
`crates/ruff_python_stdlib/src/builtins.rs` to reflect new APIs added in
Python 3.15.
2. Manually remove the incorrect inclusion of `frozenset` from
`is_immutable_non_generic_type` in
`crates/ruff_python_stdlib/src/typing.rs`. `frozenset` is a generic
type.
3. Manually add `frozendict` to `is_immutable_generic_type` and
`is_immutable_return_type` in `crates/ruff_python_stdlib/src/typing.rs`
4. Manually updates to `scripts/generate_builtin_modules.py`: use uv to
invoke Python rather than relying on many different Python versions all
being on `PATH`, drop support for Python 3.7 from the script (it can't
be installed using uv), and apply various other simplifications.
5. Regenerate `is_builtin_module` in
`crates/ruff_python_stdlib/src/sys/builtin_modules.rs` following the
changes made in (4). Note that switching to uv-managed Python installs
(PBS) appears to mean that quite a few more stdlib modules are
recognised as being builtin modules, which is interesting.

I also ran `scripts/generate_known_standard_library.py`, but it didn't
make any changes to the Rust function generated by that script.

## Test Plan

`cargo test`
2026-05-20 14:19:10 +01:00
Charlie Marsh de64770066 Treat generic frozenset annotations as immutable (#25251)
## Summary

Closes https://github.com/astral-sh/ruff/issues/25248.
2026-05-20 09:59:03 +01:00
Micha Reiser 60d75d7226 Update known stdlib (#25103)
## Summary

This adds preliminary support for Python 3.15. We'll need to re-run the
script before releasing stable 3.15 support.

Closes
https://github.com/astral-sh/ruff/issues/25100#issuecomment-4420254119

Related to https://github.com/astral-sh/ruff/issues/21119

## Test Plan

Added test
2026-05-11 07:39:24 -07:00
Vivek Khimani dd6d843057 [pyflakes] Recognize frozendict as a builtin for Python 3.15+ (#24100)
## Summary

Register `frozendict` (PEP 814) as a version-gated builtin for Python
3.15+, fixing `F821` when `target-version = "py315"`

Closes #24095

## Test plan

- `frozendict` with `target-version >= py315` → no diagnostic
- `frozendict` with `target-version < py315` → `F821` with version hint
suggesting `py315`
- Existing version-gated builtin tests still pass (e.g.
`PythonFinalizationError`, `__annotate__`)

## Local run

```────────────
 Nextest run ID ab77447d-80be-48fe-ba42-d98e29697619 with nextest profile: default
    Starting 2 tests across 1 binary (2697 tests skipped)
        PASS [   0.049s] ruff_linter rules::pyflakes::tests::f821_frozendict_py315_available
        PASS [   0.254s] ruff_linter rules::pyflakes::tests::f821_frozendict_pre_py315_undefined
```
2026-03-21 23:47:18 +00:00
Loïc Riegel 2d3466eccf [flake8-bugbear] Accept immutable slice default arguments (B008) (#21823)
Closes issue #21565

## Summary

As pointed out in the issue, slices are currently flagged by B008 but
this behavior is incorrect because slices are immutable.

## Test Plan

Added a test case in the "B006_B008.py" fixture. Sorry for the diff in
the snapshots, the only thing that changes in those flies is the line
numbers, though.

You can also test this manually with this file:
```py
# test_slice.py
def c(d=slice(0, 3)): ...
```

```sh
> target/debug/ruff check tmp/test_slice.py --no-cache --select B008
All checks passed!
```
2025-12-08 14:00:43 -05:00
liam ebfb33c30b [ruff] Extend FA102 with listed PEP 585-compatible APIs (#20659)
Resolves https://github.com/astral-sh/ruff/issues/20512

This PR expands FA102’s preview coverage to flag every
PEP 585-compatible API that breaks without from `from __future__ import
annotations`, including `collections.abc`. The rule now treats asyncio
futures, pathlib-style queues, weakref containers, shelve proxies, and
the full `collections.abc` family as generics once preview mode is
enabled.

Stable behavior is unchanged; the broader matching runs behind
`is_future_required_preview_generics_enabled`, letting us vet the new
diagnostics before marking them as stable.

I've also added a snapshot test that covers all of the newly supported
types.

Check out
https://docs.python.org/3/library/stdtypes.html#standard-generic-classes
for a list of commonly used PEP 585-compatible APIs.
2025-10-03 09:45:32 -04:00
Bhuminjay Soni cfc64d1707 [syntax-errors]: future-feature-not-defined (F407) (#20554)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

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

This PR implements
https://docs.astral.sh/ruff/rules/future-feature-not-defined/ (F407) as
a semantic syntax error.

## Test Plan

<!-- How was it tested? -->

I have written inline tests as directed in #17412

---------

Signed-off-by: 11happy <soni5happy@gmail.com>
2025-09-25 13:52:24 -04:00
Dan ParizherandAlex Waygood 346842f003 [pyflakes] Fix false positives for __annotate__ (Py3.14+) and __warningregistry__ (F821) (#20154)
## Summary

Fixes #19970

---------

Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2025-09-23 08:16:00 -04:00
Micha Reiser 9ae698fe30 Switch to Rust 2024 edition (#18129) 2025-05-16 13:25:28 +02:00
Rogdham bc7b30364d python_stdlib: update for 3.14 (#18014)
## Summary

Added version 3.14 to the script generating the `known_stdlib.rs` file.

Rebuilt the known stdlibs with latest version (2025.5.10) of [stdlibs
Python lib](https://pypi.org/project/stdlibs/) (which added support for
3.14.0b1).

_Note: Python 3.14 is now in [feature
freeze](https://peps.python.org/pep-0745/) so the modules in stdlib
should be stable._

_See also: #15506_

## Test Plan

The following command has been run. Using for tests the `compression`
module which been introduced with Python 3.14.
```sh
ruff check --no-cache --select I001 --target-version py314 --fix
```

With ruff 0.11.9:
```python
import base64
import datetime

import compression

print(base64, compression, datetime)
```

With this PR:
```python
import base64
import compression
import datetime   

print(base64, compression, datetime)
```
2025-05-11 11:25:54 -05:00
Micha Reiser fa628018b2 Use #[expect(lint)] over #[allow(lint)] where possible (#17822) 2025-05-03 21:20:31 +02:00
Micha Reiser e4d9fe036a Revert "Add all PEP-585 names to UP006 rule" (#15250) 2025-01-04 12:23:53 +01:00
04d538113a Add all PEP-585 names to UP006 rule (#5454)
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Co-authored-by: dylwil3 <dylwil3@gmail.com>
Co-authored-by: Micha Reiser <micha@reiser.io>
2024-12-30 12:21:42 +01:00
InSync d4ee6abf4a Visit PEP 764 inline TypedDicts' keys as non-type-expressions (#15073)
## Summary

Resolves #10812.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2024-12-30 15:04:55 +05:30
LokejokeandAlex Waygood bf0fd04e4e [ruff] Implemented used-dummy-variable (RUF052) (#14611)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2024-12-03 08:36:16 +01:00
Alex Waygood ef0e2a6e1b Refactor crates/ruff_python_stdlib/src/builtins.rs to make it easier to add support for new Python versions (#14632) 2024-11-27 12:20:21 +00:00
Simon Brugman 84d4f114ef Use bitshift consistently for bitflag definitions (#14265) 2024-11-11 10:20:17 +00:00
Charlie Marsh 5bf4759cff Detect permutations in redundant open modes (#14255)
## Summary

Closes https://github.com/astral-sh/ruff/issues/14235.
2024-11-10 22:48:30 -05:00
Tim Hatch c593ccb529 Regenerate known_stdlibs.rs with stdlibs 2024.10.25 (#13963)
## Summary

`stdlibs` has a new release to properly categorize the `_wmi` module
which has been [present since
~2022](https://github.com/python/cpython/issues/89545#issuecomment-1227846806).


## Test Plan

Let CI run, this is only a trivial change to categorization data.
2024-10-28 08:37:54 -04:00
Alex Waygood 5b4afd30ca Harmonise methods for distinguishing different Python source types (#13682) 2024-10-09 13:18:52 +00:00