Skip to content

Commit

Permalink
Use the exact type name in Record.__repr__
Browse files Browse the repository at this point in the history
We support Record subclasses, so include the exact type name (rather
than just 'Record') in the repr() string.
  • Loading branch information
jparise committed Oct 11, 2022
1 parent 84c99bf commit b4b03de
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
29 changes: 25 additions & 4 deletions asyncpg/protocol/record/recordobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,16 +451,31 @@ record_subscript(ApgRecordObject* o, PyObject* item)
}


static const char *
get_typename(PyTypeObject *type)
{
assert(type->tp_name != NULL);
const char *s = strrchr(type->tp_name, '.');
if (s == NULL) {
s = type->tp_name;
}
else {
s++;
}
return s;
}


static PyObject *
record_repr(ApgRecordObject *v)
{
Py_ssize_t i, n;
PyObject *keys_iter;
PyObject *keys_iter, *type_prefix;
_PyUnicodeWriter writer;

n = Py_SIZE(v);
if (n == 0) {
return PyUnicode_FromString("<Record>");
return PyUnicode_FromFormat("<%s>", get_typename(Py_TYPE(v)));
}

keys_iter = PyObject_GetIter(v->desc->keys);
Expand All @@ -471,16 +486,22 @@ record_repr(ApgRecordObject *v)
i = Py_ReprEnter((PyObject *)v);
if (i != 0) {
Py_DECREF(keys_iter);
return i > 0 ? PyUnicode_FromString("<Record ...>") : NULL;
if (i > 0) {
return PyUnicode_FromFormat("<%s ...>", get_typename(Py_TYPE(v)));
}
return NULL;
}

_PyUnicodeWriter_Init(&writer);
writer.overallocate = 1;
writer.min_length = 12; /* <Record a=1> */

if (_PyUnicodeWriter_WriteASCIIString(&writer, "<Record ", 8) < 0) {
type_prefix = PyUnicode_FromFormat("<%s ", get_typename(Py_TYPE(v)));
if (_PyUnicodeWriter_WriteStr(&writer, type_prefix) < 0) {
Py_DECREF(type_prefix);
goto error;
}
Py_DECREF(type_prefix);

for (i = 0; i < n; ++i) {
PyObject *key;
Expand Down
1 change: 1 addition & 0 deletions tests/test_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ class MyRecord(asyncpg.Record):
record_class=MyRecord,
)
self.assertIsInstance(r, MyRecord)
self.assertEqual(repr(r), "<MyRecord a=1 b='2'>")

self.assertEqual(list(r.items()), [('a', 1), ('b', '2')])
self.assertEqual(list(r.keys()), ['a', 'b'])
Expand Down

0 comments on commit b4b03de

Please sign in to comment.