Skip to content

Commit df875b9

Browse files
committed
New private API function _PyInstance_Lookup. gc will use this to figure
out whether __del__ exists, without executing any Python-level code.
1 parent cb8ed53 commit df875b9

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

Include/classobject.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
5151
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
5252
PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *);
5353

54+
/* Look up attribute with name (a string) on instance object pinst, using
55+
* only the instance and base class dicts. If a descriptor is found in
56+
* a class dict, the descriptor is returned without calling it.
57+
* Returns NULL if nothing found, else a borrowed reference to the
58+
* value associated with name in the dict in which name was found.
59+
* The point of this routine is that it never calls arbitrary Python
60+
* code, so is always "safe": all it does is dict lookups. The function
61+
* can't fail, never sets an exceptionm, and NULL is not an error (it just
62+
* means "not found").
63+
*/
64+
PyAPI_FUNC(PyObject *)_PyInstance_Lookup(PyObject *pinst, PyObject *name);
65+
5466
/* Macros for direct access to these values. Type checks are *not*
5567
done, so use with care. */
5668
#define PyMethod_GET_FUNCTION(meth) \

Objects/classobject.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,27 @@ instance_getattr(register PyInstanceObject *inst, PyObject *name)
759759
return res;
760760
}
761761

762+
/* See classobject.h comments: this only does dict lookups, and is always
763+
* safe to call.
764+
*/
765+
PyObject *
766+
_PyInstance_Lookup(PyObject *pinst, PyObject *name)
767+
{
768+
PyObject *v;
769+
PyClassObject *class;
770+
PyInstanceObject *inst; /* pinst cast to the right type */
771+
772+
assert(PyInstance_Check(pinst));
773+
inst = (PyInstanceObject *)pinst;
774+
775+
assert(PyString_Check(name));
776+
777+
v = PyDict_GetItem(inst->in_dict, name);
778+
if (v == NULL)
779+
v = class_lookup(inst->in_class, name, &class);
780+
return v;
781+
}
782+
762783
static int
763784
instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v)
764785
{

0 commit comments

Comments
 (0)