Author: Armin Rigo <[email protected]>
Branch: py3k
Changeset: r86527:80a83063cd45
Date: 2016-08-25 09:34 +0200
http://bitbucket.org/pypy/pypy/changeset/80a83063cd45/
Log: Merged in marky1991/pypy_new/py3k_add_terminal_size (pull request
#475)
Add os.get_terminal_size (py3k)
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -19,6 +19,7 @@
'statvfs_result': 'app_posix.statvfs_result',
'uname_result': 'app_posix.uname_result',
'urandom': 'app_posix.urandom',
+ 'terminal_size': 'app_posix.terminal_size'
}
if os.name == 'nt':
del appleveldefs['urandom'] # at interp on win32
@@ -74,6 +75,7 @@
'abort': 'interp_posix.abort',
'urandom': 'interp_posix.urandom',
'device_encoding': 'interp_posix.device_encoding',
+ 'get_terminal_size': 'interp_posix.get_terminal_size'
}
if hasattr(os, 'chown'):
diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py
--- a/pypy/module/posix/app_posix.py
+++ b/pypy/module/posix/app_posix.py
@@ -92,6 +92,12 @@
version = structseqfield(3, "operating system version")
machine = structseqfield(4, "hardware identifier")
+class terminal_size(metaclass=structseqtype):
+
+ name = "os.terminal_size"
+
+ columns = structseqfield(0, "width of the terminal window in characters")
+ lines = structseqfield(1, "height of the terminal window in characters")
if osname == 'posix':
# POSIX: we want to check the file descriptor when fdopen() is called,
diff --git a/pypy/module/posix/interp_posix.py
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -8,16 +8,18 @@
# some Pythons don't have errno.ENOTSUP
ENOTSUP = 0
-from rpython.rlib import rposix, rposix_stat
+from rpython.rlib import rposix, rposix_stat, rfile
from rpython.rlib import objectmodel, rurandom
from rpython.rlib.objectmodel import specialize
-from rpython.rlib.rarithmetic import r_longlong, intmask, r_uint
+from rpython.rlib.rarithmetic import r_longlong, intmask, r_uint, r_int
from rpython.rlib.unroll import unrolling_iterable
+from rpython.rtyper.lltypesystem import lltype
from rpython.tool.sourcetools import func_with_new_name
from pypy.interpreter.gateway import unwrap_spec, WrappedDefault, Unwrapper
from pypy.interpreter.error import (
- OperationError, oefmt, wrap_oserror, wrap_oserror2, strerror as _strerror)
+ OperationError, oefmt, wrap_oserror, wrap_oserror2, strerror as _strerror,
+ exception_from_saved_errno)
from pypy.interpreter.executioncontext import ExecutionContext
@@ -2142,3 +2144,50 @@
have_functions.append("HAVE_%s" % name)
if _WIN32:
have_functions.append("HAVE_MS_WINDOWS")
+
+def get_terminal_size(space, w_fd=None):
+ if w_fd is None:
+ fd = rfile.RFile(rfile.c_stdout(), close2=(None, None)).fileno()
+ else:
+ if not space.isinstance_w(w_fd, space.w_int):
+ raise oefmt(space.w_TypeError,
+ "an integer is required, got %T", w_fd)
+ else:
+ fd = space.c_int_w(w_fd)
+
+ if _WIN32:
+ if fd == 0:
+ handle_id = rwin32.STD_INPUT_HANDLE
+ elif fd == 1:
+ handle_id = rwin32.STD_OUTPUT_HANDLE
+ elif fd == 2:
+ handle_id = rwin32.STD_ERROR_HANDLE
+ else:
+ raise oefmt(space.w_ValueError, "bad file descriptor")
+
+ handle = rwin32.GetStdHandle(handle_id)
+
+ if handle == rwin32.NULL_HANDLE:
+ raise oefmt(space.w_OSError, "handle cannot be retrieved")
+ elif handle == rwin32.INVALID_HANDLE_VALUE:
+ raise rwin32.lastSavedWindowsError()
+ with lltype.scoped_alloc(rwin32.CONSOLE_SCREEN_BUFFER_INFO) as
buffer_info:
+ success = rwin32.GetConsoleScreenBufferInfo(handle, buffer_info)
+ if not success:
+ raise rwin32.lastSavedWindowsError()
+ w_columns = space.wrap(r_int(buffer_info.c_srWindow.c_Right) -
r_int(buffer_info.c_srWindow.c_Left) + 1)
+ w_lines = space.wrap(r_int(buffer_info.c_srWindow.c_Bottom) -
r_int(buffer_info.c_srWindow.c_Top) + 1)
+ else:
+ with lltype.scoped_alloc(rposix.WINSIZE) as winsize:
+ failed = rposix.c_ioctl_voidp(fd, rposix.TIOCGWINSZ, winsize)
+ if failed:
+ raise exception_from_saved_errno(space, space.w_OSError)
+
+ w_columns = space.wrap(r_uint(winsize.c_ws_col))
+ w_lines = space.wrap(r_uint(winsize.c_ws_row))
+
+ w_tuple = space.newtuple([w_columns, w_lines])
+ w_terminal_size = space.getattr(space.getbuiltinmodule(os.name),
+ space.wrap('terminal_size'))
+
+ return space.call_function(w_terminal_size, w_tuple)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -258,6 +258,7 @@
if not _WIN32:
UID_T = rffi_platform.SimpleType('uid_t', rffi.UINT)
GID_T = rffi_platform.SimpleType('gid_t', rffi.UINT)
+ TIOCGWINSZ = rffi_platform.DefinedConstantInteger('TIOCGWINSZ')
TMS = rffi_platform.Struct(
'struct tms', [('tms_utime', rffi.INT),
@@ -265,6 +266,12 @@
('tms_cutime', rffi.INT),
('tms_cstime', rffi.INT)])
+ WINSIZE = rffi_platform.Struct(
+ 'struct winsize', [('ws_row', rffi.USHORT),
+ ('ws_col', rffi.USHORT),
+ ('ws_xpixel', rffi.USHORT),
+ ('ws_ypixel', rffi.USHORT)])
+
GETPGRP_HAVE_ARG = rffi_platform.Has("getpgrp(0)")
SETPGRP_HAVE_ARG = rffi_platform.Has("setpgrp(0, 0)")
@@ -628,6 +635,8 @@
macro=True, save_err=rffi.RFFI_FULL_ERRNO_ZERO)
c_closedir = external('closedir', [DIRP], rffi.INT, releasegil=False)
c_dirfd = external('dirfd', [DIRP], rffi.INT, releasegil=False)
+ c_ioctl_voidp = external('ioctl', [rffi.INT, rffi.UINT, rffi.VOIDP],
rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
else:
dirent_config = {}
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -59,6 +59,24 @@
SYSTEMTIME = rffi_platform.Struct('SYSTEMTIME',
[])
+ Struct = rffi_platform.Struct
+ COORD = Struct("COORD",
+ [("X", rffi.SHORT),
+ ("Y", rffi.SHORT)])
+
+ SMALL_RECT = Struct("SMALL_RECT",
+ [("Left", rffi.SHORT),
+ ("Top", rffi.SHORT),
+ ("Right", rffi.SHORT),
+ ("Bottom", rffi.SHORT)])
+
+ CONSOLE_SCREEN_BUFFER_INFO = Struct("CONSOLE_SCREEN_BUFFER_INFO",
+ [("dwSize", COORD),
+ ("dwCursorPosition", COORD),
+ ("wAttributes", WORD.ctype_hint),
+ ("srWindow", SMALL_RECT),
+ ("dwMaximumWindowSize", COORD)])
+
OSVERSIONINFOEX = rffi_platform.Struct(
'OSVERSIONINFOEX',
[('dwOSVersionInfoSize', rffi.UINT),
@@ -93,7 +111,8 @@
PROCESS_VM_WRITE
CTRL_C_EVENT CTRL_BREAK_EVENT
MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION
- WC_NO_BEST_FIT_CHARS
+ WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE
+ STD_ERROR_HANDLE
"""
from rpython.translator.platform import host_factory
static_platform = host_factory()
@@ -444,3 +463,13 @@
return rffi.cast(lltype.Signed, _GetConsoleOutputCP())
_wenviron_items, _wgetenv, _wputenv = make_env_impls(win32=True)
+
+
+ _GetStdHandle = winexternal(
+ 'GetStdHandle', [DWORD], HANDLE)
+
+ def GetStdHandle(handle_id):
+ return _GetStdHandle(handle_id)
+ CONSOLE_SCREEN_BUFFER_INFO_P = lltype.Ptr(CONSOLE_SCREEN_BUFFER_INFO)
+ GetConsoleScreenBufferInfo = winexternal(
+ "GetConsoleScreenBufferInfo", [HANDLE, CONSOLE_SCREEN_BUFFER_INFO_P],
BOOL)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit