Skip to content

format-on-write launches ruff without the stdin marker, so a .py write can reformat the whole directory #1069

Description

@Vasanthdev2004

What happens

With ZERO_FORMAT_ON_WRITE=1, writing any .py file launches ruff without the argument that tells it to read standard input, and with its working directory set to the written file's own directory. Ruff's stdin marker is a trailing -; --stdin-filename only names the input. With no path argument and no -, ruff format formats the current directory, which is documented ("ruff format (format current directory)").

So a single-file write can rewrite every .py file in that directory and below, while the tool reports one file written.

Where

internal/tools/format_on_write.go, the .py entry of formatterCommands:

".py": {argv: []string{"ruff", "format", "--quiet"}, stdin: true, filenameFlag: "--stdin-filename"},

and formatWithStdin, which sets formatter.Dir to the destination's directory.

Measured

Recorded from the real launch on main at 99721c7, with a recording shim standing in for ruff, writing pkg/new_file.py into a workspace where pkg/already_here.py already exists:

ARGV  format --quiet --stdin-filename=...\pkg\new_file.py
CWD   ...\pkg

No - anywhere in the argv, and the working directory is the one holding the neighbouring file.

There is a second effect. Under --quiet ruff prints nothing to stdout in that mode, so the written file is published unformatted and the call reports success, which is why this does not show up as a formatting failure.

Suggested fix

Add - to the .py argv, after the flags, so ruff reads the bytes it is given:

".py": {argv: []string{"ruff", "format", "--quiet", "-"}, stdin: true, filenameFlag: "--stdin-filename"},

.tf and .lua already pass - for the same reason, and .zig, .gleam and .kt pass --stdin.

While there: dart format has no - either. That one errors out rather than reaching for the directory, so it fails the format and publishes the written bytes, but it means .dart files are never actually formatted.

A regression test wants to assert the argv each stdin adapter is launched with, rather than only that formatting happened, since a formatter acting on its working directory still looks like success from the outside.

Activity

  1. Vasanthdev2004 commented on Sep 24, 2026

    @Vasanthdev2004
    CollaboratorAuthor

    Closing this: the bug doesn't exist on main, and I filed it against the wrong tree.

    I recorded the ruff argv on #941's branch and attributed it to main. On main the file path is passed as the last argument, so ruff formats exactly that one file and nothing else:

    main at 99721c7    ARGV  format --quiet C:\...\pkg\new_file.py
    #941 at e93871d8   ARGV  format --quiet --stdin-filename=C:\...\pkg\new_file.py
    

    The missing - only matters once formatting moves to stdin, which is what #941 does. There it's a real regression: with no path and no -, ruff format formats its working directory. So it's a finding on #941, and I've corrected my review there to say so. The same goes for the .dart note above, which is also #941-only and unverified.

    Nothing to fix on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions