Skip to content

Instantly share code, notes, and snippets.

Last active March 15, 2023 19:03
What would you like to do?
A Python Popen that does not suck.

A Python Popen that does not suck.


import os
import subprocess

def popen(*args, **kwargs):
    output      = kwargs.get('output', False)
    directory   = kwargs.get('dir')
    environment = kwargs.get('env')
    shell       = kwargs.get('shell', True)
    raise_err   = kwargs.get('raise_err', True)

    environ     = os.environ.copy()
    if environment:

    command     = " ".join([str(arg) for arg in args])
    proc        = subprocess.Popen(command,
        stdin   = subprocess.PIPE if output else None,
        stdout  = subprocess.PIPE if output else None,
        stderr  = subprocess.PIPE if output else None,
        env     = environ,
        cwd     = directory,
        shell   = shell

    code       = proc.wait()

    if code and raise_err:
        raise subprocess.CalledProcessError(code, command)

    if output:
        output, error = proc.communicate()

        if output:
            output = output.decode('utf-8')
            if output.count('\n') == 1:
                output = output.strip('\n')

        if error:
            error  =  error.decode('utf-8')
            if  error.count('\n') == 1:
                error  =  error.strip('\n')

        return code, output, error
        return code


>>> popen('touch foobar.txt')
Copy link

Why are you using variadic parameters when you don't even rely on them?

Copy link

>>> popen('echo $FOOBAR', env = { 'FOOBAR': 'barbaz' })

Copy link

reorx commented Nov 26, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment