os.PathLike in subprocess commands (edit: nvm, works in 3.8+)

Is there a reason subprocess can’t support os.PathLike? It seems quite natural to me to write something like:

prog = Path("something")
subprocess.run([prog, "-v"])

And I’d expect __fspath__ () to be called if it exists. This has been recently implemented in several tools like nox, but is there a reason subprocess.run and family can’t support it too? os.fspath already passes strings through, though you can also just check to see if it’s an instance of os.PathLike / has a __fspath__ method first instead.

Most other places paths are accepted in Python have been updated to support the fspath protocol, but this seems like a missing one.

I looked for “pathlike”/“fspath” and “subprocess” together, but didn’t see a past discussion.

Popen’s documentation says:

Changed in version 3.6: args parameter accepts a path-like object if shell is False and a sequence containing path-like objects on POSIX.

Changed in version 3.8: args parameter accepts a path-like object if shell is False and a sequence containing bytes and path-like objects on Windows.

And run is typed as taking str | bytes | PathLike[str] | PathLike[bytes] | Sequence[str | bytes | PathLike[str] | PathLike[bytes]] in the typeshed: typeshed/stdlib/subprocess.pyi at main · python/typeshed · GitHub.

1 Like

When I try it in Python 3.11, it works:

>>> subprocess.run(["ls", "-l"])
total 0
-rw-r--r--  1 guido  staff  0 Dec  2 10:24 bar.txt
-rw-r--r--  1 guido  staff  0 Dec  2 10:24 foo.py
CompletedProcess(args=['ls', '-l'], returncode=0)
>>> subprocess.run([pathlib.Path("ls"), "-l"])
total 0
-rw-r--r--  1 guido  staff  0 Dec  2 10:24 bar.txt
-rw-r--r--  1 guido  staff  0 Dec  2 10:24 foo.py
CompletedProcess(args=[PosixPath('ls'), '-l'], returncode=0)
>>> 

Ahh, that’s embarrassing, I have seen this on a CI matrix and could have sworn it was still broken on newer Pythons, but I don’t usually run Windows locally to test it. I forget to mention, it was Windows only - 3.7 accidentally supported Path on UNIX, but produced a “TypeError: argument of type ‘WindowsPath’ is not iterable” on Windows. I’ve verified this fails on 3.7 on Windows only, and works on 3.8 and 3.9 on Windows. Thanks! “It already works” is the best sort of answer. :slight_smile: Sorry for the confusion.

(This also explains why it hasn’t come up before!)

3 Likes