Repository: ipython/traitlets (python)

Issue:
Union trait does not parse correctly from strings
Union trait does not enumerate the types in the union when parsing from string which means that incorrect type gets inferred.

Correct inference of union types is desirable in https://github.com/jupyter-server/jupyter_server/pull/949 and https://github.com/ipython/ipython/pull/13745.

Pull request description:
Fix union from string
Fixes #772, adds unit test.

Patch:
diff --git a/traitlets/traitlets.py b/traitlets/traitlets.py
index 0eae5d1..4ec17da 100644
--- a/traitlets/traitlets.py
+++ b/traitlets/traitlets.py
@@ -2179,6 +2179,15 @@ class Union(TraitType):
         else:
             return Union(self.trait_types + [other])
 
+    def from_string(self, s):
+        for trait_type in self.trait_types:
+            try:
+                v = trait_type.from_string(s)
+                return trait_type.validate(None, v)
+            except TraitError:
+                continue
+        self.error(None, s)
+
 
 # -----------------------------------------------------------------------------
 # Basic TraitTypes implementations/subclasses


Test patch:
diff --git a/traitlets/tests/test_traitlets.py b/traitlets/tests/test_traitlets.py
index 7f934f9..5735627 100644
--- a/traitlets/tests/test_traitlets.py
+++ b/traitlets/tests/test_traitlets.py
@@ -3136,6 +3136,14 @@ def test_tcp_from_string(s, expected):
     _from_string_test(TCPAddress, s, expected)
 
 
+@pytest.mark.parametrize(
+    "s, expected",
+    [("[]", []), ("{}", "{}")],
+)
+def test_union_of_list_and_unicode_from_string(s, expected):
+    _from_string_test(Union([List(), Unicode()]), s, expected)
+
+
 def test_all_attribute():
     """Verify all trait types are added to `traitlets.__all__`"""
     names = dir(traitlets)