Open hamelsmu opened 1 year ago
quartodoc doesn't support dynamic being set to true on the section (though it could!), and pydantic unfortunately is happy to accept extra fields and then discard them 😬.
Does it work if you set dynamic at the top-level (right under quartodoc) or for the individual content entries?
https://machow.github.io/quartodoc/get-started/basic-docs.html#top-level-options
https://machow.github.io/quartodoc/get-started/basic-content.html#dynamic-lookup
I wonder if we can set pydantic to be strict and not silently drop extra fields 🤔
If I set dynamic: true
on the invidiual content entry, it still doesn't render properly. Concretely, it doesn't show the signature
project:
type: website
website:
title: "."
navbar:
left:
- href: index.qmd
text: Home
- about.qmd
format:
html:
theme: cosmo
css: styles.css
toc: true
# tell quarto to read the generated sidebar
metadata-files:
- _sidebar.yml
quartodoc:
# the name used to import the package
package: modal
# write sidebar data to this file
sidebar: _sidebar.yml
sections:
- title: Documentation utilities
desc: Utilities for documentation.
contents:
- functions
- name: web_endpoint
contents: [functions.web_endpoint]
dynamic: true
Ah, web_endpoint
is created too dynamically for the relatively simple way we dynamically load docstrings. If they used decorators, then it would work...
# Currently unsupported, doesn't know web_endpoint is a function ----
@typechecked
def _web_endpoint(*args, **kwargs): ...
web_endpoint = synchronize_api(_web_endpoint)
# Supported ----
@synchronize_api
@typechecked
def web_endpoint(*args, **kwargs): ...
It looks like a special tool for dynamic loading, called the griffe Inspector can load it. Ideally, we shift to using this for dynamic loading (and contribute upstream for any funky cases):
from griffe.agents.inspector import inspect
mod = inspect("modal.functions")
# griffe Function object
obj = mod.members["web_endpoint"]
obj.docstring.value
Note that AFAICT the griffe Inspector doesn't work for packages like plotnine, so we may need to do a bit of research:
# this took ~15 seconds to run on my laptop
mod = inspect("plotnine")
"ggplot" in mod.members # False
# It seems to be in the correct submodule though
# it looks like the griffe inspector may not do Alias objects
mod = inspect("plotnine.ggplot")
mod.members["ggplot"]
There are lots of objects in plotnine so yeah, loading every module in memory and inspecting every member is quite demanding. A very small part of the logs (I added a print statement in the inspector):
% python -c 'from griffe.agents.inspector import inspect; inspect("plotnine")' | wc -l
253418
Maybe we could drastically reduce this if we didn't inspect __class__
and its potential __bases__
. But IMO that's just the disadvantage of the inspector over the visitor.
Hmmm, we might find some possible optimizations though:
inspecting plotnine.geom_area
inspecting plotnine.geom_area.DEFAULT_AES
inspecting plotnine.geom_area.DEFAULT_PARAMS
inspecting plotnine.geom_area.NON_MISSING_AES
inspecting plotnine.geom_area.REQUIRED_AES
inspecting plotnine.geom_area.__annotations__
inspecting plotnine.geom_area.__base__
inspecting plotnine.geom_area.__base__.DEFAULT_AES
inspecting plotnine.geom_area.__base__.DEFAULT_PARAMS
inspecting plotnine.geom_area.__base__.NON_MISSING_AES
inspecting plotnine.geom_area.__base__.REQUIRED_AES
inspecting plotnine.geom_area.__base__.__annotations__
inspecting plotnine.geom_area.__base__.__base__
inspecting plotnine.geom_area.__base__.__base__.DEFAULT_AES
inspecting plotnine.geom_area.__base__.__base__.DEFAULT_PARAMS
inspecting plotnine.geom_area.__base__.__base__.NON_MISSING_AES
inspecting plotnine.geom_area.__base__.__base__.REQUIRED_AES
inspecting plotnine.geom_area.__base__.__base__.__annotations__
inspecting plotnine.geom_area.__base__.__base__.__class__
inspecting plotnine.geom_area.__base__.__base__.__class__.__abstractmethods__
inspecting plotnine.geom_area.__base__.__base__.__class__.__annotations__
inspecting plotnine.geom_area.__base__.__base__.__class__.__bases__
inspecting plotnine.geom_area.__base__.__base__.__class__.__basicsize__
inspecting plotnine.geom_area.__base__.__base__.__class__.__call__
inspecting plotnine.geom_area.__base__.__base__.__class__.__class__
inspecting plotnine.geom_area.__base__.__base__.__class__.__class__.__abstractmethods__
inspecting plotnine.geom_area.__base__.__base__.__class__.__class__.__annotations__
inspecting plotnine.geom_area.__base__.__base__.__class__.__class__.__bases__
inspecting plotnine.geom_area.__base__.__base__.__class__.__class__.__basicsize__
Actually the just-merged inheritance support feature will help :slightly_smiling_face:
With Griffe installed from main branch:
% python -c 'from griffe.agents.inspector import inspect; inspect("plotnine")' | wc -l
5995
Ah, thanks! I've been digging more into how griffe and sphinx do dynamic inspection, and should have more bandwidth to contribute to the dynamic inspect stuff after scipy next week!
I'm trying to dynamically document modal.functions.web_endpoint. Here is the yaml
In Ipython you can see the help just fine
However nothing is rendered in
quartodoc
To repro, checkout the
modal
branch of this repo, and runquartodoc build
followed byquarto preview