Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1863,8 +1863,34 @@ def __enter__(self):
soft limit to 0.
"""
if sys.platform.startswith('win'):
# TODO: backport the Windows implementation
pass
# see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx
# GetErrorMode is not available on Windows XP and Windows Server 2003,
# but SetErrorMode returns the previous value, so we can use that
import ctypes
self._k32 = ctypes.windll.kernel32
SEM_NOGPFAULTERRORBOX = 0x02
self.old_value = self._k32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
self._k32.SetErrorMode(self.old_value | SEM_NOGPFAULTERRORBOX)

# Suppress assert dialogs in debug builds
# (see http://bugs.python.org/issue23314)
try:
import _testcapi
_testcapi.CrtSetReportMode
except (AttributeError, ImportError):
# no _testcapi or a release build
pass
else:
self.old_modes = {}
for report_type in [_testcapi.CRT_WARN,
_testcapi.CRT_ERROR,
_testcapi.CRT_ASSERT]:
old_mode = _testcapi.CrtSetReportMode(report_type,
_testcapi.CRTDBG_MODE_FILE)
old_file = _testcapi.CrtSetReportFile(report_type,
_testcapi.CRTDBG_FILE_STDERR)
self.old_modes[report_type] = old_mode, old_file

else:
try:
import resource
Expand Down Expand Up @@ -1906,16 +1932,16 @@ def __exit__(self, *ignore_exc):
return

if sys.platform.startswith('win'):
# TODO: backport the Windows implementation
pass
self._k32.SetErrorMode(self.old_value)

if self.old_modes:
import _testcapi
for report_type, (old_mode, old_file) in self.old_modes.items():
_testcapi.CrtSetReportMode(report_type, old_mode)
_testcapi.CrtSetReportFile(report_type, old_file)
else:
import resource
try:
import resource
except ImportError:
resource = None

if resource is not None:
try:
resource.setrlimit(resource.RLIMIT_CORE, self.old_value)
except (ValueError, OSError):
pass
resource.setrlimit(resource.RLIMIT_CORE, self.old_value)
except (ValueError, OSError):
pass
51 changes: 51 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "datetime.h"
#include "marshal.h"
#include <signal.h>
#ifdef MS_WINDOWS
# include <crtdbg.h>
#endif

#ifdef WITH_THREAD
#include "pythread.h"
Expand Down Expand Up @@ -2501,6 +2504,42 @@ test_raise_signal(PyObject* self, PyObject *args)
}


#ifdef MS_WINDOWS
static PyObject*
msvcrt_CrtSetReportMode(PyObject* self, PyObject *args)
{
int type, mode;
int res;

if (!PyArg_ParseTuple(args, "ii:CrtSetReportMode", &type, &mode)) {
return NULL;
}

res = _CrtSetReportMode(type, mode);
if (res == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return PyInt_FromLong(res);
}

static PyObject*
msvcrt_CrtSetReportFile(PyObject* self, PyObject *args)
{
int type, file;
long res;

if (!PyArg_ParseTuple(args, "ii:CrtSetReportFile", &type, &file)) {
return NULL;
}

res = (long)_CrtSetReportFile(type, (_HFILE)file);

return PyInt_FromLong(res);
}
#endif


static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"set_errno", set_errno, METH_VARARGS},
Expand Down Expand Up @@ -2613,6 +2652,10 @@ static PyMethodDef TestMethods[] = {
{"pymarshal_read_object_from_file",
pymarshal_read_object_from_file, METH_VARARGS},
{"raise_signal", (PyCFunction)test_raise_signal, METH_VARARGS},
#ifdef MS_WINDOWS
{"CrtSetReportMode", (PyCFunction)msvcrt_CrtSetReportMode, METH_VARARGS},
{"CrtSetReportFile", (PyCFunction)msvcrt_CrtSetReportFile, METH_VARARGS},
#endif
{NULL, NULL} /* sentinel */
};

Expand Down Expand Up @@ -2809,6 +2852,14 @@ init_testcapi(void)
PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
PyModule_AddObject(m, "SIZEOF_PYGC_HEAD", PyInt_FromSsize_t(sizeof(PyGC_Head)));

#ifdef MS_WINDOWS
PyModule_AddIntConstant(m, "CRT_WARN", _CRT_WARN);
PyModule_AddIntConstant(m, "CRT_ERROR", _CRT_ERROR);
PyModule_AddIntConstant(m, "CRT_ASSERT", _CRT_ASSERT);
PyModule_AddIntConstant(m, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE);
PyModule_AddIntConstant(m, "CRTDBG_FILE_STDERR", (int)_CRTDBG_FILE_STDERR);
#endif

TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
Py_INCREF(TestError);
PyModule_AddObject(m, "error", TestError);
Expand Down