Skip to content

patchwright/replace-prefix-lint

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

replace-prefix-lint

A tiny, zero-dependency linter for one specific, real bug:

if path.startswith("/blob/"):
    out = path.replace("/blob/", "")   # ← removes EVERY "/blob/", not just the prefix

str.replace(p, "") removes every occurrence of p. When it sits behind an if x.startswith(p): guard, the author almost always meant to strip the leading marker — so any value that contains the marker again is silently corrupted:

>>> "/blob/main/src/blob/utils.py".replace("/blob/", "")
'main/srcutils.py'          # expected 'main/src/blob/utils.py'

The fix is str.removeprefix (or str.removesuffix for the endswith case), or a slice on Python < 3.9.

This bug is invisible to existing linters: ruff's B005 flags .strip("multichar"), but nothing flags .replace(prefix, ""). This tool fills that one gap.

Origin: this check was written after finding exactly this bug in a real, widely-used package and fixing it upstream.

Install

pip install git+https://github.com/patchwright/replace-prefix-lint

Use

replace-prefix-lint path/to/code/
path/to/file.py:42:19: RPL001 .replace('/blob/', "") guarded by startswith('/blob/') removes every occurrence; use str.removeprefix('/blob/')

Exit code is 1 if anything is found, 0 otherwise — so it drops straight into CI or a pre-commit hook.

Why so few false positives

The check is deliberately narrow. It fires only when all of these hold:

  • an if test of <recv>.startswith(P) or <recv>.endswith(P) with a string literal P,
  • a <recv>.replace(P, "") call inside that if block,
  • the same receiver expression, the same literal P, and an empty replacement.

An unguarded .replace(p, "") (where replace-all may be intended) is never flagged. Neither is a non-empty replacement, a different literal, or a different receiver.

License

MIT

About

Tiny zero-dependency linter: flags str.replace(P,'') guarded by startswith/endswith(P) that should be removeprefix/removesuffix (the bug ruff B005 misses).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages