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

推荐订阅源

宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
V
Visual Studio Blog
爱范儿
爱范儿
H
Help Net Security
J
Java Code Geeks
I
InfoQ
Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recorded Future
Recorded Future
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
Scott Helme
Scott Helme
S
SegmentFault 最新的问题
S
Securelist
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
博客园_首页
B
Blog
F
Fortinet All Blogs
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Forbes - Security
Forbes - Security
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Schneier on Security
Project Zero
Project Zero
Martin Fowler
Martin Fowler
C
Cybersecurity and Infrastructure Security Agency CISA
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic

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

Ruff v0.0.276 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.

Jupyter Notebook support #

Ruff now ships with experimental support for linting Jupyter Notebooks:

# Run Ruff over `Notebook.ipynb`.
ruff check Notebook.ipynb

# Re-run Ruff on-save.
ruff check Notebook.ipynb --watch

# Fix any fixable errors in `Notebook.ipynb`.
ruff check Notebook.ipynb --fix

To opt-in to linting Jupyter Notebook files, add the *.ipynb pattern to your include setting, like so:

[tool.ruff]
# Allow Ruff to discover `*.ipynb` files.
include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]

This will prompt Ruff to discover Jupyter Notebook files in any specified directories, and lint them accordingly.

Alternatively, you can always pass a Notebook file to ruff directly. For example, ruff check /path/to/notebook.ipynb will always lint notebook.ipynb.

You can disable specific rules in Jupyter Notebooks using Ruff's per-file-ignores setting. For example, it's common to allow imports to appear in any cell, rather than confining them to the top of the Notebook:

[tool.ruff]
# Allow imports to appear anywhere in Jupyter Notebooks.
per-file-ignores = { "*.ipynb" = ["E402"] }

Jupyter Notebook support is currently opt-in and experimental, and comes with a few known limitations which will be ironed out in subsequent releases (most notably: lack of support for cells with mixed Jupyter Magics and Python code).

We'd love your help testing it out. Have feedback? Run into issues? Big or small, don't hesitate to let us know.

First-class import resolution #

Ruff now includes a first-class import resolver, based on Pyright's import resolver, with support for resolving imports from namespace packages, type stubs, and more.

In future releases, the resolver will allow us to remove a variety of user-provided settings (e.g., namespace-packages), resolve references across files, detect unused dependencies, and more.

New rule: unnecessary-list-cast (PERF101) #

What does it do? #

Checks for explicit casts to list on for-loop iterables.

Why does it matter? #

Using a list() call to eagerly iterate over an already-iterable type (like a tuple, list, or set) is inefficient, as it forces Python to create a new list unnecessarily.

Removing the list() call will not change the behavior of the code, but may improve performance.

Note that, as with all perflint rules, this is only intended as a micro-optimization, and will have a negligible impact on performance in most cases.

For example, given the following snippet:

items = (1, 2, 3)
for i in list(items):
    print(i)

Instead, use the iterable directly:

items = (1, 2, 3)
for i in items:
    print(i)

New rule: try-except-in-loop (PERF203) #

What does it do? #

Checks for uses of except handling via try-except within for and while loops.

Why does it matter? #

Exception handling via try-except blocks incurs some performance overhead, regardless of whether an exception is raised.

When possible, refactor your code to put the entire loop into the try-except block, rather than wrapping each iteration in a separate try-except block.

This rule is only enforced for Python versions prior to 3.11, which introduced "zero cost" exception handling.

Note that, as with all perflint rules, this is only intended as a micro-optimization, and will have a negligible impact on performance in most cases.

For example, given the following snippet:

for i in range(10):
    try:
        print(i * i)
    except:
        break

Instead, move the entire loop into the try-except block:

try:
    for i in range(10):
        print(i * i)
except:
    pass

New rule: manual-list-comprehension (PERF401) #

What does it do? #

Checks for for loops that can be replaced by a list comprehension.

Why does it matter? #

When creating a transformed list from an existing list using a for-loop, prefer a list comprehension. List comprehensions are more readable and more performant.

Using the below as an example, the list comprehension is ~10% faster on Python 3.11, and ~25% faster on Python 3.10.

Note that, as with all perflint rules, this is only intended as a micro-optimization, and will have a negligible impact on performance in most cases.

For example, given the following snippet:

original = list(range(10000))
filtered = []
for i in original:
    if i % 2:
        filtered.append(i)

Use instead:

