Skip to content

Commit afb5961

Browse files
committed
fix: use shell=True for all Windows Python versions
Windows requires shell=True to properly execute .cmd batch files like npx.cmd across all Python versions. Previous approach only applied this to Python 3.9, causing inconsistent behavior and npm cache corruption errors on other versions. Now using shell=True with properly quoted command string (via shlex.quote) for all Windows Python versions, and shell=False with list format on Unix systems for better security. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 5e5b59e commit afb5961

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/promptfoo/cli.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,28 @@ def main() -> NoReturn:
5555

5656
# Build the command: npx promptfoo@latest <args>
5757
# Use @latest to always get the most recent version
58-
# Use the full path to npx for Windows compatibility
59-
cmd = [npx_path, "--yes", "promptfoo@latest"] + sys.argv[1:]
60-
61-
# On Windows Python 3.9, we need shell=True for proper .cmd execution
62-
# On other platforms/versions, use shell=False to avoid npm cache issues
63-
is_windows_py39 = platform.system() == "Windows" and sys.version_info[:2] == (3, 9)
58+
is_windows = platform.system() == "Windows"
59+
60+
# On Windows, we need special handling for .cmd files
61+
if is_windows:
62+
# On Windows, build command as string for shell=True
63+
# This properly handles npx.cmd batch file execution
64+
import shlex
65+
args = ["npx", "--yes", "promptfoo@latest"] + sys.argv[1:]
66+
cmd = " ".join(shlex.quote(arg) for arg in args)
67+
use_shell = True
68+
else:
69+
# On Unix, use list format with shell=False (more secure)
70+
cmd = [npx_path, "--yes", "promptfoo@latest"] + sys.argv[1:]
71+
use_shell = False
6472

6573
try:
6674
# Execute the command and pass through stdio
6775
result = subprocess.run(
6876
cmd,
6977
env=os.environ.copy(),
7078
check=False, # Don't raise exception on non-zero exit
71-
shell=is_windows_py39, # Only use shell on Windows Python 3.9
79+
shell=use_shell,
7280
)
7381
sys.exit(result.returncode)
7482
except KeyboardInterrupt:

0 commit comments

Comments
 (0)