Skip to content

Commit c63c614

Browse files
authored
gh-114272: Fix or skip tests that fail due to spaces in paths (GH-114451)
1 parent d5c21c1 commit c63c614

File tree

4 files changed

+45
-25
lines changed

4 files changed

+45
-25
lines changed

Lib/test/test_asyncio/test_subprocess.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def test_kill(self):
207207

208208
def test_kill_issue43884(self):
209209
if sys.platform == 'win32':
210-
blocking_shell_command = f'{sys.executable} -c "import time; time.sleep(2)"'
210+
blocking_shell_command = f'"{sys.executable}" -c "import time; time.sleep(2)"'
211211
else:
212212
blocking_shell_command = 'sleep 1; sleep 1'
213213
creationflags = 0
@@ -745,7 +745,10 @@ async def check_stdout_output(self, coro, output):
745745

746746
def test_create_subprocess_env_shell(self) -> None:
747747
async def main() -> None:
748-
cmd = f'''{sys.executable} -c "import os, sys; sys.stdout.write(os.getenv('FOO'))"'''
748+
executable = sys.executable
749+
if sys.platform == "win32":
750+
executable = f'"{executable}"'
751+
cmd = f'''{executable} -c "import os, sys; sys.stdout.write(os.getenv('FOO'))"'''
749752
env = os.environ.copy()
750753
env["FOO"] = "bar"
751754
proc = await asyncio.create_subprocess_shell(

Lib/test/test_launcher.py

+34-21
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@
9090
"test-command=TEST_EXE.exe",
9191
])
9292

93+
94+
def quote(s):
95+
s = str(s)
96+
return f'"{s}"' if " " in s else s
97+
98+
9399
def create_registry_data(root, data):
94100
def _create_registry_data(root, key, value):
95101
if isinstance(value, dict):
@@ -542,10 +548,10 @@ def test_virtualenv_with_env(self):
542548
data1 = self.run_py([], env={**env, "PY_PYTHON": "PythonTestSuite/3"})
543549
data2 = self.run_py(["-V:PythonTestSuite/3"], env={**env, "PY_PYTHON": "PythonTestSuite/3"})
544550
# Compare stdout, because stderr goes via ascii
545-
self.assertEqual(data1["stdout"].strip(), str(venv_exe))
551+
self.assertEqual(data1["stdout"].strip(), quote(venv_exe))
546552
self.assertEqual(data1["SearchInfo.lowPriorityTag"], "True")
547553
# Ensure passing the argument doesn't trigger the same behaviour
548-
self.assertNotEqual(data2["stdout"].strip(), str(venv_exe))
554+
self.assertNotEqual(data2["stdout"].strip(), quote(venv_exe))
549555
self.assertNotEqual(data2["SearchInfo.lowPriorityTag"], "True")
550556

551557
def test_py_shebang(self):
@@ -554,55 +560,60 @@ def test_py_shebang(self):
554560
data = self.run_py([script, "-postarg"])
555561
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
556562
self.assertEqual("3.100", data["SearchInfo.tag"])
557-
self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip())
563+
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg", data["stdout"].strip())
558564

559565
def test_python_shebang(self):
560566
with self.py_ini(TEST_PY_DEFAULTS):
561567
with self.script("#! python -prearg") as script:
562568
data = self.run_py([script, "-postarg"])
563569
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
564570
self.assertEqual("3.100", data["SearchInfo.tag"])
565-
self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip())
571+
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg", data["stdout"].strip())
566572

567573
def test_py2_shebang(self):
568574
with self.py_ini(TEST_PY_DEFAULTS):
569575
with self.script("#! /usr/bin/python2 -prearg") as script:
570576
data = self.run_py([script, "-postarg"])
571577
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
572578
self.assertEqual("3.100-32", data["SearchInfo.tag"])
573-
self.assertEqual(f"X.Y-32.exe -prearg {script} -postarg", data["stdout"].strip())
579+
self.assertEqual(f"X.Y-32.exe -prearg {quote(script)} -postarg",
580+
data["stdout"].strip())
574581

