| # | |
| # Licensed to the Apache Software Foundation (ASF) under one or more | |
| # contributor license agreements. See the NOTICE file distributed with | |
| # this work for additional information regarding copyright ownership. | |
| # The ASF licenses this file to You under the Apache License, Version 2.0 | |
| # (the "License"); you may not use this file except in compliance with | |
| # the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # | |
| """Cross-platform utilities for creating subprocesses. | |
| For internal use only; no backwards-compatibility guarantees. | |
| """ | |
| # pytype: skip-file | |
| import platform | |
| import subprocess | |
| import traceback | |
| from typing import TYPE_CHECKING | |
| # On Windows, we need to use shell=True when creating subprocesses for binary | |
| # paths to be resolved correctly. | |
| force_shell = platform.system() == 'Windows' | |
| # We mimic the interface of the standard Python subprocess module. | |
| PIPE = subprocess.PIPE | |
| STDOUT = subprocess.STDOUT | |
| CalledProcessError = subprocess.CalledProcessError | |
| if TYPE_CHECKING: | |
| call = subprocess.call | |
| check_call = subprocess.check_call | |
| check_output = subprocess.check_output | |
| Popen = subprocess.Popen | |
| else: | |
| def call(*args, **kwargs): | |
| if force_shell: | |
| kwargs['shell'] = True | |
| try: | |
| out = subprocess.call(*args, **kwargs) | |
| except OSError as e: | |
| raise RuntimeError("Executable {} not found".format(args[0])) from e | |
| except subprocess.CalledProcessError as error: | |
| if isinstance(args, tuple) and (args[0][2] == "pip"): | |
| raise RuntimeError( \ | |
| "Full traceback: {}\n Pip install failed for package: {} \ | |
| \n Output from execution of subprocess: {}" \ | |
| .format(traceback.format_exc(), args[0][6], error. output)) from error | |
| else: | |
| raise RuntimeError("Full trace: {}\ | |
| \n Output of the failed child process: {} " \ | |
| .format(traceback.format_exc(), error.output)) from error | |
| return out | |
| def check_call(*args, **kwargs): | |
| if force_shell: | |
| kwargs['shell'] = True | |
| try: | |
| out = subprocess.check_call(*args, **kwargs) | |
| except OSError as e: | |
| raise RuntimeError("Executable {} not found".format(args[0])) from e | |
| except subprocess.CalledProcessError as error: | |
| if isinstance(args, tuple) and (args[0][2] == "pip"): | |
| raise RuntimeError( \ | |
| "Full traceback: {} \n Pip install failed for package: {} \ | |
| \n Output from execution of subprocess: {}" \ | |
| .format(traceback.format_exc(), args[0][6], error.output)) from error | |
| else: | |
| raise RuntimeError("Full trace: {} \ | |
| \n Output of the failed child process: {}" \ | |
| .format(traceback.format_exc(), error.output)) from error | |
| return out | |
| def check_output(*args, **kwargs): | |
| if force_shell: | |
| kwargs['shell'] = True | |
| try: | |
| out = subprocess.check_output(*args, **kwargs) | |
| except OSError as e: | |
| raise RuntimeError("Executable {} not found".format(args[0])) from e | |
| except subprocess.CalledProcessError as error: | |
| if isinstance(args, tuple) and (args[0][2] == "pip"): | |
| raise RuntimeError( \ | |
| "Full traceback: {} \n Pip install failed for package: {} \ | |
| \n Output from execution of subprocess: {}" \ | |
| .format(traceback.format_exc(), args[0][6], error.output)) from error | |
| else: | |
| raise RuntimeError("Full trace: {}, \ | |
| output of the failed child process {} "\ | |
| .format(traceback.format_exc(), error.output)) from error | |
| return out | |
| def Popen(*args, **kwargs): | |
| if force_shell: | |
| kwargs['shell'] = True | |
| return subprocess.Popen(*args, **kwargs) |