Skip to content

Commit

Permalink
Parse the entire docstring for the tooltip (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
HagaiHargil committed Jan 18, 2021
1 parent 45e7a15 commit 4bb6550
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 25 deletions.
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

0 comments on commit 4bb6550

Please sign in to comment.