Export to GitHub

mock - issue #250

Cannot patch unittest.main.os because of how unittest imports main


Posted on Apr 19, 2015 by Swift Rabbit

What steps will reproduce the problem?

unittest in the standard library provides the test case. I was trying to patch module os that is imported by unittest.main:

$ python2.7
>>> import unittest.main
>>> import mock
>>> p = mock.patch('unittest.main.os')
>>> p.getter()
<class 'unittest.main.TestProgram'>

That is incorrect. I believe this is because unittest.py imports unittest.main.main as main:

# Top of unittest/__init__.py
from .main import TestProgram, main

But at the end of unittest/main.py, they wrote:

# Bottom of unittest/main.py
main = TestProgram

What is the expected output? What do you see instead?

So when mock._patch.get_original() resolves the name of unittest.main, it gets 'unittest.main.TestProgram'. Since the original is wrong, mock._patch.start() fails:

>>> p.start() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/site-packages/mock.py", line 1396, in start result = self.enter() File "/usr/lib/python2.7/site-packages/mock.py", line 1268, in enter original, local = self.get_original() File "/usr/lib/python2.7/site-packages/mock.py", line 1242, in get_original "%s does not have the attribute %r" % (target, name) AttributeError: <class 'unittest.main.TestProgram'> does not have the attribute 'os'

What version of the product are you using? On what operating system?

Python 2.7.5

Please provide any additional information below.

Comment #1

Posted on Apr 20, 2015 by Helpful Monkey

It's hard to see how to avoid this problem (shadowed module name in a package). Any suggestions?

Status: New

Labels:
Type-Defect Priority-Medium