-
Notifications
You must be signed in to change notification settings - Fork 278
Class parameter documentation inheritance #1518
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
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1518 +/- ##
===========================================
- Coverage 86.24% 42.57% -43.67%
===========================================
Files 396 345 -51
Lines 50329 44265 -6064
Branches 5308 4971 -337
===========================================
- Hits 43405 18847 -24558
- Misses 5473 24292 +18819
+ Partials 1451 1126 -325 ☔ View full report in Codecov by Sentry. |
I've been thinking a bit more about where this functionality should live, and it seems like it really should be it's own package, mostly because I want to use its functionality independent of
|
Would now use another package to do this
Summary
Adds the ability to inherit information from a parent class's documentation and correspondingly update the class's call signature.
PR Checklist
expect style.
to a Pull Request
@simpeg/simpeg-developers
when ready for review.Reference issue
Relevant to #1420
What does this implement/fix?
Documentation implementation
Adds a mechanism to inherit documentation descriptions from parent classes. This avoids us having to copy and paste documentation code for each parameter into every single subclass. For example, we can write the description of the
mesh
parameter in one place, then make use of that in every child class. Or, we can access all of the other parameters that are less likely to be used from a parent class. It also then updates the call signature of the class's__init__
function to match the description in the documentation.As of right now, my proposed syntax for this is demonstrated in the few classes I've added this to.
The docstring for
LinearSimulation
as coded:https://github.com/jcapriot/simpeg/blob/17f934d7b25e7669dd483788f50f366b63ad224c/simpeg/simulation.py#L717-L758
Essentially the
%(....)
triggers a replacement on the docstring when the@doc_inherit()
decorator is attached to the class. Specifically a%(super.item)
triggers a lookup for the description of an argument nameditem
in the next class that describesitem
in the class's inheritance tree.%(module.ClassName.item)
would trigger a lookup foritem
specifically in the importable classmodule.ClassName
, and%(super.*)
would trigger an inclusion of every parameter from the class's inheritance tree (that is not already documented on this class already (you could also trigger this from a specific class as%(module.ClassName.*)
). There is also an option to specifically exclude parameters from the star include operation, as seen in theLinearSimulation
excluding thesolver
andsolver_opts
parameters.After the replacements the
LinearSimulation
docstring looks like:Because we have included a
%(super.*)
lookup, it doesn't include a**kwargs
description.Call signatures
Updating the documentation is nice... But it doesn't enable tab completion on most editors, or type inference, and it doesn't make the default values for optional arguments shown in the call signature. But that's the key there, you can specifically set a function's
__signature__
property to change it's call signature.So the next bit of this replacement appropriately updates the functions call signature to add the items that were included from elsewhere (that were not already part of it's call signature). This parameters are only allowed as keyword arguments, and are marked as such when added to the call signature. They are added in the order they are added to the documentation.
Now inspecting the loaded

LinearSimulation
class in a jupyter notebook we see it's description as:Tab completion in a notebook shows all of the added parameters:

The generated documentation page:

Additional information
This relies on the classes implementing the
numpydoc
style doc strings. It will search for descriptions in parents that are described in either theParamaters
orOther Parameters
sections.This spirit of this was inspired by
matplotlib
, where they automatically populate their docstrings with the multitude of parameters that their classes take.Unfortunately this does not (and cannot) effect IDE's that perform a static analysis of the written code (i.e. pycharm). But the interactive functionality is very welcome, and the static analysis is not any different than it currently is. We could generate
.pyi
files for these classes using a utility function (that could be hooked into pre-commit?) that would enable type inspection for static analyzers. I haven't looked into this too much though, just quickly tested it as a proof of concept that pycharm would look at the .pyi file and pull the signature and documentation from there (which it does).With the amount of times I felt like I wanted to add the decorator to classes, it might be better served as a
metaclass
that all simpeg classes will have access to.