sphinx-contrib / prettyspecialmethods

Shows special/magic methods in sphinx docs as the python syntax that invokes them
MIT License
5 stars 5 forks source link

Investigating switching over to a custom directive #16

Open johnpmcconnell opened 3 years ago

johnpmcconnell commented 3 years ago

In the process of working on #13, I seem to have started running into the limitations of using a transform to post-process content nodes directly. To support that feature and others in the future, we need the flexibility to provide options that control specifics of the output. A brand new directive appears to be the most straightforward and idiomatic path to getting that flexibility.

The primary obstacle was finding a way to get autodoc to generate a custom directive when appropriate, and I believe I've finally figured out a way to plug into that mechanism.

I've push a branch prototyping this functionality: https://github.com/johnpmcconnell/prettyspecialmethods/tree/prototype/custom-directive. This is not final; I've only created it for demonstrative purposes. (Hence why the code is something of a mess, with imports, commented out code, and actual dead code littered about.)

I'm creating this issue to discuss the overall approach and how to go about it.

  1. The implementation adds a directive to the Python domain and implements an autodoc Documenter that inhereits from MethodDocumenter. I believe this should ensure that we preserve the functionality Sphinx provides around methods, such as decorating them with async and classmethod indicators, while allowing us to introduce new options to customize generating output. Does this make sense? Is it idiomatic? Is there any other minutiae of method functionality that we should customize in the directive or documenter?
  2. Removing the transform is a backward incompatible change. Is that acceptable, or do we want to preserve it in some form? Should we deprecate it, possibly using a config option and issuing a warning if someone still depends on it?
  3. My testing indicates that this works as intended. Have I missed any cases? Is there anything I should double check?
eric-wieser commented 3 years ago

That branch looks quite reasonable to me. The natural extension IMO would be to make the syntax be:

.. py:specialmethod:: a + b
.. py:specialmethod:: str(self)

etc, and then continue to use :meta self-param: as a docstring-only flag for autodoc.

.. py:autospecialmethod:: MyClass.__add__
johnpmcconnell commented 3 years ago

I don't think we're on the same page. The entire point of this change was to alleviate the need to use a meta info field. If it doesn't enable doing that, I don't see the point of making the change.

johnpmcconnell commented 3 years ago

Upon further work, I don't think this works anyway. The new documenter needs to specify objtype to avoid conflicts with the existing method documenter, but if you do that, then Sphinx uses the specified objtype as the object's type, which I think will break references (the :py:meth: role).

cspotcode commented 1 year ago

The new documenter needs to specify objtype to avoid conflicts with the existing method documenter

Can you avoid conflicts by fully replacing the existing MethodDocumenter with your subclass? So that all methods go through your subclass which delegates to vanilla behavior for all non-special-methods.

That might avoid the need for a different objtype.