Skip to content
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
47 changes: 31 additions & 16 deletions python/ipywidgets/ipywidgets/widgets/tests/test_interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def check_widget(w, **d):
te = type(expected)
assert tv is te, "type({}.{}) = {!r} != {!r}".format(w.__class__.__name__, attr, tv, te)

def check_widgets(container, **to_check):
def check_widget_children(container, **to_check):
"""Check that widgets are created as expected"""
# build a widget dictionary, so it matches
widgets = {}
Expand Down Expand Up @@ -144,7 +144,7 @@ def test_list_str():
_options_labels=tuple(values),
_options_values=tuple(values),
)
check_widgets(c, lis=d)
check_widget_children(c, lis=d)

def test_list_int():
values = [3, 1, 2]
Expand All @@ -158,7 +158,7 @@ def test_list_int():
_options_labels=tuple(str(v) for v in values),
_options_values=tuple(values),
)
check_widgets(c, lis=d)
check_widget_children(c, lis=d)

def test_list_tuple():
values = [(3, 300), (1, 100), (2, 200)]
Expand All @@ -172,7 +172,7 @@ def test_list_tuple():
_options_labels=("3", "1", "2"),
_options_values=(300, 100, 200),
)
check_widgets(c, lis=d)
check_widget_children(c, lis=d)

def test_list_tuple_invalid():
for bad in [
Expand All @@ -187,17 +187,33 @@ def test_dict():
dict(a=5),
dict(a=5, b='b', c=dict),
]:
with pytest.raises(TypeError):
c = interactive(f, d=d)

c = interactive(f, d=d)
w = c.children[0]
check = dict(
cls=widgets.Dropdown,
description='d',
value=next(iter(d.values())),
options=d,
_options_labels=tuple(d.keys()),
_options_values=tuple(d.values()),
)
check_widget(w, **check)

def test_ordereddict():
from collections import OrderedDict
items = [(3, 300), (1, 100), (2, 200)]
first = items[0][1]
values = OrderedDict(items)
with pytest.raises(TypeError):
c = interactive(f, lis=values)
c = interactive(f, lis=values)
assert len(c.children) == 2
d = dict(
cls=widgets.Dropdown,
value=first,
options=values,
_options_labels=("3", "1", "2"),
_options_values=(300, 100, 200),
)
check_widget_children(c, lis=d)

def test_iterable():
def yield_values():
Expand All @@ -214,7 +230,7 @@ def yield_values():
_options_labels=("3", "1", "2"),
_options_values=(3, 1, 2),
)
check_widgets(c, lis=d)
check_widget_children(c, lis=d)

def test_iterable_tuple():
values = [(3, 300), (1, 100), (2, 200)]
Expand All @@ -228,7 +244,7 @@ def test_iterable_tuple():
_options_labels=("3", "1", "2"),
_options_values=(300, 100, 200),
)
check_widgets(c, lis=d)
check_widget_children(c, lis=d)

def test_mapping():
from collections.abc import Mapping
Expand Down Expand Up @@ -257,7 +273,7 @@ def items(self):
_options_labels=("3", "1", "2"),
_options_values=(300, 100, 200),
)
check_widgets(c, lis=d)
check_widget_children(c, lis=d)

def test_decorator_kwarg(clear_display):
with patch.object(interaction, 'display', record_display):
Expand Down Expand Up @@ -566,15 +582,14 @@ def test_multiple_selection():
check_widget(w, value=(1, 2))

# dict style
with pytest.raises(TypeError):
w = smw(options={1: 1})
w.options = {1: 1}
check_widget(w, options={1:1})

# updating
w.options = (1,)
with pytest.raises(TraitError):
w.value = (2,)
check_widget(w, options=(1,))

check_widget(w, options=(1,) )

def test_interact_noinspect():
a = 'hello'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import inspect
from unittest import TestCase

import pytest

from traitlets import TraitError

