bpo-33773: Fix test.support.fd_count() on Linux/FreBSD (GH-7421)

Substract one because listdir() opens internally a file
descriptor to list the content of the /proc/self/fd/ directory.

Add test_support.test_fd_count().

Move also MAXFD code before msvcrt.CrtSetReportMode(), to make sure
that the report mode is always restored on failure.
This commit is contained in:
Victor Stinner 2018-06-06 17:23:50 +02:00 committed by GitHub
parent 45e4efba7f
commit 492d6424a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 8 deletions

View File

@ -2768,10 +2768,19 @@ def fd_count():
if sys.platform.startswith(('linux', 'freebsd')): if sys.platform.startswith(('linux', 'freebsd')):
try: try:
names = os.listdir("/proc/self/fd") names = os.listdir("/proc/self/fd")
return len(names) # Substract one because listdir() opens internally a file
# descriptor to list the content of the /proc/self/fd/ directory.
return len(names) - 1
except FileNotFoundError: except FileNotFoundError:
pass pass
MAXFD = 256
if hasattr(os, 'sysconf'):
try:
MAXFD = os.sysconf("SC_OPEN_MAX")
except OSError:
pass
old_modes = None old_modes = None
if sys.platform == 'win32': if sys.platform == 'win32':
# bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process # bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process
@ -2789,13 +2798,6 @@ def fd_count():
msvcrt.CRT_ASSERT): msvcrt.CRT_ASSERT):
old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, 0) 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: try:
count = 0 count = 0
for fd in range(MAXFD): for fd in range(MAXFD):

View File

@ -569,6 +569,17 @@ class TestSupport(unittest.TestCase):
self.assertTrue(support.match_test(test_access)) self.assertTrue(support.match_test(test_access))
self.assertFalse(support.match_test(test_chdir)) self.assertFalse(support.match_test(test_chdir))
def test_fd_count(self):
# We cannot test the absolute value of fd_count(): on old Linux
# kernel or glibc versions, os.urandom() keeps a FD open on
# /dev/urandom device and Python has 4 FD opens instead of 3.
start = support.fd_count()
fd = os.open(__file__, os.O_RDONLY)
try:
more = support.fd_count()
finally:
os.close(fd)
self.assertEqual(more - start, 1)
# XXX -follows a list of untested API # XXX -follows a list of untested API
# make_legacy_pyc # make_legacy_pyc