| 980 | } |
| 981 | |
| 982 | PyObject* AssertSameStructure(PyObject* o1, PyObject* o2, bool check_types, |
| 983 | bool expand_composites) { |
| 984 | const std::function<int(PyObject*)>& is_sequence_helper = |
| 985 | expand_composites ? IsSequenceOrCompositeHelper : IsSequenceHelper; |
| 986 | const std::function<ValueIteratorPtr(PyObject*)>& get_value_iterator = |
| 987 | expand_composites ? GetValueIteratorForComposite : GetValueIterator; |
| 988 | const bool check_composite_tensor_type_spec = expand_composites; |
| 989 | string error_msg; |
| 990 | bool is_type_error = false; |
| 991 | AssertSameStructureHelper(o1, o2, check_types, &error_msg, &is_type_error, |
| 992 | is_sequence_helper, get_value_iterator, |
| 993 | check_composite_tensor_type_spec); |
| 994 | if (PyErr_Occurred()) { |
| 995 | // Don't hide Python exceptions while checking (e.g. errors fetching keys |
| 996 | // from custom mappings). |
| 997 | return nullptr; |
| 998 | } |
| 999 | if (!error_msg.empty()) { |
| 1000 | PyErr_SetString( |
| 1001 | is_type_error ? PyExc_TypeError : PyExc_ValueError, |
| 1002 | tensorflow::strings::StrCat( |
| 1003 | "The two structures don't have the same nested structure.\n\n", |
| 1004 | "First structure: ", PyObjectToString(o1), "\n\nSecond structure: ", |
| 1005 | PyObjectToString(o2), "\n\nMore specifically: ", error_msg) |
| 1006 | .c_str()); |
| 1007 | return nullptr; |
| 1008 | } |
| 1009 | Py_RETURN_NONE; |
| 1010 | } |
| 1011 | |
| 1012 | PyObject* AssertSameStructureForData(PyObject* o1, PyObject* o2, |
| 1013 | bool check_types) { |
nothing calls this directly
no test coverage detected