# Buggy code
def scp_send(self, local_file, remote_file, recurse=False):
    """Copy local file to remote file in parallel via SCP.

    This function returns a list of greenlets which can be
    `join`-ed on to wait for completion.

    :py:func:`gevent.joinall` function may be used to join on all greenlets
    and will also raise exceptions from them if called with
    ``raise_error=True`` - default is `False`.

    Alternatively call `.get()` on each greenlet to raise any exceptions
    from it.

    .. note::
      Creating remote directories when either ``remote_file`` contains
      directory paths or ``recurse`` is enabled requires SFTP support on
      the server as libssh2 SCP implementation lacks directory creation
      support.

    :param local_file: Local filepath to copy to remote host
    :type local_file: str
    :param remote_file: Remote filepath on remote host to copy file to
    :type remote_file: str
    :param recurse: Whether or not to descend into directories recursively.
    :type recurse: bool

    :rtype: list(:py:class:`gevent.Greenlet`) of greenlets for remote copy
      commands.

    :raises: :py:class:`pss.exceptions.SCPError` on errors copying file.
    :raises: :py:class:`OSError` on local OS errors like permission denied.
    """
    return [
        self.pool.spawn(self._scp_send, host, local_file, remote_file, recurse=recurse)
        for host in self.hosts
    ]


# Traceback (ValueError)
Traceback (most recent call last):
File "./aws-instances", line 172, in <module>
main()
File "./aws-instances", line 73, in main
facts = remote_facts(ips)
File "./aws-instances", line 146, in remote_facts
out_kern = client.run_command('uname -r')
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/native/parallel.py", line 223, in run_command
greenlet_timeout=greenlet_timeout)
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/base_pssh.py", line 96, in run_command
self.get_output(cmd, output, timeout=greenlet_timeout)
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/base_pssh.py", line 141, in get_output
(channel, host, stdout, stderr, stdin) = cmd.get(timeout=timeout)
File "src/gevent/greenlet.py", line 709, in gevent._greenlet.Greenlet.get
File "src/gevent/greenlet.py", line 317, in gevent._greenlet.Greenlet._raise_exception
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/gevent/_compat.py", line 47, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 766, in gevent._greenlet.Greenlet.run
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/native/parallel.py", line 237, in _run_command
raise ex
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/native/parallel.py", line 233, in _run_command
use_pty=use_pty, encoding=encoding, timeout=timeout)
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/native/single.py", line 442, in run_command
channel = self.execute(_command, use_pty=use_pty)
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/native/single.py", line 324, in execute
channel = self.open_session() if channel is None else channel
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/pssh/clients/native/single.py", line 297, in open_session
wait_select(self.session)
File "pssh/native/_ssh2.pyx", line 171, in pssh.native._ssh2.wait_select
File "/home/user/do-aws-ec2-facts/aws/lib64/python3.6/site-packages/gevent/select.py", line 145, in select
sel_results = _original_select(rlist, wlist, xlist, 0)
ValueError: filedescriptor out of range in select()

# Fixed code
def scp_send(self, local_file, remote_file, recurse=False):
    """Copy local file to remote file in parallel via SCP.

    This function returns a list of greenlets which can be
    `join`-ed on to wait for completion.

    :py:func:`gevent.joinall` function may be used to join on all greenlets
    and will also raise exceptions from them if called with
    ``raise_error=True`` - default is `False`.

    Alternatively call `.get()` on each greenlet to raise any exceptions
    from it.

    .. note::
      Creating remote directories when either ``remote_file`` contains
      directory paths or ``recurse`` is enabled requires SFTP support on
      the server as libssh2 SCP implementation lacks directory creation
      support.

    :param local_file: Local filepath to copy to remote host
    :type local_file: str
    :param remote_file: Remote filepath on remote host to copy file to
    :type remote_file: str
    :param recurse: Whether or not to descend into directories recursively.
    :type recurse: bool

    :rtype: list(:py:class:`gevent.Greenlet`) of greenlets for remote copy
      commands.

    :raises: :py:class:`pss.exceptions.SCPError` on errors copying file.
    :raises: :py:class:`OSError` on local OS errors like permission denied.
    """
    return [
        self.pool.spawn(
            self._scp_send, host_i, host, local_file, remote_file, recurse=recurse
        )
        for host_i, host in enumerate(self.hosts)
    ]