diff --git a/src/TensorFlowNET.Core/Python.cs b/src/TensorFlowNET.Core/Python.cs index abb26ee0..ad934eb7 100644 --- a/src/TensorFlowNET.Core/Python.cs +++ b/src/TensorFlowNET.Core/Python.cs @@ -120,6 +120,55 @@ namespace Tensorflow yield return (t1.Data(i), t2.Data(i)); } + public static IEnumerable<(T1, T2)> zip(IEnumerable e1, IEnumerable e2) + { + var iter2 = e2.GetEnumerator(); + foreach (var v1 in e1) + { + iter2.MoveNext(); + var v2 = iter2.Current; + yield return (v1, v2); + } + } + + /// + /// Untyped implementation of zip for arbitrary data + /// + /// Converts an list of lists or arrays [[1,2,3], [4,5,6], [7,8,9]] into a list of arrays + /// representing tuples of the same index of all source arrays [[1,4,7], [2,5,9], [3,6,9]] + /// + /// one or multiple sequences to be zipped + /// + public static IEnumerable zip(params object[] lists) + { + if (lists.Length == 0) + yield break; + var first = lists[0]; + if (first == null) + yield break; + var arity = (first as IEnumerable).OfType().Count(); + for (int i = 0; i < arity; i++) + { + var array= new object[lists.Length]; + for (int j = 0; j < lists.Length; j++) + array[j] = GetSequenceElementAt(lists[j], i); + yield return array; + } + } + + private static object GetSequenceElementAt(object sequence, int i) + { + switch (sequence) + { + case Array array: + return array.GetValue(i); + case IList list: + return list[i]; + default: + return (sequence as IEnumerable).OfType().Skip(Math.Max(0, i)).FirstOrDefault(); + } + } + public static IEnumerable<(int, T)> enumerate(IList values) { for (int i = 0; i < values.Count; i++) @@ -137,6 +186,7 @@ namespace Tensorflow } return dictionary; } + } public interface IPython : IDisposable diff --git a/src/TensorFlowNET.Core/Util/nest.py.cs b/src/TensorFlowNET.Core/Util/nest.py.cs index 2d43b976..b61cb0e4 100644 --- a/src/TensorFlowNET.Core/Util/nest.py.cs +++ b/src/TensorFlowNET.Core/Util/nest.py.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Text; using NumSharp; namespace Tensorflow.Util @@ -24,6 +23,14 @@ namespace Tensorflow.Util public static class nest { + public static IEnumerable zip(params object[] structures) + => Python.zip(structures); + + public static IEnumerable<(T1, T2)> zip(IEnumerable e1, IEnumerable e2) + => Python.zip(e1, e2); + + public static Dictionary ConvertToDict(object dyn) + => Python.ConvertToDict(dyn); //def _get_attrs_values(obj): // """Returns the list of values from an attrs instance.""" @@ -75,8 +82,14 @@ namespace Tensorflow.Util //# instances. This is intentional, to avoid potential bugs caused by mixing //# ordered and plain dicts (e.g., flattening a dict but using a //# corresponding `OrderedDict` to pack it back). - // result = dict(zip(_sorted(instance), args)) - // return type(instance)((key, result[key]) for key in _six.iterkeys(instance)) + switch (instance) + { + case Hashtable hash: + var result = new Hashtable(); + foreach ((object key, object value) in zip(_sorted(hash).OfType(), args)) + result[key] = value; + return result; + } } //else if( _is_namedtuple(instance) || _is_attrs(instance)) // return type(instance)(*args) @@ -140,7 +153,9 @@ namespace Tensorflow.Util } //# See the swig file (util.i) for documentation. - public static bool is_sequence(object arg) => arg is IEnumerable && !(arg is string); + public static bool is_sequence(object arg) + => arg is IEnumerable && !(arg is string) && !(arg is NDArray) && + !(arg.GetType().IsGenericType && arg.GetType().GetGenericTypeDefinition() == typeof(HashSet<>)); public static bool is_mapping(object arg) => arg is IDictionary; @@ -355,38 +370,54 @@ namespace Tensorflow.Util /// `flat_sequence` converted to have the same recursive structure as /// `structure`. /// - public static object pack_sequence_as(object structure, List flat_sequence) + public static object pack_sequence_as(object structure, IEnumerable flat_sequence) { - if (flat_sequence == null) + List flat = null; + if (flat_sequence is List) + flat = flat_sequence as List; + else + flat=new List(flat_sequence.OfType()); + if (flat_sequence==null) throw new ArgumentException("flat_sequence must not be null"); // if not is_sequence(flat_sequence): // raise TypeError("flat_sequence must be a sequence") if (!is_sequence(structure)) { - if (len(flat_sequence) != 1) - throw new ValueError($"Structure is a scalar but len(flat_sequence) == {len(flat_sequence)} > 1"); - return flat_sequence.FirstOrDefault(); + if (len(flat) != 1) + throw new ValueError($"Structure is a scalar but len(flat_sequence) == {len(flat)} > 1"); + return flat.FirstOrDefault(); } int final_index = 0; List packed = null; try { - (final_index, packed) = _packed_nest_with_indices(structure, flat_sequence, 0); - if (final_index < len(flat_sequence)) - throw new IndexOutOfRangeException($"Final index: { final_index} was smaller than len(flat_sequence): { len(flat_sequence) }"); + (final_index, packed) = _packed_nest_with_indices(structure, flat, 0); + if (final_index < len(flat)) + throw new IndexOutOfRangeException( + $"Final index: {final_index} was smaller than len(flat_sequence): {len(flat)}"); + return _sequence_like(structure, packed); } catch (IndexOutOfRangeException) { var flat_structure = flatten(structure); - if (len(flat_structure) != len(flat_sequence)) + if (len(flat_structure) != len(flat)) { throw new ValueError("Could not pack sequence. Structure had %d elements, but " + - $"flat_sequence had {len(flat_structure)} elements. flat_sequence had: {len(flat_sequence)}"); + $"flat_sequence had {len(flat_structure)} elements. flat_sequence had: {len(flat)}"); + } + return _sequence_like(structure, packed); + } + catch (ArgumentOutOfRangeException) + { + var flat_structure = flatten(structure); + if (len(flat_structure) != len(flat)) + { + throw new ValueError("Could not pack sequence. Structure had %d elements, but " + + $"flat_sequence had {len(flat_structure)} elements. flat_sequence had: {len(flat)}"); } return _sequence_like(structure, packed); } - return packed; } /// @@ -396,10 +427,9 @@ namespace Tensorflow.Util /// `structure[i]`. All structures in `structure` must have the same arity, /// and the return value will contain the results in the same structure. /// - /// - /// + /// the type of the elements of the output structure (object if diverse) /// A callable that accepts as many arguments as there are structures. - /// scalar, or tuple or list of constructed scalars and/or other + /// scalar, or tuple or list of constructed scalars and/or other /// tuples/lists, or scalars. Note: numpy arrays are considered as scalars. /// If set to /// `True` (default) the types of iterables within the structures have to be @@ -414,18 +444,41 @@ namespace Tensorflow.Util /// `check_types` is `False` the sequence types of the first structure will be /// used. /// - public static IEnumerable map_structure(Func func, IEnumerable structure, bool check_types = false) + public static IEnumerable map_structure(Func func, object structure, params object[] more_structures) { + // TODO: check structure and types + // for other in structure[1:]: + // assert_same_structure(structure[0], other, check_types=check_types) + + if (more_structures.Length==0) + { + // we don't need to zip if we have only one structure + return map_structure(a => func(new object[]{a}), structure); + } + var flat_structures = new List() { flatten(structure) }; + flat_structures.AddRange(more_structures.Select(flatten)); + var entries = zip(flat_structures); + var mapped_flat_structure = entries.Select(func); + return (pack_sequence_as(structure, mapped_flat_structure) as IEnumerable).OfType(); + } + + /// + /// Same as map_structure, but with only one structure (no combining of multiple structures) + /// + /// + /// + /// + public static IEnumerable map_structure(Func func, object structure) + { + // TODO: check structure and types // for other in structure[1:]: // assert_same_structure(structure[0], other, check_types=check_types) - // flat_structure = [flatten(s) for s in structure] - // entries = zip(*flat_structure) + var flat_structure = flatten(structure); + var mapped_flat_structure = flat_structure.Select(func).ToList(); - // return pack_sequence_as( - // structure[0], [func(*x) for x in entries]) - return null; + return (pack_sequence_as(structure, mapped_flat_structure) as IEnumerable).OfType(); } //def map_structure_with_paths(func, *structure, **kwargs): diff --git a/test/TensorFlowNET.UnitTest/PythonTest.cs b/test/TensorFlowNET.UnitTest/PythonTest.cs index 5af8bd52..890caa7a 100644 --- a/test/TensorFlowNET.UnitTest/PythonTest.cs +++ b/test/TensorFlowNET.UnitTest/PythonTest.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json.Linq; +using NumSharp; using Tensorflow; using Tensorflow.Util; @@ -25,17 +27,45 @@ namespace TensorFlowNET.UnitTest public void assertItemsEqual(ICollection given, ICollection expected) { + if (given is Hashtable && expected is Hashtable) + { + Assert.AreEqual(JObject.FromObject(expected).ToString(), JObject.FromObject(given).ToString()); + return; + } Assert.IsNotNull(expected); Assert.IsNotNull(given); var e = expected.OfType().ToArray(); var g = given.OfType().ToArray(); Assert.AreEqual(e.Length, g.Length, $"The collections differ in length expected {e.Length} but got {g.Length}"); for (int i = 0; i < e.Length; i++) - Assert.AreEqual(e[i], g[i], $"Items differ at index {i}, expected {e[i]} but got {g[i]}"); + { + if (g[i] is NDArray && e[i] is NDArray) + assertItemsEqual((g[i] as NDArray).Array, (e[i] as NDArray).Array); + else if (e[i] is ICollection && g[i] is ICollection) + assertEqual(g[i], e[i]); + else + Assert.AreEqual(e[i], g[i], $"Items differ at index {i}, expected {e[i]} but got {g[i]}"); + } } + public void assertAllEqual(ICollection given, ICollection expected) + { + assertItemsEqual(given, expected); + } + + public void assertEqual(object given, object expected) { + if (given is NDArray && expected is NDArray) + { + assertItemsEqual((given as NDArray).Array, (expected as NDArray).Array); + return; + } + if (given is Hashtable && expected is Hashtable) + { + Assert.AreEqual(JObject.FromObject(expected).ToString(), JObject.FromObject(given).ToString()); + return; + } if (given is ICollection && expected is ICollection) { assertItemsEqual(given as ICollection, expected as ICollection); @@ -54,6 +84,16 @@ namespace TensorFlowNET.UnitTest Assert.IsNotNull(given); } + public void assertFalse(bool cond) + { + Assert.IsFalse(cond); + } + + public void assertTrue(bool cond) + { + Assert.IsTrue(cond); + } + #endregion #region tensor evaluation diff --git a/test/TensorFlowNET.UnitTest/nest_test/NestTest.cs b/test/TensorFlowNET.UnitTest/nest_test/NestTest.cs index 7b0d61ba..91db7bdc 100644 --- a/test/TensorFlowNET.UnitTest/nest_test/NestTest.cs +++ b/test/TensorFlowNET.UnitTest/nest_test/NestTest.cs @@ -1,12 +1,13 @@ using System.Collections; using System.Collections.Generic; -using System.Linq; +using Colorful; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json.Linq; +using NumSharp; using Tensorflow; using Tensorflow.Util; -namespace TensorFlowNET.UnitTest.control_flow_ops_test +namespace TensorFlowNET.UnitTest.nest_test { /// /// excerpt of tensorflow/python/framework/util/nest_test.py @@ -15,11 +16,11 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test public class NestTest : PythonTest { - public class PointXY - { - public double x; - public double y; - } + //public class PointXY + //{ + // public double x; + // public double y; + //} // if attr: // class BadAttr(object): @@ -53,38 +54,35 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test [TestMethod] public void testFlattenAndPack() { - object structure = new object[] {new object[] {3, 4}, 5, new object[] {6, 7, new object[] {9, 10}, 8}}; - var flat = new List {"a", "b", "c", "d", "e", "f", "g", "h"}; + object structure = new object[] { new object[] { 3, 4 }, 5, new object[] { 6, 7, new object[] { 9, 10 }, 8 } }; + var flat = new List { "a", "b", "c", "d", "e", "f", "g", "h" }; - self.assertEqual(nest.flatten(structure), new[] {3, 4, 5, 6, 7, 9, 10, 8}); + self.assertEqual(nest.flatten(structure), new[] { 3, 4, 5, 6, 7, 9, 10, 8 }); self.assertEqual(JArray.FromObject(nest.pack_sequence_as(structure, flat)).ToString(), - JArray.FromObject(new object[] {new object[] {"a", "b"}, "c", new object[] {"d", "e", new object[] {"f", "g"}, "h"}}).ToString()); - structure = new object[] { new Hashtable {["x"] = 4, ["y"] = 2}, new object[] { new object[] { new Hashtable { ["x"] = 1,["y"] = 0}, }, }}; - flat = new List { 4, 2, 1, 0}; + JArray.FromObject(new object[] { new object[] { "a", "b" }, "c", new object[] { "d", "e", new object[] { "f", "g" }, "h" } }).ToString()); + structure = new object[] { new Hashtable { ["x"] = 4, ["y"] = 2 }, new object[] { new object[] { new Hashtable { ["x"] = 1, ["y"] = 0 }, }, } }; + flat = new List { 4, 2, 1, 0 }; self.assertEqual(nest.flatten(structure), flat); - // restructured_from_flat = nest.pack_sequence_as(structure, flat) - // self.assertEqual(restructured_from_flat, structure) - // self.assertEqual(restructured_from_flat[0].x, 4) - // self.assertEqual(restructured_from_flat[0].y, 2) - // self.assertEqual(restructured_from_flat[1][0][0].x, 1) - // self.assertEqual(restructured_from_flat[1][0][0].y, 0) - - // self.assertEqual([5], nest.flatten(5)) - // self.assertEqual([np.array([5])], nest.flatten(np.array([5]))) - - // self.assertEqual("a", nest.pack_sequence_as(5, ["a"])) - // self.assertEqual( - // np.array([5]), nest.pack_sequence_as("scalar", [np.array([5])])) - - // with self.assertRaisesRegexp(ValueError, "Structure is a scalar"): - // nest.pack_sequence_as("scalar", [4, 5]) - - // with self.assertRaisesRegexp(TypeError, "flat_sequence"): - // nest.pack_sequence_as([4, 5], "bad_sequence") - - // with self.assertRaises(ValueError): - // nest.pack_sequence_as([5, 6, [7, 8]], ["a", "b", "c"]) - + var restructured_from_flat = nest.pack_sequence_as(structure, flat) as object[]; + //Console.WriteLine(JArray.FromObject(restructured_from_flat)); + self.assertEqual(restructured_from_flat, structure); + self.assertEqual((restructured_from_flat[0] as Hashtable)["x"], 4); + self.assertEqual((restructured_from_flat[0] as Hashtable)["y"], 2); + self.assertEqual((((restructured_from_flat[1] as object[])[0] as object[])[0] as Hashtable)["x"], 1); + self.assertEqual((((restructured_from_flat[1] as object[])[0] as object[])[0] as Hashtable)["y"], 0); + + self.assertEqual(new List { 5 }, nest.flatten(5)); + flat = nest.flatten(np.array(new[] { 5 })); + self.assertEqual(new object[] { np.array(new int[] { 5 }) }, flat); + + self.assertEqual("a", nest.pack_sequence_as(5, new List { "a" })); + self.assertEqual(np.array(new[] { 5 }), + nest.pack_sequence_as("scalar", new List { np.array(new[] { 5 }) })); + + Assert.ThrowsException(() => nest.pack_sequence_as("scalar", new List() { 4, 5 })); + + Assert.ThrowsException(() => + nest.pack_sequence_as(new object[] { 5, 6, new object[] { 7, 8 } }, new List { "a", "b", "c" })); } // @parameterized.parameters({"mapping_type": collections.OrderedDict @@ -173,42 +171,56 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test // self.assertIsInstance(unflattened_custom_mapping, _CustomMapping) // self.assertEqual(list(unflattened_custom_mapping.keys()), [41]) - // def testFlatten_numpyIsNotFlattened(self): - // structure = np.array([1, 2, 3]) - // flattened = nest.flatten(structure) - // self.assertEqual(len(flattened), 1) + [TestMethod] + public void testFlatten_numpyIsNotFlattened() + { + var structure = np.array(1, 2, 3); + var flattened = nest.flatten(structure); + self.assertEqual(len(flattened), 1); + } - // def testFlatten_stringIsNotFlattened(self): - // structure = "lots of letters" - // flattened = nest.flatten(structure) - // self.assertEqual(len(flattened), 1) - // unflattened = nest.pack_sequence_as("goodbye", flattened) - // self.assertEqual(structure, unflattened) + [TestMethod] + public void testFlatten_stringIsNotFlattened() + { + var structure = "lots of letters"; + var flattened = nest.flatten(structure); + self.assertEqual(len(flattened), 1); + var unflattened = nest.pack_sequence_as("goodbye", flattened); + self.assertEqual(structure, unflattened); + } // def testPackSequenceAs_notIterableError(self) : // with self.assertRaisesRegexp(TypeError, // "flat_sequence must be a sequence"): // nest.pack_sequence_as("hi", "bye") - // def testPackSequenceAs_wrongLengthsError(self): - // with self.assertRaisesRegexp( - // ValueError, - // "Structure had 2 elements, but flat_sequence had 3 elements."): - // nest.pack_sequence_as(["hello", "world"], - // ["and", "goodbye", "again"]) + [TestMethod] + public void testPackSequenceAs_wrongLengthsError() + { + Assert.ThrowsException(() => + { + // with self.assertRaisesRegexp( + // ValueError, + // "Structure had 2 elements, but flat_sequence had 3 elements."): + nest.pack_sequence_as(new object[] { "hello", "world" }, new object[] { "and", "goodbye", "again" }); + }); + } - // @test_util.assert_no_new_pyobjects_executing_eagerly - // def testIsSequence(self): - // self.assertFalse(nest.is_sequence("1234")) - // self.assertTrue(nest.is_sequence([1, 3, [4, 5]])) - // self.assertTrue(nest.is_sequence(((7, 8), (5, 6)))) - // self.assertTrue(nest.is_sequence([])) - // self.assertTrue(nest.is_sequence({"a": 1, "b": 2})) - // self.assertFalse(nest.is_sequence(set([1, 2]))) - // ones = array_ops.ones([2, 3]) - // self.assertFalse(nest.is_sequence(ones)) - // self.assertFalse(nest.is_sequence(math_ops.tanh(ones))) - // self.assertFalse(nest.is_sequence(np.ones((4, 5)))) + [TestMethod] + public void testIsSequence() + { + self.assertFalse(nest.is_sequence("1234")); + self.assertTrue(nest.is_sequence(new object[] { 1, 3, new object[] { 4, 5 } })); + // TODO: ValueTuple + //self.assertTrue(nest.is_sequence(((7, 8), (5, 6)))); + self.assertTrue(nest.is_sequence(new object[] { })); + self.assertTrue(nest.is_sequence(new Hashtable { ["a"] = 1, ["b"] = 2 })); + self.assertFalse(nest.is_sequence(new HashSet { 1, 2 })); + var ones = array_ops.ones(new int[] { 2, 3 }); + self.assertFalse(nest.is_sequence(ones)); + self.assertFalse(nest.is_sequence(gen_math_ops.tanh(ones))); + self.assertFalse(nest.is_sequence(np.ones(new int[] { 4, 5 }))); + } // @parameterized.parameters({"mapping_type": _CustomMapping}, // {"mapping_type": dict}) @@ -363,71 +375,75 @@ namespace TensorFlowNET.UnitTest.control_flow_ops_test // nest.assert_same_structure({"a": 4}, _CustomMapping(a= 3)) // nest.assert_same_structure(_CustomMapping(b=3), {"b": 4}) - // @test_util.assert_no_new_pyobjects_executing_eagerly - // def testMapStructure(self) : - // structure1 = (((1, 2), 3), 4, (5, 6)) - // structure2 = (((7, 8), 9), 10, (11, 12)) - // structure1_plus1 = nest.map_structure(lambda x: x + 1, structure1) - // nest.assert_same_structure(structure1, structure1_plus1) - // self.assertAllEqual( - // [2, 3, 4, 5, 6, 7], - // nest.flatten(structure1_plus1)) - // structure1_plus_structure2 = nest.map_structure( - // lambda x, y: x + y, structure1, structure2) - // self.assertEqual( - // (((1 + 7, 2 + 8), 3 + 9), 4 + 10, (5 + 11, 6 + 12)), - // structure1_plus_structure2) + [TestMethod] + public void testMapStructure() + { + var structure1 = new object[] { new object[] { new object[] { 1, 2 }, 3 }, 4, new object[] { 5, 6 } }; + var structure2 = new object[] { new object[] { new object[] { 7, 8 }, 9 }, 10, new object[] { 11, 12 } }; + var structure1_plus1 = nest.map_structure(x => (int)x + 1, structure1); + var structure1_strings = nest.map_structure(x => $"{x}", structure1); + var s = JArray.FromObject(structure1_plus1).ToString(); + Console.WriteLine(s); + // nest.assert_same_structure(structure1, structure1_plus1) + self.assertAllEqual( nest.flatten(structure1_plus1), new object[] { 2, 3, 4, 5, 6, 7 }); + self.assertAllEqual(nest.flatten(structure1_strings), new object[] { "1", "2", "3", "4", "5", "6" }); + // structure1_plus_structure2 = nest.map_structure( + // lambda x, y: x + y, structure1, structure2) + // self.assertEqual( + // (((1 + 7, 2 + 8), 3 + 9), 4 + 10, (5 + 11, 6 + 12)), + // structure1_plus_structure2) - // self.assertEqual(3, nest.map_structure(lambda x: x - 1, 4)) + // self.assertEqual(3, nest.map_structure(lambda x: x - 1, 4)) - // self.assertEqual(7, nest.map_structure(lambda x, y: x + y, 3, 4)) + // self.assertEqual(7, nest.map_structure(lambda x, y: x + y, 3, 4)) - // # Empty structures - // self.assertEqual((), nest.map_structure(lambda x: x + 1, ())) - // self.assertEqual([], nest.map_structure(lambda x: x + 1, [])) - // self.assertEqual({}, nest.map_structure(lambda x: x + 1, {})) - // self.assertEqual(NestTest.EmptyNT(), nest.map_structure(lambda x: x + 1, - // NestTest.EmptyNT())) + // # Empty structures + // self.assertEqual((), nest.map_structure(lambda x: x + 1, ())) + // self.assertEqual([], nest.map_structure(lambda x: x + 1, [])) + // self.assertEqual({}, nest.map_structure(lambda x: x + 1, {})) + // self.assertEqual(NestTest.EmptyNT(), nest.map_structure(lambda x: x + 1, + // NestTest.EmptyNT())) - // # This is checking actual equality of types, empty list != empty tuple - // self.assertNotEqual((), nest.map_structure(lambda x: x + 1, [])) + // # This is checking actual equality of types, empty list != empty tuple + // self.assertNotEqual((), nest.map_structure(lambda x: x + 1, [])) - // with self.assertRaisesRegexp(TypeError, "callable"): - // nest.map_structure("bad", structure1_plus1) + // with self.assertRaisesRegexp(TypeError, "callable"): + // nest.map_structure("bad", structure1_plus1) - // with self.assertRaisesRegexp(ValueError, "at least one structure"): - // nest.map_structure(lambda x: x) + // with self.assertRaisesRegexp(ValueError, "at least one structure"): + // nest.map_structure(lambda x: x) - // with self.assertRaisesRegexp(ValueError, "same number of elements"): - // nest.map_structure(lambda x, y: None, (3, 4), (3, 4, 5)) + // with self.assertRaisesRegexp(ValueError, "same number of elements"): + // nest.map_structure(lambda x, y: None, (3, 4), (3, 4, 5)) - // with self.assertRaisesRegexp(ValueError, "same nested structure"): - // nest.map_structure(lambda x, y: None, 3, (3,)) + // with self.assertRaisesRegexp(ValueError, "same nested structure"): + // nest.map_structure(lambda x, y: None, 3, (3,)) - // with self.assertRaisesRegexp(TypeError, "same sequence type"): - // nest.map_structure(lambda x, y: None, ((3, 4), 5), [(3, 4), 5]) + // with self.assertRaisesRegexp(TypeError, "same sequence type"): + // nest.map_structure(lambda x, y: None, ((3, 4), 5), [(3, 4), 5]) - // with self.assertRaisesRegexp(ValueError, "same nested structure"): - // nest.map_structure(lambda x, y: None, ((3, 4), 5), (3, (4, 5))) + // with self.assertRaisesRegexp(ValueError, "same nested structure"): + // nest.map_structure(lambda x, y: None, ((3, 4), 5), (3, (4, 5))) - // structure1_list = [[[1, 2], 3], 4, [5, 6]] - // with self.assertRaisesRegexp(TypeError, "same sequence type"): - // nest.map_structure(lambda x, y: None, structure1, structure1_list) + // structure1_list = [[[1, 2], 3], 4, [5, 6]] + // with self.assertRaisesRegexp(TypeError, "same sequence type"): + // nest.map_structure(lambda x, y: None, structure1, structure1_list) - // nest.map_structure(lambda x, y: None, structure1, structure1_list, - // check_types=False) + // nest.map_structure(lambda x, y: None, structure1, structure1_list, + // check_types=False) - // with self.assertRaisesRegexp(ValueError, "same nested structure"): - // nest.map_structure(lambda x, y: None, ((3, 4), 5), (3, (4, 5)), - // check_types=False) + // with self.assertRaisesRegexp(ValueError, "same nested structure"): + // nest.map_structure(lambda x, y: None, ((3, 4), 5), (3, (4, 5)), + // check_types=False) - // with self.assertRaisesRegexp(ValueError, "Only valid keyword argument"): - // nest.map_structure(lambda x: None, structure1, foo="a") + // with self.assertRaisesRegexp(ValueError, "Only valid keyword argument"): + // nest.map_structure(lambda x: None, structure1, foo="a") - // with self.assertRaisesRegexp(ValueError, "Only valid keyword argument"): - // nest.map_structure(lambda x: None, structure1, check_types=False, foo="a") + // with self.assertRaisesRegexp(ValueError, "Only valid keyword argument"): + // nest.map_structure(lambda x: None, structure1, check_types=False, foo="a") - // ABTuple = collections.namedtuple("ab_tuple", "a, b") # pylint: disable=invalid-name + // ABTuple = collections.namedtuple("ab_tuple", "a, b") # pylint: disable=invalid-name + } // @test_util.assert_no_new_pyobjects_executing_eagerly // def testMapStructureWithStrings(self) :