Repository: google/jax

Issue:
Building JAX documentation raise error about jnp.array
I have tried to build JAX documentation using `sphinx-build -b html docs docs/build/html` command, error raised.

Error messages:
```
Running Sphinx v3.5.3
[autosummary] generating autosummary for: _autosummary/jax.core.ClosedJaxpr.rst, _autosummary/jax.core.Jaxpr.rst, _autosummary/jax.image.resize.rst, _autosummary/jax.image.scale_and_translate.rst, _autosummary/jax.lax.abs.rst, _autosummary/jax.lax.acos.rst, _autosummary/jax.lax.add.rst, _autosummary/jax.lax.all_gather.rst, _autosummary/jax.lax.all_to_all.rst, _autosummary/jax.lax.argmax.rst, ..., notebooks/neural_network_with_tfds_data.ipynb, notebooks/quickstart.ipynb, notebooks/score_matching.ipynb, notebooks/thinking_in_jax.ipynb, notebooks/vmapped_log_probs.ipynb, profiling.md, pytrees.md, rank_promotion_warning.rst, transformations.md, type_promotion.rst
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://numpy.org/doc/stable/objects.inv...
loading intersphinx inventory from https://docs.scipy.org/doc/scipy/reference/objects.inv...
myst v0.13.5: MdParserConfig(renderer='sphinx', commonmark_only=False, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, update_mathjax=True, enable_extensions=['dollarmath'], disable_syntax=[], url_schemes=None, heading_anchors=None, html_meta=[], footnote_transition=True, substitutions=[], sub_delimiters=['{', '}'])
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 752 source files that are out of date
updating environment: [new config] 752 added, 0 changed, 0 removed
/Users/minhoheo/jax/jax/_src/numpy/lax_numpy.py:docstring of jax._src.numpy.lax_numpy.array:1: WARNING: Inline emphasis start-string without end-string.

Extension error (sphinx_autodoc_typehints):
Handler <function process_docstring at 0x10cfe1700> for event 'autodoc-process-docstring' threw an exception (exception: unmatched ')' (<unknown>, line 1))
```

Environments:
- OS: macOS Big Sur
- python 3.8.2
- numpy: 1.20.0
- jax: 0.2.11
- jaxlib: 0.1.64



Discussion:
I don't recognize this one, and the CI doc builds don't indicate any problems: https://readthedocs.org/projects/jax/builds/

I would try updating all the doc dependencies (listed in `docs/requirements.txt`), clear the build cache and try again.
Thank you for your response!

As you mentioned, I updated all dependencies and did not work well.

So I tried again with python 3.7.9 (same as CI) and it worked fine.
I am not sure if the python version matter.
Glad it's working with Python 3.7! I build the docs locally on OSX with Python 3.8 and haven't seen any issues. Is it possible that you have a different set of dependencies installed in your 3.8 environment?
I am appreciated you tested yourself!

I have tested with new virtualenv and got errors.
(Edit: The only thing I did with new virtualenv is install to jax, jaxlib and requirements in docs/)

Here is the build command I ran to get more specific error messages.
In "docs" directory,
`python -m sphinx -T -E -W --keep-going -b html -d _build/doctrees -D jupyter_execute_notebooks=off -D language=en . _build/html`

And here is the error messages
```
Running Sphinx v3.5.3
loading translations [en]... done
making output directory... done
[autosummary] generating autosummary for: async_dispatch.rst, autodidax.ipynb, changelog.md, concurrency.rst, custom_vjp_update.md, developer.md, device_memory_profiling.md, errors.rst, faq.rst, glossary.rst, ..., notebooks/neural_network_with_tfds_data.ipynb, notebooks/quickstart.ipynb, notebooks/score_matching.ipynb, notebooks/thinking_in_jax.ipynb, notebooks/vmapped_log_probs.ipynb, profiling.md, pytrees.md, rank_promotion_warning.rst, transformations.md, type_promotion.rst
[autosummary] generating autosummary for: /Users/minhoheo/jax/docs/_autosummary/jax.core.ClosedJaxpr.rst, /Users/minhoheo/jax/docs/_autosummary/jax.core.Jaxpr.rst, /Users/minhoheo/jax/docs/_autosummary/jax.image.resize.rst, /Users/minhoheo/jax/docs/_autosummary/jax.image.scale_and_translate.rst, /Users/minhoheo/jax/docs/_autosummary/jax.lax.abs.rst, /Users/minhoheo/jax/docs/_autosummary/jax.lax.acos.rst, /Users/minhoheo/jax/docs/_autosummary/jax.lax.add.rst, /Users/minhoheo/jax/docs/_autosummary/jax.lax.all_gather.rst, /Users/minhoheo/jax/docs/_autosummary/jax.lax.all_to_all.rst, /Users/minhoheo/jax/docs/_autosummary/jax.lax.argmax.rst, ..., /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.norm.pdf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.norm.ppf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.pareto.logpdf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.pareto.pdf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.poisson.logpmf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.poisson.pmf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.t.logpdf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.t.pdf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.uniform.logpdf.rst, /Users/minhoheo/jax/docs/_autosummary/jax.scipy.stats.uniform.pdf.rst
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://numpy.org/doc/stable/objects.inv...
loading intersphinx inventory from https://docs.scipy.org/doc/scipy/reference/objects.inv...
myst v0.13.5: MdParserConfig(renderer='sphinx', commonmark_only=False, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, update_mathjax=True, enable_extensions=['dollarmath'], disable_syntax=[], url_schemes=None, heading_anchors=None, html_meta=[], footnote_transition=True, substitutions=[], sub_delimiters=['{', '}'])
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 60 source files that are out of date
updating environment: [new config] 753 added, 0 changed, 0 removed
/Users/minhoheo/jax/jax/_src/numpy/lax_numpy.py:docstring of jax._src.numpy.lax_numpy.array:1: WARNING: Inline emphasis start-string without end-string.

Traceback (most recent call last):
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/events.py", line 111, in emit
    results.append(listener.handler(self.app, *args))
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx_autodoc_typehints.py", line 376, in process_docstring
    type_hints = get_all_type_hints(obj, name)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx_autodoc_typehints.py", line 231, in get_all_type_hints
    rv = backfill_type_hints(obj, name)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx_autodoc_typehints.py", line 272, in backfill_type_hints
    obj_ast = ast.parse(textwrap.dedent(inspect.getsource(obj)), **parse_kwargs)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/ast.py", line 47, in parse
    return compile(source, filename, mode, flags,
  File "<unknown>", line 1
    lambda x, out=None: _isposneginf(-inf, x, out))
                                                  ^
SyntaxError: unmatched ')'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/cmd/build.py", line 280, in build_main
    app.build(args.force_all, filenames)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/application.py", line 352, in build
    self.builder.build_update()
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 296, in build_update
    self.build(to_build,
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 310, in build
    updated_docnames = set(self.read())
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 417, in read
    self._read_serial(docnames)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 438, in _read_serial
    self.read_doc(docname)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 478, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/io.py", line 221, in read_doc
    pub.publish()
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/core.py", line 217, in publish
    self.document = self.reader.read(self.source, self.parser,
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/io.py", line 126, in read
    self.parse()
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/readers/__init__.py", line 77, in parse
    self.parser.parse(self.input, document)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/parsers.py", line 104, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 170, in run
    results = StateMachineWS.run(self, input_lines, input_offset,
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2344, in explicit_markup
    self.explicit_list(blank_finish)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2369, in explicit_list
    newline_offset, blank_finish = self.nested_list_parse(
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 318, in nested_list_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2647, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/ext/autodoc/directive.py", line 167, in run
    documenter.generate(more_content=self.content)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 967, in generate
    self.add_content(more_content)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 628, in add_content
    for i, line in enumerate(self.process_doc(docstrings)):
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 569, in process_doc
    self.env.app.emit('autodoc-process-docstring',
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/application.py", line 462, in emit
    return self.events.emit(event, *args, allowed_exceptions=allowed_exceptions)
  File "/Users/minhoheo/test_doc/lib/python3.8/site-packages/sphinx/events.py", line 119, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <function process_docstring at 0x113405430> for event 'autodoc-process-docstring' threw an exception (exception: unmatched ')' (<unknown>, line 1))

Extension error (sphinx_autodoc_typehints):
Handler <function process_docstring at 0x113405430> for event 'autodoc-process-docstring' threw an exception (exception: unmatched ')' (<unknown>, line 1))
```

Here is Python version
```
Python 3.8.2 (default, Dec 21 2020, 15:06:04) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
```

And here is pip list
```
Package                       Version
----------------------------- ---------
absl-py                       0.12.0
alabaster                     0.7.12
apipkg                        1.5
appnope                       0.1.2
argon2-cffi                   20.1.0
async-generator               1.10
attrs                         20.3.0
Babel                         2.9.0
backcall                      0.2.0
bleach                        3.3.0
certifi                       2020.12.5
cffi                          1.14.5
chardet                       4.0.0
colorama                      0.4.4
cycler                        0.10.0
decorator                     4.4.2
defusedxml                    0.7.1
docutils                      0.16
entrypoints                   0.3
execnet                       1.8.0
flatbuffers                   1.12
gitdb                         4.0.7
GitPython                     3.1.14
idna                          2.10
imagesize                     1.2.0
importlib-metadata            3.9.1
iniconfig                     1.1.1
ipykernel                     5.5.0
ipython                       7.22.0
ipython-genutils              0.2.0
ipywidgets                    7.6.3
jax                           0.2.11
jaxlib                        0.1.64
jedi                          0.18.0
Jinja2                        2.11.3
joblib                        1.0.1
jsonschema                    3.2.0
jupyter-cache                 0.4.2
jupyter-client                6.1.12
jupyter-core                  4.7.1
jupyter-sphinx                0.3.1
jupyterlab-widgets            1.0.0
kiwisolver                    1.3.1
markdown-it-py                0.6.2
MarkupSafe                    1.1.1
matplotlib                    3.4.0
mdit-py-plugins               0.2.6
mistune                       0.8.4
myst-nb                       0.12.0
myst-parser                   0.13.5
nbclient                      0.5.3
nbconvert                     5.6.1
nbdime                        2.1.0
nbformat                      5.1.2
nest-asyncio                  1.5.1
notebook                      6.3.0
numpy                         1.20.2
opt-einsum                    3.3.0
packaging                     20.9
pandocfilters                 1.4.3
parso                         0.8.1
pexpect                       4.8.0
pickleshare                   0.7.5
Pillow                        8.1.2
pip                           21.0.1
pluggy                        0.13.1
prometheus-client             0.9.0
prompt-toolkit                3.0.18
ptyprocess                    0.7.0
py                            1.10.0
pycparser                     2.20
Pygments                      2.8.1
pyparsing                     2.4.7
pyrsistent                    0.17.3
pytest                        6.2.2
pytest-forked                 1.3.0
pytest-xdist                  2.2.1
python-dateutil               2.8.1
pytz                          2021.1
PyYAML                        5.4.1
pyzmq                         22.0.3
requests                      2.25.1
scikit-learn                  0.24.1
scipy                         1.6.2
Send2Trash                    1.5.0
setuptools                    41.2.0
six                           1.15.0
sklearn                       0.0
smmap                         4.0.0
snowballstemmer               2.1.0
Sphinx                        3.5.3
sphinx-autodoc-typehints      1.11.1
sphinx-rtd-theme              0.5.1
sphinx-togglebutton           0.2.3
sphinxcontrib-applehelp       1.0.2
sphinxcontrib-devhelp         1.0.2
sphinxcontrib-htmlhelp        1.0.3
sphinxcontrib-jsmath          1.0.1
sphinxcontrib-qthelp          1.0.3
sphinxcontrib-serializinghtml 1.1.4
SQLAlchemy                    1.3.23
terminado                     0.9.4
testpath                      0.4.4
threadpoolctl                 2.1.0
toml                          0.10.2
tornado                       6.1
traitlets                     5.0.5
urllib3                       1.26.4
wcwidth                       0.2.5
webencodings                  0.5.1
wheel                         0.36.2
widgetsnbextension            3.5.1
zipp                          3.4.1
```
Looks quite similar to this bug: https://github.com/agronholm/sphinx-autodoc-typehints/issues/148
Thanks for searching. Yes indeed it is similar.
But it seems that there is no direct solution for this kind of issue.
And since it's working with Python 3.7, so maybe it would be better to close this issue?
Or leave it open? How do you think?

