Skip to content
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

Use type hints extracted from docstring for native extension #135

Closed
jfolz opened this issue Apr 13, 2020 · 2 comments
Closed

Use type hints extracted from docstring for native extension #135

jfolz opened this issue Apr 13, 2020 · 2 comments

Comments

@jfolz
Copy link

jfolz commented Apr 13, 2020

For native code extension modules sphinx autodoc extracts the function signature, including type hints, from the first line of the docstring when autodoc_docstring_signature is set.
I dug around pretty deep in the code and as far as I can tell all of the methods used by this extension tap into the __annotations__ dict, which native functions don't have. Can this extension be configured to use the signature extraction that sphinx provides?
I guess I should add that I'm using napoleon with Google style docstrings, following #15, but writing :param:s directly doesn't make any difference.

Below is my current solution (to be put in conf.py). It works, but it's exceedingly janky and will probably breaks in many exciting ways in the future.

TYPE_HINTS = {}


# Record type hints
def record_type_hints(app, what, name, obj, options, signature, return_annotation):
    TYPE_HINTS[name] = {}
    if signature is not None:
        for arg in signature.strip('()').split(','):
            k, _, v = arg.partition(':')
            k = k.strip()
            v = v.strip()
            if k and v:
                TYPE_HINTS[name][k] = v
    if return_annotation is not None:
        TYPE_HINTS[name]['return'] = return_annotation
    return signature, return_annotation


# Add recorded type hints to function parameters
def add_type_hints(app, what, name, obj, options, lines,
                   __param_pattern=re.compile(r'^:param ([^:]+):')):
    rtype = False
    for i, line in enumerate(lines):
        m = __param_pattern.search(line)
        if m is not None:
            arg = m.groups(0)[0]
            hint = TYPE_HINTS[name].get(arg)
            if hint:
                lines[i] = line.replace(f':param {arg}:', f':param {hint} {arg}:', 1)
        elif line.startswith(':rtype:'):
            rtype = True
    if not rtype and TYPE_HINTS[name].get('return'):
        lines.append(f':rtype: {TYPE_HINTS[name].get("return")}')


def setup(app):
    app.connect("autodoc-process-signature", record_type_hints)
    app.connect("autodoc-process-docstring", add_type_hints)
@jfolz jfolz changed the title Type hints not extracted from docstring Use type hints extracted from docstring Apr 13, 2020
@jfolz
Copy link
Author

jfolz commented Apr 13, 2020

Is already broken for default values ;)

@jfolz jfolz changed the title Use type hints extracted from docstring Use type hints extracted from docstring for native extension Apr 17, 2020
@gaborbernat
Copy link
Member

I'd say the path ahead for this would be to support stub files, for which there's another issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants