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-15 12:25:19 +0300
commitd740b2be6e0e725bfdfba41cb0d3d298c404e40a (patch)
treeec42d7c0d44389d88895d534839f024b71e7bb44
parent38d300c16443b4f173067ea75cbe303fdd21618f (diff)
downloadrpm-d740b2be6e0e725bfdfba41cb0d3d298c404e40a.tar.gz
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. (cherry picked from commit 9d30318c0ad42e6a6c895d5a62bb209344d4f2da)
-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 b6e21ccd0..a790099ae 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -608,10 +608,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;