575582
def test_py3_shebang(self):
576583
with self.py_ini(TEST_PY_DEFAULTS):
577584
with self.script("#! /usr/bin/python3 -prearg") as script:
578585
data = self.run_py([script, "-postarg"])
579586
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
580587
self.assertEqual("3.100-arm64", data["SearchInfo.tag"])
581-
self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {script} -postarg", data["stdout"].strip())
588+
self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {quote(script)} -postarg",
589+
data["stdout"].strip())
582590

583591
def test_py_shebang_nl(self):
584592
with self.py_ini(TEST_PY_DEFAULTS):
585593
with self.script("#! /usr/bin/python -prearg\n") as script:
586594
data = self.run_py([script, "-postarg"])
587595
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
588596
self.assertEqual("3.100", data["SearchInfo.tag"])
589-
self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip())
597+
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg",
598+
data["stdout"].strip())
590599

591600
def test_py2_shebang_nl(self):
592601
with self.py_ini(TEST_PY_DEFAULTS):
593602
with self.script("#! /usr/bin/python2 -prearg\n") as script:
594603
data = self.run_py([script, "-postarg"])
595604
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
596605
self.assertEqual("3.100-32", data["SearchInfo.tag"])
597-
self.assertEqual(f"X.Y-32.exe -prearg {script} -postarg", data["stdout"].strip())
606+
self.assertEqual(f"X.Y-32.exe -prearg {quote(script)} -postarg",
607+
data["stdout"].strip())
598608

599609
def test_py3_shebang_nl(self):
600610
with self.py_ini(TEST_PY_DEFAULTS):
601611
with self.script("#! /usr/bin/python3 -prearg\n") as script:
602612
data = self.run_py([script, "-postarg"])
603613
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
604614
self.assertEqual("3.100-arm64", data["SearchInfo.tag"])
605-
self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {script} -postarg", data["stdout"].strip())
615+
self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {quote(script)} -postarg",
616+
data["stdout"].strip())
606617

607618
def test_py_shebang_short_argv0(self):
608619
with self.py_ini(TEST_PY_DEFAULTS):
@@ -630,7 +641,8 @@ def test_search_path(self):
630641
[script, "-postarg"],
631642
env={"PATH": f"{exe.parent};{os.getenv('PATH')}"},
632643
)
633-
self.assertEqual(f"{exe} -prearg {script} -postarg", data["stdout"].strip())
644+
self.assertEqual(f"{quote(exe)} -prearg {quote(script)} -postarg",
645+
data["stdout"].strip())
634646

635647
def test_search_path_exe(self):
636648
# Leave the .exe on the name to ensure we don't add it a second time
@@ -643,7 +655,8 @@ def test_search_path_exe(self):
643655
[script, "-postarg"],
644656
env={"PATH": f"{exe.parent};{os.getenv('PATH')}"},
645657
)
646-
self.assertEqual(f"{exe} -prearg {script} -postarg", data["stdout"].strip())
658+
self.assertEqual(f"{quote(exe)} -prearg {quote(script)} -postarg",
659+
data["stdout"].strip())
647660

648661
def test_recursive_search_path(self):
649662
stem = self.get_py_exe().stem
@@ -654,7 +667,7 @@ def test_recursive_search_path(self):
654667
env={"PATH": f"{self.get_py_exe().parent};{os.getenv('PATH')}"},
655668
)
656669
# The recursive search is ignored and we get normal "py" behavior
657-
self.assertEqual(f"X.Y.exe {script}", data["stdout"].strip())
670+
self.assertEqual(f"X.Y.exe {quote(script)}", data["stdout"].strip())
658671

659672
def test_install(self):
660673
data = self.run_py(["-V:3.10"], env={"PYLAUNCHER_ALWAYS_INSTALL": "1"}, expect_returncode=111)
@@ -674,38 +687,38 @@ def test_literal_shebang_absolute(self):
674687
with self.script("#! C:/some_random_app -witharg") as script:
675688
data = self.run_py([script])
676689
self.assertEqual(
677-
f"C:\\some_random_app -witharg {script}",
690+
f"C:\\some_random_app -witharg {quote(script)}",
678691
data["stdout"].strip(),
679692
)
680693