from ipywidgets import Dropdown, SelectionSlider, Select
Expand All @@ -16,9 +14,9 @@ class TestDropdown(TestCase):
def test_construction(self):
Dropdown()

def test_raise_mapping_options(self):
with pytest.raises(TypeError):
Dropdown(options={'One': 1, 'Two': 2, 'Three': 3})
def test_dict_mapping_options(self):
d = Dropdown(options={'One': 1, 'Two': 2, 'Three': 3})
assert d.get_state('_options_labels') == {'_options_labels': ('One', 'Two', 'Three')}

def test_setting_options_from_list(self):
d = Dropdown()
Expand All @@ -37,8 +35,10 @@ def test_setting_options_from_list_tuples(self):
def test_setting_options_from_dict(self):
d = Dropdown()
assert d.options == ()
with pytest.raises(TypeError):
d.options = {'One': 1}
d.options = {'One': 1, 'Two': 2, 'Three': 3}
assert d.get_state('_options_labels') == {'_options_labels': ('One', 'Two', 'Three')}




class TestSelectionSlider(TestCase):
Expand Down
15 changes: 9 additions & 6 deletions python/ipywidgets/ipywidgets/widgets/widget_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
_doc_snippets['selection_params'] = """
options: list
The options for the dropdown. This can either be a list of values, e.g.
``['Galileo', 'Brahe', 'Hubble']`` or ``[0, 1, 2]``, or a list of
``['Galileo', 'Brahe', 'Hubble']`` or ``[0, 1, 2]``, a list of
(label, value) pairs, e.g.
``[('Galileo', 0), ('Brahe', 1), ('Hubble', 2)]``.
``[('Galileo', 0), ('Brahe', 1), ('Hubble', 2)]``, or a Mapping between
labels and values, e.g., ``{'Galileo': 0, 'Brahe': 1, 'Hubble': 2}``.

index: int
The index of the current selection.
Expand Down Expand Up @@ -55,7 +56,8 @@
The options for the dropdown. This can either be a list of values, e.g.
``['Galileo', 'Brahe', 'Hubble']`` or ``[0, 1, 2]``, or a list of
(label, value) pairs, e.g.
``[('Galileo', 0), ('Brahe', 1), ('Hubble', 2)]``.
``[('Galileo', 0), ('Brahe', 1), ('Hubble', 2)]``, or a Mapping between
labels and values, e.g., ``{'Galileo': 0, 'Brahe': 1, 'Hubble': 2}``.
The labels are the strings that will be displayed in the UI,
representing the actual Python choices, and should be unique.

Expand Down Expand Up @@ -110,9 +112,10 @@ def _make_options(x):
The input can be
* an iterable of (label, value) pairs
* an iterable of values, and labels will be generated
* a Mapping between labels and values
"""
if isinstance(x, Mapping):
raise TypeError("options must be a iterable of values or of (label, value) pairs. If x is your Mapping, use x.items() for the options.")
x = x.items()

# only iterate once through the options.
xlist = tuple(x)
Expand Down Expand Up @@ -151,7 +154,7 @@ class _Selection(DescriptionWidget, ValueWidget, CoreWidget):
index = Int(None, help="Selected index", allow_none=True).tag(sync=True)

options = Any((),
help="""Iterable of values or (label, value) pairs that the user can select.
help="""Iterable of values, (label, value) pairs, or Mapping between labels and values that the user can select.

The labels are the strings that will be displayed in the UI, representing the
actual Python choices, and should be unique.
Expand Down Expand Up @@ -298,7 +301,7 @@ class _MultipleSelection(DescriptionWidget, ValueWidget, CoreWidget):
index = TypedTuple(trait=Int(), help="Selected indices").tag(sync=True)

options = Any((),
help="""Iterable of values or (label, value) pairs that the user can select.
help="""Iterable of values, (label, value) pairs, or Mapping between labels and values that the user can select.

The labels are the strings that will be displayed in the UI, representing the
actual Python choices, and should be unique.
Expand Down