summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-07-25 15:45:53 (GMT)
committerGitHub <noreply@github.com>2017-07-25 15:45:53 (GMT)
commit302bbbe9ba5c72559913e2ea006c921f698a729d (patch)
tree78ed5a4f6ed2bf2240d519fee8ef96396e4b81bd /Lib
parent90addd6d1c1fde4ec12a6b554d1deacfac6a879c (diff)
downloadcpython-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__.py58
-rw-r--r--Lib/test/test_regrtest.py14
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')