diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-07-25 15:45:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-25 15:45:53 (GMT) |
commit | 302bbbe9ba5c72559913e2ea006c921f698a729d (patch) | |
tree | 78ed5a4f6ed2bf2240d519fee8ef96396e4b81bd /Lib | |
parent | 90addd6d1c1fde4ec12a6b554d1deacfac6a879c (diff) | |
download | cpython-302bbbe9ba5c72559913e2ea006c921f698a729d.zip cpython-302bbbe9ba5c72559913e2ea006c921f698a729d.tar.gz cpython-302bbbe9ba5c72559913e2ea006c921f698a729d.tar.bz2 |
bpo-31009: Fix support.fd_count() on Windows (#2862)
* bpo-31009: Fix support.fd_count() on Windows
On Windows, test.support.fd_count() now calls
msvcrt.CrtSetReportMode() to not kill the process nor log any error
on stderr on os.dup(fd) if the file descriptor is invalid.
* Fix for release mode
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/support/__init__.py | 58 | ||||
-rw-r--r-- | Lib/test/test_regrtest.py | 14 |
2 files changed, 43 insertions, 29 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 3a4d27e..7a4671c 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2649,12 +2649,6 @@ def disable_faulthandler(): faulthandler.enable(file=fd, all_threads=True) -try: - MAXFD = os.sysconf("SC_OPEN_MAX") -except Exception: - MAXFD = 256 - - def fd_count(): """Count the number of open file descriptors. """ @@ -2665,16 +2659,48 @@ def fd_count(): except FileNotFoundError: pass - count = 0 - for fd in range(MAXFD): + old_modes = None + if sys.platform == 'win32': + # bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process + # on invalid file descriptor if Python is compiled in debug mode try: - # Prefer dup() over fstat(). fstat() can require input/output - # whereas dup() doesn't. - fd2 = os.dup(fd) - except OSError as e: - if e.errno != errno.EBADF: - raise + import msvcrt + msvcrt.CrtSetReportMode + except (AttributeError, ImportError): + # no msvcrt or a release build + pass else: - os.close(fd2) - count += 1 + old_modes = {} + for report_type in (msvcrt.CRT_WARN, + msvcrt.CRT_ERROR, + msvcrt.CRT_ASSERT): + old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, 0) + + MAXFD = 256 + if hasattr(os, 'sysconf'): + try: + MAXFD = os.sysconf("SC_OPEN_MAX") + except OSError: + pass + + try: + count = 0 + for fd in range(MAXFD): + try: + # Prefer dup() over fstat(). fstat() can require input/output + # whereas dup() doesn't. + fd2 = os.dup(fd) + except OSError as e: + if e.errno != errno.EBADF: + raise + else: + os.close(fd2) + count += 1 + finally: + if old_modes is not None: + for report_type in (msvcrt.CRT_WARN, + msvcrt.CRT_ERROR, + msvcrt.CRT_ASSERT): + msvcrt.CrtSetReportMode(report_type, old_modes[report_type]) + return count diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index f63ed64..b756839 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -835,22 +835,10 @@ class ArgsTestCase(BaseTestCase): import os import unittest - # Issue #25306: Disable popups and logs to stderr on assertion - # failures in MSCRT - try: - import msvcrt - msvcrt.CrtSetReportMode - except (ImportError, AttributeError): - # no Windows, o release build - pass - else: - for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: - msvcrt.CrtSetReportMode(m, 0) - class FDLeakTest(unittest.TestCase): def test_leak(self): fd = os.open(__file__, os.O_RDONLY) - # bug: never cloes the file descriptor + # bug: never close the file descriptor """) self.check_leak(code, 'file descriptors') |