sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.32k stars 453 forks source link

Update to sphinx 3 #28856

Closed timokau closed 4 years ago

timokau commented 4 years ago

Migrate to sphinx 3.

The attributes todo_all_todos and citations were previously implicitly initialized by sphinx. That changed in sphinx 2.1 due to some refactoring:

https://github.com/sphinx-doc/sphinx/commit/9abb4820b18201f63d77fdccb4ef394a21442f7a https://github.com/sphinx-doc/sphinx/commit/885d35e374b56d1d17f5036fe07b74229cdbec7f

So now we need to check for the case where they are not initialized yet. We can't actually update to sphinx 2.1 yet, since it's python3 only. This is mostly intended to make things easier for distros and allow us to update in the future.

Another issue occurs with intersphinx. Since a refactoring (https://github.com/sphinx-doc/sphinx/pull/5826) the build fails with

[manifolds] Exception occurred:
[manifolds]   File "/nix/store/ldl3rb92yvl070c7q3nnjgwl5mdx2wvb-python3.7-sphinx-2.0.0/lib/python3.7/site-packages/sphinx/ext/intersphinx.py", line 207, in load_mappings
[manifolds]     for key, (name, (uri, invs)) in app.config.intersphinx_mapping.items():
[manifolds] ValueError: too many values to unpack (expected 2)
[manifolds] The full traceback has been saved in /build/sphinx-err-e6h8o39l.log, if you want to report the issue to the developers.
[manifolds] Please also report this if it was a user error, so that a better error message can be provided next time.
[manifolds] A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
Traceback (most recent call last):
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 328, in <module>
    runsphinx()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 317, in runsphinx
    sys.stderr.raise_errors()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 252, in raise_errors
    raise OSError(self._error)
OSError: Exception occurred:
Error building the documentation.
Traceback (most recent call last):
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__main__.py", line 2, in <module>
    main()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 1671, in main
    builder()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 310, in _wrapper
    getattr(get_builder(document), name)(*args, **kwds)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 504, in _wrapper
    build_many(build_ref_doc, L)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 258, in build_many
    _build_many(target, args, processes=NUM_THREADS)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/utils.py", line 283, in build_many
    raise worker_exc.original_exception

which seems to suggest that the normalization hook added in the refactoring PR is not called.

Tarballs:

Depends on #28000 Depends on #29547

CC: @antonio-rojas @kiwifb @saraedum @fchapoton @jhpalmieri @jdemeyer @qed777 @tobihan @strogdon

Component: packages: standard

Keywords: sphinx

Author: Timo Kaufmann, John Palmieri, François Bissey, Antonio Rojas

Branch: bd99462

Reviewer: Timo Kaufmann, John Palmieri, François Bissey, Antonio Rojas

Issue created by migration from https://trac.sagemath.org/ticket/28856

timokau commented 4 years ago

Branch: u/gh-timokau/sphinx-2.1-support

timokau commented 4 years ago

Commit: af695b2

timokau commented 4 years ago

New commits:

af695b2Make docbuild merging compatible with spinx >=2.1
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Changed commit from af695b2 to a3382d8

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

a3382d8Make docbuild merging compatible with spinx 2.1
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

1c30994Make docbuild merging compatible with spinx 2.1
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Changed commit from a3382d8 to 1c30994

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

4c3780cMake docbuild merging compatible with spinx 2.1
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Changed commit from 1c30994 to 4c3780c

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Changed commit from 4c3780c to 447b6b0

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

447b6b0Make docbuild merging compatible with spinx 2.1
timokau commented 4 years ago
comment:8

Remaining problem:

[manifolds] Exception occurred:
[manifolds]   File "/nix/store/ldl3rb92yvl070c7q3nnjgwl5mdx2wvb-python3.7-sphinx-2.0.0/lib/python3.7/site-packages/sphinx/ext/intersphinx.py", line 207, in load_mappings
[manifolds]     for key, (name, (uri, invs)) in app.config.intersphinx_mapping.items():
[manifolds] ValueError: too many values to unpack (expected 2)
[manifolds] The full traceback has been saved in /build/sphinx-err-erras5d4.log, if you want to report the issue to the developers.
[manifolds] Please also report this if it was a user error, so that a better error message can be provided next time.
[manifolds] A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
Traceback (most recent call last):
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 328, in <module>
    runsphinx()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 317, in runsphinx
    sys.stderr.raise_errors()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 252, in raise_errors
    raise OSError(self._error)
OSError: Exception occurred:
Error building the documentation.
Traceback (most recent call last):
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__main__.py", line 2, in <module>
    main()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 1671, in main
    builder()
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 310, in _wrapper
    getattr(get_builder(document), name)(*args, **kwds)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 504, in _wrapper
    build_many(build_ref_doc, L)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 258, in build_many
    _build_many(target, args, processes=NUM_THREADS)
  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/utils.py", line 283, in build_many
    raise worker_exc.original_exception
subprocess.CalledProcessError: Command '['python', '-um', 'sage_setup.docbuild.sphinxbuild', '-N', '-b', 'html', '-d', '/build/share/doc/sage/doctrees/en/reference/manifolds', '-D', 'multidoc_first_pass=0', '/bui>
builder for '/nix/store/rbwjmqg1dp0padhni45xkhj4vqmxc4x9-sagedoc-9.0.beta6.drv' failed with exit code 1

Related to https://github.com/sphinx-doc/sphinx/pull/5826 and the way we use intersphinx.

slel commented 4 years ago

Description changed:

--- 
+++ 
@@ -1,4 +1,4 @@
-The attributes "todo_all_todos" and "citations" were previously
+The attributes `todo_all_todos` and `citations` were previously
 implicitly initialized by sphinx. That changed in sphinx 2.1 due to some
 refactoring:

@@ -6,7 +6,7 @@
 https://github.com/sphinx-doc/sphinx/commit/885d35e374b56d1d17f5036fe07b74229cdbec7f

 So now we need to check for the case where they are not initialized yet.
-We can't actually update to sphinx 2.1 yet, since its python3 only. This
+We can't actually update to sphinx 2.1 yet, since it's python3 only. This
 is mostly intended to make things easier for distros and allow us to
 update in the future.
slel commented 4 years ago

Changed keywords from none to sphinx

timokau commented 4 years ago

Description changed:

--- 
+++ 
@@ -10,3 +10,47 @@
 is mostly intended to make things easier for distros and allow us to
 update in the future.

+
+Another issue occurs with intersphinx. Since a refactoring (https://github.com/sphinx-doc/sphinx/pull/5826) the build fails with
+
+```
+[manifolds] Exception occurred:
+[manifolds]   File "/nix/store/ldl3rb92yvl070c7q3nnjgwl5mdx2wvb-python3.7-sphinx-2.0.0/lib/python3.7/site-packages/sphinx/ext/intersphinx.py", line 207, in load_mappings
+[manifolds]     for key, (name, (uri, invs)) in app.config.intersphinx_mapping.items():
+[manifolds] ValueError: too many values to unpack (expected 2)
+[manifolds] The full traceback has been saved in /build/sphinx-err-e6h8o39l.log, if you want to report the issue to the developers.
+[manifolds] Please also report this if it was a user error, so that a better error message can be provided next time.
+[manifolds] A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
+Traceback (most recent call last):
+  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 193, in _run_module_as_main
+    "__main__", mod_spec)
+  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 85, in _run_code
+    exec(code, run_globals)
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 328, in <module>
+    runsphinx()
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 317, in runsphinx
+    sys.stderr.raise_errors()
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/sphinxbuild.py", line 252, in raise_errors
+    raise OSError(self._error)
+OSError: Exception occurred:
+Error building the documentation.
+Traceback (most recent call last):
+  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 193, in _run_module_as_main
+    "__main__", mod_spec)
+  File "/nix/store/9894fxjpg8v99j14kip6b13rdfgf4m5k-python3-3.7.5/lib/python3.7/runpy.py", line 85, in _run_code
+    exec(code, run_globals)
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__main__.py", line 2, in <module>
+    main()
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 1671, in main
+    builder()
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 310, in _wrapper
+    getattr(get_builder(document), name)(*args, **kwds)
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 504, in _wrapper
+    build_many(build_ref_doc, L)
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/__init__.py", line 258, in build_many
+    _build_many(target, args, processes=NUM_THREADS)
+  File "/nix/store/i0gjbmskaxkmj2qif96ayvb803l6hm4k-python3.7-sagelib-9.0.beta6/lib/python3.7/site-packages/sage_setup/docbuild/utils.py", line 283, in build_many
+    raise worker_exc.original_exception
+```
+
+which seems to suggest that the normalization hook added in the refactoring PR is not called.
timokau commented 4 years ago
comment:11

Since I have little experience with sphinx and don't know how and why our intersphinx usage differs from normal usage, I'm having issues fixing this issue.

I've CC'ed some people who have touched the sphinx config in the past. Can anybody help with the second issue described in the top post (regarding intersphinx)?

timokau commented 4 years ago
comment:12

Does anyone have experience with sphinx hooks? Understanding why the hook introduced in https://github.com/sphinx-doc/sphinx/pull/5826 isn't called would help a lot.

mwageringel commented 4 years ago
comment:13

I do not have much experience with sphinx, but, at the bottom of src/sage/docs/conf.py, it appears that intersphinx is not loaded the usual way by adding it to the extensions list, but instead it is manually initialized in order to inject a custom function for missing_reference.

        app.add_config_value('intersphinx_mapping', {}, False)
        app.add_config_value('intersphinx_cache_limit', 5, False)
        # We do *not* fully initialize intersphinx since we call it by hand
        # in find_sage_dangling_links.
        #   app.connect('missing-reference', missing_reference)
        app.connect('missing-reference', find_sage_dangling_links)
        import sphinx.ext.intersphinx
        app.connect('builder-inited', set_intersphinx_mappings)
        app.connect('builder-inited', sphinx.ext.intersphinx.load_mappings)

Probably this means that normalize_intersphinx_mapping is never called, but adjusting the code above as in the PR might fix it.

embray commented 4 years ago
comment:14

Ticket retargeted after milestone closed

timokau commented 4 years ago
comment:15

For what it's worth, I have not been able to get this working and don't have time to work on it any further right now. My current attempt (trying to get the normalization in there at the right point):

diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py
index d86fc9c6d1..013f1794e4 100644
--- a/src/sage/docs/conf.py
+++ b/src/sage/docs/conf.py
@@ -8,6 +8,7 @@ from docutils import nodes
 from docutils.transforms import Transform
 from sphinx.ext.doctest import blankline_re
 from sphinx import highlighting
+import sphinx.ext.intersphinx as intersphinx
 from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer

 # If your extensions are in another directory, add it here.
@@ -175,7 +176,7 @@ intersphinx_mapping = {
                              "python{}.inv".format(python_version))),
     'pplpy': (PPLPY_DOCS, None)}

-def set_intersphinx_mappings(app, _config):
+def set_intersphinx_mappings(app, config):
     """
     Add precompiled inventory (the objects.inv)
     """
@@ -201,6 +202,8 @@ def set_intersphinx_mappings(app, _config):
             dst = os.path.join(invpath, directory, 'objects.inv')
             app.config.intersphinx_mapping[src] = dst

+    intersphinx.normalize_intersphinx_mapping(app, config)
+

 # By default document are not master.
 multidocs_is_master = True
@@ -669,7 +672,7 @@ def call_intersphinx(app, env, node, contnode):
     """
     debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget'])
     builder = app.builder
-    res =  sphinx.ext.intersphinx.missing_reference(
+    res =  intersphinx.missing_reference(
         app, env, node, contnode)
     if res:
         # Replace absolute links to $SAGE_DOC by relative links: this
@@ -852,12 +855,11 @@ def setup(app):
     if app.srcdir.startswith(SAGE_DOC_SRC):
         app.add_config_value('intersphinx_mapping', {}, False)
         app.add_config_value('intersphinx_cache_limit', 5, False)
+        app.connect('config-inited', set_intersphinx_mappings)
+        # app.connect('config-inited', intersphinx.normalize_intersphinx_mapping)
+        app.connect('builder-inited', intersphinx.load_mappings)
         # We do *not* fully initialize intersphinx since we call it by hand
         # in find_sage_dangling_links.
         #   app.connect('missing-reference', missing_reference)
         app.connect('missing-reference', find_sage_dangling_links)
-        import sphinx.ext.intersphinx
-        app.connect('config-inited', set_intersphinx_mappings)
-        app.connect('config-inited', sphinx.ext.intersphinx.normalize_intersphinx_mapping)
-        app.connect('builder-inited', sphinx.ext.intersphinx.load_mappings)
         app.connect('builder-inited', nitpick_patch_config)
jhpalmieri commented 4 years ago
comment:16

I have been attempting to initialize intersphinx as an ordinary Sphinx extension. The reference manual builds this way, but other pieces of the documentation fail because of missing citations, and I don't know why. But succeeding with the reference manual seems like progress. Anyway, here is my current attempt; this is using the version of Sphinx which is included in Sage — I thought I would try get that to work first with this approach, and then move on to a more recent version of Sphinx.

diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py
index 23cf5d6792..226e68a31b 100644
--- a/src/sage/docs/conf.py
+++ b/src/sage/docs/conf.py
@@ -25,6 +25,7 @@ extensions = ['inventory_builder',
               'sphinx.ext.inheritance_diagram',
               'sphinx.ext.todo',
               'sphinx.ext.extlinks',
+              'sphinx.ext.intersphinx',
               'IPython.sphinxext.ipython_directive',
               'matplotlib.sphinxext.plot_directive']

@@ -88,11 +89,6 @@ from sage.all_cmdline import *
 plot_html_show_formats = False
 plot_formats = ['svg', 'pdf', 'png']

-# We do *not* fully initialize intersphinx since we call it by hand
-# in find_sage_dangling_links.
-#, 'sphinx.ext.intersphinx']
-
-
 # Add any paths that contain templates here, relative to this directory.
 templates_path = [os.path.join(SAGE_DOC_SRC, 'common', 'templates'), 'templates']

@@ -850,10 +846,6 @@ def setup(app):
     # set to a temporary directory.  We don't want to use intersphinx,
     # etc., when doing introspection.
     if app.srcdir.startswith(SAGE_DOC_SRC):
-        app.add_config_value('intersphinx_mapping', {}, False)
-        app.add_config_value('intersphinx_cache_limit', 5, False)
-        # We do *not* fully initialize intersphinx since we call it by hand
-        # in find_sage_dangling_links.
         #   app.connect('missing-reference', missing_reference)
         app.connect('missing-reference', find_sage_dangling_links)
         import sphinx.ext.intersphinx
timokau commented 4 years ago
comment:17

Sounds like good progress indeed! Throwing away our hacks and becoming a "normal" intersphinx consumer would be the best solution.

antonio-rojas commented 4 years ago
comment:18

Opened #29095 for the runtime issues with latest sphinx (which are much easier to fix)

timokau commented 4 years ago
comment:19

Just as a heads-up: The combination of an outdated sphinx version and a newer (>=0.15) docutils version leads to (harmless) doctest failures:

File "/nix/store/kyzn2mbdpjgdh1n8ldqwah3s1k4b6mza-sage-src-8.9/src/sage/interfaces/tachyon.py", line 191, in sage.interfaces.tachyon.TachyonRT.help
Failed example:
    t.help(use_pager=False)
Expected:
    This help, which was written by John Stone, describes ...
Got:
    doctest:warning
      File "/nix/store/kra72yycg2ixhkmx944qgrlgaqhr6ia4-sage-with-env-8.9/bin/sage-runtests", line 179, in <module>
        err = DC.run()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/control.py", line 1227, in run
        self.run_doctests()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/control.py", line 928, in run_doctests
        self.dispatcher.dispatch()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 2041, in dispatch
        self.parallel_dispatch()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 1933, in parallel_dispatch
        w.start()  # This might take some time
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 2208, in start
        super(DocTestWorker, self).start()
      File "/nix/store/k5iyhnvy9cdlq3mpavw6s8blyr0px522-python-2.7.17/lib/python2.7/multiprocessing/process.py", line 130, in start
        self._popen = Popen(self)
      File "/nix/store/k5iyhnvy9cdlq3mpavw6s8blyr0px522-python-2.7.17/lib/python2.7/multiprocessing/forking.py", line 126, in __init__
        code = process_obj._bootstrap()
      File "/nix/store/k5iyhnvy9cdlq3mpavw6s8blyr0px522-python-2.7.17/lib/python2.7/multiprocessing/process.py", line 267, in _bootstrap
        self.run()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 2180, in run
        task(self.options, self.outtmpfile, msgpipe, self.result_queue)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 2512, in __call__
        doctests, extras = self._run(runner, options, results)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 2561, in _run
        result = runner.run(test)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 897, in run
        return self._run(test, compileflags, out)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 681, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/doctest/forker.py", line 1131, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.interfaces.tachyon.TachyonRT.help[2]>", line 1, in <module>
        t.help(use_pager=False)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/interfaces/tachyon.py", line 784, in help
        f = format(s)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/misc/sagedoc.py", line 720, in format
        s = detex(s, embedded=embedded)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/misc/sagedoc.py", line 228, in detex
        s = sphinxify(s, format='text')
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sage/misc/sphinxify.py", line 123, in sphinxify
        sphinx_app.build(None, [rst_name])
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/application.py", line 338, in build
        self.builder.build_specific(filenames)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 335, in build_specific
        summary=__('%d source files given on command line') % len(to_write))
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 360, in build
        updated_docnames = set(self.read())
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 468, in read
        self._read_serial(docnames)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 490, in _read_serial
        self.read_doc(docname)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 534, in read_doc
        doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/io.py", line 318, in read_doc
        pub.publish()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/docutils/core.py", line 219, in publish
        self.apply_transforms()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/docutils/core.py", line 200, in apply_transforms
        self.document.transformer.apply_transforms()
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/transforms/__init__.py", line 90, in apply_transforms
        Transformer.apply_transforms(self)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/docutils/transforms/__init__.py", line 171, in apply_transforms
        transform.apply(**kwargs)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/transforms/__init__.py", line 245, in apply
        apply_source_workaround(n)
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/sphinx/util/nodes.py", line 94, in apply_source_workaround
        for classifier in reversed(node.parent.traverse(nodes.classifier)):
      File "/nix/store/3j74nni97qk6pj1slbbgn67q5qw4r51s-python-2.7.17-env/lib/python2.7/site-packages/docutils/nodes.py", line 46, in wrapper
        warnings.warn(msg, FutureWarning, stacklevel=2)
    :
    FutureWarning: 
       The iterable returned by Node.traverse()
       will become an iterator instead of a list in Docutils > 0.16.
    This help, which was written by John Stone, describes how to create
    scene files.
    <BLANKLINE>
    At the present time, scene description files are very simple. The
    parser can't handle multiple file scene descriptions, although they
    may be added in the future.  Most of the objects and their scene
    description are closely related to the RAY API *(See the API docs for
    additional info.)*

These will likely turn into errors for docutils 0.16, but are already fixed in sphinx upstream: https://github.com/sphinx-doc/sphinx/commit/faedcc48ccb942b9a7b758b699b30f0d026c0771

jhpalmieri commented 4 years ago
comment:20

In the meantime, a beta for Sphinx 3.0.0 is available: see https://github.com/sphinx-doc/sphinx/blob/3.0.x/CHANGES

kiwifb commented 4 years ago
comment:21

A user of sage-on-gentoo did go and talk to upstream about our difficulties with intersphinx in https://github.com/sphinx-doc/sphinx/issues/7409 and one of the dev took it to heart. Apparently we have to switch from builder-inetd to config-inetd and make sure we have sphinx including https://github.com/sphinx-doc/sphinx/pull/7415

I haven't got around figuring out how to use all that information.

kiwifb commented 4 years ago
comment:22

And now that I have looked more closely, it is all included in the newly released sphinx-3.0.

kiwifb commented 4 years ago
comment:23

I am trying to get to support sphinx 3.0 in gentoo in time for sage-9.1. So far I have combined the branch attached to this ticket plus comment:15.

--- a/sage/docs/conf.py
+++ b/sage/docs/conf.py
@@ -8,6 +8,7 @@ from docutils import nodes
 from docutils.transforms import Transform
 from sphinx.ext.doctest import blankline_re
 from sphinx import highlighting
+import sphinx.ext.intersphinx as intersphinx
 from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer

 # If your extensions are in another directory, add it here.
@@ -175,7 +176,7 @@ intersphinx_mapping = {
                              "python{}.inv".format(python_version))),
     'pplpy': (PPLPY_DOCS, None)}

-def set_intersphinx_mappings(app):
+def set_intersphinx_mappings(app, config):
     """
     Add precompiled inventory (the objects.inv)
     """
@@ -201,6 +202,8 @@ def set_intersphinx_mappings(app):
             dst = os.path.join(invpath, directory, 'objects.inv')
             app.config.intersphinx_mapping[src] = dst

+    intersphinx.normalize_intersphinx_mapping(app, config)
+

 # By default document are not master.
 multidocs_is_master = True
@@ -669,7 +672,7 @@ def call_intersphinx(app, env, node, contnode):
     """
     debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget'])
     builder = app.builder
