mirror of https://github.com/python/cpython
gh-85283: Build _testconsole extension with limited C API (#117125)
This commit is contained in:
parent
8bea6c411d
commit
abdd1f938f
|
@ -1527,7 +1527,7 @@ Build Changes
|
|||
* The ``errno``, ``fcntl``, ``grp``, ``md5``, ``pwd``, ``resource``,
|
||||
``termios``, ``winsound``,
|
||||
``_ctypes_test``, ``_multiprocessing.posixshmem``, ``_scproxy``, ``_stat``,
|
||||
``_statistics``, ``_testimportmultiple`` and ``_uuid``
|
||||
``_statistics``, ``_testconsole``, ``_testimportmultiple`` and ``_uuid``
|
||||
C extensions are now built with the
|
||||
:ref:`limited C API <limited-c-api>`.
|
||||
(Contributed by Victor Stinner in :gh:`85283`.)
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
The ``fcntl``, ``grp``, ``pwd``, ``termios`` and ``_statistics`` C extensions are now
|
||||
built with the :ref:`limited C API <limited-c-api>`. Patch by Victor Stinner.
|
||||
The ``fcntl``, ``grp``, ``pwd``, ``termios``, ``_statistics`` and
|
||||
``_testconsole`` C extensions are now built with the :ref:`limited C API
|
||||
<limited-c-api>`. Patch by Victor Stinner.
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
/* Testing module for multi-phase initialization of extension modules (PEP 489)
|
||||
*/
|
||||
|
||||
#ifndef Py_BUILD_CORE_BUILTIN
|
||||
# define Py_BUILD_CORE_MODULE 1
|
||||
// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
|
||||
#include "pyconfig.h" // Py_GIL_DISABLED
|
||||
#ifndef Py_GIL_DISABLED
|
||||
# define Py_LIMITED_API 0x030c0000
|
||||
#endif
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
||||
#include "pycore_fileutils.h" // _Py_get_osfhandle()
|
||||
#include "pycore_runtime.h" // _Py_ID()
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -57,20 +56,24 @@ module _testconsole
|
|||
|
||||
_testconsole.write_input
|
||||
file: object
|
||||
s: PyBytesObject
|
||||
s: Py_buffer
|
||||
|
||||
Writes UTF-16-LE encoded bytes to the console as if typed by a user.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_testconsole_write_input_impl(PyObject *module, PyObject *file,
|
||||
PyBytesObject *s)
|
||||
/*[clinic end generated code: output=48f9563db34aedb3 input=4c774f2d05770bc6]*/
|
||||
_testconsole_write_input_impl(PyObject *module, PyObject *file, Py_buffer *s)
|
||||
/*[clinic end generated code: output=58631a8985426ad3 input=68062f1bb2e52206]*/
|
||||
{
|
||||
INPUT_RECORD *rec = NULL;
|
||||
|
||||
PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr(
|
||||
&_Py_ID(_io), &_Py_ID(_WindowsConsoleIO));
|
||||
PyObject *mod = PyImport_ImportModule("_io");
|
||||
if (mod == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyTypeObject *winconsoleio_type = (PyTypeObject *)PyObject_GetAttrString(mod, "_WindowsConsoleIO");
|
||||
Py_DECREF(mod);
|
||||
if (winconsoleio_type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -81,8 +84,8 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const wchar_t *p = (const wchar_t *)PyBytes_AS_STRING(s);
|
||||
DWORD size = (DWORD)PyBytes_GET_SIZE(s) / sizeof(wchar_t);
|
||||
const wchar_t *p = (const wchar_t *)s->buf;
|
||||
DWORD size = (DWORD)s->len / sizeof(wchar_t);
|
||||
|
||||
rec = (INPUT_RECORD*)PyMem_Calloc(size, sizeof(INPUT_RECORD));
|
||||
if (!rec)
|
||||
|
@ -96,9 +99,11 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file,
|
|||
prec->Event.KeyEvent.uChar.UnicodeChar = *p;
|
||||
}
|
||||
|
||||
HANDLE hInput = _Py_get_osfhandle(((winconsoleio*)file)->fd);
|
||||
if (hInput == INVALID_HANDLE_VALUE)
|
||||
HANDLE hInput = (HANDLE)_get_osfhandle(((winconsoleio*)file)->fd);
|
||||
if (hInput == INVALID_HANDLE_VALUE) {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
goto error;
|
||||
}
|
||||
|
||||
DWORD total = 0;
|
||||
while (total < size) {
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
# include "pycore_gc.h" // PyGC_Head
|
||||
# include "pycore_runtime.h" // _Py_ID()
|
||||
#endif
|
||||
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
|
||||
PyDoc_STRVAR(_testconsole_write_input__doc__,
|
||||
|
@ -17,58 +11,30 @@ PyDoc_STRVAR(_testconsole_write_input__doc__,
|
|||
"Writes UTF-16-LE encoded bytes to the console as if typed by a user.");
|
||||
|
||||
#define _TESTCONSOLE_WRITE_INPUT_METHODDEF \
|
||||
{"write_input", _PyCFunction_CAST(_testconsole_write_input), METH_FASTCALL|METH_KEYWORDS, _testconsole_write_input__doc__},
|
||||
{"write_input", (PyCFunction)(void(*)(void))_testconsole_write_input, METH_VARARGS|METH_KEYWORDS, _testconsole_write_input__doc__},
|
||||
|
||||
static PyObject *
|
||||
_testconsole_write_input_impl(PyObject *module, PyObject *file,
|
||||
PyBytesObject *s);
|
||||
_testconsole_write_input_impl(PyObject *module, PyObject *file, Py_buffer *s);
|
||||
|
||||
static PyObject *
|
||||
_testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_testconsole_write_input(PyObject *module, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 2
|
||||
static struct {
|
||||
PyGC_Head _this_is_not_used;
|
||||
PyObject_VAR_HEAD
|
||||
PyObject *ob_item[NUM_KEYWORDS];
|
||||
} _kwtuple = {
|
||||
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
|
||||
.ob_item = { &_Py_ID(file), &_Py_ID(s), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"file", "s", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "write_input",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[2];
|
||||
static char *_keywords[] = {"file", "s", NULL};
|
||||
PyObject *file;
|
||||
PyBytesObject *s;
|
||||
Py_buffer s = {NULL, NULL};
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
|
||||
if (!args) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oy*:write_input", _keywords,
|
||||
&file, &s))
|
||||
goto exit;
|
||||
}
|
||||
file = args[0];
|
||||
if (!PyBytes_Check(args[1])) {
|
||||
_PyArg_BadArgument("write_input", "argument 's'", "bytes", args[1]);
|
||||
goto exit;
|
||||
}
|
||||
s = (PyBytesObject *)args[1];
|
||||
return_value = _testconsole_write_input_impl(module, file, s);
|
||||
return_value = _testconsole_write_input_impl(module, file, &s);
|
||||
|
||||
exit:
|
||||
/* Cleanup for s */
|
||||
if (s.obj) {
|
||||
PyBuffer_Release(&s);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
@ -83,48 +49,21 @@ PyDoc_STRVAR(_testconsole_read_output__doc__,
|
|||
"Reads a str from the console as written to stdout.");
|
||||
|
||||
#define _TESTCONSOLE_READ_OUTPUT_METHODDEF \
|
||||
{"read_output", _PyCFunction_CAST(_testconsole_read_output), METH_FASTCALL|METH_KEYWORDS, _testconsole_read_output__doc__},
|
||||
{"read_output", (PyCFunction)(void(*)(void))_testconsole_read_output, METH_VARARGS|METH_KEYWORDS, _testconsole_read_output__doc__},
|
||||
|
||||
static PyObject *
|
||||
_testconsole_read_output_impl(PyObject *module, PyObject *file);
|
||||
|
||||
static PyObject *
|
||||
_testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
_testconsole_read_output(PyObject *module, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
static struct {
|
||||
PyGC_Head _this_is_not_used;
|
||||
PyObject_VAR_HEAD
|
||||
PyObject *ob_item[NUM_KEYWORDS];
|
||||
} _kwtuple = {
|
||||
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
|
||||
.ob_item = { &_Py_ID(file), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"file", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "read_output",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
static char *_keywords[] = {"file", NULL};
|
||||
PyObject *file;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!args) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:read_output", _keywords,
|
||||
&file))
|
||||
goto exit;
|
||||
}
|
||||
file = args[0];
|
||||
return_value = _testconsole_read_output_impl(module, file);
|
||||
|
||||
exit:
|
||||
|
@ -140,4 +79,4 @@ exit:
|
|||
#ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF
|
||||
#define _TESTCONSOLE_READ_OUTPUT_METHODDEF
|
||||
#endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */
|
||||
/*[clinic end generated code: output=08a1c844b3657272 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=d60ce07157e3741a input=a9049054013a1b77]*/
|
||||
|
|
Loading…
Reference in New Issue