I just hit this error in Python 3.8 on OSX. I'm not sure what changed in my environment
#6318 addresses the new warning you saw above with numpy 1.20
I suspect this is why it works in 3.7 but not in 3.8: https://github.com/agronholm/sphinx-autodoc-typehints/blob/49face656c51e370b68108a4a59c7032ed398a2e/sphinx_autodoc_typehints.py#L290-L299
Ah, the culprit is the inspect module:
```python
>>> import sys; sys.version_info                                                                                                                                                 
sys.version_info(major=3, minor=8, micro=2, releaselevel='final', serial=0)

>>> import jax.numpy as jnp

>>> import inspect                                                                                                                                                               

>>> inspect.getsource(jnp.isposinf)                                                                                                                                              
'  lambda x, out=None: _isposneginf(inf, x, out))\n'
```
I sent a fix in https://github.com/agronholm/sphinx-autodoc-typehints/pull/168; it looks like there's been some activity in the repo over the last week or two, so hopefully this fix can be put into a release soon!

Resolving patch:
diff --git a/jax/_src/numpy/lax_numpy.py b/jax/_src/numpy/lax_numpy.py
--- a/jax/_src/numpy/lax_numpy.py
+++ b/jax/_src/numpy/lax_numpy.py
@@ -1928,10 +1928,12 @@ def _isposneginf(infinity, x, out):
     return full_like(x, False, dtype=bool_)
 
 isposinf = _wraps(np.isposinf, skip_params=['out'])(
-  lambda x, out=None: _isposneginf(inf, x, out))
+  lambda x, out=None: _isposneginf(inf, x, out)
+)
 
 isneginf = _wraps(np.isneginf, skip_params=['out'])(
-  lambda x, out=None: _isposneginf(-inf, x, out))
+  lambda x, out=None: _isposneginf(-inf, x, out)
+)
 
 @_wraps(np.isnan)
 def isnan(x):
diff --git a/jax/_src/numpy/util.py b/jax/_src/numpy/util.py
--- a/jax/_src/numpy/util.py
+++ b/jax/_src/numpy/util.py
@@ -21,6 +21,7 @@
 _section_break = re.compile(r"\n(?=[^\n]{3,15}\n-{3,15})", re.MULTILINE)
 _numpy_signature_re = re.compile(r'^([\w., ]+=)?\s*[\w\.]+\([\w\W]*?\)$', re.MULTILINE)
 _versionadded = re.compile(r'^\s+\.\.\s+versionadded::', re.MULTILINE)
+_docreference = re.compile(r':doc:`(.*?)\s*<.*?>`')
 
 class ParsedDoc(NamedTuple):
   """
@@ -48,6 +49,10 @@ def _parse_numpydoc(docstr: Optional[str]) -> ParsedDoc:
   if docstr is None or not docstr.strip():
     return ParsedDoc(docstr)
 
+  # Remove any :doc: directives in the docstring to avoid sphinx errors
+  docstr = _docreference.sub(
+    lambda match: f"{match.groups()[0]}", docstr)
+
   signature, body = "", docstr
   match = _numpy_signature_re.match(body)
   if match:


Test patch: