bpo-37421: Fix test_distutils.test_build_ext() (GH-14564)

test_distutils.test_build_ext() is now able to remove the temporary
directory on Windows: don't import the newly built C extension ("xx")
in the current process, but test it in a separated process.
This commit is contained in:
Victor Stinner 2019-07-03 11:12:27 +02:00 committed by GitHub
parent 684cb47fff
commit 74c9dd5777
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 23 deletions

View File

@ -6,6 +6,7 @@ import tempfile
import unittest import unittest
import sysconfig import sysconfig
from copy import deepcopy from copy import deepcopy
import test.support
from distutils import log from distutils import log
from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL
@ -64,8 +65,8 @@ class TempdirManager(object):
os.chdir(self.old_cwd) os.chdir(self.old_cwd)
super().tearDown() super().tearDown()
while self.tempdirs: while self.tempdirs:
d = self.tempdirs.pop() tmpdir = self.tempdirs.pop()
shutil.rmtree(d, os.name in ('nt', 'cygwin')) test.support.rmtree(tmpdir)
def mkdtemp(self): def mkdtemp(self):
"""Create a temporary directory that will be cleaned up. """Create a temporary directory that will be cleaned up.

View File

@ -15,6 +15,7 @@ from distutils.errors import (
import unittest import unittest
from test import support from test import support
from test.support.script_helper import assert_python_ok
# http://bugs.python.org/issue4373 # http://bugs.python.org/issue4373
# Don't load the xx module more than once. # Don't load the xx module more than once.
@ -26,11 +27,8 @@ class BuildExtTestCase(TempdirManager,
unittest.TestCase): unittest.TestCase):
def setUp(self): def setUp(self):
# Create a simple test environment # Create a simple test environment
# Note that we're making changes to sys.path
super(BuildExtTestCase, self).setUp() super(BuildExtTestCase, self).setUp()
self.tmp_dir = self.mkdtemp() self.tmp_dir = self.mkdtemp()
self.sys_path = sys.path, sys.path[:]
sys.path.append(self.tmp_dir)
import site import site
self.old_user_base = site.USER_BASE self.old_user_base = site.USER_BASE
site.USER_BASE = self.mkdtemp() site.USER_BASE = self.mkdtemp()
@ -40,15 +38,11 @@ class BuildExtTestCase(TempdirManager,
# bpo-30132: On Windows, a .pdb file may be created in the current # bpo-30132: On Windows, a .pdb file may be created in the current
# working directory. Create a temporary working directory to cleanup # working directory. Create a temporary working directory to cleanup
# everything at the end of the test. # everything at the end of the test.
self.temp_cwd = support.temp_cwd() change_cwd = support.change_cwd(self.tmp_dir)
self.temp_cwd.__enter__() change_cwd.__enter__()
self.addCleanup(self.temp_cwd.__exit__, None, None, None) self.addCleanup(change_cwd.__exit__, None, None, None)
def tearDown(self): def tearDown(self):
# Get everything back to normal
support.unload('xx')
sys.path = self.sys_path[0]
sys.path[:] = self.sys_path[1]
import site import site
site.USER_BASE = self.old_user_base site.USER_BASE = self.old_user_base
from distutils.command import build_ext from distutils.command import build_ext
@ -88,19 +82,34 @@ class BuildExtTestCase(TempdirManager,
else: else:
ALREADY_TESTED = type(self).__name__ ALREADY_TESTED = type(self).__name__
import xx code = textwrap.dedent(f"""
tmp_dir = {self.tmp_dir!r}
for attr in ('error', 'foo', 'new', 'roj'): import sys
self.assertTrue(hasattr(xx, attr)) import unittest
from test import support
self.assertEqual(xx.foo(2, 5), 7) sys.path.insert(0, tmp_dir)
self.assertEqual(xx.foo(13,15), 28) import xx
self.assertEqual(xx.new().demo(), None)
if support.HAVE_DOCSTRINGS: class Tests(unittest.TestCase):
doc = 'This is a template module just for instruction.' def test_xx(self):
self.assertEqual(xx.__doc__, doc) for attr in ('error', 'foo', 'new', 'roj'):
self.assertIsInstance(xx.Null(), xx.Null) self.assertTrue(hasattr(xx, attr))
self.assertIsInstance(xx.Str(), xx.Str)
self.assertEqual(xx.foo(2, 5), 7)
self.assertEqual(xx.foo(13,15), 28)
self.assertEqual(xx.new().demo(), None)
if support.HAVE_DOCSTRINGS:
doc = 'This is a template module just for instruction.'
self.assertEqual(xx.__doc__, doc)
self.assertIsInstance(xx.Null(), xx.Null)
self.assertIsInstance(xx.Str(), xx.Str)
unittest.main()
""")
assert_python_ok('-c', code)
def test_solaris_enable_shared(self): def test_solaris_enable_shared(self):
dist = Distribution({'name': 'xx'}) dist = Distribution({'name': 'xx'})

View File

@ -0,0 +1,3 @@
test_distutils.test_build_ext() is now able to remove the temporary
directory on Windows: don't import the newly built C extension ("xx") in the
current process, but test it in a separated process.