2

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

The code below is 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 the PowerShell,

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

It does work for the path which doesn't containing 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 problem for using argparse with PowerShell?

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

Cynki
  • 23
  • 5
  • 2
    `argparse` does not change any input strings. It uses the strings in `sys.argv` exactly as given. But its entirely possible that powershell has edited those commandline values. – hpaulj Feb 22 '23 at 02:03
  • 2
    You should install the updated cross-platform PowerShell 7.x, which doesn't have this problem. – Mark Reed Feb 22 '23 at 02:15

1 Answers1

3

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, this string must be placed as ".\test test\\" on the process command line constructed behind the scenes when calling an external program, 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: While PowerShell (Core) 7+ has fixed this particular problem, there is still a long-standing problem with respect to intentionally embedded " characters in arguments passed to external programs - see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Wild. I bet this has caused a lot of people untold pain. – flakes Feb 22 '23 at 02:12
  • Can you explain why this doesn't seem to be an issue for the powershell `echo` command? Is this somehow different than a normal process? – flakes Feb 22 '23 at 02:15
  • 1
    @flakes, the problem only surfaces with calls to _external programs_ - calls to PowerShell-native commands aren't affected (such as to `echo`, a built-in alias of [`Write-Output`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/write-output)). Unfortunately, the problem at hand is just the tip of the iceberg - please see the link I've added to the answer. – mklement0 Feb 22 '23 at 02:20
  • 1
    It actually works with PowerShell 7. It's enough for me. Thank you :). – Cynki Feb 22 '23 at 02:38