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

Parse the entire docstring for the tooltip #108

Merged
merged 3 commits into from
Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions magicgui/function_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from __future__ import annotations

import inspect
import re
import warnings
from typing import Any, Callable, Dict, Optional, TypeVar, Union, overload

Expand All @@ -26,16 +25,13 @@ def _inject_tooltips_from_docstrings(
if not docstring:
return
for param in parse(docstring).params:
# make the tooltip from the first sentence in the param doc description
tooltip = param.description.split(".", maxsplit=1)[0]
tooltip = re.split(r",?\s?([bB]y )?[dD]efault", tooltip)[0]
# this is to catch potentially bad arg_name parsing in docstring_parser
# if using napoleon style google docstringss
argname = param.arg_name.split(" ", maxsplit=1)[0]
if argname not in param_options:
param_options[argname] = {}
# use setdefault so as not to override an explicitly provided tooltip
param_options[argname].setdefault("tooltip", tooltip)
param_options[argname].setdefault("tooltip", param.description)


class FunctionGui(Container):
Expand Down
45 changes: 25 additions & 20 deletions tests/test_magicgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,11 @@ def func():
def test_tooltips_from_numpydoc():
"""Test that numpydocs docstrings can be used for tooltips."""

@magicgui(x={"tooltip": "override tooltip"}, z={"tooltip": None})
x_tooltip = "override tooltip"
y_docstring = """A greeting, by default 'hi'. Notice how we miraculously pull
the entirety of the docstring just like that"""

@magicgui(x={"tooltip": x_tooltip}, z={"tooltip": None})
def func(x: int, y: str = "hi", z=None):
"""Do a little thing.

Expand All @@ -492,60 +496,61 @@ def func(x: int, y: str = "hi", z=None):
x : int
An integer for you to use
y : str, optional
A greeting, by default 'hi'. Only the first sentence
will be used. Even if the docstring is very long indeed,
I mean super super long ... then it will still use only
the first sentence (everything before the first period in
the description).
A greeting, by default 'hi'. Notice how we miraculously pull
the entirety of the docstring just like that
z : Any, optional
No tooltip for me please.
"""
pass

assert func.x.tooltip == "override tooltip"
assert func.y.tooltip == "A greeting" # the "by default" part is stripped
assert func.x.tooltip == x_tooltip
assert func.y.tooltip == y_docstring
assert not func.z.tooltip


def test_tooltips_from_google_doc():
"""Test that google docstrings can be used for tooltips."""

x_docstring = "An integer for you to use"
y_docstring = """A greeting. Notice how we miraculously pull
the entirety of the docstring just like that"""

@magicgui
def func(x: int, y: str = "hi"):
"""Do a little thing.

Args:
x (int): An integer for you to use
y (str, optional): A greeting. Only the first
sentence will be used. Even if the docstring is very long indeed, I mean
super super long ... then it will still use only the first sentence
(everything before the first period in the description).
y (str, optional): A greeting. Notice how we miraculously pull
the entirety of the docstring just like that
"""
pass

assert func.x.tooltip == "An integer for you to use"
assert func.y.tooltip == "A greeting" # the "by default" part is stripped
assert func.x.tooltip == x_docstring
assert func.y.tooltip == y_docstring


def test_tooltips_from_rest_doc():
"""Test that google docstrings can be used for tooltips."""

x_docstring = "An integer for you to use"
y_docstring = """A greeting, by default 'hi'. Notice how we miraculously pull
the entirety of the docstring just like that"""

@magicgui
def func(x: int, y: str = "hi", z=None):
"""Do a little thing.

:param x: An integer for you to use
:param y: A greeting, by default 'hi'. Only the first sentence will be used.
Even if the docstring is very long indeed, I mean super super long ...
then it will still use only the first sentence (everything before the
first period in the description).
:param y: A greeting, by default 'hi'. Notice how we miraculously pull
the entirety of the docstring just like that
:type x: int
:type y: str
"""
pass

assert func.x.tooltip == "An integer for you to use"
assert func.y.tooltip == "A greeting"
assert func.x.tooltip == x_docstring
assert func.y.tooltip == y_docstring


def test_no_tooltips_from_numpydoc():
Expand Down