summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <Panu Matilainen pmatilai@redhat.com>2011-07-06 11:05:42 +0300
committerPanu Matilainen <Panu Matilainen pmatilai@redhat.com>2011-07-06 11:05:42 +0300
commit9d30318c0ad42e6a6c895d5a62bb209344d4f2da (patch)
tree1e94f60b5aa53e38aa799e9e94919d3eb3884592
parentd686c9b9b24ac93d2eb1098ad3f98e85f7810a28 (diff)
downloadlibrpm-tizen-9d30318c0ad42e6a6c895d5a62bb209344d4f2da.tar.gz
librpm-tizen-9d30318c0ad42e6a6c895d5a62bb209344d4f2da.tar.bz2
librpm-tizen-9d30318c0ad42e6a6c895d5a62bb209344d4f2da.zip
Fix the broken python header __getattr__() behavior, take 13 (or so)
- Tags as header attributes seemed like a nice idea at the time... but has been a PITA due to side-effects it causes, such as breaking getattr() use for "capability testing", eg: >>> h2 = copy.deepcopy(h) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/copy.py", line 172, in deepcopy copier = getattr(x, "__deepcopy__", None) ValueError: unknown header tag - Since we can't really go removing the brainded feature (somebody might actually be using it) try harder to fix it: if its not an actual attribute, save the exception we got from PyObject_GenericGetAttr() and if its not a valid tag either, restore the original exception. This allows cases like the above __deepcopy__ to work properly.
-rw-r--r--python/header-py.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/python/header-py.c b/python/header-py.c
index e594ebe2a..3482dd2a8 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -623,10 +623,18 @@ static PyObject * hdr_getattro(hdrObject * s, PyObject * n)
{
PyObject *res = PyObject_GenericGetAttr((PyObject *) s, n);
if (res == NULL) {
+ PyObject *type, *value, *traceback;
rpmTagVal tag;
+
+ /* Save and restore original exception if it's not a valid tag either */
+ PyErr_Fetch(&type, &value, &traceback);
if (tagNumFromPyObject(n, &tag)) {
- PyErr_Clear();
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
res = hdrGetTag(s->h, tag);
+ } else {
+ PyErr_Restore(type, value, traceback);
}
}
return res;