Skip to content

Commit 71b8bce

Browse files
committed
task: allow overriding methods of PythonTask
1 parent ba256a8 commit 71b8bce

File tree

2 files changed

+25
-28
lines changed

2 files changed

+25
-28
lines changed

panda/src/event/pythonTask.cxx

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,25 @@ exception() const {
283283
*/
284284
int PythonTask::
285285
__setattr__(PyObject *self, PyObject *attr, PyObject *v) {
286-
if (PyObject_GenericSetAttr(self, attr, v) == 0) {
287-
return 0;
288-
}
289-
290-
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
286+
#if PY_MAJOR_VERSION >= 3
287+
if (!PyUnicode_Check(attr)) {
288+
#else
289+
if (!PyString_Check(attr)) {
290+
#endif
291+
PyErr_Format(PyExc_TypeError,
292+
"attribute name must be string, not '%.200s'",
293+
attr->ob_type->tp_name);
291294
return -1;
292295
}
293296

294-
PyErr_Clear();
297+
PyObject *descr = _PyType_Lookup(Py_TYPE(self), attr);
298+
if (descr != nullptr) {
299+
Py_INCREF(descr);
300+
descrsetfunc f = descr->ob_type->tp_descr_set;
301+
if (f != nullptr) {
302+
return f(descr, self, v);
303+
}
304+
}
295305

296306
if (task_cat.is_debug()) {
297307
PyObject *str = PyObject_Repr(v);
@@ -352,31 +362,18 @@ __delattr__(PyObject *self, PyObject *attr) {
352362
* object.
353363
*/
354364
PyObject *PythonTask::
355-
__getattr__(PyObject *attr) const {
356-
// Note that with the new Interrogate behavior, this method behaves more
357-
// like the Python __getattr__ rather than being directly assigned to the
358-
// tp_getattro slot (a la __getattribute__). So, we won't get here when the
359-
// attribute has already been found via other methods.
360-
365+
__getattribute__(PyObject *self, PyObject *attr) const {
366+
// We consult the instance dict first, since the user may have overridden a
367+
// method or something.
361368
PyObject *item = PyDict_GetItem(__dict__, attr);
362369

363-
if (item == nullptr) {
364-
// PyDict_GetItem does not raise an exception.
365-
#if PY_MAJOR_VERSION < 3
366-
PyErr_Format(PyExc_AttributeError,
367-
"'PythonTask' object has no attribute '%.400s'",
368-
PyString_AS_STRING(attr));
369-
#else
370-
PyErr_Format(PyExc_AttributeError,
371-
"'PythonTask' object has no attribute '%U'",
372-
attr);
373-
#endif
374-
return nullptr;
370+
if (item != nullptr) {
371+
// PyDict_GetItem returns a borrowed reference.
372+
Py_INCREF(item);
373+
return item;
375374
}
376375

377-
// PyDict_GetItem returns a borrowed reference.
378-
Py_INCREF(item);
379-
return item;
376+
return PyObject_GenericGetAttr(self, attr);
380377
}
381378

382379
/**

panda/src/event/pythonTask.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class PythonTask final : public AsyncTask {
5555
PUBLISHED:
5656
int __setattr__(PyObject *self, PyObject *attr, PyObject *v);
5757
int __delattr__(PyObject *self, PyObject *attr);
58-
PyObject *__getattr__(PyObject *attr) const;
58+
PyObject *__getattribute__(PyObject *self, PyObject *attr) const;
5959

6060
int __traverse__(visitproc visit, void *arg);
6161
int __clear__();

0 commit comments

Comments
 (0)