Cynki
Cynki

Reputation: 33

Python argparse not working corrrectly with path in Windows

The argparse library in python doesn't work for any path containing a space and \ (backslash) at the end. The parser will parse the backslash at the end of path to be " (double quotation).

The code below is a sample that has same problem:

import argparse


if __name__=="__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-w', '--weight', type=str)

    args = parser.parse_args()

    print(args.weight_path)

For example in PowerShell:

PS > python sample.py -w ".\test test\"
.\test test"

It does work for any path which doesn't contain a space:

PS > python sample.py -w ".\testtest\"
.\test test\
PS > python sample.py -w "testtest\"
test test\
PS > python sample.py -w "testtest"
test test

Is there any issues with using argparse with PowerShell?

I don't even know how to search for a solution to this problem...

Upvotes: 3

Views: 557

Answers (1)

mklement0
mklement0

Reputation: 439777

You're seeing what is a bug in Windows PowerShell, which has since been corrected in PowerShell (Core) 7+:

  • To PowerShell, based on the syntax of its own string literals, the verbatim value of string ".\test test\" is .\test test\, because \ has no special meaning in PowerShell (PowerShell's escape character is `, the so-called backtick).

  • However, based on the most widely used conventions for parsing a process command line on Windows, when calling external program, this string must be placed as
    ".\test test\\" on the process command line constructed behind the scenes
    - of necessity enclosed in "...", because the argument contains space(s)[1] - given that processes are expected to parse \" as an escaped " char.

    • While PowerShell (Core) 7+ now does do that behind the scenes, Windows PowerShell does not: it places ".\test test\", which causes Python to interpret the closing \" as a verbatim " (while not complaining that a closing unescaped " - i.e. one with syntactic function - is then missing).

The workaround for Windows PowerShell is to manually double the \ char. before the closing ":

# Windows PowerShell only: double the \ before the closing "
python sample.py -w ".\test test\\"

As an aside:

  • PowerShell (Core) 7, in v7.3+, has also fixed another long-standing problem that will continue to plague Windows PowerShell, namely with respect to intentionally embedded " characters in arguments passed to external programs - see this answer.

[1] Note that an argument without spaces, e.g. .\test_test\, would not cause the problem, because PowerShell - when it builds the true process command line behind the scenes - does not enclose such arguments in "..." (does not double-quote them).

Upvotes: 4

Related Questions