def run(self, args=[], create_fhs=[], attach_fhs={}):
        if self.handles:
            raise RuntimeError('Already running')

        standard_handles = {
            'stdin': (sys.stdin, 'wb'),
            'stdout': (sys.stdout, 'rb'),
            'stderr': (sys.stderr, 'rb'),
        }

        gpg_handles = {
            'passphrase': 'wb',
        }

        self.handles = {}
        self.parent_fds = []
        child_fds = []
        fd_args = []
        std_fds = {}

        # If not given, attach standard streams
        for name, value in standard_handles.items():
            if name not in create_fhs and name not in attach_fhs:
                fobj, mode = value
                attach_fhs[name] = fobj

        for name in create_fhs:
            if name in standard_handles:
                _, mode = standard_handles[name]
            elif name in gpg_handles:
                mode = gpg_handles[name]
            else:
                close_fds(self.parent_fds, child_fds)
                raise ValueError('Invalid handle: %s' % name)

            pipe_r, pipe_w = os.pipe()
            if mode == 'wb':
                for_parent = pipe_w
                for_child = pipe_r
            elif mode == 'rb':
                for_parent = pipe_r
                for_child = pipe_w
            else:
                assert 0

            if name in standard_handles:
                std_fds[name] = for_child
            else:
                fd_args += ['--%s-fd' % name, str(for_child)]

            self.handles[name] = os.fdopen(for_parent, mode)
            self.parent_fds.append(for_parent)
            child_fds.append(for_child)

        for name, fobj in attach_fhs.items():
            if name in standard_handles:
                _, mode = standard_handles[name]
                target_fd = fobj.fileno()
            elif name in gpg_handles:
                mode = gpg_handles[name]
                target_fd = None
            else:
                close_fds(self.parent_fds, child_fds)
                raise ValueError('Invalid handle %s' % name)

            # Determine the file descriptor
            if hasattr(fobj, 'fileno') and callable(fobj.fileno):
                source_fd = fobj.fileno()
                self.handles[name] = fobj
            elif isinstance(fobj, int):
                source_fd = fobj
                self.handles[name] = os.fdopen(source_fd, mode)
            else:
                close_fds(self.parent_fds, child_fds)
                raise ValueError('No file descriptor to attach for %s' % name)

            if name in standard_handles:
                std_fds[name] = target_fd
            else:
                fd_args += ['--%s-fd' % name, str(source_fd)]

        def preexec():
            close_fds(self.parent_fds)

        cmdline = ['gpg'] + fd_args + self.default_args + self.args + args
        self.p = subprocess.Popen(cmdline, preexec_fn=preexec,
                                  close_fds=False, **std_fds)

        close_fds(child_fds)
dataset/ETHPy150Open akheron/sala/sala/gpg.py/GnuPG.run/original