diff options
author | Panu Matilainen <Panu Matilainen pmatilai@redhat.com> | 2011-07-06 11:05:42 +0300 |
---|---|---|
committer | Panu Matilainen <Panu Matilainen pmatilai@redhat.com> | 2011-07-06 11:05:42 +0300 |
commit | 9d30318c0ad42e6a6c895d5a62bb209344d4f2da (patch) | |
tree | 1e94f60b5aa53e38aa799e9e94919d3eb3884592 | |
parent | d686c9b9b24ac93d2eb1098ad3f98e85f7810a28 (diff) | |
download | librpm-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.c | 10 |
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; |