fix(formats): keep Windows paths intact in requirements option lines - #3863
fix(formats): keep Windows paths intact in requirements option lines#3863deepspace28 wants to merge 1 commit into
Conversation
shlex.split runs in POSIX mode, where a backslash escapes the next character. Option lines carrying a native Windows path were therefore mangled before argparse ever saw them: -e C:\src\pkg arrived as C:srcpkg, and the same for -r. Escape backslashes on Windows before splitting, so quoting keeps working as it does elsewhere.
|
Withdrawing this - I should have checked the reference implementation first. pip does exactly the same thing, for the same reason: >>> from pip._internal.req.req_file import break_args_options, build_parser
>>> # pip 26.2.1
>>> opts, _ = parser.parse_args(shlex.split(break_args_options(r"-e C:\src\pkg")[1]), defaults)
>>> opts.editables
["C:srcpkg"]
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3863 +/- ##
=======================================
Coverage 88.72% 88.73%
=======================================
Files 120 120
Lines 13278 13284 +6
Branches 2254 2255 +1
=======================================
+ Hits 11781 11787 +6
Misses 931 931
Partials 566 566
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Option lines go through
shlex.split, which runs in POSIX mode where a backslash escapes the next character. A native Windows path in a-eor-rline is destroyed before argparse ever sees it:So
pdm importof a requirements file that references a local package or a nested requirements file by absolute Windows path silently resolves the wrong location. There is no error - the path just loses its separators.Escape backslashes on Windows before splitting, which keeps quoting behaving as it does everywhere else:
POSIX platforms are untouched, since a backslash there is a legitimate escape. Covered by a parametrized test that pins
os.nameso it runs on every platform.