click-contrib / sphinx-click

A Sphinx plugin to automatically document click-based applications
MIT License
212 stars 57 forks source link

sphinx-click doesn't seem to work with automocking #86

Closed gibsondan closed 5 months ago

gibsondan commented 2 years ago

Hi, I'm encountering an error when using sphinx-click in a project that uses sphinx automocking.

When I run sphinx-build I get the following error:

/Users/dgibson/dagster/docs/sphinx/sections/api/apidocs/libraries/dagster-celery.rst:117:Failed to import "worker_start_command" from "dagster_celery.cli". The following exception was raised:
Traceback (most recent call last):
  File "/Users/dgibson/.pyenv/versions/3.8.3/envs/docsnodeps/lib/python3.8/site-packages/sphinx_click/ext.py", line 385, in _load_module
    mod = __import__(module_name, globals(), locals(), [attr_name])
  File "/Users/dgibson/dagster/python_modules/libraries/dagster-celery/dagster_celery/cli.py", line 6, in <module>
    from celery.utils.nodenames import default_nodename, host_format
ModuleNotFoundError: No module named 'celery'

I'm sure that I have celery in the list of autodoc_mock_imports (and removing it from that list breaks other sphinx imports that are not using sphinx-click). I'm using sphinx-click 3.0.1 (and Sphinx 3.5.2).

Is this behavior expected / are there workarounds for mocking imports in modules imported by sphinx-click? Thanks for your help!

stephenfin commented 2 years ago

autodoc_mock_imports is part of the configuration for the autodoc extension in Sphinx core. It has no relevance for this extension. To achieve what you want, we'd need to grown our own auto-mocking functionality or somehow reuse the functionality from autodoc. I've no issues with doing this, but I'm unlikely to have the time to do this work myself, unfortunately.

I'm going to keep this open as a potential enhancement, but to be honest, unless you do this work yourself it's unlikely to happen. Sorry to disappoint!

stephenfin commented 2 years ago

Actually, this might not be as complicated as I first thought. @gibsondan Can you please take a look at #88 and see if this would fix your issue? It's a huge hack so no promises.

MattF-NSIDC commented 2 years ago

Just wanted to throw my use case in the ring here: My project, QGreenland, uses autodoc and we use autodoc's mocks for dependencies like fiona that can't, as far as I can tell, be installed in the readthedocs build environment correctly (it requires shared libraries that we install with conda). When we recently added sphinx-click to automatically document our click CLIs (this is awesome to have, by the way, thank you!) we realized that it doesn't have the same mock functionality and, for cases like fiona, we can't just add those to the readthedocs requirements.txt and move on because they will fail to install when looking for shared libraries.

Our workaround was to move those imports from the module-level into the CLI function bodies. The imports affected in that patch are not third-party, but they import things that import third-party things further downstream. Not quite ideal, but worth it for autogenerated docs :)

prajeeshag commented 1 year ago

I have a similar situation where I need to mock many imports. I used sphinx.ext.autodoc.mock to solve this issue. Please have a look at #120. This way one needs only to specify the root package of the dependencies themselves and omit the sub-modules, on the other hand, using unittest.mock.MagicMock as in #88 would require specifying the all the sub-modules separately.

stephenfin commented 5 months ago

This was done in #129.