I'm trying to autogenerate documentation for Readthedocs. I mock some dependencies as they suggest in FAQ, but from type annotations of functions I get some parts of documentation to look like
Return type: <MagicMock id=‘140517266915680’>
Which is of course unacceptable. So I rewritten mock like this:
from unittest.mock import Mock
class ModuleMock(Mock):
def __init__(self, path='', *args, **kwargs):
super().__init__(*args, *kwargs)
self.path = path
def __getattr__(self, name):
return ModuleMock(path=self.path + '.' + name)
def __repr__(self):
return self.path
So I could do
>>> x = ModuleMock('x')
>>> x
x
>>> x.y.z
x.y.z
But with this I get exception
...
File "<frozen importlib._bootstrap>", line 906, in _find_spec
File "<frozen importlib._bootstrap_external>", line 1280, in find_spec
File "<frozen importlib._bootstrap_external>", line 1246, in _get_spec
TypeError: 'ModuleMock' object is not iterable
When I instead try to inherit from MagicMock
, I get RecursionError
.
What should I do to properly isolate dependencies for documentation generation, and make that documentation readable?
It because MagicMock uses _mock_methods
and _mock_unsafe
attributes, but Mock doesn't (seems).
I use Python 2.7
Correct implementation:
from mock import MagicMock
class ModuleMock(MagicMock):
def __init__(self, path='', *args, **kwargs):
super(ModuleMock, self).__init__(*args, **kwargs)
self.path = path
def __repr__(self):
return self.path
def __getattr__(self, name):
#print(name)
if name in ('_mock_methods', '_mock_unsafe'):
return super(ModuleMock, self).__getattr__(name)
return ModuleMock(self.path + "." + name)
if __name__ == '__main__':
x = ModuleMock('x')
print(x)
print(x.y.z)
So if you print attribute name inside __getattr__
, you can see MagicMock has several calls.
Result:
_mock_methods
_mock_methods
x
y
_mock_methods
z
_mock_methods
_mock_methods
x.y.z