# Path: invoke/terminals.py
# def pty_size():
#     """
#     Determine current local pseudoterminal dimensions.
# 
#     :returns:
#         A ``(num_cols, num_rows)`` two-tuple describing PTY size. Defaults to
#         ``(80, 24)`` if unable to get a sensible result dynamically.
# 
#     .. versionadded:: 1.0
#     """
#     cols, rows = _pty_size() if not WINDOWS else _win_pty_size()
#     # TODO: make defaults configurable?
#     return ((cols or 80), (rows or 24))
# 
# def bytes_to_read(input_):
#     """
#     Query stream ``input_`` to see how many bytes may be readable.
# 
#     .. note::
#         If we are unable to tell (e.g. if ``input_`` isn't a true file
#         descriptor or isn't a valid TTY) we fall back to suggesting reading 1
#         byte only.
# 
#     :param input: Input stream object (file-like).
# 
#     :returns: `int` number of bytes to read.
# 
#     .. versionadded:: 1.0
#     """
#     # NOTE: we have to check both possibilities here; situations exist where
#     # it's not a tty but has a fileno, or vice versa; neither is typically
#     # going to work re: ioctl().
#     if not WINDOWS and isatty(input_) and has_fileno(input_):
#         fionread = fcntl.ioctl(input_, termios.FIONREAD, "  ")
#         return struct.unpack("h", fionread)[0]
#     return 1
# 
# WINDOWS = sys.platform == "win32"


import fcntl
import termios
from mock import Mock, patch
from pytest import skip, mark
from invoke.terminals import pty_size, bytes_to_read, WINDOWS
        @patch("fcntl.ioctl")
        def uses_default_when_stdout_lacks_fileno(self, ioctl, stdout):
            # i.e. when accessing it throws AttributeError
            stdout.fileno.side_effect = AttributeError
            assert pty_size() == (80, 24)

        @patch("sys.stdout")
        @patch("fcntl.ioctl")
        def uses_default_when_stdout_triggers_ioctl_error(self, ioctl, stdout):
            ioctl.side_effect = TypeError
            assert pty_size() == (80, 24)

    class bytes_to_read_:
        @patch("invoke.terminals.fcntl")
        def returns_1_when_stream_lacks_fileno(self, fcntl):
            # A fileno() that exists but returns a non-int is a quick way
            # to fail util.has_fileno().
            assert bytes_to_read(Mock(fileno=lambda: None)) == 1
            assert not fcntl.ioctl.called

        @patch("invoke.terminals.fcntl")
        def returns_1_when_stream_has_fileno_but_is_not_a_tty(self, fcntl):
            # It blows up otherwise anyways (struct.unpack gets mad because
            # result isn't a string of the right length) but let's make
            # ioctl die similarly to the real world case we're testing for
            # here (#425)
            fcntl.ioctl.side_effect = IOError(
                "Operation not supported by device"
            )
            stream = Mock(isatty=lambda: False, fileno=lambda: 17)  # arbitrary

# Path: invoke/terminals.py
# def pty_size():
#     """
#     Determine current local pseudoterminal dimensions.
# 
#     :returns:
#         A ``(num_cols, num_rows)`` two-tuple describing PTY size. Defaults to
#         ``(80, 24)`` if unable to get a sensible result dynamically.
# 
#     .. versionadded:: 1.0
#     """
#     cols, rows = _pty_size() if not WINDOWS else _win_pty_size()
#     # TODO: make defaults configurable?
#     return ((cols or 80), (rows or 24))
# 
# def bytes_to_read(input_):
#     """
#     Query stream ``input_`` to see how many bytes may be readable.
# 
#     .. note::
#         If we are unable to tell (e.g. if ``input_`` isn't a true file
#         descriptor or isn't a valid TTY) we fall back to suggesting reading 1
#         byte only.
# 
#     :param input: Input stream object (file-like).
# 
#     :returns: `int` number of bytes to read.
# 
#     .. versionadded:: 1.0
#     """
#     # NOTE: we have to check both possibilities here; situations exist where
#     # it's not a tty but has a fileno, or vice versa; neither is typically
#     # going to work re: ioctl().
#     if not WINDOWS and isatty(input_) and has_fileno(input_):
#         fionread = fcntl.ioctl(input_, termios.FIONREAD, "  ")
#         return struct.unpack("h", fionread)[0]
#     return 1
# 
# WINDOWS = sys.platform == "win32"


# Path: tests/terminals.py
import fcntl
import termios
from mock import Mock, patch
from pytest import skip, mark
from invoke.terminals import pty_size, bytes_to_read, WINDOWS

        @patch("fcntl.ioctl")
        def uses_default_when_stdout_lacks_fileno(self, ioctl, stdout):
            # i.e. when accessing it throws AttributeError
            stdout.fileno.side_effect = AttributeError
            assert pty_size() == (80, 24)

        @patch("sys.stdout")
        @patch("fcntl.ioctl")
        def uses_default_when_stdout_triggers_ioctl_error(self, ioctl, stdout):
            ioctl.side_effect = TypeError
            assert pty_size() == (80, 24)

    class bytes_to_read_:
        @patch("invoke.terminals.fcntl")
        def returns_1_when_stream_lacks_fileno(self, fcntl):
            # A fileno() that exists but returns a non-int is a quick way
            # to fail util.has_fileno().
            assert bytes_to_read(Mock(fileno=lambda: None)) == 1
            assert not fcntl.ioctl.called

        @patch("invoke.terminals.fcntl")
        def returns_1_when_stream_has_fileno_but_is_not_a_tty(self, fcntl):
            # It blows up otherwise anyways (struct.unpack gets mad because
            # result isn't a string of the right length) but let's make
            # ioctl die similarly to the real world case we're testing for
            # here (#425)
            fcntl.ioctl.side_effect = IOError(
                "Operation not supported by device"
            )
            stream = Mock(isatty=lambda: False, fileno=lambda: 17)  # arbitrary

            assert bytes_to_read(stream) == 1