diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -4,9 +4,11 @@ frozen_util, source_util = util.import_importlib('importlib.util') frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') +import os import os.path import sys from test import support +import tempfile import types import unittest import warnings @@ -333,6 +335,52 @@ self.assertEqual(loader.path, init_path) self.assertEqual(ns, expected) + def _add_namespace_portion(self, sub, rootdir, content='eggs = None'): + name, _, modname = sub.rpartition('.') + # Set up the portion dir. + pathentry = '{}-{}'.format(tempfile.mkdtemp(dir=rootdir), modname) + portionpath = os.path.join(rootdir, pathentry, *name.split('.')) + os.makedirs(portionpath) + # Set up the module. + filename = os.path.join(portionpath, '{}.py'.format(modname)) + with open(filename, 'w') as pyfile: + pyfile.write(content) + return pathentry, portionpath + + def test_reload_namespace_additions(self): + name = 'spam' + subnames = ['{}.{}'.format(name, sub) + for sub in ['ham', 'eggs']] + extra = '{}.{}'.format(name, 'cheddar') + with support.temp_cwd(None) as cwd: + with util.uncache(name, *subnames): + pathentries = [] + for sub in subnames: + pe, _ = self._add_namespace_portion(sub, cwd) + pathentries.append(pe) + with support.DirsOnSysPath(*pathentries): + self.init.invalidate_caches() + module = self.init.import_module(name) + before = module.__path__ + for sub in subnames: + self.init.import_module(sub) + with self.assertRaises(ImportError): + self.init.import_module(extra) + + # Add more portions + pe, extrapath = self._add_namespace_portion(extra, cwd) + with support.DirsOnSysPath(pe): + #self.init.invalidate_caches() + reloaded = self.init.reload(module) + after = reloaded.__path__ + for sub in subnames: + self.init.import_module(sub) + self.init.import_module(extra) + diff = set(after) - set(before) + empty = set(before) - set(after) + self.assertEqual(empty, set()) + self.assertEqual(diff, {extrapath}) + def test_reload_submodule(self): # See #19851. name = 'spam'