681694
def test_literal_shebang_relative(self):
682695
with self.script("#! ..\\some_random_app -witharg") as script:
683696
data = self.run_py([script])
684697
self.assertEqual(
685-
f"{script.parent.parent}\\some_random_app -witharg {script}",
698+
f"{quote(script.parent.parent / 'some_random_app')} -witharg {quote(script)}",
686699
data["stdout"].strip(),
687700
)
688701

689702
def test_literal_shebang_quoted(self):
690703
with self.script('#! "some random app" -witharg') as script:
691704
data = self.run_py([script])
692705
self.assertEqual(
693-
f'"{script.parent}\\some random app" -witharg {script}',
706+
f"{quote(script.parent / 'some random app')} -witharg {quote(script)}",
694707
data["stdout"].strip(),
695708
)
696709

697710
with self.script('#! some" random "app -witharg') as script:
698711
data = self.run_py([script])
699712
self.assertEqual(
700-
f'"{script.parent}\\some random app" -witharg {script}',
713+
f"{quote(script.parent / 'some random app')} -witharg {quote(script)}",
701714
data["stdout"].strip(),
702715
)
703716

704717
def test_literal_shebang_quoted_escape(self):
705718
with self.script('#! some\\" random "app -witharg') as script:
706719
data = self.run_py([script])
707720
self.assertEqual(
708-
f'"{script.parent}\\some\\ random app" -witharg {script}',
721+
f"{quote(script.parent / 'some/ random app')} -witharg {quote(script)}",
709722
data["stdout"].strip(),
710723
)
711724

@@ -714,7 +727,7 @@ def test_literal_shebang_command(self):
714727
with self.script('#! test-command arg1') as script:
715728
data = self.run_py([script])
716729
self.assertEqual(
717-
f"TEST_EXE.exe arg1 {script}",
730+
f"TEST_EXE.exe arg1 {quote(script)}",
718731
data["stdout"].strip(),
719732
)
720733

@@ -723,7 +736,7 @@ def test_literal_shebang_invalid_template(self):
723736
data = self.run_py([script])
724737
expect = script.parent / "/usr/bin/not-python"
725738
self.assertEqual(
726-
f"{expect} arg1 {script}",
739+
f"{quote(expect)} arg1 {quote(script)}",
727740
data["stdout"].strip(),
728741
)
729742

@@ -746,8 +759,8 @@ def test_shebang_command_in_venv(self):
746759

747760
with self.script(f'#! /usr/bin/env {stem} arg1') as script:
748761
data = self.run_py([script], env=env)
749-
self.assertEqual(data["stdout"].strip(), f"{venv_exe} arg1 {script}")
762+
self.assertEqual(data["stdout"].strip(), f"{quote(venv_exe)} arg1 {quote(script)}")
750763

751764
with self.script(f'#! /usr/bin/env {exe.stem} arg1') as script:
752765
data = self.run_py([script], env=env)
753-
self.assertEqual(data["stdout"].strip(), f"{exe} arg1 {script}")
766+
self.assertEqual(data["stdout"].strip(), f"{quote(exe)} arg1 {quote(script)}")

Lib/test/test_os.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -4596,8 +4596,11 @@ def test_pipe_spawnl(self):
45964596
with open(filename, "w") as fp:
45974597
print(code, file=fp, end="")
45984598

4599-
cmd = [sys.executable, filename]
4600-
exitcode = os.spawnl(os.P_WAIT, cmd[0], *cmd)
4599+
executable = sys.executable
4600+
cmd = [executable, filename]
4601+
if os.name == "nt" and " " in cmd[0]:
4602+
cmd[0] = f'"{cmd[0]}"'
4603+
exitcode = os.spawnl(os.P_WAIT, executable, *cmd)
46014604
self.assertEqual(exitcode, 0)
46024605

46034606

Lib/test/test_webbrowser.py

+1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ def test_get(self):
307307
webbrowser.get('fakebrowser')
308308
self.assertIsNotNone(webbrowser._tryorder)
309309

310+
@unittest.skipIf(" " in sys.executable, "test assumes no space in path (GH-114452)")
310311
def test_synthesize(self):
311312
webbrowser = import_helper.import_fresh_module('webbrowser')
312313
name = os.path.basename(sys.executable).lower()

0 commit comments

Comments
 (0)