Skip to content

Commit

Permalink
C implementation, and add tests that BaseException isn't caught.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Aug 2, 2018
1 parent 1e9f7c4 commit 31d240a
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
62 changes: 61 additions & 1 deletion persistent/cPersistence.c
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,66 @@ Per_set_sticky(cPersistentObject *self, PyObject* value)
return 0;
}

static PyObject*
repr_helper(PyObject *o, char* format)
{
/* Returns a new reference, or NULL on error */
PyObject *exc_t;
PyObject *exc_v;
PyObject *exc_tb;
PyObject *result;

if (o)
{
result = PyUnicode_FromFormat(format, o);
if (!result && PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_Exception))
{
PyErr_Fetch(&exc_t, &exc_v, &exc_tb);
PyErr_NormalizeException(&exc_t, &exc_v, &exc_tb);
PyErr_Clear();

result = PyUnicode_FromFormat(format, exc_v);
Py_DECREF(exc_t);
Py_DECREF(exc_v);
Py_DECREF(exc_tb);
}
}
else
{
result = PyUnicode_FromString("");
}

return result;

}

static PyObject*
Per_repr(cPersistentObject *self)
{
PyObject *oid_str = NULL;
PyObject *jar_str = NULL;
PyObject *result = NULL;


oid_str = repr_helper(self->oid, " oid %R");
if (!oid_str)
goto cleanup;

jar_str = repr_helper(self->jar, " in %R");
if (!jar_str)
goto cleanup;

result = PyUnicode_FromFormat("<%s object at %p%S%S>",
Py_TYPE(self)->tp_name, self,
oid_str, jar_str);

cleanup:
Py_XDECREF(oid_str);
Py_XDECREF(jar_str);

return result;
}

static PyGetSetDef Per_getsets[] = {
{"_p_changed", (getter)Per_get_changed, (setter)Per_set_changed},
{"_p_jar", (getter)Per_get_jar, (setter)Per_set_jar},
Expand Down Expand Up @@ -1454,7 +1514,7 @@ static PyTypeObject Pertype = {
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
(reprfunc)Per_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
Expand Down
21 changes: 21 additions & 0 deletions persistent/tests/test_persistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,27 @@ def __repr__(self):
"<persistent.Persistent object at 0xdeadbeef oid Exception('oid repr failed')"
" in Exception('jar repr failed')>")

def test_repr_no_oid_repr_jar_raises_baseexception(self):
p = self._makeOne()

class Jar(object):
def __repr__(self):
raise BaseException('jar repr failed')

p._p_jar = Jar()
with self.assertRaisesRegex(BaseException, 'jar repr failed'):
repr(p)

def test_repr_oid_raises_baseexception_no_jar(self):
p = self._makeOne()

class BadOID(bytes):
def __repr__(self):
raise BaseException("oid repr failed")
p._p_oid = BadOID(b'12345678')

with self.assertRaisesRegex(BaseException, 'oid repr failed'):
repr(p)

def test_repr_oid_and_jar(self):
p = self._makeOne()
Expand Down

0 comments on commit 31d240a

Please sign in to comment.