python / python/cpython

`py -V:X.Y script.py` fails with "No suitable Python runtime found" when script arguments contain forward slashes

Open Beginner friendly
#148,478 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

3.13 3.14 3.15 interpreter-core OS-windows
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Summary

When using the Python Launcher (py.exe) with a version flag (-V:X.Y), any script argument containing a forward slash (e.g. ./output, /tmp, C:/foo) causes exit code 103 ("No suitable Python runtime found"), even though the specified Python version is installed.

Reproduction

# test_simple.py
import sys
print('ran ok, argv:', sys.argv[1:])
py -V:3.14 test_simple.py files      # OK
py -V:3.14 test_simple.py ./files    # FAIL: "No suitable Python runtime found"
py -V:3.14 test_simple.py --help     # OK  (no slash)
py -V:3.14 test_simple.py .\files    # OK  (backslash is fine)
py -V:3.14 test_simple.py /files     # FAIL
py -V:3.14 test_simple.py C:/files   # FAIL

py test_simple.py ./files            # OK  (no -V: flag = unaffected)

Root cause

In PC/launcher2.c, parseCommandLine() parses -V:company/tag as follows:

const wchar_t *argStart = wcschr(arg, L':') + 1;   // points past ':' in "-V:3.14"
const wchar_t *tagStart = wcschr(argStart, L'/');   // BUG: scans entire remaining cmdline

arg points into the full command-line string (from GetCommandLineW), not just the current token. tail (the whitespace-bounded end of the -V: token) is computed earlier but is not used to bound the wcschr search.

For py -V:3.14 script.py ./files, argStart is "3.14 script.py ./files...". The unbounded wcschr finds the / in ./files, and misparses:

company = "3.14 script.py ."   (should be empty)
tag     = "files"               (should be "3.14")

selectEnvironment then finds no Python matching this bogus company/tag and returns RC_NO_PYTHON.

Fix

Limit the / search to within tail:

const wchar_t *argStart = wcschr(arg, L':') + 1;
// Search for '/' only within the current token boundary
const wchar_t *tagStart = NULL;
for (const wchar_t *p = argStart; p < tail; ++p) {
    if (*p == L'/') { tagStart = p; break; }
}

Environment

  • Python 3.14.4 (Windows 11, version 25H2)
  • py.exe version: 3.14.4 (C:\Windows\py.EXE)
  • Also present in launcher2.c on main and 3.13 branches (same code)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in PC/launcher2.c at parseCommandLine(), then reproduce the issue with the listed py -V:3.14 commands and test_simple.py on Windows. Done means slash-containing script arguments no longer produce “No suitable Python runtime found” when a version flag is used, while the existing company/tag parsing still works.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, python
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.