0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ruffによるメソッドチェーンのフォーマット設定

0
Last updated at Posted at 2026-08-14

はじめに

データ処理用のプログラム開発時など、実装が複雑化してくると非常に長いメソッドチェーンの記載が必要となる場合があります。この際、特段の設定を行わずフォーマッタにかけると、改行によって逆に可読性が下がる場合があります。
OSS上でのRuffのメソッドチェーンに関する現行の議論を踏まえて、暫定版のRuffの設定を作成しました。
※今回の設定にはプレビュー版の項目が含まれています。今後の議論や仕様変更にも注視が必要です(2026年8月14日時点)。

コンセプト

メソッドチェーンを処理単位で縦に並べ、コードの可読性を高めることを目指します。

実装

Ruffの設定ファイルは次のとおりです。GitHubでも公開しています。
https://github.com/MySweetEden/polars-format

ruff.toml
target-version = "py310"
line-length = 100
indent-width = 4

[lint]
select = ["I"]

[lint.isort]
# Ruff format accepts one or two blank lines after imports. The isort fix makes
# the preset deterministic by requiring two.
lines-after-imports = 2

[format]
quote-style = "double"
indent-style = "space"
line-ending = "lf"
skip-magic-trailing-comma = false
docstring-code-format = true
docstring-code-line-length = "dynamic"
# Required for Ruff's fluent-chain style (the value before the first dot is
# placed on its own line). Preview formatting may change between Ruff releases,
# so tests pin the Ruff version.
preview = true

検証

Polarsでのデータ処理プログラムについて、今回作成したruff.tomlを適用してフォーマットした結果、適用せずフォーマットした結果を載せています。
適用してフォーマットした結果の方が若干可読性が高いと信じています。

without_ruff_toml.py
import polars as pl

result = (
    df.filter(pl.col("status") == "active")
    .with_columns((pl.col("price") * pl.col("quantity")).alias("total"))
    .select("customer_id", "total")
)

summary = (
    df.group_by("region")
    .agg(
        pl.col("total").sum().alias("revenue"),
        pl.col("customer_id").n_unique().alias("customers"),
    )
    .sort("revenue", descending=True)
)

customer_orders = (
    orders.join(customers, on="customer_id", how="left")
    .filter(pl.col("total") > 0)
    .select("order_id", "customer_id", "name", "total")
)

daily_revenue = (
    orders.lazy()
    .with_columns(
        (pl.col("price") * pl.col("quantity")).alias("total"),
        pl.col("ordered_at").dt.date().alias("order_date"),
    )
    .group_by("order_date")
    .agg(pl.col("total").sum().alias("revenue"))
    .sort("order_date")
    .collect()
)

with_ruff_toml.py
import polars as pl


result = (
    df
    .filter(pl.col("status") == "active")
    .with_columns((pl.col("price") * pl.col("quantity")).alias("total"))
    .select("customer_id", "total")
)

summary = (
    df
    .group_by("region")
    .agg(
        pl.col("total").sum().alias("revenue"),
        pl.col("customer_id").n_unique().alias("customers"),
    )
    .sort("revenue", descending=True)
)

customer_orders = (
    orders
    .join(customers, on="customer_id", how="left")
    .filter(pl.col("total") > 0)
    .select("order_id", "customer_id", "name", "total")
)

daily_revenue = (
    orders
    .lazy()
    .with_columns(
        (pl.col("price") * pl.col("quantity")).alias("total"),
        pl.col("ordered_at").dt.date().alias("order_date"),
    )
    .group_by("order_date")
    .agg(pl.col("total").sum().alias("revenue"))
    .sort("order_date")
    .collect()
)

補足

Ruffにおけるメソッドチェーンのフォーマットについては、以下のIssueやPull Requestで議論されています(2026年8月14日時点)。

関連リンク:

Issue #9577はPolarsのメソッドチェーンに関するもので、最終的には、より一般的なメソッドチェーンのフォーマットを扱うIssue #8598に統合されました。

その後、Pull Request #21369でfluent method-chain formattingが実装されました。一方で、pl.col(...)、pd.read_csv(...)、np.arange(...)のようなnamespace-style callまで分割される点については、現在も議論が続いています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?