Use PyObject_GetOptionalAttrString in PyObject_FastGetAttrString when available (#164624)

Python 3.13 added PyObject_GetOptionalAttrString. I'm not 100% certain that it is strictly better than the old approach in all cases, but based on documentation/comments it seems to be meant for this type of use, and it's faster when I profile torchtitan training (which gets to the "check for the `__torch_function__` attr on some object" part of maybe_has_torch_function frequently enough to notice, but wastes a bunch of time generating exceptions that we then suppressed here).
Pull Request resolved: https://github.com/pytorch/pytorch/pull/164624
Approved by: https://github.com/Skylion007
This commit is contained in:
Scott Wolchok
2025-10-03 17:02:13 -07:00
committed by PyTorch MergeBot
parent af32d16a71
commit 11f5f65686

View File

@ -3,6 +3,7 @@
#include <torch/csrc/python_headers.h>
#include <torch/csrc/utils/object_ptr.h>
#include <torch/csrc/utils/pybind.h>
#include <torch/csrc/utils/python_compat.h>
#include <stdexcept>
#include <string>
@ -98,6 +99,14 @@ inline void THPUtils_internStringInPlace(PyObject** obj) {
*/
inline py::object PyObject_FastGetAttrString(PyObject* obj, const char* name) {
#if IS_PYTHON_3_13_PLUS
PyObject* res = (PyObject*)nullptr;
int result_code = PyObject_GetOptionalAttrString(obj, name, &res);
if (result_code == -1) {
PyErr_Clear();
}
return py::reinterpret_steal<py::object>(res);
#else
PyTypeObject* tp = Py_TYPE(obj);
PyObject* res = (PyObject*)nullptr;
@ -122,4 +131,5 @@ inline py::object PyObject_FastGetAttrString(PyObject* obj, const char* name) {
}
}
return py::reinterpret_steal<py::object>(res);
#endif
}