MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / AssertSameStructureHelper

Function AssertSameStructureHelper

tensorflow/python/util/util.cc:655–838  ·  view source on GitHub ↗

Returns true iff there were no "internal" errors. In other words, errors that has nothing to do with structure checking. If an "internal" error occurred, the appropriate Python error will be set and the caller can propage it directly to the user. Both `error_msg` and `is_type_error` must be non-null. `error_msg` must be empty. Leaves `error_msg` empty if structures matched. Else, fills `error_msg

Source from the content-addressed store, hash-verified

653// with appropriate error and sets `is_type_error` to true iff
654// the error to be raised should be TypeError.
655bool AssertSameStructureHelper(
656 PyObject* o1, PyObject* o2, bool check_types, string* error_msg,
657 bool* is_type_error,
658 const std::function<int(PyObject*)>& is_sequence_helper,
659 const std::function<ValueIteratorPtr(PyObject*)>& value_iterator_getter,
660 bool check_composite_tensor_type_spec) {
661 DCHECK(error_msg);
662 DCHECK(is_type_error);
663 const bool is_seq1 = is_sequence_helper(o1);
664 const bool is_seq2 = is_sequence_helper(o2);
665 if (PyErr_Occurred()) return false;
666 if (is_seq1 != is_seq2) {
667 string seq_str = is_seq1 ? PyObjectToString(o1) : PyObjectToString(o2);
668 string non_seq_str = is_seq1 ? PyObjectToString(o2) : PyObjectToString(o1);
669 *is_type_error = false;
670 *error_msg = tensorflow::strings::StrCat(
671 "Substructure \"", seq_str, "\" is a sequence, while substructure \"",
672 non_seq_str, "\" is not");
673 return true;
674 }
675
676 // Got to objects that are considered non-sequences. Note that in tf.data
677 // use case lists and sparse_tensors are not considered sequences. So finished
678 // checking, structures are the same.
679 if (!is_seq1) return true;
680
681 if (check_types) {
682 const PyTypeObject* type1 = o1->ob_type;
683 const PyTypeObject* type2 = o2->ob_type;
684
685 // We treat two different namedtuples with identical name and fields
686 // as having the same type.
687 const PyObject* o1_tuple = IsNamedtuple(o1, true);
688 if (o1_tuple == nullptr) return false;
689 const PyObject* o2_tuple = IsNamedtuple(o2, true);
690 if (o2_tuple == nullptr) {
691 Py_DECREF(o1_tuple);
692 return false;
693 }
694 bool both_tuples = o1_tuple == Py_True && o2_tuple == Py_True;
695 Py_DECREF(o1_tuple);
696 Py_DECREF(o2_tuple);
697
698 if (both_tuples) {
699 const PyObject* same_tuples = SameNamedtuples(o1, o2);
700 if (same_tuples == nullptr) return false;
701 bool not_same_tuples = same_tuples != Py_True;
702 Py_DECREF(same_tuples);
703 if (not_same_tuples) {
704 *is_type_error = true;
705 *error_msg = tensorflow::strings::StrCat(
706 "The two namedtuples don't have the same sequence type. "
707 "First structure ",
708 PyObjectToString(o1), " has type ", type1->tp_name,
709 ", while second structure ", PyObjectToString(o2), " has type ",
710 type2->tp_name);
711 return true;
712 }

Callers 2

AssertSameStructureFunction · 0.85

Calls 13

IsNamedtupleFunction · 0.85
SameNamedtuplesFunction · 0.85
IsMappingHelperFunction · 0.85
IsCompositeTensorFunction · 0.85
IsTypeSpecFunction · 0.85
SetDifferentKeysErrorFunction · 0.85
PyObjectToStringFunction · 0.70
StrCatFunction · 0.50
getMethod · 0.45
resetMethod · 0.45
validMethod · 0.45
nextMethod · 0.45

Tested by

no test coverage detected