Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-ipywidgets for openSUSE:Factory checked in at 2022-09-10 20:17:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-ipywidgets (Old) and /work/SRC/openSUSE:Factory/.python-ipywidgets.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ipywidgets" Sat Sep 10 20:17:25 2022 rev:11 rq:1002374 version:8.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-ipywidgets/python-ipywidgets.changes 2022-08-29 09:43:11.095829404 +0200 +++ /work/SRC/openSUSE:Factory/.python-ipywidgets.new.2083/python-ipywidgets.changes 2022-09-10 20:17:50.324913421 +0200 @@ -1,0 +2,14 @@ +Thu Sep 8 14:49:13 UTC 2022 - Arun Persaud <a...@gmx.de> + +- update to version 8.0.2: + * Add a regression test for time and datetime cross validation + * datetime test lint + * Accept None for Date[time]Picker widgets + * Export the NaiveDatetimePicker as well + * Delete unused import. + * Rename check_widgets -> check_widget_children to be more clear + * Fix tests# + * Allow Mappings to be given as the options in a selection widget + again. + +------------------------------------------------------------------- Old: ---- ipywidgets-8.0.1.tar.gz New: ---- ipywidgets-8.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-ipywidgets.spec ++++++ --- /var/tmp/diff_new_pack.e3F0Ck/_old 2022-09-10 20:17:50.832914728 +0200 +++ /var/tmp/diff_new_pack.e3F0Ck/_new 2022-09-10 20:17:50.840914748 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-ipywidgets -Version: 8.0.1 +Version: 8.0.2 Release: 0 Summary: IPython HTML widgets for Jupyter License: BSD-3-Clause ++++++ ipywidgets-8.0.1.tar.gz -> ipywidgets-8.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/PKG-INFO new/ipywidgets-8.0.2/PKG-INFO --- old/ipywidgets-8.0.1/PKG-INFO 2022-08-18 11:33:37.857040600 +0200 +++ new/ipywidgets-8.0.2/PKG-INFO 2022-09-02 20:40:07.634295700 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ipywidgets -Version: 8.0.1 +Version: 8.0.2 Summary: Jupyter interactive widgets Home-page: http://jupyter.org Author: Jupyter Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/_version.py new/ipywidgets-8.0.2/ipywidgets/_version.py --- old/ipywidgets-8.0.1/ipywidgets/_version.py 2022-08-18 11:33:10.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/_version.py 2022-09-02 20:39:55.000000000 +0200 @@ -1,7 +1,7 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -__version__ = '8.0.1' +__version__ = '8.0.2' __protocol_version__ = '2.1.0' __control_protocol_version__ = '1.0.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/__init__.py new/ipywidgets-8.0.2/ipywidgets/widgets/__init__.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/__init__.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/__init__.py 2022-09-02 20:27:45.000000000 +0200 @@ -15,7 +15,7 @@ from .widget_int import IntText, BoundedIntText, IntSlider, IntProgress, IntRangeSlider, Play, SliderStyle from .widget_color import ColorPicker from .widget_date import DatePicker -from .widget_datetime import DatetimePicker +from .widget_datetime import DatetimePicker, NaiveDatetimePicker from .widget_time import TimePicker from .widget_output import Output from .widget_selection import RadioButtons, ToggleButtons, ToggleButtonsStyle, Dropdown, Select, SelectionSlider, SelectMultiple, SelectionRangeSlider diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_interaction.py new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_interaction.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_interaction.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_interaction.py 2022-09-02 20:27:45.000000000 +0200 @@ -52,7 +52,7 @@ 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 = {} @@ -144,7 +144,7 @@ _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] @@ -158,7 +158,7 @@ _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)] @@ -172,7 +172,7 @@ _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 [ @@ -187,17 +187,33 @@ 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(): @@ -214,7 +230,7 @@ _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)] @@ -228,7 +244,7 @@ _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 @@ -257,7 +273,7 @@ _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): @@ -566,15 +582,14 @@ 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' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_widget_datetime.py new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_widget_datetime.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_widget_datetime.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_widget_datetime.py 2022-09-02 20:27:45.000000000 +0200 @@ -6,7 +6,9 @@ import pytest +from contextlib import nullcontext import datetime +import itertools import pytz from traitlets import TraitError @@ -14,98 +16,142 @@ from ..widget_datetime import DatetimePicker +dt_1442 = datetime.datetime(1442, 1, 1, tzinfo=pytz.utc) +dt_1664 = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc) +dt_1994 = datetime.datetime(1994, 1, 1, tzinfo=pytz.utc) +dt_2002 = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) +dt_2056 = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc) + def test_time_creation_blank(): w = DatetimePicker() assert w.value is None def test_time_creation_value(): - t = datetime.datetime.now(pytz.utc) - w = DatetimePicker(value=t) - assert w.value is t + dt = datetime.datetime.now(pytz.utc) + w = DatetimePicker(value=dt) + assert w.value is dt -def test_time_validate_value_none(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(1442, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(value=t, min=t_min, max=t_max) +def test_datetime_validate_value_none(): + dt = dt_2002 + dt_min = dt_1442 + dt_max = dt_2056 + w = DatetimePicker(value=dt, min=dt_min, max=dt_max) w.value = None assert w.value is None -def test_time_validate_value_vs_min(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(2019, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(min=t_min, max=t_max) - w.value = t +def _permuted_dts(): + ret = [] + combos = list(itertools.product([None, dt_1442, dt_2002, dt_2056], repeat=3)) + for vals in combos: + expected = vals[0] + if vals[1] and vals[2] and vals[1] > vals[2]: + expected = TraitError + elif vals[0] is None: + pass + elif vals[1] and vals[1] > vals[0]: + expected = vals[1] + elif vals[2] and vals[2] < vals[0]: + expected = vals[2] + ret.append(vals + (expected,)) + return ret + + +@pytest.mark.parametrize( + "input_value,input_min,input_max,expected", + _permuted_dts() +) +def test_datetime_cross_validate_value_min_max( + input_value, + input_min, + input_max, + expected, +): + w = DatetimePicker(value=dt_2002, min=dt_2002, max=dt_2002) + should_raise = expected is TraitError + with pytest.raises(expected) if should_raise else nullcontext(): + with w.hold_trait_notifications(): + w.value = input_value + w.min = input_min + w.max = input_max + if not should_raise: + assert w.value is expected + + +def test_datetime_validate_value_vs_min(): + dt = dt_2002 + dt_min = datetime.datetime(2019, 1, 1, tzinfo=pytz.utc) + dt_max = dt_2056 + w = DatetimePicker(min=dt_min, max=dt_max) + w.value = dt assert w.value.year == 2019 -def test_time_validate_value_vs_max(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(1994, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(min=t_min, max=t_max) - w.value = t +def test_datetime_validate_value_vs_max(): + dt = dt_2002 + dt_min = dt_1664 + dt_max = dt_1994 + w = DatetimePicker(min=dt_min, max=dt_max) + w.value = dt assert w.value.year == 1994 -def test_time_validate_min_vs_value(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(2019, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(value=t, max=t_max) - w.min = t_min +def test_datetime_validate_min_vs_value(): + dt = dt_2002 + dt_min = datetime.datetime(2019, 1, 1, tzinfo=pytz.utc) + dt_max = dt_2056 + w = DatetimePicker(value=dt, max=dt_max) + w.min = dt_min assert w.value.year == 2019 -def test_time_validate_min_vs_max(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(2112, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(value=t, max=t_max) +def test_datetime_validate_min_vs_max(): + dt = dt_2002 + dt_min = datetime.datetime(2112, 1, 1, tzinfo=pytz.utc) + dt_max = dt_2056 + w = DatetimePicker(value=dt, max=dt_max) with pytest.raises(TraitError): - w.min = t_min + w.min = dt_min -def test_time_validate_max_vs_value(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(1994, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(value=t, min=t_min) - w.max = t_max +def test_datetime_validate_max_vs_value(): + dt = dt_2002 + dt_min = dt_1664 + dt_max = dt_1994 + w = DatetimePicker(value=dt, min=dt_min) + w.max = dt_max assert w.value.year == 1994 -def test_time_validate_max_vs_min(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(1337, 1, 1, tzinfo=pytz.utc) - w = DatetimePicker(value=t, min=t_min) +def test_datetime_validate_max_vs_min(): + dt = dt_2002 + dt_min = dt_1664 + dt_max = datetime.datetime(1337, 1, 1, tzinfo=pytz.utc) + w = DatetimePicker(value=dt, min=dt_min) with pytest.raises(TraitError): - w.max = t_max + w.max = dt_max -def test_time_validate_naive(): - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc) - t_min = datetime.datetime(1442, 1, 1, tzinfo=pytz.utc) - t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc) +def test_datetime_validate_naive(): + dt = dt_2002 + dt_min = dt_1442 + dt_max = dt_2056 - w = DatetimePicker(value=t, min=t_min, max=t_max) + w = DatetimePicker(value=dt, min=dt_min, max=dt_max) with pytest.raises(TraitError): - w.max = t_max.replace(tzinfo=None) + w.max = dt_max.replace(tzinfo=None) with pytest.raises(TraitError): - w.min = t_min.replace(tzinfo=None) + w.min = dt_min.replace(tzinfo=None) with pytest.raises(TraitError): - w.value = t.replace(tzinfo=None) + w.value = dt.replace(tzinfo=None) def test_datetime_tzinfo(): tz = pytz.timezone('Australia/Sydney') - t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=tz) - w = DatetimePicker(value=t) - assert w.value == t + dt = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=tz) + w = DatetimePicker(value=dt) + assert w.value == dt # tzinfo only changes upon input from user assert w.value.tzinfo == tz diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_widget_selection.py new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_widget_selection.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_widget_selection.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_widget_selection.py 2022-09-02 20:27:45.000000000 +0200 @@ -4,8 +4,6 @@ import inspect from unittest import TestCase -import pytest - from traitlets import TraitError from ipywidgets import Dropdown, SelectionSlider, Select @@ -16,9 +14,9 @@ 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() @@ -37,8 +35,10 @@ 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): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_widget_time.py new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_widget_time.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/tests/test_widget_time.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/tests/test_widget_time.py 2022-09-02 20:27:45.000000000 +0200 @@ -24,6 +24,20 @@ assert w.value is t +def test_time_cross_validate_value_min_max(): + w = TimePicker(value=datetime.time(2), min=datetime.time(2), max=datetime.time(2)) + with w.hold_trait_notifications(): + w.value = None + w.min = datetime.time(4) + w.max = datetime.time(6) + assert w.value is None + with w.hold_trait_notifications(): + w.value = datetime.time(4) + w.min = None + w.max = None + assert w.value == datetime.time(4) + + def test_time_validate_value_none(): t = datetime.time(13, 37, 42, 7) t_min = datetime.time(2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/widget_date.py new/ipywidgets-8.0.2/ipywidgets/widgets/widget_date.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/widget_date.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/widget_date.py 2022-09-02 20:27:45.000000000 +0200 @@ -54,6 +54,8 @@ def _validate_value(self, proposal): """Cap and floor value""" value = proposal["value"] + if value is None: + return value if self.min and self.min > value: value = max(value, self.min) if self.max and self.max < value: @@ -64,6 +66,8 @@ def _validate_min(self, proposal): """Enforce min <= value <= max""" min = proposal["value"] + if min is None: + return min if self.max and min > self.max: raise TraitError("Setting min > max") if self.value and min > self.value: @@ -74,6 +78,8 @@ def _validate_max(self, proposal): """Enforce min <= value <= max""" max = proposal["value"] + if max is None: + return max if self.min and max < self.min: raise TraitError("setting max < min") if self.value and max < self.value: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/widget_datetime.py new/ipywidgets-8.0.2/ipywidgets/widgets/widget_datetime.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/widget_datetime.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/widget_datetime.py 2022-09-02 20:27:45.000000000 +0200 @@ -61,6 +61,8 @@ def _validate_value(self, proposal): """Cap and floor value""" value = proposal["value"] + if value is None: + return value value = self._validate_tz(value) if self.min and self.min > value: value = max(value, self.min) @@ -72,6 +74,8 @@ def _validate_min(self, proposal): """Enforce min <= value <= max""" min = proposal["value"] + if min is None: + return min min = self._validate_tz(min) if self.max and min > self.max: raise TraitError("Setting min > max") @@ -83,6 +87,8 @@ def _validate_max(self, proposal): """Enforce min <= value <= max""" max = proposal["value"] + if max is None: + return max max = self._validate_tz(max) if self.min and max < self.min: raise TraitError("setting max < min") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/widget_selection.py new/ipywidgets-8.0.2/ipywidgets/widgets/widget_selection.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/widget_selection.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/widget_selection.py 2022-09-02 20:27:45.000000000 +0200 @@ -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. @@ -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. @@ -110,9 +112,10 @@ 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 list of values or a list of (label, value) tuples") + x = x.items() # only iterate once through the options. xlist = tuple(x) @@ -151,7 +154,7 @@ 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. @@ -298,7 +301,7 @@ 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. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets/widgets/widget_time.py new/ipywidgets-8.0.2/ipywidgets/widgets/widget_time.py --- old/ipywidgets-8.0.1/ipywidgets/widgets/widget_time.py 2022-08-18 11:00:27.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets/widgets/widget_time.py 2022-09-02 20:27:45.000000000 +0200 @@ -63,6 +63,8 @@ def _validate_value(self, proposal): """Cap and floor value""" value = proposal["value"] + if value is None: + return value if self.min and self.min > value: value = max(value, self.min) if self.max and self.max < value: @@ -73,6 +75,8 @@ def _validate_min(self, proposal): """Enforce min <= value <= max""" min = proposal["value"] + if min is None: + return min if self.max and min > self.max: raise TraitError("Setting min > max") if self.value and min > self.value: @@ -83,6 +87,8 @@ def _validate_max(self, proposal): """Enforce min <= value <= max""" max = proposal["value"] + if max is None: + return max if self.min and max < self.min: raise TraitError("setting max < min") if self.value and max < self.value: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipywidgets-8.0.1/ipywidgets.egg-info/PKG-INFO new/ipywidgets-8.0.2/ipywidgets.egg-info/PKG-INFO --- old/ipywidgets-8.0.1/ipywidgets.egg-info/PKG-INFO 2022-08-18 11:33:37.000000000 +0200 +++ new/ipywidgets-8.0.2/ipywidgets.egg-info/PKG-INFO 2022-09-02 20:40:07.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ipywidgets -Version: 8.0.1 +Version: 8.0.2 Summary: Jupyter interactive widgets Home-page: http://jupyter.org Author: Jupyter Development Team