0

Imagine the following scenario: You have a python package named 'foo' that depends on 'bar'. The package 'bar' itself depends on another python package, let's say shapely, that depends on a C library that cannot be installed on readthedocs.io. Therefore, 'bar' mocks out shapely by

class Mock(MagicMock):
    @classmethod
    def __getattr__(cls, name):
            return MagicMock()

MOCK_MODULES = ['shapely', 'shapely.wkt', 'shapely.wkb', 'shapely.geometry', 'shapely.ops']
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)

in the conf.py file.

Now, I would like to just mock out the dependency shapely from 'bar', but still install 'bar' on RTD in order to let build the docs of 'foo' properly. How can I tell readthedocs.io to mock up 'bar's dependency shapely?

gplssm
  • 129
  • 1
  • 7

1 Answers1

2

Check for environment variable READTHEDOCS:

import os
if 'READTHEDOCS' in os.environ:
    class Mock(MagicMock):
        @classmethod
        def __getattr__(cls, name):
                return MagicMock()

    MOCK_MODULES = ['shapely', 'shapely.wkt', 'shapely.wkb', 'shapely.geometry', 'shapely.ops']
    sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
phd
  • 82,685
  • 13
  • 120
  • 165
  • Thanks for the hint! To understand it more precisely. Would you recommend to add this check for the dependency 'bar' in scenario described above? Hence, I would not mock out 'bar' itself, but 'bar's conf.py mocks out shapely, right? – gplssm Sep 05 '17 at 13:11
  • That should work. You can test that locally by removing the compiled extension and passing environment variable `READTHEDOCS` yourself. – phd Sep 05 '17 at 13:16
  • Actually I don't understand how to test it locally :(. But I tried to suggested approach of `if 'READTHEDOCS' in os.environ:` with RTD. Sadly, it had no effect. The problem is still that I have to specify 'bar' as required dependency in the rtd_requirements.txt in order to install my package on RTD. Then, 'bar' triggers the installation of shapely and the whole process fails. I think my problem is that I don't have enough understanding of how this mocking works. Does it affect the installation process on RTD? – gplssm Sep 06 '17 at 07:54
  • Move `bar` from `requirements.txt` to `setup.py`. Mock `Shapely` during `setup.py install` If 'READTHEDOCS' is detected. – phd Sep 06 '17 at 15:17
  • Thanks for the instructions. Works so far: 'bar' and Shapely are not installed on RTD. But, this raises another issue: now the API docs aren't build because the import of 'bar' and Shapely fail to be import in some files. Therefore, I mock the import like [here](https://github.com/openego/eDisGo/blob/83bf1b05e26793e2ec4bc6f2776b3055b51e88e6/edisgo/data/import_data.py#L8-#L11). Now I ask: is there a more elegant way to do this? But this is maybe a question for another thread... – gplssm Sep 13 '17 at 09:10