Windows: grep parsing fails when using ripgrep with absolute paths
Environment
- OS: Windows 11
- Python: 3.12
ripgrep (rg) installed and available in PATH
Description
The grep tool incorrectly parses every match on Windows when ripgrep is used.
The parser (_parse_rg) assumes that each ripgrep output line can be split using:
However, ripgrep is invoked with an absolute search path, and on Windows absolute paths begin with a drive letter (e.g. C:\). The drive letter introduces an extra : before the expected field separators, causing the parser to misinterpret the output.
This issue only occurs when ripgrep is available (shutil.which("rg") succeeds). The pure-Python fallback (_py_grep) is unaffected, which is why the problem is not visible on Linux/macOS or in CI environments that don't use Windows.
Where
-
coworker/tools/search.py:81
base = (root / (path or ".")).resolve()
- Always resolves to an absolute path.
-
coworker/tools/search.py:101
cmd.append(str(base))
- Passes the absolute Windows path to
rg.
-
coworker/tools/search.py:135
parts = line.split(":", 2)
- Incorrectly parses Windows drive-letter paths.
Reproduction
Ripgrep emits matches in the following format:
On Windows, the path is absolute:
C:\Users\me\ws\a.py:12:def hello():
Current parsing:
f, ln, txt = "C:\\Users\\me\\ws\\a.py:12:def hello():".split(":", 2)
Result:
f = "C"
ln = "\\Users\\me\\ws\\a.py"
txt = "12:def hello():"
Since ln is no longer numeric, it falls back to line 0.
The parsed match becomes:
- File:
C
- Line:
0
- Text:
12:def hello():
instead of:
- File:
C:\Users\me\ws\a.py
- Line:
12
- Text:
def hello():
Expected Behavior
The parser should correctly handle Windows drive-letter paths so that matches are reported with:
- The full file path
- The correct line number
- The correct matched text
Actual Behavior
Every ripgrep match on Windows is parsed incorrectly:
- File becomes only the drive letter (
C)
- Line number becomes
0
- The actual line number is included in the matched text
Impact
This affects any Windows developer who has ripgrep installed.
The existing test:
tests/test_code_tools.py::test_grep_finds_matches_and_respects_glob
expects file names such as:
With ripgrep on Windows, the parsed result instead becomes:
causing the test to fail.
Additional Notes
The pure-Python implementation (_py_grep) does not have this issue because it does not parse ripgrep output. As a result, the bug only appears on Windows when rg is available in PATH.
Windows:
grepparsing fails when using ripgrep with absolute pathsEnvironment
ripgrep(rg) installed and available inPATHDescription
The
greptool incorrectly parses every match on Windows whenripgrepis used.The parser (
_parse_rg) assumes that each ripgrep output line can be split using:However, ripgrep is invoked with an absolute search path, and on Windows absolute paths begin with a drive letter (e.g.
C:\). The drive letter introduces an extra:before the expected field separators, causing the parser to misinterpret the output.This issue only occurs when
ripgrepis available (shutil.which("rg")succeeds). The pure-Python fallback (_py_grep) is unaffected, which is why the problem is not visible on Linux/macOS or in CI environments that don't use Windows.Where
coworker/tools/search.py:81base = (root / (path or ".")).resolve()coworker/tools/search.py:101cmd.append(str(base))rg.coworker/tools/search.py:135parts = line.split(":", 2)Reproduction
Ripgrep emits matches in the following format:
On Windows, the path is absolute:
Current parsing:
Result:
Since
lnis no longer numeric, it falls back to line0.The parsed match becomes:
C012:def hello():instead of:
C:\Users\me\ws\a.py12def hello():Expected Behavior
The parser should correctly handle Windows drive-letter paths so that matches are reported with:
Actual Behavior
Every ripgrep match on Windows is parsed incorrectly:
C)0Impact
This affects any Windows developer who has
ripgrepinstalled.The existing test:
expects file names such as:
{"a.py"}With ripgrep on Windows, the parsed result instead becomes:
{"C"}causing the test to fail.
Additional Notes
The pure-Python implementation (
_py_grep) does not have this issue because it does not parse ripgrep output. As a result, the bug only appears on Windows whenrgis available inPATH.