From 4143e7eb0c3e474fe3cb031666b4620cf1e0d832 Mon Sep 17 00:00:00 2001 From: azhu Date: Fri, 19 Apr 2024 11:03:18 +1200 Subject: [PATCH] Fix assigning string value to Set Assigning a string value to a Set trait used to implicitly cast to a set containing the string, but it accidentally became a set of the string's characters after #883. Fix this and add a unit test. --- tests/test_traitlets.py | 18 ++++++++++++++++++ traitlets/traitlets.py | 7 +------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/test_traitlets.py b/tests/test_traitlets.py index dfcf3f0f..f9f623b4 100644 --- a/tests/test_traitlets.py +++ b/tests/test_traitlets.py @@ -1658,6 +1658,24 @@ def coerce(self, value): return value +class SetTrait(HasTraits): + value = Set(Unicode()) + + +class TestSet(TraitTestBase): + obj = SetTrait() + + _default_value: t.Set[str] = set() + _good_values = [{"a", "b"}, "ab"] + _bad_values = [1] + + def coerce(self, value): + if isinstance(value, str): + # compatibility handling: convert string to set containing string + value = {value} + return value + + class Foo: pass diff --git a/traitlets/traitlets.py b/traitlets/traitlets.py index 1d1675ab..ecd0d7cc 100644 --- a/traitlets/traitlets.py +++ b/traitlets/traitlets.py @@ -3698,12 +3698,7 @@ def validate_elements(self, obj: t.Any, value: t.Any) -> t.Any: def set(self, obj: t.Any, value: t.Any) -> None: if isinstance(value, str): - return super().set( - obj, - set( - value, - ), - ) + return super().set(obj, {value}) else: return super().set(obj, value)