python: cygpty hack improvements

In case of cygpty we want to fake a tty and at the same time make
Python behave as if it was attached to a console.

This improves two thing in that regard:

* Update the is_cygpty patch to cover more isatty() checks (likely
  they were added since the patch was created)
* Default the stdio encoding to the console output encoding by default.
  This is only in effect if stdout isn't redirected (then is uses the ANSI code page)
  and no real console is used (then it forces utf-8). Python never considers the
  case were isatty() and no console, so we have to add this.

This makes printing unicode work again in MSYS2 bash.
This commit is contained in:
Christoph Reiter
2021-01-06 18:19:22 +01:00
parent 49c9709eab
commit 55bb9c2d1d
3 changed files with 103 additions and 4 deletions

View File

@@ -351,3 +351,67 @@ diff -Naur Python-3.8.0-orig/Python/pylifecycle.c Python-3.8.0/Python/pylifecycl
return 1;
if (!Py_InteractiveFlag)
return 0;
--- Python-3.8.7/Python/bltinmodule.c.orig 2020-12-21 17:25:24.000000000 +0100
+++ Python-3.8.7/Python/bltinmodule.c 2021-01-06 16:50:48.899457200 +0100
@@ -1,6 +1,7 @@
/* Built-in functions */
#include "Python.h"
+#include "iscygpty.h"
#include <ctype.h>
#include "ast.h"
#undef Yield /* undefine macro conflicting with <winbase.h> */
@@ -1980,7 +1981,7 @@
Py_DECREF(tmp);
if (fd < 0 && PyErr_Occurred())
return NULL;
- tty = fd == fileno(stdin) && isatty(fd);
+ tty = fd == fileno(stdin) && (isatty(fd) || is_cygpty(fd));
}
if (tty) {
tmp = _PyObject_CallMethodId(fout, &PyId_fileno, NULL);
@@ -1993,7 +1994,7 @@
Py_DECREF(tmp);
if (fd < 0 && PyErr_Occurred())
return NULL;
- tty = fd == fileno(stdout) && isatty(fd);
+ tty = fd == fileno(stdout) && (isatty(fd) || is_cygpty(fd));
}
}
--- Python-3.8.7/Objects/fileobject.c.orig 2020-12-21 17:25:24.000000000 +0100
+++ Python-3.8.7/Objects/fileobject.c 2021-01-06 16:51:19.605061600 +0100
@@ -2,6 +2,7 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
+#include "iscygpty.h"
#include "pycore_pystate.h"
#if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER)
@@ -434,7 +435,7 @@
}
Py_BEGIN_ALLOW_THREADS
- res = isatty(self->fd);
+ res = isatty(self->fd) || is_cygpty(self->fd);
Py_END_ALLOW_THREADS
return PyBool_FromLong(res);
--- Python-3.8.7/Python/fileutils.c.orig 2020-12-21 17:25:24.000000000 +0100
+++ Python-3.8.7/Python/fileutils.c 2021-01-06 16:50:56.153853200 +0100
@@ -1,4 +1,5 @@
#include "Python.h"
+#include "iscygpty.h"
#include "pycore_fileutils.h"
#include "osdefs.h"
#include <locale.h>
@@ -59,7 +60,7 @@
#endif
int valid;
_Py_BEGIN_SUPPRESS_IPH
- valid = isatty(fd);
+ valid = isatty(fd) || is_cygpty(fd);
_Py_END_SUPPRESS_IPH
if (!valid)
Py_RETURN_NONE;

View File

@@ -0,0 +1,31 @@
--- Python-3.8.7/Python/initconfig.c.orig 2020-12-21 17:25:24.000000000 +0100
+++ Python-3.8.7/Python/initconfig.c 2021-01-06 18:07:12.498508100 +0100
@@ -1,4 +1,5 @@
#include "Python.h"
+#include "iscygpty.h"
#include "osdefs.h" /* DELIM */
#include "pycore_fileutils.h"
#include "pycore_getopt.h"
@@ -1598,6 +1599,22 @@
}
}
+ #ifdef MS_WINDOWS
+ /* In case of is_cygpty() we still want the console encoding.
+ XXX: we ignore GetConsoleCP() here as Python always uses one encoding
+ in init_sys_streams(), and GetConsoleOutputCP() seems more important */
+ if (config->stdio_encoding == NULL) {
+ if ((isatty((int)fileno(stdout)) || is_cygpty((int)fileno(stdout)))) {
+ char encoding[20];
+ PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetConsoleOutputCP());
+ status = PyConfig_SetBytesString(config, &config->stdio_encoding, encoding);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ }
+ #endif
+
/* Choose the default error handler based on the current locale. */
if (config->stdio_encoding == NULL) {
status = config_get_locale_encoding(config, &config->stdio_encoding);

View File

@@ -18,7 +18,7 @@ pkgbase="mingw-w64-${_realname}"
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}")
_pybasever=3.8
pkgver=${_pybasever}.7
pkgrel=1
pkgrel=2
provides=("${MINGW_PACKAGE_PREFIX}-python3=${pkgver}")
conflicts=("${MINGW_PACKAGE_PREFIX}-python3"
"${MINGW_PACKAGE_PREFIX}-python2<2.7.16-7")
@@ -117,6 +117,7 @@ source=("https://www.python.org/ftp/python/${pkgver%rc?}/Python-${pkgver}.tar.xz
1650-expose-sem_unlink.patch
1700-cygpty-isatty.patch
1701-disable-broken-gdbm-module.patch
1702-default-to-console-cp-for-cygpty.patch
1800-link-win-resource-files-and-build-pythonw.patch
1810-3.7-mpdec-mingw.patch
1850-disable-readline.patch
@@ -255,11 +256,13 @@ prepare() {
1650-expose-sem_unlink.patch
# Extend some isatty calls to check for mintty when checking for
# a terminal output.
# a terminal output. And default stdout/in to the console CP for cygpty
# (once we have conpty this can be removed)
# https://github.com/Alexpux/MINGW-packages/issues/2645
# https://github.com/Alexpux/MINGW-packages/issues/2656
apply_patch_with_msg \
1700-cygpty-isatty.patch
1700-cygpty-isatty.patch \
1702-default-to-console-cp-for-cygpty.patch
# gdbm is broken and as a result breaks dbm/shelve.
# Don't include it so the dbm.dumb backend is used instead,
@@ -534,8 +537,9 @@ sha256sums=('ddcc1df16bb5b87aa42ec5d20a5b902f2d088caa269b28e01590f97a798ec50a'
'7e2652a26a8e7198b9b6fd2bfd476c514362f347ba75b1dd014faac443266fd7'
'8ea5b335b10bfb4e492646902db043aee06c953941b3eca7fe24603a3238abf8'
'a9977459a8e6c31f1643da7ede6ac7199dee96559d74188f5c9d3799787ac4fa'
'df598e955ce9886159f857378314b59ac07aaa167bc23ffb656f5f61b7ff1b01'
'7bab1dfb1d5b288e3270a61f9b1892c151f1dd1f8e32c07ae6adc37ef14844bb'
'551047905350e113384f99e0e929e9381dc0a4ed514ca4ebe279dcdad798edce'
'5e1ce61087a5f4acbd45cd7afca45744fa7df44b906eaf155dc519f870203360'
'1da319664d39427156488b9b39ff39e33c53ef608f66319fdf9fb9bcdb29020d'
'fc6164a90f0ca2a9341aaf4448b4334c3393459ca5cbad6d7149f8bcf70da5fe'
'181672743d9e2449064a1b18764fa400af5d3cd268098e7b7e5069d0b128caa2'