Fix misuse of PyObject_IsSubclass (#44769)

Summary:
PyObject_IsSubclass may set python live exception bit if given object is not a class. `IsNamedTuple` is currently using it incorrectly, which may trip all following python operations in debug-build python. Normal release-build python is not affected because `assert` is no-op in release-build.

Fixes https://github.com/pytorch/pytorch/issues/43577

Pull Request resolved: https://github.com/pytorch/pytorch/pull/44769

Reviewed By: jamesr66a

Differential Revision: D23725584

Pulled By: gmagogsfm

fbshipit-source-id: 2dabd4f8667a045d5bf75813500876c6fd81542b
This commit is contained in:
Yanan Cao
2020-09-16 16:16:05 -07:00
committed by Facebook GitHub Bot
parent 43fe034514
commit 6befc09465

View File

@ -720,8 +720,12 @@ std::shared_ptr<SugaredValue> PythonExceptionValue::call(
bool isNamedTupleClass(const py::object& obj) {
auto tuple_type = reinterpret_cast<PyObject*>(&PyTuple_Type);
return PyObject_IsSubclass(obj.ptr(), tuple_type) &&
py::hasattr(obj, "_fields");
int is_tuple_class = PyObject_IsSubclass(obj.ptr(), tuple_type);
if (is_tuple_class == -1) {
PyErr_Clear();
return false;
}
return is_tuple_class == 1 && py::hasattr(obj, "_fields");
}
TypePtr registerNamedTuple(const py::object& obj, const SourceRange& loc) {
@ -770,14 +774,13 @@ TypePtr registerNamedTuple(const py::object& obj, const SourceRange& loc) {
}
bool isEnumClass(py::object obj) {
py::bool_ is_class = py::module::import("inspect").attr("isclass")(obj);
if (!py::cast<bool>(is_class)) {
return false;
}
auto enum_type_obj =
py::cast<py::object>(py::module::import("enum").attr("Enum"));
int ret = PyObject_IsSubclass(obj.ptr(), enum_type_obj.ptr());
if (ret == -1) {
PyErr_Clear();
return false;
}
return ret == 1;
}