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

Linking to param in docstring of function itself #11

Closed
Bibo-Joshi opened this issue Oct 19, 2021 · 6 comments · Fixed by #12
Closed

Linking to param in docstring of function itself #11

Bibo-Joshi opened this issue Oct 19, 2021 · 6 comments · Fixed by #12

Comments

@Bibo-Joshi
Copy link
Contributor

Hi. thanks for this awesome extension!

I was very happy to find that it also works with sphinx.ext.napoleon by now :) - learned about this extension via https://stackoverflow.com/a/20845306/10606962 where it said that it didn't support napoleon at the time.
However, I noticed that references are not resolved if you link to a parameter from within the docstring of the function itself, i.e. if you have something like

def foo(arg):
    """:paramref:`arg`.

    Args:
        arg: stuff
    """

TBH I'm not sure, if this specific to napoleon, as I haven't tried with the default docstrings. It is rather easy to work around this, though. Instead of using the built-in PyXRefRole for the paramref role, I used a subclass along the lines

class ParamXRefRole(PyXRefRole):

    def process_link(self, env, refnode, has_explicit_title, title, target):
        title, target = super().process_link(env, refnode, has_explicit_title, title, target)
        try:
            # if we just have :paramref:`arg` and not :paramref:`namespace.arg`, we must assume that
            # the current namespace is meant. Let's extract it from the refnode and prepend it
            if '.' not in target:
                target = f"{refnode.source.rsplit('.', maxsplit=1)[-1]}.{target}"
            return title, target
        except Exception:
            return title, target

For now this does the trick as workaround, but I thought that it could be maybe added to this lib :) By the readme, it's important to you to rely on as few sphinx internals as possible, so I can't judge if this would be acceptable for you. But IISC you use some attributes of nodes already …

Anyway, let me know what you think :) If you like the solution, I could send a PR.

@zzzeek
Copy link
Contributor

zzzeek commented Oct 19, 2021

OK I usually can never rely upon partial paths like that so I always fully qualify a ":paramref: wherever I'm typing it out.

for the workaround above isnt there a missing link hook that might be useful ?

@Bibo-Joshi
Copy link
Contributor Author

Bibo-Joshi commented Oct 20, 2021

for the workaround above isnt there a missing link hook that might be useful ?

You're right, one could also insert this logic into the lookup_params hook:

def lookup_params(app, env, node, contnode):
    ... 
    tokens = target.split(".")

    # if we just have :paramref:`arg` and not :paramref:`namespace.arg`, we must assume that
    # the current namespace is meant. Let's extract it from the refnode and prepend it
    if tokens == [target]:
        tokens.insert(0, node.source.rsplit('.', maxsplit=1)[-1])
    ...

This may be indeed better if one would like to integrate this logic into this lib. The upside of the ParamXRefRole approach is for now that it allows me to patch sphinx-paramlinks without fiddling with the internals …

BTW, I had the idea for this workaround after noticing that :paramref:`~func.arg` is a workaround - I just don't want to type ~func. everywhere :D

@zzzeek
Copy link
Contributor

zzzeek commented Oct 20, 2021

yeah so like a one liner in the lookup_params method, does that work? as long as it doesnt break anything I can accept that

@Bibo-Joshi
Copy link
Contributor Author

Nice 👍 I'll double check with non-napoleon params and PR if it works fine. Do you have any standard test cases or unit tests somewhere?

@zzzeek
Copy link
Contributor

zzzeek commented Oct 20, 2021

that would be nice to have but no, i have not figured out what the testing approach for sphinx extensions would be. if you have any ideas.

basically I build my docs and read them very closely :)

@Bibo-Joshi
Copy link
Contributor Author

haha, okay :D I've only seen some diffs on sphinx PRs, but never dived into them. IIRC they basically check that the produced rst/html is correct …

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

Successfully merging a pull request may close this issue.

2 participants