Coverage Report

Created: 2026-03-19 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Objects/stringlib/repr.h
Line
Count
Source
1
/* stringlib: repr() implementation */
2
3
#ifndef STRINGLIB_FASTSEARCH_H
4
#error must include "stringlib/fastsearch.h" before including this module
5
#endif
6
7
8
static void
9
STRINGLIB(repr)(PyObject *unicode, Py_UCS4 quote,
10
                STRINGLIB_CHAR *odata)
11
1.53k
{
12
1.53k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.53k
    const void *idata = PyUnicode_DATA(unicode);
14
1.53k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
4.19M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
4.19M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
4.19M
        if ((ch == quote) || (ch == '\\')) {
22
27.5k
            *odata++ = '\\';
23
27.5k
            *odata++ = ch;
24
27.5k
            continue;
25
27.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
4.16M
        if (ch == '\t') {
29
4.67k
            *odata++ = '\\';
30
4.67k
            *odata++ = 't';
31
4.67k
        }
32
4.16M
        else if (ch == '\n') {
33
11.7k
            *odata++ = '\\';
34
11.7k
            *odata++ = 'n';
35
11.7k
        }
36
4.15M
        else if (ch == '\r') {
37
3.40k
            *odata++ = '\\';
38
3.40k
            *odata++ = 'r';
39
3.40k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
4.14M
        else if (ch < ' ' || ch == 0x7F) {
43
1.63M
            *odata++ = '\\';
44
1.63M
            *odata++ = 'x';
45
1.63M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
1.63M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
1.63M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.51M
        else if (ch < 0x7F) {
51
2.04M
            *odata++ = ch;
52
2.04M
        }
53
54
        /* Non-ASCII characters */
55
464k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
464k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
313k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
313k
                if (ch <= 0xff) {
63
310k
                    *odata++ = 'x';
64
310k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
310k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
310k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.21k
                else if (ch <= 0xffff) {
69
2.50k
                    *odata++ = 'u';
70
2.50k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
2.50k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
2.50k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
2.50k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
2.50k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
715
                else {
77
715
                    *odata++ = 'U';
78
715
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
715
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
715
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
715
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
715
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
715
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
715
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
715
                    *odata++ = Py_hexdigits[ch & 0xF];
86
715
                }
87
313k
            }
88
            /* Copy characters as-is */
89
150k
            else {
90
150k
                *odata++ = ch;
91
150k
            }
92
464k
        }
93
4.16M
    }
94
1.53k
    *odata = quote;
95
1.53k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
1.13k
{
12
1.13k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.13k
    const void *idata = PyUnicode_DATA(unicode);
14
1.13k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
2.20M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
2.19M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
2.19M
        if ((ch == quote) || (ch == '\\')) {
22
15.2k
            *odata++ = '\\';
23
15.2k
            *odata++ = ch;
24
15.2k
            continue;
25
15.2k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
2.18M
        if (ch == '\t') {
29
2.86k
            *odata++ = '\\';
30
2.86k
            *odata++ = 't';
31
2.86k
        }
32
2.18M
        else if (ch == '\n') {
33
3.98k
            *odata++ = '\\';
34
3.98k
            *odata++ = 'n';
35
3.98k
        }
36
2.17M
        else if (ch == '\r') {
37
2.03k
            *odata++ = '\\';
38
2.03k
            *odata++ = 'r';
39
2.03k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
2.17M
        else if (ch < ' ' || ch == 0x7F) {
43
773k
            *odata++ = '\\';
44
773k
            *odata++ = 'x';
45
773k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
773k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
773k
        }
48
49
        /* Copy ASCII characters as-is */
50
1.40M
        else if (ch < 0x7F) {
51
960k
            *odata++ = ch;
52
960k
        }
53
54
        /* Non-ASCII characters */
55
441k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
441k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
308k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
308k
                if (ch <= 0xff) {
63
306k
                    *odata++ = 'x';
64
306k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
306k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
306k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
1.47k
                else if (ch <= 0xffff) {
69
1.12k
                    *odata++ = 'u';
70
1.12k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.12k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.12k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.12k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.12k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
355
                else {
77
355
                    *odata++ = 'U';
78
355
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
355
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
355
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
355
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
355
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
355
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
355
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
355
                    *odata++ = Py_hexdigits[ch & 0xF];
86
355
                }
87
308k
            }
88
            /* Copy characters as-is */
89
133k
            else {
90
133k
                *odata++ = ch;
91
133k
            }
92
441k
        }
93
2.18M
    }
94
1.13k
    *odata = quote;
95
1.13k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
215
{
12
215
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
215
    const void *idata = PyUnicode_DATA(unicode);
14
215
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
928k
    for (Py_ssize_t i = 0; i < isize; i++) {
18
927k
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
927k
        if ((ch == quote) || (ch == '\\')) {
22
7.22k
            *odata++ = '\\';
23
7.22k
            *odata++ = ch;
24
7.22k
            continue;
25
7.22k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
920k
        if (ch == '\t') {
29
1.48k
            *odata++ = '\\';
30
1.48k
            *odata++ = 't';
31
1.48k
        }
32
919k
        else if (ch == '\n') {
33
2.74k
            *odata++ = '\\';
34
2.74k
            *odata++ = 'n';
35
2.74k
        }
36
916k
        else if (ch == '\r') {
37
596
            *odata++ = '\\';
38
596
            *odata++ = 'r';
39
596
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
915k
        else if (ch < ' ' || ch == 0x7F) {
43
264k
            *odata++ = '\\';
44
264k
            *odata++ = 'x';
45
264k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
264k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
264k
        }
48
49
        /* Copy ASCII characters as-is */
50
651k
        else if (ch < 0x7F) {
51
632k
            *odata++ = ch;
52
632k
        }
53
54
        /* Non-ASCII characters */
55
19.0k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
19.0k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
4.41k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
4.41k
                if (ch <= 0xff) {
63
3.14k
                    *odata++ = 'x';
64
3.14k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.14k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.14k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
1.27k
                else if (ch <= 0xffff) {
69
1.02k
                    *odata++ = 'u';
70
1.02k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.02k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.02k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.02k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.02k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
247
                else {
77
247
                    *odata++ = 'U';
78
247
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
247
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
247
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
247
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
247
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
247
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
247
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
247
                    *odata++ = Py_hexdigits[ch & 0xF];
86
247
                }
87
4.41k
            }
88
            /* Copy characters as-is */
89
14.6k
            else {
90
14.6k
                *odata++ = ch;
91
14.6k
            }
92
19.0k
        }
93
920k
    }
94
215
    *odata = quote;
95
215
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
187
{
12
187
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
187
    const void *idata = PyUnicode_DATA(unicode);
14
187
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.06M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.06M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.06M
        if ((ch == quote) || (ch == '\\')) {
22
5.04k
            *odata++ = '\\';
23
5.04k
            *odata++ = ch;
24
5.04k
            continue;
25
5.04k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.06M
        if (ch == '\t') {
29
329
            *odata++ = '\\';
30
329
            *odata++ = 't';
31
329
        }
32
1.06M
        else if (ch == '\n') {
33
5.03k
            *odata++ = '\\';
34
5.03k
            *odata++ = 'n';
35
5.03k
        }
36
1.05M
        else if (ch == '\r') {
37
773
            *odata++ = '\\';
38
773
            *odata++ = 'r';
39
773
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.05M
        else if (ch < ' ' || ch == 0x7F) {
43
598k
            *odata++ = '\\';
44
598k
            *odata++ = 'x';
45
598k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
598k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
598k
        }
48
49
        /* Copy ASCII characters as-is */
50
460k
        else if (ch < 0x7F) {
51
456k
            *odata++ = ch;
52
456k
        }
53
54
        /* Non-ASCII characters */
55
3.24k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
3.24k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
1.40k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
1.40k
                if (ch <= 0xff) {
63
933
                    *odata++ = 'x';
64
933
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
933
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
933
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
471
                else if (ch <= 0xffff) {
69
358
                    *odata++ = 'u';
70
358
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
358
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
358
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
358
                    *odata++ = Py_hexdigits[ch & 0xF];
74
358
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
113
                else {
77
113
                    *odata++ = 'U';
78
113
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
113
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
113
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
113
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
113
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
113
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
113
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
113
                    *odata++ = Py_hexdigits[ch & 0xF];
86
113
                }
87
1.40k
            }
88
            /* Copy characters as-is */
89
1.84k
            else {
90
1.84k
                *odata++ = ch;
91
1.84k
            }
92
3.24k
        }
93
1.06M
    }
94
187
    *odata = quote;
95
187
}