-
Notifications
You must be signed in to change notification settings - Fork 3
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
add list of list support to buttongroup widget #90
Changes from 4 commits
d56cfce
cf94d0e
6a93233
97fd8b1
920f207
531087b
f017ccd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,13 @@ | ||
{% from "buttons.inc.htm" import render_button %} | ||
<label class="shc label float-btn">{{ label }}</label> | ||
<div class="ui buttons right floated"> | ||
{% for button in buttons %} | ||
{{ render_button(button) }} | ||
<div class="ui spaced horizontal list right floated"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the use of |
||
{% for button_group in button_groups %} | ||
<div class="item"> | ||
<div class="ui buttons"> | ||
{% for button in button_group %} | ||
{{ render_button(button) }} | ||
{% endfor %} | ||
</div> | ||
</div> | ||
{% endfor %} | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,19 @@ | |
import json | ||
import pathlib | ||
from os import PathLike | ||
from typing import Any, Type, Union, Iterable, List, Generic, Tuple, TypeVar, Optional, Callable | ||
from typing import ( | ||
Any, | ||
cast, | ||
Type, | ||
Union, | ||
Iterable, | ||
List, | ||
Generic, | ||
Tuple, | ||
TypeVar, | ||
Optional, | ||
Callable, | ||
) | ||
|
||
import markupsafe | ||
from markupsafe import Markup | ||
|
@@ -322,19 +334,28 @@ class ButtonGroup(WebPageItem): | |
`Connectable`. | ||
|
||
:param label: The label to be shown left of the buttons | ||
:param buttons: List of button descriptors | ||
:param buttons: List or a List if List of button descriptors | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One afterthought: Can you please add a more detailed description on how to use the parameter, i.e. what effect the single list of button descriptors and the list of lists of button descriptors will have? You can either write it in the parameter description or as a separate paragraph above. |
||
""" | ||
def __init__(self, label: Union[str, Markup], buttons: Iterable["AbstractButton"]): | ||
def __init__( | ||
self, | ||
label: Union[str, Markup], | ||
buttons: Union[Iterable["AbstractButton"], Iterable[Iterable["AbstractButton"]]], | ||
): | ||
super().__init__() | ||
self.label = label | ||
self.buttons = buttons | ||
if all(isinstance(item, Iterable) for item in buttons): | ||
self.buttons: Iterable["AbstractButton"] = list(itertools.chain(*buttons)) | ||
self.button_groups = cast(Iterable[Iterable["AbstractButton"]], buttons) | ||
else: | ||
self.buttons = cast(Iterable["AbstractButton"], buttons) | ||
self.button_groups = cast(Iterable[Iterable["AbstractButton"]], [buttons]) | ||
|
||
def get_connectors(self) -> Iterable[WebUIConnector]: | ||
return self.buttons # type: ignore | ||
|
||
async def render(self) -> str: | ||
return await jinja_env.get_template('widgets/buttongroup.htm')\ | ||
.render_async(label=self.label, buttons=self.buttons) | ||
.render_async(label=self.label, button_groups=self.button_groups) | ||
|
||
|
||
class AbstractButton(metaclass=abc.ABCMeta): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea why
mypy
wants this now here and not at other places, e.g.ui_showcase.py
. Maybe you have an idea how to solve it without the cast. Looks kind of ugly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MyPy tries to guess the type of that list here, based on the first common ancestor class of the two buttons it finds. Unfortunately it finds the common ancestor
WebDisplayDatapoint[bool]
instead ofAbstractButton
. So it complains that we are passing a list of ``WebDisplayDatapoint[bool]s instead of a list of
AbstractButtons`. I assume that, without the new `Union` in the parameter type hint, MyPy was smart enough to find that `List[AbstractButton]`, as expected by the parameter, is also a valid type of that list, so it used that instead of trying to guess the type.I think, the "correct" solution would be to explicitly type-hint the list:
However, that also looks kind of ugly, especially in the example code. So maybe, we go for a simple type-ignore with a comment, like
# type: ignore # MyPy has problems with guessing the correct type of the list of buttons
.Maybe, MyPy will learn this type inference eventually and we can remove the comment. (I will check that once in a while by running MyPy with
--warn-unused-ignores
locally.)