Open Griatch opened 3 years ago
I think this is more of an issue of sphinx itself. I have successfully overcome the autodoc problem by forcing the reload of cached modules in the sphinx importer function.
The fact remains that without -c confdir_absolute
this problem goes away. :shrug:
Sure, I'm not the maintainer. 👍
I think this is more of an issue of sphinx itself. I have successfully overcome the autodoc problem by forcing the reload of cached modules in the sphinx importer function.
I'm interested in that solution but I don't know quite how to implement that. I can't find an event to make a callback for. This autodoc-process-docstring event is the closest thing I found. Do you have an example somewhere?
Duplicate of #76
I know this issue is older, but #76 is more generically applicable.
Summary
Running
sphinx-multisession
will runconf.py
two times per branch/tag, so if the code is imported inconf.py
it will be cached by Python and the calling branch's code will be used for all autodocs across all versions.The setup
Here's how a part of my conf.py looks (simplfied to show the concept):
This is a requirement of
mypackage
since for sphinx to be able to import and work withmypackage
, it must be properly initialized first at least once. Not shown are also that this configures autodoc to build automatic api documentation frommypackage
docstrings.The issue
Let's say I have
master
anddevelop
branches, with the same content. I then make a docstring change to a function only in thedevelop
branch.sphinx-multiversion
from thedevelop
branch, the result is that the develop change I did is now visible in both thedevelop
andmaster
documentation.master
branch, the opposite is true - the master-version of the docstring will be used and the change I did will now not show up in thedevelop
docs either.Needless to say, this makes
sphinx-multiversion
somewhat useless. :)Analysis
We'll consider three directories:
develop/
this is the normal location of the code, checked out in the develop branchtmpdevelop/
this is the develop-branch checked out in atmp/
directorytmpmaster/
this is the master branch checked out in atmp/
directoryWhen printing the
ROOT_DIR
value it's clearsphinx-multiversion
callssphinx
one time too many. If we run it fromdevelop
branch,develop
branch docs (first subprocess)ROOT_DIR
will first bedevelop/
ROOT_DIR
then becomestmpdevelop/
master
branch docs (second subprocess):ROOT_DIR
will first bedevelop
again (!)ROOT_DIR
then becomestmpmaster/
as expectedAs seen above, the
conf
file will always be intialized once under the path you callsphinx-multiversion
from. This means that in my conf file, the import ofmypackage
will be cached by Python and not be reimported when it is then called again later (since that happens in the same subprocess). The result is that the package always appears to thesphinx
process as being thedevelop
-branch version and will use the docstrings from that branch.Solution
Here's how I could rewrite the conf file:
In other words, one must clean all packages and sub-packages of
mypackage
manually to get rid of the previous install (just doing aimportlib.reload(mypackage)
doesn't work ifmypackage
is a complex package with a lot of sub-packages like in this case). Doing the for-loop does fix the issue, but it will lead to a truckload of warning messages on every build since Python will warn that doing this is not recommended and can lead to strange side effects (and maybe it does, it's hard to verify without going through every docstring).One could also consider trying to identify which calling args are being used to see if
mypackage
should be initialized or not. This feels pretty hacky though.The true reason for this issue is in
sphinx-multiversion
, inmain.py
, line 322-323:Commenting out
-c confir_absolute
resolves this issue because thensphinx-multiversion
will only be callingconf.py
one time per branch/tag (within eachtmp/
dir) and since the branches are each processed in a separate process there is no risk of this bug appearing.I'd make a PR for it, but it's a trivial fix and I don't know if there is some other reason for the calling location's
conf.py
to be passed that I'm not aware of.