From 50865e300e6e90c5cc80c8878949a2f3bcaaeeec Mon Sep 17 00:00:00 2001 From: Bo Maryniuk Date: Thu, 25 Aug 2016 16:47:08 +0200 Subject: [PATCH 16/16] Improve Mock to be flexible and able to mock methods from the mocked modules * Configure importing Mock to handle 'total' method from psutils properly --- doc/conf.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 9cefed8..b73ca2a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -15,31 +15,40 @@ from sphinx.directives import TocTree # pylint: disable=R0903 class Mock(object): ''' - Mock out specified imports + Mock out specified imports. This allows autodoc to do its thing without having oodles of req'd installed libs. This doesn't work with ``import *`` imports. + This Mock class can be configured to return a specific values at specific names, if required. + http://read-the-docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules ''' - def __init__(self, *args, **kwargs): - pass + def __init__(self, mapping=None, *args, **kwargs): + """ + Mapping allows to bypass the Mock object, but actually assign + a specific value, expected by a specific attribute returned. + """ + self.__mapping = mapping or {} __all__ = [] def __call__(self, *args, **kwargs): - ret = Mock() # If mocked function is used as a decorator, expose decorated function. # if args and callable(args[-1]): # functools.update_wrapper(ret, args[0]) - return ret - - @classmethod - def __getattr__(cls, name): - if name in ('__file__', '__path__'): - return '/dev/null' + return Mock(mapping=self.__mapping) + + def __getattr__(self, name): + #__mapping = {'total': 0} + data = None + if name in self.__mapping: + data = self.__mapping.get(name) + elif name in ('__file__', '__path__'): + data = '/dev/null' else: - return Mock() + data = Mock(mapping=self.__mapping) + return data # pylint: enable=R0903 MOCK_MODULES = [ @@ -133,7 +142,11 @@ MOCK_MODULES = [ ] for mod_name in MOCK_MODULES: - sys.modules[mod_name] = Mock() + if mod_name == 'psutil': + mock = Mock(mapping={'total': 0}) # Otherwise it will crash Sphinx + else: + mock = Mock() + sys.modules[mod_name] = mock def mock_decorator_with_params(*oargs, **okwargs): ''' -- 2.9.3