From 0270a1230e8da0291ad6e68d3706e72fe5c2e740 Mon Sep 17 00:00:00 2001 From: nfnty Date: Sat, 5 Nov 2016 06:35:54 +0100 Subject: ext.spawn: Refactor Rename `spawn` to `check_output` Mimic `subprocess.check_output` --- ranger/container/fsobject.py | 4 +-- ranger/core/linemode.py | 4 +-- ranger/ext/spawn.py | 63 ++++++++++++++++++-------------------------- ranger/ext/vcs/vcs.py | 28 +++++++++----------- 4 files changed, 42 insertions(+), 57 deletions(-) diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index d73fa76c..9b312e6d 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -20,7 +20,7 @@ from pwd import getpwuid from ranger.core.linemode import * from ranger.core.shared import FileManagerAware, SettingsAware from ranger.ext.shell_escape import shell_escape -from ranger.ext.spawn import spawn +from ranger.ext import spawn from ranger.ext.lazy_property import lazy_property from ranger.ext.human_readable import human_readable @@ -131,7 +131,7 @@ class FileSystemObject(FileManagerAware, SettingsAware): @lazy_property def filetype(self): try: - return spawn(["file", '-Lb', '--mime-type', self.path]) + return spawn.check_output(["file", '-Lb', '--mime-type', self.path]) except OSError: return "" diff --git a/ranger/core/linemode.py b/ranger/core/linemode.py index a8ce4e6d..c7839723 100644 --- a/ranger/core/linemode.py +++ b/ranger/core/linemode.py @@ -7,7 +7,7 @@ import sys from abc import * from datetime import datetime from ranger.ext.human_readable import human_readable -from ranger.ext.spawn import spawn +from ranger.ext import spawn DEFAULT_LINEMODE = "filename" @@ -100,7 +100,7 @@ class FileInfoLinemode(LinemodeBase): if not file.is_directory: from subprocess import Popen, PIPE, CalledProcessError try: - fileinfo = spawn(["file", "-bL", file.path]).strip() + fileinfo = spawn.check_output(["file", "-bL", file.path]).strip() except CalledProcessError: return "unknown" if sys.version_info[0] >= 3: diff --git a/ranger/ext/spawn.py b/ranger/ext/spawn.py index 393d48d9..77983341 100644 --- a/ranger/ext/spawn.py +++ b/ranger/ext/spawn.py @@ -1,57 +1,44 @@ # This file is part of ranger, the console file manager. # License: GNU GPL version 3, see the file "AUTHORS" for details. +from os import devnull from subprocess import Popen, PIPE, CalledProcessError ENCODING = 'utf-8' -def spawn(*args, **kwargs): - """Runs a program, waits for its termination and returns its stdout +def check_output(popenargs, **kwargs): + """Runs a program, waits for its termination and returns its output - This function is similar to python 2.7's subprocess.check_output, + This function is functionally identical to python 2.7's subprocess.check_output, but is favored due to python 2.6 compatibility. - The arguments may be: + Will be run through shell if popenargs is a string, otherwise the command + is executed directly. - spawn(string) - spawn(command, arg1, arg2...) - spawn([command, arg1, arg2]) - - The string will be run through a shell, otherwise the command is executed - directly. - - The keyword argument "decode" determines if the output shall be decoded - with the encoding '%s'. + The keyword argument `decode` determines if the output shall be decoded + with the encoding ENCODING. Further keyword arguments are passed to Popen. - """ % (ENCODING, ) + """ - if len(args) == 1: - popen_arguments = args[0] - shell = isinstance(popen_arguments, str) - else: - popen_arguments = args - shell = False + do_decode = kwargs.pop('decode', True) + kwargs.setdefault('stdout', PIPE) + kwargs.setdefault('shell', isinstance(popenargs, str)) - if 'decode' in kwargs: - do_decode = kwargs['decode'] - del kwargs['decode'] + if 'stderr' in kwargs: + process = Popen(popenargs, **kwargs) + stdout, _ = process.communicate() else: - do_decode = True - if 'stdout' not in kwargs: - kwargs['stdout'] = PIPE - if 'shell' not in kwargs: - kwargs['shell'] = shell - - process = Popen(popen_arguments, **kwargs) - stdout, stderr = process.communicate() - return_value = process.poll() - if return_value: - error = CalledProcessError(return_value, popen_arguments[0]) + with open(devnull, mode='w') as fd_devnull: + process = Popen(popenargs, stderr=fd_devnull, **kwargs) + stdout, _ = process.communicate() + + if process.returncode != 0: + error = CalledProcessError(process.returncode, popenargs) error.output = stdout raise error - if do_decode: - return stdout.decode(ENCODING) - else: - return stdout + if do_decode and stdout is not None: + stdout = stdout.decode(ENCODING) + + return stdout diff --git a/ranger/ext/vcs/vcs.py b/ranger/ext/vcs/vcs.py index 9c2a8b5a..03a72bb4 100644 --- a/ranger/ext/vcs/vcs.py +++ b/ranger/ext/vcs/vcs.py @@ -8,7 +8,8 @@ import subprocess import threading import time from logging import getLogger -from ranger.ext.spawn import spawn + +from ranger.ext import spawn # Python2 compatibility try: @@ -119,20 +120,17 @@ class Vcs(object): # pylint: disable=too-many-instance-attributes if path is None: path = self.path - with open(os.devnull, 'w') as devnull: - try: - if catchout: - output = spawn(cmd, cwd=path, stderr=devnull, - decode=not retbytes) - if (not retbytes and rstrip_newline and - output.endswith('\n')): - if rstrip_newline and output.endswith('\n'): - return output[:-1] - return output - else: - subprocess.check_call(cmd, cwd=path, stdout=devnull, stderr=devnull) - except (subprocess.CalledProcessError, FileNotFoundError): - raise VcsError('{0:s}: {1:s}'.format(str(cmd), path)) + try: + if catchout: + output = spawn.check_output(cmd, cwd=path, decode=not retbytes) + if not retbytes and rstrip_newline and output.endswith('\n'): + return output[:-1] + return output + else: + with open(os.devnull, mode='w') as fd_devnull: + subprocess.check_call(cmd, cwd=path, stdout=fd_devnull, stderr=fd_devnull) + except (subprocess.CalledProcessError, FileNotFoundError): + raise VcsError('{0:s}: {1:s}'.format(str(cmd), path)) def _get_repotype(self, path): """Get type for path""" -- cgit 1.4.1-2-gfad0