惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
T
Threatpost
P
Palo Alto Networks Blog
NISL@THU
NISL@THU
O
OpenAI News
Project Zero
Project Zero
G
GRAHAM CLULEY
P
Privacy International News Feed
A
Arctic Wolf
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
M
MIT News - Artificial intelligence
T
Threat Research - Cisco Blogs
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
D
Docker
aimingoo的专栏
aimingoo的专栏
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
W
WeLiveSecurity
P
Proofpoint News Feed
腾讯CDC
Cloudbric
Cloudbric
S
Secure Thoughts
C
Check Point Blog
博客园 - Franky
T
The Exploit Database - CXSecurity.com
T
Troy Hunt's Blog
GbyAI
GbyAI
Security Archives - TechRepublic
Security Archives - TechRepublic
Application and Cybersecurity Blog
Application and Cybersecurity Blog
月光博客
月光博客
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
TaoSecurity Blog
TaoSecurity Blog
L
Lohrmann on Cybersecurity
V
Visual Studio Blog
F
Fortinet All Blogs
博客园 - 叶小钗
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
C
Cisco Blogs
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
Y
Y Combinator Blog
Apple Machine Learning Research
Apple Machine Learning Research

Blog - Astral

Vulnerability and malware checks in uv Open source security at Astral Astral to join OpenAI ty: An extremely fast Python type checker and language server Python 3.14 Ruff v0.13.0 Astral OSS Fund: One Year Later pyx: a Python-native package registry, now in Beta An experimental, variant-enabled build of uv uv security advisory: ZIP payload obfuscation Ruff v0.12.0 Ruff v0.10.0 Ruff v0.9.0 A new home for python-build-standalone Ruff v0.8.0 Ruff v0.7.0 uv: Unified Python packaging Ruff v0.6.0 Announcing the Astral OSS Fund Ruff v0.5.0 Ruff v0.4.5: Ruff's language server is now written in Rust Ruff v0.4.0: a hand-written recursive descent parser for Python Ruff v0.3.0 uv: Python packaging in Rust Ruff v0.2.0 Ruff v0.1.8 Ruff v0.1.5 The Ruff Formatter: An extremely fast, Black-compatible Python formatter Ruff v0.1.0 Ruff v0.0.292 Ruff v0.0.285 Ruff v0.0.283 Ruff v0.0.281 Ruff v0.0.278 Ruff v0.0.276 Announcing Astral, the company behind Ruff
Ruff v0.15.0
dylan@astral · 2026-02-03 · via Blog - Astral

Ruff v0.15.0 is available now! Install it from PyPI, or with your package manager of choice:

uv tool install ruff@latest

As a reminder: Ruff is an extremely fast Python linter and formatter, written in Rust. Ruff can be used to replace Black, Flake8 (plus dozens of plugins), isort, pydocstyle, pyupgrade, and more, all while executing tens or hundreds of times faster than any individual tool.

This release welcomes in sixteen new stable lint rules, six stabilized behaviors for existing lint rules, and support for range suppressions in the linter, as well as the new style guide for the Ruff formatter.

The Ruff 2026 style guide #

The Ruff formatter has seen a host of improvements in the past year, from bug fixes to features to new styles. As always, this is thanks in large part to excellent community contributions, whether it be through submitting issues or opening pull requests.

A few of the most impactful changes include:

  • Lambda parameters are now kept on the same line and lambda bodies will be parenthesized to let them break across multiple lines.
  • Parentheses around tuples of exceptions in except clauses will now be removed on Python 3.14 and later.
  • A single empty line is now permitted at the beginning of function bodies.

These are covered in more detail below. For a full description of all changes, see the release notes.

Improved lambda formatting #

Lambda parameter lists are now forced onto the same line as the lambda keyword itself, and the body of the lambda can now be parenthesized, allowing it to break across multiple lines.

In the 2025 style, the formatter preferred to break long lambda parameter lists across multiple lines over parenthesizing and indenting the body expression, causing the parameters to blend in with the surrounding lines in certain contexts. The 2026 style instead keeps parameters on a single line and prefers to parenthesize the body if necessary:

--- 2025
+++ 2026

 def a():
     return b(
         c,
         d,
         e,
-        f=lambda self,
-        *args,
-        **kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs),
+        f=lambda self, *args, **kwargs: (
+            aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs)
+        ),
     )

The new formatting helps to preserve the separation between the lambda's parameters and other entries in a surrounding list. This change also more closely aligns Ruff with the formatting produced by Black for such expressions.

Simplified except and except* blocks on Python 3.14 #

With the adoption of PEP 758 in Python 3.14, unparenthesized except and except* blocks are now permitted when catching multiple exceptions. Ruff now enforces this more concise style in the formatter, as long as your target-version is 3.14 or later.

--- 2025
+++ 2026

 try:
     ...
-except (A, B, C):
+except A, B, C:
     ...

Preserved empty line at the start of function definitions #

In certain cases it can help legibility to use an empty line to separate a function header or docstring from the body of a function. The 2026 style leaves this up to the user, preserving up to a single blank line in this case.

