#11732: add a new suppress_crash_popup() context manager to test.support that disables crash popups on Windows and use it in test_ctypes.

This commit is contained in:
Ezio Melotti 2013-03-07 18:44:29 +02:00
parent f9164e13fc
commit 1f38621a33
4 changed files with 41 additions and 6 deletions

View File

@ -365,6 +365,13 @@ The :mod:`test.support` module defines the following functions:
assert s.getvalue() == "hello\n" assert s.getvalue() == "hello\n"
.. function:: suppress_crash_popup()
A context manager that disables Windows Error Reporting dialogs using
`SetErrorMode <http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621%28v=vs.85%29.aspx>`_.
On other platforms it's a no-op.
.. function:: import_module(name, deprecated=False) .. function:: import_module(name, deprecated=False)
This function imports and returns the named module. Unlike a normal This function imports and returns the named module. Unlike a normal

View File

@ -56,7 +56,7 @@ __all__ = [
"reap_children", "cpython_only", "check_impl_detail", "get_attribute", "reap_children", "cpython_only", "check_impl_detail", "get_attribute",
"swap_item", "swap_attr", "requires_IEEE_754", "swap_item", "swap_attr", "requires_IEEE_754",
"TestHandler", "Matcher", "can_symlink", "skip_unless_symlink", "TestHandler", "Matcher", "can_symlink", "skip_unless_symlink",
"import_fresh_module", "failfast", "run_with_tz" "import_fresh_module", "failfast", "run_with_tz", "suppress_crash_popup",
] ]
class Error(Exception): class Error(Exception):
@ -1775,6 +1775,30 @@ def skip_unless_symlink(test):
msg = "Requires functional symlink implementation" msg = "Requires functional symlink implementation"
return test if ok else unittest.skip(msg)(test) return test if ok else unittest.skip(msg)(test)
if sys.platform.startswith('win'):
@contextlib.contextmanager
def suppress_crash_popup():
"""Disable Windows Error Reporting dialogs using SetErrorMode."""
# see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621%28v=vs.85%29.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
k32 = ctypes.windll.kernel32
SEM_NOGPFAULTERRORBOX = 0x02
old_error_mode = k32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
k32.SetErrorMode(old_error_mode | SEM_NOGPFAULTERRORBOX)
try:
yield
finally:
k32.SetErrorMode(old_error_mode)
else:
# this is a no-op for other platforms
@contextlib.contextmanager
def suppress_crash_popup():
yield
def patch(test_instance, object_to_patch, attr_name, new_value): def patch(test_instance, object_to_patch, attr_name, new_value):
"""Override 'object_to_patch'.'attr_name' with 'new_value'. """Override 'object_to_patch'.'attr_name' with 'new_value'.

View File

@ -46,11 +46,12 @@ class CAPITest(unittest.TestCase):
@unittest.skipUnless(threading, 'Threading required for this test.') @unittest.skipUnless(threading, 'Threading required for this test.')
def test_no_FatalError_infinite_loop(self): def test_no_FatalError_infinite_loop(self):
p = subprocess.Popen([sys.executable, "-c", with support.suppress_crash_popup():
'import _testcapi;' p = subprocess.Popen([sys.executable, "-c",
'_testcapi.crash_no_current_thread()'], 'import _testcapi;'
stdout=subprocess.PIPE, '_testcapi.crash_no_current_thread()'],
stderr=subprocess.PIPE) stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(out, err) = p.communicate() (out, err) = p.communicate()
self.assertEqual(out, b'') self.assertEqual(out, b'')
# This used to cause an infinite loop. # This used to cause an infinite loop.

View File

@ -950,6 +950,9 @@ Extension Modules
Tests Tests
----- -----
- Issue #11732: add a new suppress_crash_popup() context manager to test.support
that disables crash popups on Windows and use it in test_ctypes.
- Issue #13898: test_ssl no longer prints a spurious stack trace on Ubuntu. - Issue #13898: test_ssl no longer prints a spurious stack trace on Ubuntu.
- Issue #17249: convert a test in test_capi to use unittest and reap threads. - Issue #17249: convert a test in test_capi to use unittest and reap threads.