summaryrefslogtreecommitdiffstats
path: root/Objects/unicodeobject.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-04-12 19:51:34 (GMT)
committerGitHub <noreply@github.com>2019-04-12 19:51:34 (GMT)
commit0fc91eef34a1d9194904fa093c9fbd711af0f26c (patch)
treebeec907827203135c5c5baa9303fcb27776088a3 /Objects/unicodeobject.c
parent23a683adf803eef405d248cc9c2a7eb08a7300e2 (diff)
downloadcpython-0fc91eef34a1d9194904fa093c9fbd711af0f26c.zip
cpython-0fc91eef34a1d9194904fa093c9fbd711af0f26c.tar.gz
cpython-0fc91eef34a1d9194904fa093c9fbd711af0f26c.tar.bz2
bpo-36389: Add _PyObject_CheckConsistency() function (GH-12803)
Add a new _PyObject_CheckConsistency() function which can be used to help debugging. The function is available in release mode. Add a 'check_content' parameter to _PyDict_CheckConsistency().
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r--Objects/unicodeobject.c93
1 files changed, 44 insertions, 49 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index e00dc37..f6e68c9 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -401,23 +401,20 @@ PyUnicode_GetMax(void)
#endif
}
-#ifdef Py_DEBUG
int
_PyUnicode_CheckConsistency(PyObject *op, int check_content)
{
-#define ASSERT(expr) _PyObject_ASSERT(op, (expr))
-
PyASCIIObject *ascii;
unsigned int kind;
- ASSERT(PyUnicode_Check(op));
+ _PyObject_ASSERT(op, PyUnicode_Check(op));
ascii = (PyASCIIObject *)op;
kind = ascii->state.kind;
if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
- ASSERT(kind == PyUnicode_1BYTE_KIND);
- ASSERT(ascii->state.ready == 1);
+ _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND);
+ _PyObject_ASSERT(op, ascii->state.ready == 1);
}
else {
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
@@ -425,41 +422,41 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
if (ascii->state.compact == 1) {
data = compact + 1;
- ASSERT(kind == PyUnicode_1BYTE_KIND
- || kind == PyUnicode_2BYTE_KIND
- || kind == PyUnicode_4BYTE_KIND);
- ASSERT(ascii->state.ascii == 0);
- ASSERT(ascii->state.ready == 1);
- ASSERT (compact->utf8 != data);
+ _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND
+ || kind == PyUnicode_2BYTE_KIND
+ || kind == PyUnicode_4BYTE_KIND);
+ _PyObject_ASSERT(op, ascii->state.ascii == 0);
+ _PyObject_ASSERT(op, ascii->state.ready == 1);
+ _PyObject_ASSERT(op, compact->utf8 != data);
}
else {
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
data = unicode->data.any;
if (kind == PyUnicode_WCHAR_KIND) {
- ASSERT(ascii->length == 0);
- ASSERT(ascii->hash == -1);
- ASSERT(ascii->state.compact == 0);
- ASSERT(ascii->state.ascii == 0);
- ASSERT(ascii->state.ready == 0);
- ASSERT(ascii->state.interned == SSTATE_NOT_INTERNED);
- ASSERT(ascii->wstr != NULL);
- ASSERT(data == NULL);
- ASSERT(compact->utf8 == NULL);
+ _PyObject_ASSERT(op, ascii->length == 0);
+ _PyObject_ASSERT(op, ascii->hash == -1);
+ _PyObject_ASSERT(op, ascii->state.compact == 0);
+ _PyObject_ASSERT(op, ascii->state.ascii == 0);
+ _PyObject_ASSERT(op, ascii->state.ready == 0);
+ _PyObject_ASSERT(op, ascii->state.interned == SSTATE_NOT_INTERNED);
+ _PyObject_ASSERT(op, ascii->wstr != NULL);
+ _PyObject_ASSERT(op, data == NULL);
+ _PyObject_ASSERT(op, compact->utf8 == NULL);
}
else {
- ASSERT(kind == PyUnicode_1BYTE_KIND
- || kind == PyUnicode_2BYTE_KIND
- || kind == PyUnicode_4BYTE_KIND);
- ASSERT(ascii->state.compact == 0);
- ASSERT(ascii->state.ready == 1);
- ASSERT(data != NULL);
+ _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND
+ || kind == PyUnicode_2BYTE_KIND
+ || kind == PyUnicode_4BYTE_KIND);
+ _PyObject_ASSERT(op, ascii->state.compact == 0);
+ _PyObject_ASSERT(op, ascii->state.ready == 1);
+ _PyObject_ASSERT(op, data != NULL);
if (ascii->state.ascii) {
- ASSERT (compact->utf8 == data);
- ASSERT (compact->utf8_length == ascii->length);
+ _PyObject_ASSERT(op, compact->utf8 == data);
+ _PyObject_ASSERT(op, compact->utf8_length == ascii->length);
}
else
- ASSERT (compact->utf8 != data);
+ _PyObject_ASSERT(op, compact->utf8 != data);
}
}
if (kind != PyUnicode_WCHAR_KIND) {
@@ -471,20 +468,20 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
#endif
)
{
- ASSERT(ascii->wstr == data);
- ASSERT(compact->wstr_length == ascii->length);
+ _PyObject_ASSERT(op, ascii->wstr == data);
+ _PyObject_ASSERT(op, compact->wstr_length == ascii->length);
} else
- ASSERT(ascii->wstr != data);
+ _PyObject_ASSERT(op, ascii->wstr != data);
}
if (compact->utf8 == NULL)
- ASSERT(compact->utf8_length == 0);
+ _PyObject_ASSERT(op, compact->utf8_length == 0);
if (ascii->wstr == NULL)
- ASSERT(compact->wstr_length == 0);
+ _PyObject_ASSERT(op, compact->wstr_length == 0);
}
- /* check that the best kind is used */
- if (check_content && kind != PyUnicode_WCHAR_KIND)
- {
+
+ /* check that the best kind is used: O(n) operation */
+ if (check_content && kind != PyUnicode_WCHAR_KIND) {
Py_ssize_t i;
Py_UCS4 maxchar = 0;
void *data;
@@ -499,27 +496,25 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
}
if (kind == PyUnicode_1BYTE_KIND) {
if (ascii->state.ascii == 0) {
- ASSERT(maxchar >= 128);
- ASSERT(maxchar <= 255);
+ _PyObject_ASSERT(op, maxchar >= 128);
+ _PyObject_ASSERT(op, maxchar <= 255);
}
else
- ASSERT(maxchar < 128);
+ _PyObject_ASSERT(op, maxchar < 128);
}
else if (kind == PyUnicode_2BYTE_KIND) {
- ASSERT(maxchar >= 0x100);
- ASSERT(maxchar <= 0xFFFF);
+ _PyObject_ASSERT(op, maxchar >= 0x100);
+ _PyObject_ASSERT(op, maxchar <= 0xFFFF);
}
else {
- ASSERT(maxchar >= 0x10000);
- ASSERT(maxchar <= MAX_UNICODE);
+ _PyObject_ASSERT(op, maxchar >= 0x10000);
+ _PyObject_ASSERT(op, maxchar <= MAX_UNICODE);
}
- ASSERT(PyUnicode_READ(kind, data, ascii->length) == 0);
+ _PyObject_ASSERT(op, PyUnicode_READ(kind, data, ascii->length) == 0);
}
return 1;
-
-#undef ASSERT
}
-#endif
+
static PyObject*
unicode_result_wchar(PyObject *unicode)