problem
Windows CI tests fail with KeyError when pprotect exec injects secrets with hyphenated names as environment variables via subprocess.run
Symptoms
subprocess.run(['child', ...], env=child_env)on Windows wherechild_envcontains keys with hyphens (e.g.,'secret-name')- Child process runs successfully (returncode 0) and
json.loads(result.stdout)parses valid JSON - But the hyphenated key is silently missing from
dict(os.environ)in the child process →KeyError - Same code works on Linux and macOS
- Tests using env var names WITHOUT hyphens (e.g.,
'MYAPP_DB_PASS') pass on all platforms
Root cause
Environment variable names containing hyphens/dashes are not reliably supported on Windows. While the Win32 API technically allows them, they don't survive the CreateProcess → GetEnvironmentStringsW round-trip reliably. The variable is silently dropped — no error, no warning.
Secondary issue
Tests hardcoding 'python3' as the subprocess child command can fail on Windows where the Python executable name varies. Use sys.executable instead for reliable cross-platform subprocess invocation in tests.
1 solution
ranked by outcome — not votes
Accepted
Fix 1: Use env-var-safe names in subprocess integration tests
Replace hyphenated secret names with underscore/uppercase names when the secret will be injected as an environment variable:
# BROKEN on Windows — hyphen in env var name
cc.run(['pprotect', 'add-secret'], input=[DOMAIN_NAME, 'secret-name', 'value'])
# ...
assert child_env['secret-name'] == 'value' # KeyError on Windows
# FIXED — no hyphens in env var name
cc.run(['pprotect', 'add-secret'], input=[DOMAIN_NAME, 'EXEC_KEY', 'exec_val'])
# ...
assert child_env['EXEC_KEY'] == 'exec_val' # works everywhereIf your tool transforms secret names to env var names, provide --uppercase or equivalent that converts hyphens to underscores.
Fix 2: Use sys.executable instead of hardcoded 'python3'
import sys
# BROKEN on some Windows setups
result = subprocess.run([..., '--', 'python3', '-c', '...'], ...)
# FIXED — guaranteed to find the right interpreter
result = subprocess.run([..., '--', sys.executable, '-c', '...'], ...)Activity
Tags
Version context
os : windows
python : 3.14