|
19 | 19 |
|
20 | 20 |
|
21 | 21 | PY_EXE = "py.exe"
|
| 22 | +DEBUG_BUILD = False |
22 | 23 | if sys.executable.casefold().endswith("_d.exe".casefold()):
|
23 | 24 | PY_EXE = "py_d.exe"
|
| 25 | + DEBUG_BUILD = True |
24 | 26 |
|
25 | 27 | # Registry data to create. On removal, everything beneath top-level names will
|
26 | 28 | # be deleted.
|
@@ -232,7 +234,7 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non
|
232 | 234 | p.stdin.close()
|
233 | 235 | p.wait(10)
|
234 | 236 | out = p.stdout.read().decode("utf-8", "replace")
|
235 |
| - err = p.stderr.read().decode("ascii", "replace") |
| 237 | + err = p.stderr.read().decode("ascii", "replace").replace("\uFFFD", "?") |
236 | 238 | if p.returncode != expect_returncode and support.verbose and not allow_fail:
|
237 | 239 | print("++ COMMAND ++")
|
238 | 240 | print([self.py_exe, *args])
|
@@ -273,7 +275,7 @@ def script(self, content, encoding="utf-8"):
|
273 | 275 | def fake_venv(self):
|
274 | 276 | venv = Path.cwd() / "Scripts"
|
275 | 277 | venv.mkdir(exist_ok=True, parents=True)
|
276 |
| - venv_exe = (venv / Path(sys.executable).name) |
| 278 | + venv_exe = (venv / ("python_d.exe" if DEBUG_BUILD else "python.exe")) |
277 | 279 | venv_exe.touch()
|
278 | 280 | try:
|
279 | 281 | yield venv_exe, {"VIRTUAL_ENV": str(venv.parent)}
|
@@ -521,6 +523,9 @@ def test_virtualenv_in_list(self):
|
521 | 523 | self.assertEqual(str(venv_exe), m.group(1))
|
522 | 524 | break
|
523 | 525 | else:
|
| 526 | + if support.verbose: |
| 527 | + print(data["stdout"]) |
| 528 | + print(data["stderr"]) |
524 | 529 | self.fail("did not find active venv path")
|
525 | 530 |
|
526 | 531 | data = self.run_py(["-0"], env=env)
|
@@ -616,25 +621,29 @@ def test_py_handle_64_in_ini(self):
|
616 | 621 | self.assertEqual("True", data["SearchInfo.oldStyleTag"])
|
617 | 622 |
|
618 | 623 | def test_search_path(self):
|
619 |
| - stem = Path(sys.executable).stem |
| 624 | + exe = Path("arbitrary-exe-name.exe").absolute() |
| 625 | + exe.touch() |
| 626 | + self.addCleanup(exe.unlink) |
620 | 627 | with self.py_ini(TEST_PY_DEFAULTS):
|
621 |
| - with self.script(f"#! /usr/bin/env {stem} -prearg") as script: |
| 628 | + with self.script(f"#! /usr/bin/env {exe.stem} -prearg") as script: |
622 | 629 | data = self.run_py(
|
623 | 630 | [script, "-postarg"],
|
624 |
| - env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, |
| 631 | + env={"PATH": f"{exe.parent};{os.getenv('PATH')}"}, |
625 | 632 | )
|
626 |
| - self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) |
| 633 | + self.assertEqual(f"{exe} -prearg {script} -postarg", data["stdout"].strip()) |
627 | 634 |
|
628 | 635 | def test_search_path_exe(self):
|
629 | 636 | # Leave the .exe on the name to ensure we don't add it a second time
|
630 |
| - name = Path(sys.executable).name |
| 637 | + exe = Path("arbitrary-exe-name.exe").absolute() |
| 638 | + exe.touch() |
| 639 | + self.addCleanup(exe.unlink) |
631 | 640 | with self.py_ini(TEST_PY_DEFAULTS):
|
632 |
| - with self.script(f"#! /usr/bin/env {name} -prearg") as script: |
| 641 | + with self.script(f"#! /usr/bin/env {exe.name} -prearg") as script: |
633 | 642 | data = self.run_py(
|
634 | 643 | [script, "-postarg"],
|
635 |
| - env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, |
| 644 | + env={"PATH": f"{exe.parent};{os.getenv('PATH')}"}, |
636 | 645 | )
|
637 |
| - self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) |
| 646 | + self.assertEqual(f"{exe} -prearg {script} -postarg", data["stdout"].strip()) |
638 | 647 |
|
639 | 648 | def test_recursive_search_path(self):
|
640 | 649 | stem = self.get_py_exe().stem
|
@@ -727,15 +736,18 @@ def test_shebang_command_in_venv(self):
|
727 | 736 | data = self.run_py([script], expect_returncode=103)
|
728 | 737 |
|
729 | 738 | with self.fake_venv() as (venv_exe, env):
|
730 |
| - # Put a real Python (ourselves) on PATH as a distraction. |
| 739 | + # Put a "normal" Python on PATH as a distraction. |
731 | 740 | # The active VIRTUAL_ENV should be preferred when the name isn't an
|
732 | 741 | # exact match.
|
733 |
| - env["PATH"] = f"{Path(sys.executable).parent};{os.environ['PATH']}" |
| 742 | + exe = Path(Path(venv_exe).name).absolute() |
| 743 | + exe.touch() |
| 744 | + self.addCleanup(exe.unlink) |
| 745 | + env["PATH"] = f"{exe.parent};{os.environ['PATH']}" |
734 | 746 |
|
735 | 747 | with self.script(f'#! /usr/bin/env {stem} arg1') as script:
|
736 | 748 | data = self.run_py([script], env=env)
|
737 | 749 | self.assertEqual(data["stdout"].strip(), f"{venv_exe} arg1 {script}")
|
738 | 750 |
|
739 |
| - with self.script(f'#! /usr/bin/env {Path(sys.executable).stem} arg1') as script: |
| 751 | + with self.script(f'#! /usr/bin/env {exe.stem} arg1') as script: |
740 | 752 | data = self.run_py([script], env=env)
|
741 |
| - self.assertEqual(data["stdout"].strip(), f"{sys.executable} arg1 {script}") |
| 753 | + self.assertEqual(data["stdout"].strip(), f"{exe} arg1 {script}") |
0 commit comments