(self, cmd, environ)
| 672 | python_opts.append('-E') |
| 673 | |
| 674 | def _execute_python(self, cmd, environ): |
| 675 | # Make sure that messages before execv() are logged |
| 676 | sys.stdout.flush() |
| 677 | sys.stderr.flush() |
| 678 | |
| 679 | cmd_text = shlex.join(cmd) |
| 680 | try: |
| 681 | # Android and iOS run tests in embedded mode. To update their |
| 682 | # Python options, see the comment in _add_ci_python_opts. |
| 683 | if not cmd[0]: |
| 684 | raise ValueError("No Python executable is present") |
| 685 | |
| 686 | print(f"+ {cmd_text}", flush=True) |
| 687 | if hasattr(os, 'execv') and not MS_WINDOWS: |
| 688 | os.execv(cmd[0], cmd) |
| 689 | # On success, execv() do no return. |
| 690 | # On error, it raises an OSError. |
| 691 | else: |
| 692 | import subprocess |
| 693 | with subprocess.Popen(cmd, env=environ) as proc: |
| 694 | try: |
| 695 | proc.wait() |
| 696 | except KeyboardInterrupt: |
| 697 | # There is no need to call proc.terminate(): on CTRL+C, |
| 698 | # SIGTERM is also sent to the child process. |
| 699 | try: |
| 700 | proc.wait(timeout=EXIT_TIMEOUT) |
| 701 | except subprocess.TimeoutExpired: |
| 702 | proc.kill() |
| 703 | proc.wait() |
| 704 | sys.exit(EXITCODE_INTERRUPTED) |
| 705 | |
| 706 | sys.exit(proc.returncode) |
| 707 | except Exception as exc: |
| 708 | print_warning(f"Failed to change Python options: {exc!r}\n" |
| 709 | f"Command: {cmd_text}") |
| 710 | # continue executing main() |
| 711 | |
| 712 | def _add_python_opts(self) -> None: |
| 713 | python_opts: list[str] = [] |
no test coverage detected