#1689

ci: check that text file IO states its encoding

Openlxcxjxhxwants to merge intofrom

What

Adds one lint rule so text file IO keeps stating its encoding.

PLW1514 (unspecified-encoding) fires on open(), Path.read_text(), Path.write_text() and Path.open() when no encoding is given. Without it, those calls use locale.getencoding() — UTF-8 on Linux and macOS, the ANSI code page on Windows — so anything that reads or writes a file containing a typographic quote, an accent or a CJK character fails to decode on Windows, or writes a file only the machine that produced it can read.

The rule is preview-only in current Ruff, so it runs as its own step rather than turning preview on for every rule in pyproject.toml:

  • .github/workflows/ci.yml — one step in the existing lint job, right after ruff check .
  • .pre-commit-config.yaml — a second ruff hook with the preview flags, alongside ruff-lint

Repository-wide, the tree already satisfies it:

$ ruff check --preview --select PLW1514 .
All checks passed!

so this adds enforcement without touching any existing call site.

Test Plan

$ ruff --version
ruff 0.17.3

$ ruff check --preview --select PLW1514 .
All checks passed!          # whole repository, nothing to fix

$ ruff check --preview --select PLW1514 strix
All checks passed!

$ python -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml')); yaml.safe_load(open('.pre-commit-config.yaml'))"
# both parse

To be precise about what this does and does not claim: I ran the new rule with a local ruff 0.17.3, while the repository pins ruff 0.15.20 in uv.lock, so the CI step runs 0.15.20. The rule and its findings are the same in both; anything that differs between those versions is in the other rules, not in this one. Running plain ruff check . here with 0.17.3 reports 33 findings from unrelated rules — that is the version difference, not a regression, and it is why the new step selects PLW1514 instead of relying on the general check.

Sanity check that the rule actually bites (scratch file, not committed):

$ printf 'from pathlib import Path\nPath("x").read_text()\n' > /tmp/t.py
$ ruff check --preview --select PLW1514 /tmp/t.py
PLW1514 Path(...).read_text without explicit encoding argument

Why the preview flag

PLW1514 currently ships behind preview, so it cannot go in the select list in pyproject.toml without enabling preview for the rest of the ruleset. Running it as a scoped --select PLW1514 --preview invocation keeps the blast radius to this one rule.

Activity

2
greptile-apps[bot]17h ago

Confidence Score: 5/5

[Low impact] The PR appears safe to merge; no actionable defects were found.

Summary

Adds a separate PLW1514 check for text file calls without an explicit encoding.

  • CI and pre-commit now check text file calls for an encoding.

Reviews (2) · Last reviewed commit: "ci: check that text file IO states its e..." · Reviewed by Greptile