Repository navigation
DOC: solve_discrete_riccati_system is missing from the API docs, and its deprecation warning points to an import that fails #987
Description
Summary
docs/source/tools/matrix_eqn.rst documents solve_discrete_riccati_system under .. currentmodule:: quantecon, but quantecon/__init__.py does not import that function. Autodoc therefore cannot import it, so the function has no entry in the built API docs, and the build still succeeds. Separately, the deprecated quantecon.matrix_eqn shim tells users to write from quantecon import solve_discrete_riccati_system, which raises ImportError. Adding the name to the existing import in quantecon/__init__.py fixes both problems. Editing the generated .rst by hand would fail CI.
What the code does
docs/source/tools/matrix_eqn.rst#L4-L10:
.. currentmodule:: quantecon
...
.. autofunction:: solve_discrete_riccati_systemquantecon/__init__.py#L45 imports only two of the three functions:
from ._matrix_eqn import solve_discrete_lyapunov, solve_discrete_riccatiThe shim's warning, quantecon/matrix_eqn.py#L25-L28:
warnings.warn(f"Please use `{name}` from the `quantecon` namespace, the "
"`quantecon.matrix_eqn` namespace is deprecated. You can use"
f" the following instead:\n `from quantecon import {name}`.",
category=DeprecationWarning, stacklevel=2)I built main's docs locally with Sphinx 7.4.7 and numpydoc 1.10.0, using the repo's conf.py with two changes: alabaster in place of sphinx_rtd_theme (not installed here) and intersphinx turned off. The build gives:
WARNING: autodoc: failed to import function 'solve_discrete_riccati_system' from module 'quantecon'; the following exception was raised:
...
AttributeError: module 'quantecon' has no attribute 'solve_discrete_riccati_system'. Did you mean: 'solve_discrete_riccati'?
The built tools/matrix_eqn.html documents only quantecon.solve_discrete_lyapunov and quantecon.solve_discrete_riccati. Sphinx still reports build succeeded, 6 warnings. and exits 0. Nothing flags the missing entry: CI builds without -W (ci.yml#L145-L147), and .readthedocs.yaml sets no fail_on_warning. Read the Docs builds the same committed stub. I have not checked the live page (https://quanteconpy.readthedocs.io/en/latest/tools/matrix_eqn.html), which would confirm this.
The other five warnings are the same failure for five more names: ckron and gridmake (the tools/ce_util page has no entries at all), annotate_nodes, num_compositions_jit and simulate_linear_model. Their shims give the same from quantecon import ... advice, and it fails for each of them.
Reproducer
import warnings
import quantecon as qe
import quantecon.matrix_eqn
print(qe.__version__)
print(hasattr(qe, "solve_discrete_riccati_system"))
# The deprecated shim still works, and says where to import it from instead
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
quantecon.matrix_eqn.solve_discrete_riccati_system
print(w[0].category.__name__ + ":", w[0].message)
# Following that advice fails
try:
from quantecon import solve_discrete_riccati_system
print("import works")
except ImportError as e:
print("ImportError:", str(e).split(" (")[0]) # drop the local file pathOutput on main (70fa215, Python 3.13.14):
0.13.0
False
DeprecationWarning: Please use `solve_discrete_riccati_system` from the `quantecon` namespace, the `quantecon.matrix_eqn` namespace is deprecated. You can use the following instead:
`from quantecon import solve_discrete_riccati_system`.
ImportError: cannot import name 'solve_discrete_riccati_system' from 'quantecon'
Suggested fix
Export the function in quantecon/__init__.py#L45:
from ._matrix_eqn import solve_discrete_lyapunov, solve_discrete_riccati, \
solve_discrete_riccati_systemquantecon has never exported this function, so this adds a public name, which is an API decision for the maintainers. It changes no existing outputs or tests. I checked this on a scratch branch of main with only this change:
- The reproducer prints
Trueandimport works, so the shim's advice becomes correct without changing the shim. - The committed stub works unchanged. The docs build documents
quantecon.solve_discrete_riccati_system, and the warnings drop to 5 (the five names above). cd docs && python qe_apidoc.pyleavesdocs/sourceunchanged, andflake8 --select=F401,F405,E231 quanteconis clean.pytest quanteconcollects the same 767 tests as main. All of them pass except the threefetch_nb_dependenciestests inquantecon/util/tests/test_notebooks.py. Those tests download from github.com, which my offline sandbox blocks, and they fail the same way on unmodified main.
Pointing the .rst at quantecon._matrix_eqn by hand does not work, because the files in docs/source are generated. write_base_module in docs/qe_apidoc.py#L275-L281 writes one directive under currentmodule:: quantecon for each name in a shim's __all__. CI reruns the script and fails on any difference (ci.yml#L127-L144). I committed that hand edit on a scratch branch and replayed both CI steps. qe_apidoc.py restored .. autofunction:: solve_discrete_riccati_system, and the drift step failed with ::error::docs/source is stale. make html also reruns qe_apidoc.py first (docs/Makefile#L78-L80).
If the maintainers would rather not add a public name, a docs-only fix has to go in write_base_module. For names that quantecon/__init__.py does not import, it would fall back to quantecon._<module>.<name>; it can find those names with ast, the same way it already reads __all__. The stubs are then regenerated. A scratch prototype rewrote 5 stubs, passed the drift check once they were committed, and built with 0 warnings. Two drawbacks remain: the entry is then titled quantecon._matrix_eqn.solve_discrete_riccati_system, and the shim's advice still fails.
Context
Found while verifying #984, the fix for #982. The stub has used currentmodule:: quantecon since c58ded5 (#850, first released in v0.11.3); the earlier automodule:: quantecon.matrix_eqn stub with :members: documents all three functions when built against main's code.
🤖 Generated with Claude Code
Activity