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

推荐订阅源

GbyAI
GbyAI
博客园 - 三生石上(FineUI控件)
S
Securelist
U
Unit 42
The Cloudflare Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Simon Willison's Weblog
Simon Willison's Weblog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog
T
Tenable Blog
The Hacker News
The Hacker News
The Register - Security
The Register - Security
IT之家
IT之家
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
P
Privacy & Cybersecurity Law Blog
博客园_首页
T
Tailwind CSS Blog
人人都是产品经理
人人都是产品经理
C
Cybersecurity and Infrastructure Security Agency CISA
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
T
Tor Project blog
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
V
Vulnerabilities – Threatpost
A
Arctic Wolf
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
V
Visual Studio Blog
月光博客
月光博客
爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
G
GRAHAM CLULEY
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Heimdal Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

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.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.278 Ruff v0.0.276 Announcing Astral, the company behind Ruff
Ruff v0.0.281
charlie@astr · 2023-07-31 · via Blog - Astral

Ruff v0.0.281 is out now. Install it from PyPI, or your package manager of choice:

pip install --upgrade ruff

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

View the full changelog on GitHub, or read on for the highlights.

Ruff's lexer is 2-3x faster #

Ruff's lexer is now 2-3x faster than in previous releases:

group                       v0.0.280                               v0.0.281
-----                       --------                               --------
lexer/large/dataset.py      2.18    665.9±5.64µs    61.1 MB/sec    1.00    304.9±3.79µs   133.4 MB/sec
lexer/numpy/ctypeslib.py    2.39    154.4±0.84µs   107.8 MB/sec    1.00     64.5±0.61µs   258.1 MB/sec
lexer/numpy/globals.py      2.89     18.1±0.14µs   163.3 MB/sec    1.00      6.3±0.06µs   471.8 MB/sec
lexer/pydantic/types.py     2.57    326.4±2.23µs    78.1 MB/sec    1.00    127.2±0.71µs   200.5 MB/sec

The lexer is responsible for tokenizing Python source code into a stream of tokens, which are then used by the parser to build an abstract syntax tree (AST). The lexer is the first step in Ruff's analysis pipeline, and is run on every file that Ruff analyzes.

Improving lexer performance not only improves linter performance, but will also improve the performance of future tools that leverage Ruff's lexer, like Ruff's formatter.

The new lexer leverages more cache-friendly data structures, performs fewer allocations, and includes optimizations for ASCII-only source code. See #38 for more details.

End-of-line # ruff: noqa comments are now ignored #

Ruff allows lint rules to be disabled across an entire file via # ruff: noqa suppression comments. For example, the following will ignore all lint errors across the file:

# ruff: noqa
import os
import sys

Similarly, the following will ignore all unused import (F401) errors across the file:

# ruff: noqa: F401
import os
import sys

Historically, Ruff respected these suppression comments even when they appeared at the end of a line, as in:

import os  # ruff: noqa: F401
import sys

Such end-of-line comments are likely a mistake (instead, use # noqa: F401 to suppress an error on a single line). Ruff will now warn and ignore these end-of-line, file-level suppression comments.

New rule: unused-private-type-var (PYI018) #

What does it do? #

Checks for the presence of unused private TypeVar declarations.

Why does it matter? #

A private TypeVar that is defined but not used is likely a mistake, and should either be used, made public, or removed to avoid confusion.

For example, given the following snippet:

import typing

_T = typing.TypeVar("_T")

The TypeVar is not used anywhere, and so should either be used, made public, or removed.

This rule is derived from flake8-pyi.

Contributed by @LaBatata101.

New rule: unused-private-protocol (PYI046) #

What does it do? #

Checks for the presence of unused private typing.Protocol definitions.

Why does it matter? #

A private typing.Protocol that is defined but not used is likely a mistake, and should either be used, made public, or removed to avoid confusion.

For example, given the following snippet:

import typing


class _PrivateProtocol(typing.Protocol):
    field: int

The _PrivateProtocol class is not used anywhere, and so should either be used, made public, or removed.

This rule is derived from flake8-pyi.

Contributed by @LaBatata101.

New rule: unused-private-type-alias (PYI047) #

What does it do? #

Checks for the presence of unused private typing.TypeAlias definitions.

Why does it matter? #

A private typing.TypeAlias that is defined but not used is likely a mistake, and should either be used, made public, or removed to avoid confusion.

For example, given the following snippet:

import typing

_UnusedTypeAlias: typing.TypeAlias = int

The type alias is not used anywhere, and so should either be used, made public, or removed.

This rule is derived from flake8-pyi.

Contributed by @LaBatata101.

New rule: unused-private-typed-dict (PYI049) #

What does it do? #

Checks for the presence of unused private typing.TypedDict definitions.

Why does it matter? #

A private typing.TypedDict that is defined but not used is likely a mistake, and should either be used, made public, or removed to avoid confusion.

For example, given the following snippet:

import typing


class _UnusedPrivateTypedDict(typing.TypedDict):
    field: list[int]

The __UnusedPrivateTypedDict class is not used anywhere, and so should either be used, made public, or removed.

This rule is derived from flake8-pyi.

Contributed by @LaBatata101.

New rule: unsupported-method-call-on-all (PYI056) #

What does it do? #

Checks that append, extend and remove methods are not called on __all__.

Why does it matter? #

Different type checkers have varying levels of support for calling these methods on __all__. Instead, use the += operator to add items to __all__, which is known to be supported by all major type checkers.

For example, given the following snippet:

__all__ = ["A"]
__all__.append("B")

Instead, use an augmented assignment statement to add items to __all__:

__all__ = ["A"]
__all__ += ["B"]

This rule is derived from flake8-pyi.

Contributed by @LaBatata101.

New rule: self-assigning-variable (PLW0127) #

What does it do? #

Checks for self-assignment of variables.

Why does it matter? #

Self-assignment of variables is redundant and likely a mistake.

For example, given the following snippet:

country = "Poland"
country = country

Instead, use the variable directly:

This rule is derived from Pylint.

Contributed by @tjkuson.

New rule: subprocess-popen-preexec-fn (PLW1509) #

What does it do? #

Checks for uses of subprocess.Popen with a preexec_fn argument.

Why does it matter? #

The preexec_fn argument is unsafe within threads as it can lead to deadlocks. Furthermore, preexec_fn is targeted for deprecation.

Instead, consider using task-specific arguments such as env, start_new_session, and process_group. These are not prone to deadlocks and are more explicit.

For example, given the following snippet:

import os, subprocess

subprocess.Popen(foo, preexec_fn=os.setsid)
subprocess.Popen(bar, preexec_fn=os.setpgid(0, 0))

Instead, use arguments like start_new_session and process_group:

import subprocess

subprocess.Popen(foo, start_new_session=True)
subprocess.Popen(bar, process_group=0)  # Introduced in Python 3.11

This rule is derived from Pylint.

Contributed by @tjkuson.

New rule: os-sep-split (PTH206) #

What does it do? #

Checks for uses of .split(os.sep)

Why does it matter? #

The pathlib module in the standard library should be used for path manipulation. It provides a high-level API with the functionality needed for common operations on Path objects.

For example, given the following snippet:

If not all parts of the path are needed, then the name and parent attributes of the Path object should be used. Otherwise, the parts attribute can be used as shown in the last example.

import os

"path/to/file_name.txt".split(os.sep)[-1]

"path/to/file_name.txt".split(os.sep)[-2]

if any(part in blocklist for part in "my/file/path".split(os.sep)):
    ...

Instead, use the Path object:

from pathlib import Path

Path("path/to/file_name.txt").name

Path("path/to/file_name.txt").parent.name

if any(part in blocklist for part in Path("my/file/path").parts):
    ...

Contributed by @sbrugman.

New rule: glob (PTH207) #

What does it do? #

Checks for the use of glob and iglob.

Why does it matter? #

pathlib offers a high-level API for path manipulation, as compared to the lower-level API offered by os and glob.

When possible, using Path object methods such as Path.glob() can improve readability over their low-level counterparts (e.g., glob.glob()).

Note that glob.glob and Path.glob are not exact equivalents:

globPath.glob
Hidden filesExcludes hidden files by default. From Python 3.11 onwards, the include_hidden keyword can used to include hidden directories.Includes hidden files by default.
Iteratoriglob returns an iterator. Under the hood, glob simply converts the iterator to a list.Path.glob returns an iterator.
Working directoryglob takes a root_dir keyword to set the current working directory.Path.rglob can be used to return the relative path.
Globstar (**)glob requires the recursive flag to be set to True for the ** pattern to match any files and zero or more directories, subdirectories, and symbolic links.The ** pattern in Path.glob means "this directory and all subdirectories, recursively". In other words, it enables recursive globbing.

For example, given the following snippet:

import glob
import os

glob.glob(os.path.join(path, "requirements*.txt"))

Instead, use the Path object:

from pathlib import Path

Path(path).glob("requirements*.txt")

Contributed by @sbrugman.