Skip to content

Commit 9b17815

Browse files
committed
Add back set_title and get_title to selection containers.
Also, we eagerly compute a title list that updates when the children are updated, so that .titles is always reasonable. Fixes #3471.
1 parent 474bbc9 commit 9b17815

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

python/ipywidgets/ipywidgets/widgets/tests/test_selectioncontainer.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,17 @@ def test_selected_index(self):
2626
def test_selected_index_out_of_bounds(self):
2727
with self.assertRaises(TraitError):
2828
Accordion(self.children, selected_index=-1)
29+
30+
31+
def test_titles(self):
32+
accordion = Accordion(self.children, selected_index=None)
33+
assert accordion.get_state()['titles'] == (None, None)
34+
assert accordion.titles == (None, None)
35+
accordion.set_title(1, 'Title 1')
36+
assert accordion.get_state()['titles'] == (None, 'Title 1')
37+
assert accordion.titles[1] == 'Title 1'
38+
assert accordion.get_title(1) == 'Title 1'
39+
with self.assertRaises(IndexError):
40+
accordion.set_title(2, 'out of bounds')
41+
with self.assertRaises(IndexError):
42+
accordion.get_title(2)

python/ipywidgets/ipywidgets/widgets/widget_selectioncontainer.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
from .widget_core import CoreWidget
1313
from traitlets import Unicode, Dict, CInt, TraitError, validate, observe
1414
from .trait_types import TypedTuple
15+
from itertools import chain, repeat, islice
16+
17+
# Inspired by an itertools recipe: https://docs.python.org/3/library/itertools.html#itertools-recipes
18+
def pad_none(iterable, length=None):
19+
"""Returns the sequence elements and then returns None up to the given size (or indefinitely if size is None)."""
20+
return islice(chain(iterable, repeat(None)), length)
1521

1622
class _SelectionContainer(Box, CoreWidget):
1723
"""Base class used to display multiple child widgets."""
@@ -29,10 +35,39 @@ def _validated_index(self, proposal):
2935
else:
3036
raise TraitError('Invalid selection: index out of bounds')
3137

38+
@validate('titles')
39+
def _validate_titles(self, proposal):
40+
return tuple(pad_none(proposal.value, len(self.children)))
41+
3242
@observe('children')
3343
def _observe_children(self, change):
3444
if self.selected_index is not None and len(change.new) < self.selected_index:
3545
self.selected_index = None
46+
if len(self.titles) != len(change.new):
47+
# Run validation function
48+
self.titles = tuple(self.titles)
49+
50+
def set_title(self, index, title):
51+
"""Sets the title of a container page.
52+
Parameters
53+
----------
54+
index : int
55+
Index of the container page
56+
title : unicode
57+
New title
58+
"""
59+
titles = list(self.titles)
60+
titles[index]=title
61+
self.titles = tuple(titles)
62+
63+
def get_title(self, index):
64+
"""Gets the title of a container pages.
65+
Parameters
66+
----------
67+
index : int
68+
Index of the container page
69+
"""
70+
return self.titles[index]
3671

3772
@register
3873
class Accordion(_SelectionContainer):

0 commit comments

Comments
 (0)