Rendering the 404 page causes AttributeError: 'Sphinx' object has no attribute 'get_target_uri'
Hi, I tried to add sphinx-notfound-page (Version 0.6 or master) for Flask (with Pallets Sphinx Themes).
with the following conf:
extensions = [
# ...
'notfound.extension',
]
notfound_template = '404.html'
notfound_urls_prefix = None
then the build failed:
Running Sphinx v3.5.4
loading translations [en]... done
making output directory... done
...
generating indices... genindex py-modindex done
Traceback (most recent call last):
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/builders/html/__init__.py", line 1054, in handle_page
output = self.templates.render(templatename, ctx)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/readthedocs_ext/readthedocs.py", line 185, in rtd_render
content = old_render(template, render_context)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/jinja2glue.py", line 192, in render
return self.environment.get_template(template).render(context)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/jinja2/environment.py", line 1127, in render
self.environment.handle_exception()
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/jinja2/environment.py", line 814, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/pallets_sphinx_themes/themes/pocoo/404.html", line 3, in top-level template code
{% set title = _('Page Not Found') %}
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/pallets_sphinx_themes/themes/pocoo/layout.html", line 22, in top-level template code
{% set version_warning = current_version.banner() if current_version %}
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/jinja2/sandbox.py", line 382, in call
return __context.call(__obj, *args, **kwargs)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/pallets_sphinx_themes/versions.py", line 156, in banner
).format(latest=latest.name, href=latest.href(context))
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/pallets_sphinx_themes/versions.py", line 134, in href
path = builder.get_target_uri(pagename)
AttributeError: 'Sphinx' object has no attribute 'get_target_uri'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/cmd/build.py", line 280, in build_main
app.build(args.force_all, filenames)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/application.py", line 352, in build
self.builder.build_update()
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 298, in build_update
len(to_build))
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/builders/__init__.py", line 363, in build
self.finish()
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/builders/html/__init__.py", line 622, in finish
self.finish_tasks.add_task(self.gen_pages_from_extensions)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/util/parallel.py", line 49, in add_task
res = task_func()
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/builders/html/__init__.py", line 646, in gen_pages_from_extensions
self.handle_page(pagename, context, template)
File "/home/docs/checkouts/readthedocs.org/user_builds/flaskx/envs/fix-docs-404/lib/python3.7/site-packages/sphinx/builders/html/__init__.py", line 1062, in handle_page
(pagename, exc)) from exc
sphinx.errors.ThemeError: An error happened in rendering the page 404.
Reason: AttributeError("'Sphinx' object has no attribute 'get_target_uri'")
Theme error:
An error happened in rendering the page 404.
Reason: AttributeError("'Sphinx' object has no attribute 'get_target_uri'")
Full build log: https://readthedocs.org/projects/flaskx/builds/13534094/
The error related to this line in Pallets Sphinx Theme. I'm not quite sure if it's an issue of sphinx-notfound-page since I'm not very familiar with Sphinx, any thoughts will be helpful. Thanks!
Related issue: https://github.com/pallets/pallets-sphinx-themes/issues/34
Hi! Thanks for opening this issue.
I took a quick look at this and it seems that for some reason builder variable at the line you linked is a Sphinx sphinx.application.Sphinx instead of a Sphinx HTML builder (e.g. sphinx.builders.html.StandaloneHTMLBuilder).
I don't know too much about how the theme works, but I'd say that this line https://github.com/pallets/pallets-sphinx-themes/blob/master/src/pallets_sphinx_themes/versions.py#L132 is not returning what we are expecting (an Sphinx HTML builder)
We are overriding the pathto function for the context at https://github.com/readthedocs/sphinx-notfound-page/blob/master/notfound/extension.py#L148 so that may be the reason.
Could you explain a little more what pathto.__closure__[0].cell_contents does?
@greyli friendly ping :)
Could you explain a little more what pathto.closure[0].cell_contents does?
I'm not familiar with the Sphinx theme either...
Hey @davidism, could you explain what this line does?
It's been a long time since I looked at this code.
That function is called in the Jinja page template to generate a URL to a different version of the docs. It's a bit hazy, but I recall having to be fairly careful about how I generated the URL to account for different Sphinx configurations.
In order to generate a URL, I need to call the get_target_uri method on the Sphinx builder object, but neither of those are available in the Jinja render context. However, the pathto function, which is defined as an inner function of the buider.handle_page method, is available. Since pathto references self, I can look at the function closure to get that reference to self again, which is the builder object.
It's entirely possible I missed something while writing this code the first time. These Sphinx objects, and the way they're called and interact, is essentially undocumented, so I spent quite a lot of time just stepping through with a debugger and finding things that would generate the values I needed. If there had been a way to get a reference to the builder at a different time, I would hopefully have used that, but one way or another I couldn't find that while writing the code.
Hey, I've just encountered this error again on my end, see https://app.readthedocs.org/projects/flask-utils/builds/24649777
Are you still able to reproduce this issue? If so, can you try rebuilding your docs without using this extension? Do you have the same issue? I'm asking because I still don't see this issue related to this extension in particular 🤷🏼