-
-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug: Typing.Overload from pyi file not showing in generated docs #182
Comments
Hi @nvoxland-al, thanks for the report! Without the implementation, Griffe indeed doesn't know where to attach the overloads (and they are simply never used by mkdocstrings-python). I see two solutions:
I would love to get your feedback on the second solution |
Just rendering the overloads as regular functions is not possible because they share the same name/path, and we can't have members with the same name, by design, either in Griffe or in the object inventories generated by mkdocstrings. Happy to hear about any other solution you can think of! |
Thanks for the followup, @pawamoy . You are saying that the way it overall works is that while regular methods can be picked out from the .pyi files, for overloaded methods it needs to look at the actual available method implementations? And those actual methods can either be in python files, or via an installed native module? Because the docs show correctly for all the regular methods documented in the .pyi files when those are all that mkdocstrings can see. For option 1: I was hoping to avoid having to build the c++ module in order to manage the docs. We have people we'd like to help with the docs who won't have the whole c++ build environment available. So I'd like to avoid that. For option 2: If we did have the overloaded methods in py files instead of .pyi the docs would have shown correctly? If you are generating fake implementations based on what you see in the pyi files are you able to use the signatures from there as if we had specified the different overload methods in the py files? |
The data provenance (.pyi or .py files) actually doesn't matter: we load from both and merge data together. The issue here is that only the overloads are available, and not the implementation (for legitimate reasons, as you explained). And overloads have to be attached to a Function object in order for mkdocstrings to render them. This Function object is supposed to represent the implementation, which we don't have here. In short, with only the overload signatures, Griffe has incomplete data that mkdocstrings doesn't know how to render. Since you'd like to avoid building the C++ module, let's go with a fake implementation and an empty signature, which will be the least incorrect or confusing thing to show to readers. I'll send you some code tomorrow for a Griffe extension that you'll be able to use locally (without having to publish it on PyPI) :) |
You could try something like this: # griffe_exts.py
from typing import Any
import griffe
class FixOrphanOverloads(griffe.Extension):
"""Dispatch remaining overloads to their respective functions."""
def _dispatch_overloads(self, mod_or_cls: griffe.Module | griffe.Class) -> None:
for name, overloads in mod_or_cls.overloads.items():
if overloads:
try:
function: griffe.Function = mod_or_cls.members[name] # type: ignore[assignment]
except KeyError:
function = griffe.Function(name)
mod_or_cls.set_member(name, function)
function.overloads = overloads
del mod_or_cls.overloads[name]
def on_module_members(self, *, mod: griffe.Module, **kwargs: Any) -> None: # noqa: ARG002
"""Dispatch remaining overloads to their respective functions."""
self._dispatch_overloads(mod)
def on_class_members(self, *, cls: griffe.Class, **kwargs: Any) -> None: # noqa: ARG002
"""Dispatch remaining overloads to their respective functions."""
self._dispatch_overloads(cls) Put that code in a file somewhere and load it in mkdocs.yml: plugins:
- mkdocstrings:
handlers:
python:
options:
extensions:
- path/to/griffe_exts.py With this, your overloads should start showing up. Note however that overload support is still pretty basic, you can subscribe to this issue: #135. |
Thanks @pawamo, sorry it took me a while to get back to you. Back on the documentation focus now... When I add your extension, it fails with this error:
Where my copy of your extension is at To control the order and structure of the md file, I'm specifying the classes to render, sort of like this:
Any idea of what is causing the error? |
Right, just need to iterate on a copy of the dict to prevent this error :) for ... in dict(....items()):
... |
Thanks. Putting it as With my setup using the griffle overload to generate the fake implementation, do I have an ability to custom blend the content from each of the overloaded versions into the single generated function? It seems to work in theory with the docstring but not parameters? If I modify my function to:
my generated docs has "Generated Docstring" after my signatures (I'm using separate_signature: True) but the parameters don't show. Is there a way to attach generated parameters and examples the generated function like that? |
I maybe spoke a bit too soon. I think I see what's going on... Even in your example, the docs now generate an additional version of the function with no arguments (because we are generating And in my example with the BUT: is there a way to make that stub implementation object not show up in the docs? Is I did try just using the function from the 1st overload as the actual function:
but then I get a duplicate version of one of the signatures. |
It should be possible yes, but as noted earlier: "Griffe is not able to combine multiple signatures into one (it's typing territory and probably far from trivial)". You are of course free to try anyway to combine parameters from all overloads into the fake implementation 🙂 If you add parameters to the function manually, you still have to reference them in the docstring for them to be rendered. You can either use a specific docstring style (google, numpydoc, sphinx) and set the function docstring's function.docstring.parsed.append(griffe.DocstringSectionParameters(...))
I wonder: instead of creating a fake implementation, then hiding it from the docs, couldn't you simply declare your real implementation signature in the .pyi file, with an ellipsis as body? @overload
def function(...) -> ...: ...
@overload
def function(...) -> ...: ...
# signature of the implementation
def function(...) -> ...: ... I believe this would not overwrite the actual implementation for users, and this would provide correct information to both Griffe and type-checkers. Though maybe you'd still want to hide the implementation signature from the docs? |
Yes, I'd still want to hide the implementation signature from the docs. I just want the users to see the overloaded variations. Is there a way to mark the implementation function signature as hidden from the docs? Or to even programmatically exclude certain signatures from being rendered in the docs via an extension? |
I see, thanks. Sounds like a valid request. I'll think about implementing an option for it.
You could override templates and make use of Griffe objects' |
Yes, that does generate the docs correctly, and probably easier to manage for us than programmatically generating the stub master version.
Thanks, I'll take a look at that |
I opened this feature request: #213. Please upvote to push it higher in our backlog 😄 Closing this issue since there's nothing actionable and a solution to the original issue was provided (add an implementation after the overloads in the stubs file). |
Description of the bug
I have methods defined with
@typing.overload
but they are not showing up in the generated docs. Other methods show up fine, but not the overload ones. There are no warnings. I am using the insiders version of mkdocstring-python and griffeMy docs are generated from definitions like this in my pyi file:
NOTE: There is not any backing .py file because this is a wrapper around a c++ python module. So the mkdocstrings generation is purely going against the .pyi files.
To Reproduce
.pyi file with the definitions above
Expected behavior
Expect the overloaded methods to show in the docs
Environment information
mkdocs
v1.6.0mkdocstrings
v0.25.2mkdocstrings-python
v1.10.8.1.8.3griffe
v0.49.0.1.2.1.dev2+g5d4e082Additional context
The text was updated successfully, but these errors were encountered: