<s> from __future__ import absolute_import <EOL> import os <EOL> import sys <EOL> import subprocess <EOL> import shutil <EOL> import io <EOL> import threading <EOL> import errno <EOL> try : <EOL> import pty <EOL> except ImportError : <EOL> pty = None <EOL> from . tempdir import create_temporary_dir <EOL> from . files import FileOperations <EOL> from . import results <EOL> from . io import IoHandler , Channel <EOL> from . errors import NoSuchCommandError <EOL> class LocalShell ( object ) : <EOL> def __enter__ ( self ) : <EOL> return self <EOL> def __exit__ ( self , * args ) : <EOL> pass <EOL> def upload_dir ( self , source , dest , ignore = None ) : <EOL> shutil . copytree ( source , dest , ignore = shutil . ignore_patterns ( * ignore ) ) <EOL> def upload_file ( self , source , dest ) : <EOL> shutil . copyfile ( source , dest ) <EOL> def open ( self , name , mode = "<STR_LIT:r>" ) : <EOL> return open ( name , mode ) <EOL> def write_file ( self , remote_path , contents ) : <EOL> subprocess . check_call ( [ "<STR_LIT>" , "<STR_LIT>" , os . path . dirname ( remote_path ) ] ) <EOL> open ( remote_path , "<STR_LIT:w>" ) . write ( contents ) <EOL> def spawn ( self , command , * args , ** kwargs ) : <EOL> stdout = kwargs . pop ( "<STR_LIT>" , None ) <EOL> stderr = kwargs . pop ( "<STR_LIT>" , None ) <EOL> allow_error = kwargs . pop ( "<STR_LIT>" , False ) <EOL> store_pid = kwargs . pop ( "<STR_LIT>" , False ) <EOL> use_pty = kwargs . pop ( "<STR_LIT>" , False ) <EOL> encoding = kwargs . pop ( "<STR_LIT>" , None ) <EOL> if use_pty : <EOL> if pty is None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> master , slave = pty . openpty ( ) <EOL> stdin_arg = slave <EOL> stdout_arg = slave <EOL> stderr_arg = subprocess . STDOUT <EOL> else : <EOL> stdin_arg = subprocess . PIPE <EOL> stdout_arg = subprocess . PIPE <EOL> stderr_arg = subprocess . PIPE <EOL> try : <EOL> process = subprocess . Popen ( <EOL> stdin = stdin_arg , <EOL> stdout = stdout_arg , <EOL> stderr = stderr_arg , <EOL> bufsize = <NUM_LIT:0> , <EOL> ** self . _subprocess_args ( command , * args , ** kwargs ) <EOL> ) <EOL> except OSError as error : <EOL> if self . _is_no_such_command_oserror ( error , command [ <NUM_LIT:0> ] ) : <EOL> raise NoSuchCommandError ( command [ <NUM_LIT:0> ] ) <EOL> else : <EOL> raise <EOL> if use_pty : <EOL> process_stdin = os . fdopen ( os . dup ( master ) , "<STR_LIT:wb>" , <NUM_LIT:0> ) <EOL> process_stdout = os . fdopen ( master , "<STR_LIT:rb>" , <NUM_LIT:0> ) <EOL> process_stderr = io . BytesIO ( ) <EOL> def close_slave_on_exit ( ) : <EOL> process . wait ( ) <EOL> os . close ( slave ) <EOL> thread = threading . Thread ( target = close_slave_on_exit ) <EOL> thread . daemon = True <EOL> thread . start ( ) <EOL> else : <EOL> process_stdin = process . stdin <EOL> process_stdout = process . stdout <EOL> process_stderr = process . stderr <EOL> spur_process = LocalProcess ( <EOL> process , <EOL> allow_error = allow_error , <EOL> process_stdin = process_stdin , <EOL> io_handler = IoHandler ( [ <EOL> Channel ( process_stdout , stdout , is_pty = use_pty ) , <EOL> Channel ( process_stderr , stderr , is_pty = use_pty ) , <EOL> ] , encoding = encoding ) <EOL> ) <EOL> if store_pid : <EOL> spur_process . pid = process . pid <EOL> return spur_process <EOL> def run ( self , * args , ** kwargs ) : <EOL> return self . spawn ( * args , ** kwargs ) . wait_for_result ( ) <EOL> def temporary_dir ( self ) : <EOL> return create_temporary_dir ( ) <EOL> @ property <EOL> def files ( self ) : <EOL> return FileOperations ( self ) <EOL> def _subprocess_args ( self , command , cwd = None , update_env = None , new_process_group = False ) : <EOL> kwargs = { <EOL> "<STR_LIT:args>" : command , <EOL> "<STR_LIT>" : cwd , <EOL> } <EOL> if update_env is not None : <EOL> new_env = os . environ . copy ( ) <EOL> new_env . update ( update_env ) <EOL> kwargs [ "<STR_LIT>" ] = new_env <EOL> if new_process_group : <EOL> kwargs [ "<STR_LIT>" ] = os . setpgrp <EOL> return kwargs <EOL> def _is_no_such_command_oserror ( self , error , command ) : <EOL> if error . errno != errno . ENOENT : <EOL> return False <EOL> if sys . version_info [ <NUM_LIT:0> ] < <NUM_LIT:3> : <EOL> return error . filename is None <EOL> else : <EOL> return error . args [ <NUM_LIT:1> ] == os . strerror ( error . errno ) + "<STR_LIT>" + repr ( command ) <EOL> class LocalProcess ( object ) : <EOL> def __init__ ( self , subprocess , allow_error , process_stdin , io_handler ) : <EOL> self . _subprocess = subprocess <EOL> self . _allow_error = allow_error <EOL> self . _process_stdin = process_stdin <EOL> self . _result = None <EOL> self . _io = io_handler <EOL> def is_running ( self ) : <EOL> return self . _subprocess . poll ( ) is None <EOL> def stdin_write ( self , value ) : <EOL> self . _process_stdin . write ( value ) <EOL> def send_signal ( self , signal ) : <EOL> self . _subprocess . send_signal ( signal ) <EOL> def wait_for_result ( self ) : <EOL> if self . _result is None : <EOL> self . _result = self . _generate_result ( ) <EOL> return self . _result <EOL> def _generate_result ( self ) : <EOL> output , stderr_output = self . _io . wait ( ) <EOL> return_code = self . _subprocess . wait ( ) <EOL> return results . result ( <EOL> return_code , <EOL> self . _allow_error , <EOL> output , <EOL> stderr_output <EOL> ) </s>
