github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/utils/processes.py (about) 1 # 2 # Licensed to the Apache Software Foundation (ASF) under one or more 3 # contributor license agreements. See the NOTICE file distributed with 4 # this work for additional information regarding copyright ownership. 5 # The ASF licenses this file to You under the Apache License, Version 2.0 6 # (the "License"); you may not use this file except in compliance with 7 # the License. You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 """Cross-platform utilities for creating subprocesses. 19 20 For internal use only; no backwards-compatibility guarantees. 21 """ 22 23 # pytype: skip-file 24 25 import platform 26 import subprocess 27 import traceback 28 from typing import TYPE_CHECKING 29 30 # On Windows, we need to use shell=True when creating subprocesses for binary 31 # paths to be resolved correctly. 32 force_shell = platform.system() == 'Windows' 33 34 # We mimic the interface of the standard Python subprocess module. 35 PIPE = subprocess.PIPE 36 STDOUT = subprocess.STDOUT 37 CalledProcessError = subprocess.CalledProcessError 38 39 if TYPE_CHECKING: 40 call = subprocess.call 41 check_call = subprocess.check_call 42 check_output = subprocess.check_output 43 Popen = subprocess.Popen 44 45 else: 46 47 def call(*args, **kwargs): 48 if force_shell: 49 kwargs['shell'] = True 50 try: 51 out = subprocess.call(*args, **kwargs) 52 except OSError: 53 raise RuntimeError("Executable {} not found".format(args[0])) 54 except subprocess.CalledProcessError as error: 55 if isinstance(args, tuple) and (args[0][2] == "pip"): 56 raise RuntimeError( \ 57 "Full traceback: {}\n Pip install failed for package: {} \ 58 \n Output from execution of subprocess: {}" \ 59 .format(traceback.format_exc(), args[0][6], error. output)) 60 else: 61 raise RuntimeError("Full trace: {}\ 62 \n Output of the failed child process: {} " \ 63 .format(traceback.format_exc(), error.output)) 64 return out 65 66 def check_call(*args, **kwargs): 67 if force_shell: 68 kwargs['shell'] = True 69 try: 70 out = subprocess.check_call(*args, **kwargs) 71 except OSError: 72 raise RuntimeError("Executable {} not found".format(args[0])) 73 except subprocess.CalledProcessError as error: 74 if isinstance(args, tuple) and (args[0][2] == "pip"): 75 raise RuntimeError( \ 76 "Full traceback: {} \n Pip install failed for package: {} \ 77 \n Output from execution of subprocess: {}" \ 78 .format(traceback.format_exc(), args[0][6], error.output)) 79 else: 80 raise RuntimeError("Full trace: {} \ 81 \n Output of the failed child process: {}" \ 82 .format(traceback.format_exc(), error.output)) 83 return out 84 85 def check_output(*args, **kwargs): 86 if force_shell: 87 kwargs['shell'] = True 88 try: 89 out = subprocess.check_output(*args, **kwargs) 90 except OSError: 91 raise RuntimeError("Executable {} not found".format(args[0])) 92 except subprocess.CalledProcessError as error: 93 if isinstance(args, tuple) and (args[0][2] == "pip"): 94 raise RuntimeError( \ 95 "Full traceback: {} \n Pip install failed for package: {} \ 96 \n Output from execution of subprocess: {}" \ 97 .format(traceback.format_exc(), args[0][6], error.output)) 98 else: 99 raise RuntimeError("Full trace: {}, \ 100 output of the failed child process {} "\ 101 .format(traceback.format_exc(), error.output)) 102 return out 103 104 def Popen(*args, **kwargs): 105 if force_shell: 106 kwargs['shell'] = True 107 return subprocess.Popen(*args, **kwargs)