# Source - remains the same with the 2026 style guide
def some_function():

    some_more_code()

# 2025 style guide - removes the blank line
def some_function():
    some_more_code()

In other formatting news... #

Keep your one-liners #

In previous versions of Ruff, skip directives like # fmt: skip only applied to at most one node. For example:

--- Source
+++ Ruff v0.14.0

- import this; import that # fmt: skip
+ import this
+ import that # fmt: skip

- def add_one(x): return x+1 # fmt: skip
+ def add_one(x):
    return x+1 # fmt: skip

The only way to suppress formatting in these cases was to surround the one-liner with a range suppression, using fmt: on and fmt: off comments. Of course, this turns the one-liner into a three-liner, which is not ideal.

Ruff now respects these directives for the entire (logical) line containing the skip directive. This also improves compatibility with Black's treatment of these suppression comments.

Note that this change has been in effect since Ruff v0.14.13 and will not change previously formatted code. However, any one-liners you write going forward should now be preserved.

Check out our preview styles #

At the time of this writing there are only two formatting styles that remain in preview. So now is an excellent time to turn on preview and let us know what you think! Both features offer some styling innovations, and would be intentional deviations from Black. We are eager to refine them in line with feedback from the community.

Fluent layout for method chains (GitHub Discussion): #

This preview style emphasizes the interpretation of a long chain of methods as a sequence of transformations or operations being performed on a specific object of interest. We highlight this by attempting to keep the inferred "object of interest" on the first line, and breaking at each method call, which leads to the following change in practice:

 x = (
-    df.filter(at_this_very_long > boolean_conditions)
+    df
+    .filter(at_this_very_long > boolean_conditions)
     .agg(using_this_long_function)
     .merge(other)
 )

Hugging parentheses with brackets and braces (GitHub Discussion): #

This preview style reduces indentation and vertical space while highlighting the essential content of containers:

 def foo_brackets(request):
-    return JsonResponse(
-        {
-            "var_1": foo,
-            "var_2": bar,
-        }
-    )
+    return JsonResponse({
+        "var_1": foo,
+        "var_2": bar,
+    })

Introducing linter block suppressions #

In previous versions of Ruff, only two levels of granularity were available for suppressing lint diagnostics: file-level via ruff: noqa comments, and line-level via inline noqa comments.

As one example, if you wanted to enforce PEP 8 naming conventions in your code, but needed to maintain a single function with arguments that did not follow this style, multiple suppression comments could be needed:

def foo(
    legacyArg1,  # noqa: N803
    legacyArg2,  # noqa: N803
    legacyArg3,  # noqa: N803
    legacyArg4,  # noqa: N803
): ...

Ruff v0.15 stabilizes a new kind of suppression comment for allowing rule violations in blocks of code. The example above can be rewritten more succinctly with these new ruff: disable and ruff: enable comments:

# ruff: disable[N803]
def foo(
    legacyArg1,
    legacyArg2,
    legacyArg3,
    legacyArg4,
): ...
# ruff: enable[N803]

Note that unlike the file- and line-level suppression comments, the bracketed list of codes is required for block-level suppression comments. See the documentation on block suppressions for the full specification.

Also see the newly stabilized lint rules RUF103 and RUF104 for validating your suppression comments automatically.

Rule stabilizations #

The following rules have been stabilized and are no longer in preview:

Other behavior stabilizations #

This release also stabilizes some additional behavior, previously only available in preview mode:

  • The --output-format flag is now respected when running Ruff in --watch mode, and the full output format is now used by default, matching the regular CLI output.

  • builtin-attribute-shadowing (A003) now detects the use of shadowed built-in names in additional contexts like decorators, default arguments, and other attribute definitions.

  • duplicate-union-member (PYI016) now considers typing.Optional when searching for duplicate union members.

  • split-static-string (SIM905) now offers an autofix when the maxsplit argument is provided, even without a sep argument.

  • dict-get-with-none-default (SIM910) now applies to more types of key expressions.

  • super-call-with-parameters (UP008) now has a safe fix when it will not delete comments.

  • unnecessary-default-type-args (UP043) now applies to stub (.pyi) files on Python versions before 3.13.

Other breaking changes #

This release also includes a few miscellaneous breaking changes, mostly related to the release process.

  • The ruff:alpine Docker image is now based on Alpine 3.23 (up from 3.21).
  • The ruff:debian and ruff:debian-slim Docker images are now based on Debian 13 "Trixie" instead of Debian 12 "Bookworm."
  • Binaries for the ppc64 (64-bit big-endian PowerPC) architecture are no longer included in our releases. It should still be possible to build Ruff manually for this platform, if needed.
  • Ruff now resolves all extended configuration files before falling back on a default Python version.

Thank you! #

Thank you to everyone who provided feedback regarding the changes included in Ruff's preview mode and to our contributors. It's an honor building Ruff with you!


View the full changelog on GitHub.

Read more about Astral — the company behind Ruff.

Thanks to Dhruv Manilawala and Brent Westbrook who contributed to this blog post.