original = list(range(10000))
filtered = [x for x in original if x % 2]

If you're instead appending to an existing list, use the extend method:

original = list(range(10000))
filtered.extend(x for x in original if x % 2)

New rule: manual-list-copy (PERF402) #

What does it do? #

Checks for for loops that can be replaced by a making a copy of a list.

Why does it matter? #

When creating a copy of an existing list using a for-loop, prefer list or list.copy instead. Making a direct copy is more readable and more performant.

Using the below as an example, the list-based copy is ~2x faster on Python 3.11.

Note that, as with all perflint rules, this is only intended as a micro-optimization, and will have a negligible impact on performance in most cases.

For example, given the following snippet:

original = list(range(10000))
filtered = []
for i in original:
    filtered.append(i)

Use instead:

original = list(range(10000))
filtered = list(original)

New rule: numpy-deprecated-function (NPY003) #

What does it do? #

Checks for uses of deprecated NumPy functions.

Why does it matter? #

NumPy 1.25.0 finalized a variety of deprecations that were introduced in previous releases.

When NumPy functions are deprecated, they are usually replaced with newer, more efficient versions, or with functions that are more consistent with the rest of the NumPy API. Prefer newer APIs over deprecated ones.

For example, given the following snippet:

import numpy as np

np.alltrue([True, False])

Use instead:

import numpy as np

np.all([True, False])

New rule: single-string-slots (PLC0205) #

What does it do? #

Checks for single strings assigned to __slots__.

Why does it matter? #

Any string iterable may be assigned to __slots__ (most commonly, a tuple of strings). If a string is assigned to __slots__, it is interpreted as a single attribute name, rather than an iterable of attribute names. This can cause confusion, as users that iterate over the __slots__ value may expect to iterate over a sequence of attributes, but would instead iterate over the characters of the string.

To use a single string attribute in __slots__, wrap the string in an iterable container type, like a tuple.

For example, given the following snippet:

class Person:
    __slots__: str = "name"

    def __init__(self, name: str) -> None:
        self.name = name

Instead, wrap the string in a tuple:

class Person:
    __slots__: tuple[str, ...] = ("name",)

    def __init__(self, name: str) -> None:
        self.name = name

New rule: complex-if-statement-in-stub (PYI002) #

What does it do? #

Checks for if statements with complex conditionals in stubs.

Why does it matter? #

Stub files support simple conditionals to test for differences in Python versions and platforms. However, type checkers only understand a limited subset of these conditionals; complex conditionals may result in false positives or false negatives.

For example, given the following snippet:

import sys

if (2, 7) < sys.version_info < (3, 5):
    ...

Use instead:

import sys

if sys.version_info < (3, 5):
    ...

New rule: unrecognized-version-info-check (PYI003) #

What does it do? #

Checks for problematic sys.version_info-related conditions in stubs.

Why does it matter? #

Stub files support simple conditionals to test for differences in Python versions using sys.version_info. However, there are a number of common mistakes involving sys.version_info comparisons that should be avoided. For example, comparing against a string can lead to unexpected behavior.

For example, given the following snippet:

import sys

if sys.version_info[0] == "2":
    ...

Use instead:

import sys

if sys.version_info[0] == 2:
    ...

New rule: patch-version-comparison (PYI004) #

What does it do? #

Checks for Python version comparisons in stubs that compare against patch versions (e.g., Python 3.8.3) instead of major and minor versions (e.g., Python 3.8).

Why does it matter? #

Stub files support simple conditionals to test for differences in Python versions and platforms. However, type checkers only understand a limited subset of these conditionals. In particular, type checkers don't support patch versions (e.g., Python 3.8.3), only major and minor versions (e.g., Python 3.8). Therefore, version checks in stubs should only use the major and minor versions.

For example, given the following snippet:

import sys

if sys.version_info >= (3, 4, 3):
    ...

Use instead:

import sys

if sys.version_info >= (3, 4):
    ...

New rule: wrong-tuple-length-version-comparison (PYI005) #

What does it do? #

Checks for Python version comparisons that compare against a tuple of the wrong length.

Why does it matter? #

Stub files support simple conditionals to test for differences in Python versions and platforms. When comparing against sys.version_info, avoid comparing against tuples of the wrong length, which can lead to unexpected behavior.

For example, given the following snippet:

import sys

if sys.version_info[:2] == (3,):
    ...

Use instead:

import sys

if sys.version_info[0] == 3:
    ...

Bug fixes #