Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Lib/test/test_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,34 @@ def test_import_from_unloaded_package(self):
import package2.submodule1
package2.submodule1.submodule2

def test_rebinding(self):
# The same data is also used for testing pkgutil.resolve_name()
# in test_pkgutil and mock.patch in test_unittest.
path = os.path.join(os.path.dirname(__file__), 'data')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
from package3 import submodule
self.assertEqual(submodule.attr, 'rebound')
import package3.submodule as submodule
self.assertEqual(submodule.attr, 'rebound')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
import package3.submodule as submodule
self.assertEqual(submodule.attr, 'rebound')
from package3 import submodule
self.assertEqual(submodule.attr, 'rebound')

def test_rebinding2(self):
path = os.path.join(os.path.dirname(__file__), 'data')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
import package4.submodule as submodule
self.assertEqual(submodule.attr, 'submodule')
from package4 import submodule
self.assertEqual(submodule.attr, 'submodule')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
from package4 import submodule
self.assertEqual(submodule.attr, 'origin')
import package4.submodule as submodule
self.assertEqual(submodule.attr, 'submodule')


class OverridingImportBuiltinTests(unittest.TestCase):
def test_override_builtin(self):
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_import/data/package3/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""Rebinding the package attribute after importing the module."""
from .submodule import submodule
7 changes: 7 additions & 0 deletions Lib/test/test_import/data/package3/submodule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
attr = 'submodule'
class A:
attr = 'submodule'
class submodule:
attr = 'rebound'
class B:
attr = 'rebound'
5 changes: 5 additions & 0 deletions Lib/test/test_import/data/package4/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Binding the package attribute without importing the module."""
class submodule:
attr = 'origin'
class B:
attr = 'origin'
3 changes: 3 additions & 0 deletions Lib/test/test_import/data/package4/submodule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
attr = 'submodule'
class A:
attr = 'submodule'
35 changes: 35 additions & 0 deletions Lib/test/test_pkgutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import shutil
import zipfile

from test.support.import_helper import DirsOnSysPath
from test.test_importlib.util import uncache

# Note: pkgutil.walk_packages is currently tested in test_runpy. This is
# a hack to get a major issue resolved for 3.3b2. Longer term, it should
# be moved back here, perhaps by factoring out the helper code for
Expand Down Expand Up @@ -318,6 +321,38 @@ def test_name_resolution(self):
with self.assertRaises(exc):
pkgutil.resolve_name(s)

def test_name_resolution_import_rebinding(self):
# The same data is also used for testing import in test_import and
# mock.patch in test_unittest.
path = os.path.join(os.path.dirname(__file__), 'test_import', 'data')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package3.submodule.attr'), 'submodule')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package3.submodule:attr'), 'submodule')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package3:submodule.attr'), 'rebound')
self.assertEqual(pkgutil.resolve_name('package3.submodule.attr'), 'submodule')
self.assertEqual(pkgutil.resolve_name('package3:submodule.attr'), 'rebound')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package3:submodule.attr'), 'rebound')
self.assertEqual(pkgutil.resolve_name('package3.submodule:attr'), 'submodule')
self.assertEqual(pkgutil.resolve_name('package3:submodule.attr'), 'rebound')

def test_name_resolution_import_rebinding2(self):
path = os.path.join(os.path.dirname(__file__), 'test_import', 'data')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package4.submodule.attr'), 'submodule')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package4.submodule:attr'), 'submodule')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package4:submodule.attr'), 'origin')
self.assertEqual(pkgutil.resolve_name('package4.submodule.attr'), 'submodule')
self.assertEqual(pkgutil.resolve_name('package4:submodule.attr'), 'submodule')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
self.assertEqual(pkgutil.resolve_name('package4:submodule.attr'), 'origin')
self.assertEqual(pkgutil.resolve_name('package4.submodule:attr'), 'submodule')
self.assertEqual(pkgutil.resolve_name('package4:submodule.attr'), 'submodule')


class PkgutilPEP302Tests(unittest.TestCase):

Expand Down
67 changes: 67 additions & 0 deletions Lib/test/test_unittest/testmock/testpatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
from collections import OrderedDict

import unittest
import test
from test.test_unittest.testmock import support
from test.test_unittest.testmock.support import SomeClass, is_instance

from test.support.import_helper import DirsOnSysPath
from test.test_importlib.util import uncache
from unittest.mock import (
NonCallableMock, CallableMixin, sentinel,
Expand Down Expand Up @@ -1728,6 +1730,71 @@ def test(mock):
'exception traceback not propagated')


def test_name_resolution_import_rebinding(self):
# Currently mock.patch uses pkgutil.resolve_name(), but repeat
# similar tests just for the case.
# The same data is also used for testing import in test_import and
# pkgutil.resolve_name() in test_pkgutil.
path = os.path.join(os.path.dirname(test.__file__), 'test_import', 'data')
def check(name):
p = patch(name)
p.start()
p.stop()
def check_error(name):
p = patch(name)
self.assertRaises(AttributeError, p.start)
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
check('package3.submodule.A.attr')
check_error('package3.submodule.B.attr')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
check('package3.submodule:A.attr')
check_error('package3.submodule:B.attr')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
check('package3:submodule.B.attr')
check_error('package3:submodule.A.attr')
check('package3.submodule.A.attr')
check_error('package3.submodule.B.attr')
check('package3:submodule.B.attr')
check_error('package3:submodule.A.attr')
with uncache('package3', 'package3.submodule'), DirsOnSysPath(path):
check('package3:submodule.B.attr')
check_error('package3:submodule.A.attr')
check('package3.submodule:A.attr')
check_error('package3.submodule:B.attr')
check('package3:submodule.B.attr')
check_error('package3:submodule.A.attr')

def test_name_resolution_import_rebinding2(self):
path = os.path.join(os.path.dirname(test.__file__), 'test_import', 'data')
def check(name):
p = patch(name)
p.start()
p.stop()
def check_error(name):
p = patch(name)
self.assertRaises(AttributeError, p.start)
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
check('package4.submodule.A.attr')
check_error('package4.submodule.B.attr')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
check('package4.submodule:A.attr')
check_error('package4.submodule:B.attr')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
check('package4:submodule.B.attr')
check_error('package4:submodule.A.attr')
check('package4.submodule.A.attr')
check_error('package4.submodule.B.attr')
check('package4:submodule.A.attr')
check_error('package4:submodule.B.attr')
with uncache('package4', 'package4.submodule'), DirsOnSysPath(path):
check('package4:submodule.B.attr')
check_error('package4:submodule.A.attr')
check('package4.submodule:A.attr')
check_error('package4.submodule:B.attr')
check('package4:submodule.A.attr')
check_error('package4:submodule.B.attr')


def test_create_and_specs(self):
for kwarg in ('spec', 'spec_set', 'autospec'):
p = patch('%s.doesnotexist' % __name__, create=True,
Expand Down
2 changes: 2 additions & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -2380,6 +2380,8 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_import/data/circular_imports/subpkg2/parent \
test/test_import/data/package \
test/test_import/data/package2 \
test/test_import/data/package3 \
test/test_import/data/package4 \
test/test_import/data/unwritable \
test/test_importlib \
test/test_importlib/builtin \
Expand Down