-    res =  sphinx.ext.intersphinx.missing_reference(
+    res =  intersphinx.missing_reference(
         app, env, node, contnode)
     if res:
         # Replace absolute links to $SAGE_DOC by relative links: this
@@ -852,11 +855,11 @@ def setup(app):
     if app.srcdir.startswith(SAGE_DOC_SRC):
         app.add_config_value('intersphinx_mapping', {}, False)
         app.add_config_value('intersphinx_cache_limit', 5, False)
+        app.connect('config-inited', set_intersphinx_mappings)
+        # app.connect('config-inited', intersphinx.normalize_intersphinx_mapping)
+        app.connect('builder-inited', intersphinx.load_mappings)
         # We do *not* fully initialize intersphinx since we call it by hand
         # in find_sage_dangling_links.
         #   app.connect('missing-reference', missing_reference)
         app.connect('missing-reference', find_sage_dangling_links)
-        import sphinx.ext.intersphinx
-        app.connect('builder-inited', set_intersphinx_mappings)
-        app.connect('builder-inited', sphinx.ext.intersphinx.load_mappings)
         app.connect('builder-inited', nitpick_patch_config)
diff --git a/sage_setup/docbuild/ext/multidocs.py b/sage_setup/docbuild/ext/multidocs.py
index 71a08cd..3a3d09a 100644
--- a/sage_setup/docbuild/ext/multidocs.py
+++ b/sage_setup/docbuild/ext/multidocs.py
@@ -47,24 +47,30 @@ def merge_environment(app, env):
     - domaindata['py']['modules'] # list of python modules
     """
     logger.info(bold('Merging environment/index files...'))
+    if not hasattr(env, "todo_all_todos"):
+        env.todo_all_todos = []
+    if not hasattr(env.domaindata["std"], "citations"):
+        env.domaindata["std"]["citations"] = dict()
     for curdoc in app.env.config.multidocs_subdoc_list:
         logger.info("    %s:"%curdoc, nonl=1)
         docenv = get_env(app, curdoc)
         if docenv is not None:
             fixpath = lambda path: os.path.join(curdoc, path)
+            todos = docenv.todo_all_todos if hasattr(docenv, "todo_all_todos") else []
+            citations = docenv.domaindata["std"].get("citations", dict())
             logger.info(" %s todos, %s index, %s citations"%(
-                    len(docenv.todo_all_todos),
+                    len(todos),
                     len(docenv.indexentries),
-                    len(docenv.domaindata["std"]["citations"])
+                    len(citations)
                     ), nonl=1)

             # merge titles
             for t in docenv.titles:
                 env.titles[fixpath(t)] = docenv.titles[t]
             # merge the todo links
-            for dct in docenv.todo_all_todos:
+            for dct in todos:
                 dct['docname'] = fixpath(dct['docname'])
-            env.todo_all_todos += docenv.todo_all_todos
+            env.todo_all_todos += todos
             # merge the html index links
             newindex = {}
             for ind in docenv.indexentries:
@@ -86,8 +92,7 @@ def merge_environment(app, env):
                 env.metadata[ind] = md
             # merge the citations
             newcite = {}
-            citations = docenv.domaindata["std"]["citations"]
-            for ind, (path, tag, lineno) in six.iteritems(docenv.domaindata["std"]["citations"]):
+            for ind, (path, tag, lineno) in six.iteritems(citations):
                 # TODO: Warn on conflicts
                 newcite[ind] = (fixpath(path), tag, lineno)
             env.domaindata["std"]["citations"].update(newcite)
@@ -253,7 +258,7 @@ def fetch_citation(app, env):
     with open(filename, 'rb') as f:
         cache = cPickle.load(f)
     logger.info("done (%s citations)."%len(cache))
-    cite = env.domaindata["std"]["citations"]
+    cite = env.domaindata["std"].get("citations", dict())
     for ind, (path, tag, lineno) in six.iteritems(cache):
         if ind not in cite: # don't override local citation
             cite[ind] = (os.path.join("..", path), tag, lineno)

And it goes some way with multiple warnings

[plot3d   ] /usr/lib/python3.7/site-packages/sphinx/pycode/__init__.py:186: RemovedInSphinx40Warning: ModuleAnalyzer.encoding is deprecated.
[plot3d   ]   RemovedInSphinx40Warning)

which is probably coming from something else (like docutils - I have to track it). But ultimately it breaks down at

[combinat ] /dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/build/lib/sage/combinat/permutation.py:docstring of sage.combinat.permutation.Permutation.left_action_product:1: WARNING: duplicate object description of sage.combinat.permutation.Permutation.left_action_product, other instance in sage/combinat/permutation, use :noindex: for one of them
[combinat ] /dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/build/lib/sage/combinat/permutation.py:docstring of sage.combinat.permutation.Permutation.right_action_product:1: WARNING: duplicate object description of sage.combinat.permutation.Permutation.right_action_product, other instance in sage/combinat/permutation, use :noindex: for one of them

which leads to the build of documentation stopping

Error building the documentation.
Traceback (most recent call last):
  File "sage_setup/docbuild/__main__.py", line 2, in <module>
    main()
  File "/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/sage_setup/docbuild/__init__.py", line 1720, in main
    builder()
  File "/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/sage_setup/docbuild/__init__.py", line 327, in _wrapper
    getattr(get_builder(document), 'inventory')(*args, **kwds)
  File "/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/sage_setup/docbuild/__init__.py", line 552, in _wrapper
    self._build_everything_except_bibliography(lang, format, *args, **kwds)
  File "/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/sage_setup/docbuild/__init__.py", line 538, in _build_everything_except_bibliography
    build_many(build_ref_doc, non_references)
  File "/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/sage_setup/docbuild/__init__.py", line 280, in build_many
    _build_many(target, args, processes=NUM_THREADS)
  File "/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/sage_setup/docbuild/utils.py", line 283, in build_many
    raise worker_exc.original_exception
OSError: /dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_7/build/lib/`sage/combinat/permutation.py:docstring of sage.combinat.permutation.Permutation.left_action_product:1: WARNING: duplicate object description of sage.combinat.permutation.Permutation.left_action_product, other instance in sage/combinat/permutation, use :noindex: for one of them

I have looked at sage/combinat/permutation.py but I cannot figure where I should add :noindex:. Some assistance at this stage would be welcome.

antonio-rojas commented 4 years ago
comment:24

The deprecation warnings come from sage itself, specifically from https://github.com/sagemath/sagetrac-mirror/blob/develop/src/sage_setup/docbuild/ext/sage_autodoc.py#n539 - fixing it gives a similar amount of warnings, this time about safe_getmembers. Haven't looked into the replacement for that one yet.

Building with -k makes it go past the duplicate object error, but then one gets again the ValueError: too many values to unpack error when it reaches the second pass.

kiwifb commented 4 years ago
comment:25

I see the safe_getmembers warnings as well - without fixing sage_autodoc. It floods a little less :) I thought sphinx-3.0 was supposed to help with the "too many value to unpack". I guess that was too optimistic.

antonio-rojas commented 4 years ago
comment:26

I added some debug, seems that normalize_intersphinx_mapping is never being run

antonio-rojas commented 4 years ago
comment:27

Alright, turns out that was my fault... conf.py was moved to sagelib a while ago so I was using the (unpatched) version from the installed sagemath instead of the patched one in the source code when building sagemath-doc.

Now, after sorting it out, the new errors (on the second pass) are:

[tutorial ]   File "/usr/lib/python3.8/urllib/parse.py", line 108, in <genexpr>
[tutorial ]     return tuple(x.decode(encoding, errors) if x else '' for x in args)
[tutorial ] AttributeError: 'tuple' object has no attribute 'decode'

These seem to be cause by a bad intersphinx mapping normalization... looks like normalize_intersphinx_mapping is not idempotent, and when running it on an already normalized item it will try to renormalize it and break its format.

antonio-rojas commented 4 years ago
comment:28

Getting closer: with the attached patch the double normalization issue is worked around and the compilation finishes (with -k). It also fixes the most annoying deprecation warnings. However, there are many files missing which were present when compiling with sphinx 1.

Not sure if it's related, but at the end of the first pass one gets the error:

[reference] Extension error:
[reference] Domain 'index' is not registered

so it seems that the index attribute also needs to be explicitely initialized now, similar to citations and todo_all_todos

obsolete patch removed

antonio-rojas commented 4 years ago
comment:29

Updated patch that fixes the Domain 'index' is not registered error and all sphinx deprecation warnings. Still, html for the reference manual subdirs is not being generated.

obsolete patch removed

kiwifb commented 4 years ago
comment:30

Well, that's some progress I guess. I think we should move this ticket milestone to 9.2 and make it "upgrade to sphinx 3", that would be more honest because I don't think we can keep it compatible with sphinx-1.8 at the same time.

antonio-rojas commented 4 years ago
comment:32

Found the problem, some used sphinx API has been removed. With the attached version the docs compile (still with -k). Next issue: citation links are not working.

--- a/src/sage_setup/docbuild/__init__.py
+++ b/src/sage_setup/docbuild/__init__.py
@@ -817,9 +817,13 @@ class ReferenceSubBuilder(DocBuilder):

         env_pickle = os.path.join(self._doctrees_dir(), 'environment.pickle')
         try:
-            env = BuildEnvironment.frompickle(env_pickle, FakeApp(self.dir))
-            logger.debug("Opened Sphinx environment: %s", env_pickle)
-            return env
+            with open(env_pickle, 'rb') as f:
+                import pickle
+                env = pickle.load(f)
+                env.app = FakeApp(self.dir)
+                env.config.values = env.app.config.values
+                logger.debug("Opened Sphinx environment: %s", env_pickle)
+                return env
         except IOError as err:
             logger.debug("Failed to open Sphinx environment: %s", err)

--- a/src/sage/docs/conf.py
+++ b/src/sage/docs/conf.py
@@ -8,6 +8,7 @@ from docutils import nodes
 from docutils.transforms import Transform
 from sphinx.ext.doctest import blankline_re
 from sphinx import highlighting
+import sphinx.ext.intersphinx as intersphinx
 from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer

 # If your extensions are in another directory, add it here.
@@ -169,13 +169,8 @@ todo_include_todos = True

 # Cross-links to other project's online documentation.
 python_version = sys.version_info.major
-intersphinx_mapping = {
-    'python': ('https://docs.python.org/',
-                os.path.join(SAGE_DOC_SRC, "common",
-                             "python{}.inv".format(python_version))),
-    'pplpy': (PPLPY_DOCS, None)}

-def set_intersphinx_mappings(app):
+def set_intersphinx_mappings(app, config):
     """
     Add precompiled inventory (the objects.inv)
     """
@@ -186,7 +182,11 @@ def set_intersphinx_mappings(app):
         app.config.intersphinx_mapping = {}
         return

-    app.config.intersphinx_mapping = intersphinx_mapping
+    app.config.intersphinx_mapping =  {
+    'python': ('https://docs.python.org/',
+                os.path.join(SAGE_DOC_SRC, "common",
+                             "python{}.inv".format(python_version))),
+    'pplpy': (PPLPY_DOCS, None)}

     # Add master intersphinx mapping
     dst = os.path.join(invpath, 'objects.inv')
@@ -201,6 +201,7 @@ def set_intersphinx_mappings(app):
             dst = os.path.join(invpath, directory, 'objects.inv')
             app.config.intersphinx_mapping[src] = dst

+    intersphinx.normalize_intersphinx_mapping(app, config)

 # By default document are not master.
 multidocs_is_master = True
@@ -669,7 +672,7 @@ def call_intersphinx(app, env, node, contnode):
     """
     debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget'])
     builder = app.builder
-    res =  sphinx.ext.intersphinx.missing_reference(
+    res =  intersphinx.missing_reference(
         app, env, node, contnode)
     if res:
         # Replace absolute links to $SAGE_DOC by relative links: this
@@ -852,11 +855,10 @@ def setup(app):
     if app.srcdir.startswith(SAGE_DOC_SRC):
         app.add_config_value('intersphinx_mapping', {}, False)
         app.add_config_value('intersphinx_cache_limit', 5, False)
+        app.connect('config-inited', set_intersphinx_mappings)
+        app.connect('builder-inited', intersphinx.load_mappings)
         # We do *not* fully initialize intersphinx since we call it by hand
         # in find_sage_dangling_links.
         #   app.connect('missing-reference', missing_reference)
         app.connect('missing-reference', find_sage_dangling_links)
-        import sphinx.ext.intersphinx
-        app.connect('builder-inited', set_intersphinx_mappings)
-        app.connect('builder-inited', sphinx.ext.intersphinx.load_mappings)
         app.connect('builder-inited', nitpick_patch_config)
--- a/src/sage_setup/docbuild/ext/multidocs.py
+++ b/src/sage_setup/docbuild/ext/multidocs.py
@@ -47,32 +47,39 @@ def merge_environment(app, env):
     - domaindata['py']['modules'] # list of python modules
     """
     logger.info(bold('Merging environment/index files...'))
+    if not hasattr(env, "todo_all_todos"):
+        env.todo_all_todos = []
+    if not env.domaindata["std"].get("citations"):
+        env.domaindata["std"]["citations"] = dict()
     for curdoc in app.env.config.multidocs_subdoc_list:
         logger.info("    %s:"%curdoc, nonl=1)
         docenv = get_env(app, curdoc)
         if docenv is not None:
             fixpath = lambda path: os.path.join(curdoc, path)
+            todos = docenv.todo_all_todos if hasattr(docenv, "todo_all_todos") else []
+            citations = docenv.domaindata["std"].get("citations", dict())
+            indexentries = docenv.domaindata["index"].get("entries", dict())
             logger.info(" %s todos, %s index, %s citations"%(
-                    len(docenv.todo_all_todos),
-                    len(docenv.indexentries),
-                    len(docenv.domaindata["std"]["citations"])
+                    len(todos),
+                    len(indexentries),
+                    len(citations)
                     ), nonl=1)

             # merge titles
             for t in docenv.titles:
                 env.titles[fixpath(t)] = docenv.titles[t]
             # merge the todo links
-            for dct in docenv.todo_all_todos:
+            for dct in todos:
                 dct['docname'] = fixpath(dct['docname'])
-            env.todo_all_todos += docenv.todo_all_todos
+            env.todo_all_todos += todos
             # merge the html index links
             newindex = {}
-            for ind in docenv.indexentries:
+            for ind in indexentries:
                 if ind.startswith('sage/'):
-                    newindex[fixpath(ind)] = docenv.indexentries[ind]
+                    newindex[fixpath(ind)] = indexentries[ind]
                 else:
-                    newindex[ind] = docenv.indexentries[ind]
-            env.indexentries.update(newindex)
+                    newindex[ind] = indexentries[ind]
+            env.domaindata['index']['entries'].update(newindex)
             # merge the all_docs links, needed by the js index
             newalldoc = {}
             for ind in docenv.all_docs:
@@ -86,24 +93,23 @@ def merge_environment(app, env):
                 env.metadata[ind] = md
             # merge the citations
             newcite = {}
-            citations = docenv.domaindata["std"]["citations"]
-            for ind, (path, tag, lineno) in six.iteritems(docenv.domaindata["std"]["citations"]):
+            for ind, (path, tag, lineno) in six.iteritems(citations):
                 # TODO: Warn on conflicts
                 newcite[ind] = (fixpath(path), tag, lineno)
-            env.domaindata["std"]["citations"].update(newcite)
+            env.domaindata['std']['citations'].update(newcite)
             # merge the py:module indexes
             newmodules = {}
-            for ind,(modpath,v1,v2,v3) in (
+            for ind,(modpath,v1,v2,v3,v4) in (
                 six.iteritems(docenv.domaindata['py']['modules'])):
-                newmodules[ind] = (fixpath(modpath),v1,v2,v3)
+                newmodules[ind] = (fixpath(modpath),v1,v2,v3,v4)
             env.domaindata['py']['modules'].update(newmodules)
             logger.info(", %s modules"%(len(newmodules)))
     logger.info('... done (%s todos, %s index, %s citations, %s modules)'%(
             len(env.todo_all_todos),
-            len(env.indexentries),
-            len(env.domaindata["std"]["citations"]),
+            len(env.domaindata['index']['entries']),
+            len(env.domaindata['std']['citations']),
             len(env.domaindata['py']['modules'])))
-    write_citations(app, env.domaindata["std"]["citations"])
+    write_citations(app, env.domaindata['std']['citations'])

 def get_env(app, curdoc):
@@ -253,7 +259,7 @@ def fetch_citation(app, env):
     with open(filename, 'rb') as f:
         cache = cPickle.load(f)
     logger.info("done (%s citations)."%len(cache))
-    cite = env.domaindata["std"]["citations"]
+    cite = env.domaindata["std"].get("citations", dict())
     for ind, (path, tag, lineno) in six.iteritems(cache):
         if ind not in cite: # don't override local citation
             cite[ind] = (os.path.join("..", path), tag, lineno)
--- a/src/sage_setup/docbuild/ext/sage_autodoc.py
+++ b/src/sage_setup/docbuild/ext/sage_autodoc.py
@@ -35,14 +35,15 @@ import sys
 from docutils.statemachine import ViewList

 import sphinx
-from sphinx.ext.autodoc.importer import mock, import_object, get_object_members
+from sphinx.ext.autodoc import mock
+from sphinx.ext.autodoc.importer import import_object, get_object_members, get_module_members
 from sphinx.locale import _, __
 from sphinx.pycode import ModuleAnalyzer
 from sphinx.errors import PycodeError
 from sphinx.util import logging
 from sphinx.util import rpartition, force_decode
 from sphinx.util.docstrings import prepare_docstring
-from sphinx.util.inspect import isdescriptor, safe_getmembers, \
+from sphinx.util.inspect import isdescriptor, \
     safe_getattr, object_description, is_builtin_class_method, \
     isenumattribute, isclassmethod, isstaticmethod, getdoc

@@ -536,7 +537,7 @@ class Documenter(object):

         # add content from docstrings
         if not no_docstring:
-            encoding = self.analyzer and self.analyzer.encoding
+            encoding = self.analyzer and self.analyzer._encoding
             docstrings = self.get_doc(encoding)
             if not docstrings:
                 # append at least a dummy docstring, so that the event
@@ -882,7 +883,7 @@ class ModuleDocumenter(Documenter):
             if not hasattr(self.object, '__all__'):
                 # for implicit module members, check __module__ to avoid
                 # documenting imported objects
-                return True, safe_getmembers(self.object)
+                return True, get_module_members(self.object)
             else:
                 memberlist = self.object.__all__
                 # Sometimes __all__ is broken...
@@ -893,7 +894,7 @@ class ModuleDocumenter(Documenter):
                         '(in module %s) -- ignoring __all__' %
                         (memberlist, self.fullname))
                     # fall back to all members
-                    return True, safe_getmembers(self.object)
+                    return True, get_module_members(self.object)
         else:
             memberlist = self.options.members or []
         ret = []
antonio-rojas commented 4 years ago
comment:33

Replying to @kiwifb:

Well, that's some progress I guess. I think we should move this ticket milestone to 9.2 and make it "upgrade to sphinx 3", that would be more honest because I don't think we can keep it compatible with sphinx-1.8 at the same time.

That seems totally reasonable to me - it's too late for 9.1, and I hope nobody will object to move on to py3-only for 9.2

antonio-rojas commented 4 years ago

Changed branch from u/gh-timokau/sphinx-2.1-support to u/arojas/sphinx-2.1-support

antonio-rojas commented 4 years ago

Changed commit from 447b6b0 to 7041a6b

antonio-rojas commented 4 years ago

Changed author from Timo Kaufmann to Timo Kaufmann, John Palmieri, François Bissey, Antonio Rojas

antonio-rojas commented 4 years ago
comment:35

I've pushed the current status to the branch. This now builds fine with -k, including references and citations.

It remains to figure out the WARNING: duplicate object description so it builds without -k (or decide that it's not important and whitelist the warning)


New commits:

2ac886aMerge remote-tracking branch 'origin/develop' into t/28856/sphinx-2.1-support
9a98405Normalize intersphinx mappings
f2087ccUpdate sphinx to 3.0.1
1fe8969Fix deprecation warnings with sphinx 3
34294f3Port away from BuildEnvironment.frompickle, removed in sphinx 3
8cc052dUse correct citation domain
0854100docenv.domaindata['py']['modules'] has one more entry in sphinx 3
7041a6bPort to index domain
mwageringel commented 4 years ago
comment:36

Replying to @antonio-rojas:

It remains to figure out the WARNING: duplicate object description so it builds without -k (or decide that it's not important and whitelist the warning)

The methods left_action_product and right_action_product actually do appear twice in the documentation, which is caused by this block:

    .. automethod:: Permutation.left_action_product
    .. automethod:: Permutation.right_action_product

In the past, this block was referencing private functions _left_to_right_multiply_on_right/_left_to_right_multiply_on_left, so the automethod directive was used to make those underscore functions appear in the documentation. Since these functions are not private anymore and appear in the documentation by default, this block is not needed anymore and removing it should solve the problem I hope.

antonio-rojas commented 4 years ago
comment:37

Removing those lines does indeed fix this warning. But then compilation stops a while later with another warning:

OSError: /build/sagemath-doc/src/sage-9.0/src/doc/en/thematic_tutorials/structures_in_coding_theory.rst:722: WARNING: Could not lex literal_block as "python". Highlighting skipped.
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Branch pushed to git repo; I updated commit sha1. New commits:

0705982fix WARNING: duplicate object description
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Changed commit from 7041a6b to 0705982

tobihan commented 4 years ago
comment:39

Thanks for the patch. I tried it with sphinx 2.4.3 which is what we have in Debian now. It failed with the following error:

[dochtml] [reference] Merging environment/index files...
[dochtml] [reference] Exception occurred:
[dochtml] [reference]   File "/home/thansen/src/sage/sagemath/sagemath/sage/src/sage_setup/docbuild/ext/multidocs.py", line 105, in merge_environment
[dochtml] [reference]     for ind,(modpath,v1,v2,v3,v4) in (
[dochtml] [reference] ValueError: not enough values to unpack (expected 5, got 4)

Do I have to change anything for sphinx 2.4? Which command are you running with -k?

antonio-rojas commented 4 years ago
comment:40

Replying to @tobihan:

Thanks for the patch. I tried it with sphinx 2.4.3 which is what we have in Debian now. It failed with the following error:

[dochtml] [reference] Merging environment/index files...
[dochtml] [reference] Exception occurred:
[dochtml] [reference]   File "/home/thansen/src/sage/sagemath/sagemath/sage/src/sage_setup/docbuild/ext/multidocs.py", line 105, in merge_environment
[dochtml] [reference]     for ind,(modpath,v1,v2,v3,v4) in (
[dochtml] [reference] ValueError: not enough values to unpack (expected 5, got 4)

Do I have to change anything for sphinx 2.4? Which command are you running with -k?

Yes, the relevant sphinx change [1] is only in 3.x. For 2.4, remove the two line changes adding the v4 parameter from the patch.

The command I'm using to build the docs is python sage_setup/docbuild --no-pdf-links --mathjax all html -k

[1] https://github.com/sphinx-doc/sphinx/commit/5ff3b9dc4d07b5c324680e17b2aeaa298e619a9a

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Branch pushed to git repo; I updated commit sha1. New commits:

10c7ffdPort to todo domain
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 4 years ago

Changed commit from 0705982 to 10c7ffd

antonio-rojas commented 4 years ago
comment:42

I see the WARNING: Could not lex literal_block as "python" issue already came up in https://groups.google.com/forum/#!msg/sage-release/xcGXMuHuEOw/eqISWOiDAAAJ but, in that case, it affected python2 only.