>>> if (! PyInt_Check(p))
>>> {
>>> if (PyDict_Check(p))
>>> {
>>> if (PyString_Check(name) || PyUnicode_Check(name))
>>> {
>>> ASSIGN(p, PyObject_GetItem(p, name));
>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>
>>> if (p == NULL) {
>>> puts("PyObject returned NULL");
>>> PyErr_Clear();
>>> }
>>> }
>>> else
>>> p = PyInt_FromLong((long)1);
>>>
[Tim]
>> I note that all of this is nested inside another "if (p) {...}" block.
>> That implies the "p = PyInt_FromLong((long)1);" line is at least a
>> memory leak: it overwrites p without decref'ing p first.
[Jim]
> The ASSIGN macro DECREFs it's first argument if it is non-NULL.
>
> It loosly models a Python assignment, assuming that it owns the
> reference to the second argument.
ASSIGN isn't executed on the path in question. I really can't follow
nesting with that indentation style. Reformatting in Python style
makes it obvious to me:
if (p) {
if (! PyInt_Check(p)) {
if (PyDict_Check(p)) {
if (PyString_Check(name) || PyUnicode_Check(name)) {
ASSIGN(p, PyObject_GetItem(p, name));
if (p == NULL)
PyErr_Clear();
}
else
p = PyInt_FromLong(1);
}
else {
ASSIGN(p, callfunction2(p, name, value));
if (p == NULL)
goto err;
}
}
}
"p = PyInt_FromLong(1)" is in an ``else`` block. The only ASSIGN
before it is in that ``else`` block's disjoint ``if`` block.
_______________________________________________
Python-Dev mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com