2016-04-04 7 views
3

Ich fange an, mein erstes asyncio-basiertes Projekt mit Sphinx zu dokumentieren. Ich habe bemerkt, dass einige Projekte dieses "coroutine" Präfix vor einigen Methoden haben und ich möchte das gleiche in der Dokumentation meines Projekts tun, aber ich kann nicht herausfinden, wie.Dokumentieren von Python-Koroutinen mit Sphinx autodoc

Zum Beispiel aiohttp's HTTP client reference zeigt dies:

Klasseaiohttp.ClientSession (...):

Koroutinerequest (...)

Das Projekt scheint Verwenden Sie eine coroutinemethod Direktive, um dies zu erreichen, aber ich dokumentiere alle meine Funktionen und Klassen Inline mit Docstrings und diese Direktive funktioniert nur, wenn Sie die Dokumente in einem reStructuredText Dokument schreiben.

Kann jemand dieses Ergebnis mit Autodoc erzielen?

Bearbeiten: Ich werde auch Antworten akzeptieren, die erklären, wie man eine Sphinx-Erweiterung macht, um dies zu tun, wenn Sphinx es nicht unterstützt. Bonuspunkte, wenn jemand auf eine Art und Weise zeigen kann, die automatisch erkennt, ob die Methode eine Coroutine ist oder nicht inspect.iscoroutinefunction() verwendet.

Bearbeiten: Ich freue mich auf die "pyspecific" Sphinx extension im CPython-Projekt zur Inspiration. Ich muss jedoch das Verhalten von autodoc ändern, keine neuen Anweisungen hinzufügen. Nach ein wenig Nachforschungen sieht es so aus, als hätte autodoc einen autodoc-process-signature event, mit dem die Funktionssignatur angepasst werden kann, aber das Objekt scheint nicht von der Erweiterung "pyspecific" verwendet zu werden.

Antwort

2

Diese Funktionalität ist nicht bereits in Sphinx integriert. pull request #1826 fügt jedoch Unterstützung für Generatoren, Coroutine-Funktionen, Coroutine-Methoden mit eingebauter Erkennung von Korotinen in den Autodoc-Anweisungen autofunction und automethod hinzu.

hier ein Pflaster ist, die ich diese lokal in Sphinx 1.4 ermöglichen angewendet (erfordert sphinx-build ‚s -W Option "Warnungen in Fehler drehen" Deaktivieren):

# Recipe stolen from open PR (https://github.com/sphinx-doc/sphinx/pull/1826). 


from inspect import iscoroutinefunction 

from sphinx import addnodes 
from sphinx.domains.python import (
    PyClassmember, 
    PyModulelevel, 
) 
from sphinx.ext.autodoc import FunctionDocumenter as _FunctionDocumenter 
from sphinx.ext.autodoc import MethodDocumenter as _MethodDocumenter 


class PyCoroutineMixin(object): 
    """Helper for coroutine-related Sphinx custom directives.""" 

    def handle_signature(self, sig, signode): 
     ret = super(PyCoroutineMixin, self).handle_signature(sig, signode) 
     signode.insert(0, addnodes.desc_annotation('coroutine ', 'coroutine ')) 
     return ret 


class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel): 
    """Sphinx directive for coroutine functions.""" 

    def run(self): 
     self.name = 'py:function' 
     return PyModulelevel.run(self) 


class PyCoroutineMethod(PyCoroutineMixin, PyClassmember): 
    """Sphinx directive for coroutine methods.""" 

    def run(self): 
     self.name = 'py:method' 
     return PyClassmember.run(self) 


class FunctionDocumenter(_FunctionDocumenter): 
    """Automatically detect coroutine functions.""" 

    def import_object(self): 
     ret = _FunctionDocumenter.import_object(self) 
     if not ret: 
      return ret 

     obj = self.parent.__dict__.get(self.object_name) 
     if iscoroutinefunction(obj): 
      self.directivetype = 'coroutine' 
      self.member_order = _FunctionDocumenter.member_order + 2 
     return ret 


class MethodDocumenter(_MethodDocumenter): 
    """Automatically detect coroutine methods.""" 

    def import_object(self): 
     ret = _MethodDocumenter.import_object(self) 
     if not ret: 
      return ret 

     obj = self.parent.__dict__.get(self.object_name) 
     if iscoroutinefunction(obj): 
      self.directivetype = 'coroutinemethod' 
      self.member_order = _MethodDocumenter.member_order + 2 
     return ret 


def setup(app): 
    """Sphinx extension entry point.""" 

    # Add new directives. 
    app.add_directive_to_domain('py', 'coroutine', PyCoroutineFunction) 
    app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod) 

    # Customize annotations for anything that looks like a coroutine. 
    app.add_autodocumenter(FunctionDocumenter) 
    app.add_autodocumenter(MethodDocumenter) 

    # Return extension meta data. 
    return { 
     'version': '1.0', 
     'parallel_read_safe': True, 
    } 
Verwandte Themen