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

推荐订阅源

V
V2EX
爱范儿
爱范儿
Martin Fowler
Martin Fowler
T
The Blog of Author Tim Ferriss
B
Blog RSS Feed
博客园 - 聂微东
G
GRAHAM CLULEY
Engineering at Meta
Engineering at Meta
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
WordPress大学
WordPress大学
Scott Helme
Scott Helme
AI
AI
S
Security Affairs
T
Threat Research - Cisco Blogs
M
MIT News - Artificial intelligence
T
Troy Hunt's Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
AWS News Blog
AWS News Blog
T
Threatpost
Cyberwarzone
Cyberwarzone
www.infosecurity-magazine.com
www.infosecurity-magazine.com
U
Unit 42
V
Vulnerabilities – Threatpost
J
Java Code Geeks
博客园 - Franky
月光博客
月光博客
Blog — PlanetScale
Blog — PlanetScale
NISL@THU
NISL@THU
D
Docker
小众软件
小众软件
N
News and Events Feed by Topic
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
A
Arctic Wolf
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
Forbes - Security
Forbes - Security
量子位
PCI Perspectives
PCI Perspectives
美团技术团队
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
I
InfoQ
Security Archives - TechRepublic
Security Archives - TechRepublic
有赞技术团队
有赞技术团队
腾讯CDC
P
Proofpoint News Feed
S
Security @ Cisco Blogs
G
Google Developers Blog
C
Cisco Blogs

Blog - Astral

Vulnerability and malware checks in uv Open source security at Astral Astral to join OpenAI Ruff v0.15.0 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.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.10.0
brent@astral · 2025-03-13 · via Blog - Astral

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

uv pip install --upgrade ruff

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.

Migrating to v0.10 #

As usual for Ruff minor releases, v0.10 contains few breaking changes, and most users should be able to upgrade without significant modifications to their code or configuration. However, there are a few changes worth calling out individually.

Improved Python version detection #

This change and the updated behavior of PGH004 described below were unintentionally omitted from v0.10 and were instead included in v0.11, which released shortly after v0.10.

This release makes Python version detection more intuitive for projects with a pyproject.toml file.

Ruff uses your Python version to offer more accurate suggestions for lint rules, import sorting, and other formatting decisions — just to name a few.1 If you've been following recent preview changes, we're also working on better detection of version-related syntax errors (such as the use of match before Python 3.10). These rely on your specified Python version to avoid false positives.

In previous versions of Ruff, you could specify your Python version with:

  • The target-version option in a ruff.toml file or the [tool.ruff] section of a pyproject.toml file.
  • The project.requires-python field in a pyproject.toml file with a [tool.ruff] section.

These options worked well in most cases, and are still recommended for fine control of the Python version. However, because of the way Ruff discovers config files, pyproject.toml files without a [tool.ruff] section would be ignored, including the requires-python setting. Ruff would then use the default Python version (3.9 as of this writing) instead, which is surprising when you've attempted to request another version.

In v0.10, config discovery has been updated to address this issue:

  1. If Ruff finds a ruff.toml file without a target-version, it will check for a pyproject.toml file in the same directory and respect its requires-python version, even if it does not contain a [tool.ruff] section.
  2. If there is no config file (ruff.toml or pyproject.toml with a [tool.ruff] section) in the directory of the file being checked, Ruff will search for the closest pyproject.toml in the parent directories and use its requires-python setting.2

These changes will have no effect if you're already using the target-version option or requires-python in a pyproject.toml with a [tool.ruff] section.3

See the new documentation for more details.

More robust suppression comments #

The inline (# noqa) and file-level (# ruff: noqa) suppression comment parsing have been unified and overall made more robust.

In the following situations, a comment will suppress more rules than it used to:

  • Leading comments are now allowed for file-level suppression comments, e.g. # Some context # ruff: noqa. Previously, this noqa was silently ignored.
  • Trailing comments are now allowed for file-level suppression comments, e.g. # ruff: noqa This file is rough!, whereas previously this resulted in an error and the suppression did not take effect.
  • To support the previous change, invalid syntax like ruff: noqa UP035 (missing colon after noqa) will now suppress all rules. This is consistent with the existing inline behavior and is guarded against by blanket-noqa (PGH004).
  • Missing items in lists of rules are now accepted but emit a warning. For example, #noqa: F401,,F841 will suppress F401 and F841 but display a warning.
  • Similarly, missing delimiters in lists of rules are now accepted in both the inline and file-level comments but emit a warning. For example, # ruff: noqa: F401F841 will suppress both F401 and F841 but display a warning.

In the following situations, a comment may suppress fewer rules than it used to:

  • It is now disallowed to have an invalid rule suffix in inline suppression comments, e.g. # noqa: UP035abc. This will log an error and suppress no rules. This matches the current behavior for file-level suppression comments.
  • Whitespace is now allowed between the colon and rule list, e.g. #noqa : F401. This previously suppressed all rules but will now only suppress F401, as was likely intended.

Updated TYPE_CHECKING behavior #

This release brings Ruff's treatment of TYPE_CHECKING symbols into alignment with other tools like mypy and pyright.

typing.TYPE_CHECKING is a special constant in the standard library typing module that can be used to avoid expensive imports at runtime but include them for use by type checkers (and linters). This often looks something like this example adapted from the typing documentation:

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    import expensive_mod

def fun(arg: expensive_mod.SomeType) -> None: ...

However, in some cases the typing import itself may be undesirable. In the past, Ruff and many type checkers have allowed if statements like if 0: ... or if False: ... in place of if TYPE_CHECKING: ... to avoid the typing import. That has fallen out of favor and been generally replaced by using a local symbol named TYPE_CHECKING instead, for example:

from __future__ import annotations

TYPE_CHECKING = False
if TYPE_CHECKING:
    import expensive_mod

def fun(arg: expensive_mod.SomeType) -> None: ...

This release stabilizes both of these changes in Ruff:

  1. Support for if 0 and if False instead of if TYPE_CHECKING has been removed.
  2. Support for any symbol named TYPE_CHECKING rather than precisely typing.TYPE_CHECKING has been added.

As an added benefit, this change strengthens rules like if-else-block-instead-of-if-exp (SIM108), which previously could not collapse if 0 or if False blocks in case they were actually for TYPE_CHECKING.

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:

  • Options for the flake8-builtins rules with redundant builtins- prefixes have been deprecated. For example, the lint.flake8-builtins.builtins-allowed-modules option is now lint.flake8-builtins.allowed-modules.
  • The flake8-builtins rule stdlib-module-shadowing (A005) now defaults to non-strict module name checking (e.g. a utils/logging.py module will not be flagged as conflicting with the logging builtin module). See the lint.flake8-builtins.strict-checking option to restore the old default.
  • custom-type-var-for-self (PYI019) now uses a more accurate approach for replacing custom TypeVars with Self, can apply to methods without a return annotation, and offers an automatic fix.
  • blanket-noqa (PGH004) now detects file-level suppression comments in addition to inline comments.
  • invalid-envvar-default (PLW1508) has been extended to recognize os.environ.get as well as os.getenv.
  • invalid-first-argument-name-for-class-method (N804) no longer flags __new__ methods, which are technically static methods rather than class methods. bad-staticmethod-argument (PLW0211) now applies to __new__ methods instead.

See the full changelog on GitHub for other, smaller changes.

Rule deprecations #

  • suspicious-xmle-tree-usage (S320) has been deprecated because the issues it checks for in the lxml package have been resolved.
  • non-pep604-isinstance (UP038) has been deprecated because using PEP 604 union syntax in isinstance and issubclass calls is not actually a recommended pattern and may also hurt performance.

Thank you! #

Thank you to everyone who provided feedback regarding the changes included in Ruff's preview mode, and especially, 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 Dylan Wilson, Micha Reiser, Dhruv Manilawala, and Zanie Blue who contributed to this blog post.

Footnotes #

  1. See the v0.8 release notes for a more specific list if you're curious! ↩

  2. Ruff only performs this search if the --isolated flag is not used and no target version is passed via the --config or --target-version flags. ↩

  3. These changes also won't affect you if you don't have a project.requires-python setting or a pyproject.toml at all. In those cases, Ruff will continue using its internal default version of Python 3.9 (as of this writing). ↩