Autodoc Inheritance - Don't show members from 'Object' - python

I'm using autodoc to document some classes and so far, :members:, :private-members:, and :special-members: get me exactly what I want. However, I would also like to see members that are inherited.
There is an additional option, :inherited-members:, which gives me all those things I want... And a bunch of other crap I don't want, because it shows members inherited from Object.
Is there a way to get it to ignore members inherited from certain parents, or to only follow the inheritance chain as far up as my own defined classes, not ones that are built-in?

It'll be possible in Sphinx 3: https://github.com/sphinx-doc/sphinx/issues/5923

Related

Sphinx: create toc entries for each method

I am using sphinx-autodoc for documenting a class. I want the methods of the class to correspond to individual entries in the Sphinx TOC, so that they each spawn a link in the 'local TOC' sidebar.
How can I achieve this?
AFAICT, the autoclass directive does not support this. I tried to use autosummary, but I can't get that one to work either: it wants the individual methods in separate .rst files. I would rather have them all on the same page.
I guess I could manually create a section for each member like so:
Foo.bar()
---------
.. automethod:: Foo.bar
But that feels weird and unnecessarily complicated.
I wrote a sphinx plugin called autoclasstoc that does something similar to what you want. The plugin provides a directive that creates a table of links to the documentation for each method of a particular class. The links don't end up in the TOC sidebar, but they still make the class documentation much easier to navigate. It's also worth mentioning that these links can be organized into groups (e.g. public methods, private methods, etc.) and that links to inherited methods are grouped by superclass and collapsed by default.
Even though this doesn't exactly answer your question, it's a good way to achive a similar effect.

Sphinx Documentation - Exclude class variables for all the modules in the hierarchy

I'm trying to remove all the class variables from my Sphinx documentation (because I haven't documented them and it doesn't look good if there's only a list of them) for all the classes of my project including the modules in the folders.
Is there an easy way to do it without having to exclude each one of them?
P.S.: I'm a beginner at this, so the answer could be something easy. Also, this could already be answered, but I couldn't find anything.
You can use :no-undoc-members: to tell sphinx to ignore the undocumented (in your case the class) variables.
:undoc-members: (no value)
If set, autodoc will also generate document for the members not having docstrings:
Here is the documentation - https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directive-option-automodule-undoc-members

Can sphinx-apidoc include explicit docs for superclass methods?

I'm considering Sphinx for documenting Python projects. I'd like the api docs for a class to contain docs for all of the methods that can be called from the class. The default behavior seems to be to provide a links to superclasses. Thus to see all callable methods I have to click back through the inheritance tree. Docs I've seen produced by (I think) javadoc or doxygen show at least the names of all methods that can be called.
Is it possible in sphinx to display docs for local methods, and at least the names of methods defined in superclasses? To me this is desirable. Is there some reason that what I want is not such a good idea? Is there some alternative approach from within Sphinx?
Plan B will be to explore Pydoctor. Any suggestions for a Plan C, D, ... ?

sphinx autosummary and dynamic methods

I have found much use of using setattr() to make dynamically generated class methods and attributes. I have also been using sphinx to create documentation, which is fantastic.
The problem is that i cannot use the autosummary feature of sphinx if the attributes and methods are dynamic. Is there a clever way to do this? The dynamic methods and attributes are created upon initialization.
Try this (it's a little wacky):
Create an instance of your class in your conf.py file.
Use the autodoc-process-docstring event to fire a handler (which you will need to write) to copy the __doc__ elements for the various dynamic methods from the instance you created in 1) into the output for the class.
It's not a simple solution, nor easy, and heck, maybe not even possible, but it Just Might Work if you can figure out how to get things to happen at thw right time.

Is adding attributes dynamically frowned upon in Python?

In Python, you can assign an arbitrary attribute from outside the defining class:
class Profile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=140)
p = Profile()
p.age = 42
The underlying mechanism here is __dict__ attribute that maintains a dictionary of all attributes.
We were all told not to expose our inner workings to the client code, but attaching new data doesn't have to do with encapsulation at all, right? Is this idiom common for Python code?
Just What I Mean…
Each Tweet has standard fields, like id, text, owner.
When returning tweet list for a user, you want to display if a tweet is “favorited” by this user.
Obviously, to obtain is_favorite you need to query many-to-many relationship for this user.
Would it be OK to pre-fill Tweet objects with is_favorite corresponding to current user?
Sure I could expose a method is_favorite_for(user) but I'm hitting Django template language limitations that doesn't allow to call methods with arguments from inside the template. Also, I believe a template should not be calling methods at all.
I know this will work fine, but I wonder if doing something like that in an open source project would get other developers to look on me with contempt.
Sidenote:
I come from C#/.NET background where dynamic types were introduced very recently and aren't adapted widely except for some niche areas (interoperability, IoC frameworks, REST client frameworks, etc).
My view is that it is a bad practice.
The object doesn't know that you're messing with its attributes. Consider, for example, what would happen if Profile were later expanded to have an attribute called age, unrelated to p.age in your code.
If you want to add attributes, why not subclass Profile, or have an external mapping of Profiles to an object with your custom attributes?
I think the answer is: It depends. First, if you really want to prevent it you can by defining __slots__ in the class. And it is not generally a good practice to add attributes not actually defined in the class, as it can be confusing to someone reading
the code and is rarely useful.
But at certain times, it is useful to be able to do this and Python documentation discusses this as a way to get something similar to a C struct or Pascal Record (see http://docs.python.org/tutorial/classes.html under section 9.7 Odds and Ends.)
If the attribute is only there sometimes, you risk getting an AttributeError out of nowhere for one object while the code worked fine for another object of the same class (yes, exact types aren't that important when duck-typing, but objects of the same class are frequently assumed to be of the same "duck type"). Even if it doesn't happen, you can't be sure just by looking at part of the code, and it's much harder to check in any case. So, doing this only makes your code less reliable.
Then there's the option of providing a default attribute as class attribute or property, only assigning an object attribute when it differs from the default. But for stuff that is expected to vary per object, the clarity of having every attribute ever listed in __init__ usually outweights any potential advantages of delaying instance attribute access.
That is not to say it's not acceptable, but you'd have to make a compelling argument for it to be considered a good idea.

Categories

Resources