Coverage Report

Created: 2026-05-16 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/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
5.92M
{
12
5.92M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.92M
    const void *idata = PyUnicode_DATA(unicode);
14
5.92M
    int ikind = PyUnicode_KIND(unicode);
15
16
5.92M
    *odata++ = quote;
17
229M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
223M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
223M
        if ((ch == quote) || (ch == '\\')) {
22
207k
            *odata++ = '\\';
23
207k
            *odata++ = ch;
24
207k
            continue;
25
207k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
223M
        if (ch == '\t') {
29
455k
            *odata++ = '\\';
30
455k
            *odata++ = 't';
31
455k
        }
32
223M
        else if (ch == '\n') {
33
3.83M
            *odata++ = '\\';
34
3.83M
            *odata++ = 'n';
35
3.83M
        }
36
219M
        else if (ch == '\r') {
37
12.6k
            *odata++ = '\\';
38
12.6k
            *odata++ = 'r';
39
12.6k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
219M
        else if (ch < ' ' || ch == 0x7F) {
43
156M
            *odata++ = '\\';
44
156M
            *odata++ = 'x';
45
156M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
156M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
156M
        }
48
49
        /* Copy ASCII characters as-is */
50
62.8M
        else if (ch < 0x7F) {
51
52.9M
            *odata++ = ch;
52
52.9M
        }
53
54
        /* Non-ASCII characters */
55
9.96M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.96M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
323k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
323k
                if (ch <= 0xff) {
63
71.4k
                    *odata++ = 'x';
64
71.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
71.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
71.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
251k
                else if (ch <= 0xffff) {
69
90.3k
                    *odata++ = 'u';
70
90.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
90.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
90.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
90.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
90.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
161k
                else {
77
161k
                    *odata++ = 'U';
78
161k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
161k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
161k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
161k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
161k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
161k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
161k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
161k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
161k
                }
87
323k
            }
88
            /* Copy characters as-is */
89
9.64M
            else {
90
9.64M
                *odata++ = ch;
91
9.64M
            }
92
9.96M
        }
93
223M
    }
94
5.92M
    *odata = quote;
95
5.92M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
5.67M
{
12
5.67M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.67M
    const void *idata = PyUnicode_DATA(unicode);
14
5.67M
    int ikind = PyUnicode_KIND(unicode);
15
16
5.67M
    *odata++ = quote;
17
76.7M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
71.0M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
71.0M
        if ((ch == quote) || (ch == '\\')) {
22
118k
            *odata++ = '\\';
23
118k
            *odata++ = ch;
24
118k
            continue;
25
118k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
70.9M
        if (ch == '\t') {
29
430k
            *odata++ = '\\';
30
430k
            *odata++ = 't';
31
430k
        }
32
70.5M
        else if (ch == '\n') {
33
3.74M
            *odata++ = '\\';
34
3.74M
            *odata++ = 'n';
35
3.74M
        }
36
66.7M
        else if (ch == '\r') {
37
5.83k
            *odata++ = '\\';
38
5.83k
            *odata++ = 'r';
39
5.83k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
66.7M
        else if (ch < ' ' || ch == 0x7F) {
43
46.8M
            *odata++ = '\\';
44
46.8M
            *odata++ = 'x';
45
46.8M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
46.8M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
46.8M
        }
48
49
        /* Copy ASCII characters as-is */
50
19.9M
        else if (ch < 0x7F) {
51
19.7M
            *odata++ = ch;
52
19.7M
        }
53
54
        /* Non-ASCII characters */
55
150k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
150k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
76.7k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
76.7k
                if (ch <= 0xff) {
63
31.5k
                    *odata++ = 'x';
64
31.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
31.5k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
31.5k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
45.2k
                else if (ch <= 0xffff) {
69
36.1k
                    *odata++ = 'u';
70
36.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
36.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
36.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
36.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
36.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
9.05k
                else {
77
9.05k
                    *odata++ = 'U';
78
9.05k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
9.05k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
9.05k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
9.05k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
9.05k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
9.05k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
9.05k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
9.05k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
9.05k
                }
87
76.7k
            }
88
            /* Copy characters as-is */
89
73.8k
            else {
90
73.8k
                *odata++ = ch;
91
73.8k
            }
92
150k
        }
93
70.9M
    }
94
5.67M
    *odata = quote;
95
5.67M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
240k
{
12
240k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
240k
    const void *idata = PyUnicode_DATA(unicode);
14
240k
    int ikind = PyUnicode_KIND(unicode);
15
16
240k
    *odata++ = quote;
17
134M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
134M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
134M
        if ((ch == quote) || (ch == '\\')) {
22
67.3k
            *odata++ = '\\';
23
67.3k
            *odata++ = ch;
24
67.3k
            continue;
25
67.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
134M
        if (ch == '\t') {
29
21.4k
            *odata++ = '\\';
30
21.4k
            *odata++ = 't';
31
21.4k
        }
32
134M
        else if (ch == '\n') {
33
83.7k
            *odata++ = '\\';
34
83.7k
            *odata++ = 'n';
35
83.7k
        }
36
134M
        else if (ch == '\r') {
37
3.75k
            *odata++ = '\\';
38
3.75k
            *odata++ = 'r';
39
3.75k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
134M
        else if (ch < ' ' || ch == 0x7F) {
43
93.6M
            *odata++ = '\\';
44
93.6M
            *odata++ = 'x';
45
93.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
93.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
93.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
40.8M
        else if (ch < 0x7F) {
51
31.4M
            *odata++ = ch;
52
31.4M
        }
53
54
        /* Non-ASCII characters */
55
9.41M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.41M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
181k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
181k
                if (ch <= 0xff) {
63
36.7k
                    *odata++ = 'x';
64
36.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
36.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
36.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
144k
                else if (ch <= 0xffff) {
69
25.7k
                    *odata++ = 'u';
70
25.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
25.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
25.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
25.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
25.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
118k
                else {
77
118k
                    *odata++ = 'U';
78
118k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
118k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
118k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
118k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
118k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
118k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
118k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
118k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
118k
                }
87
181k
            }
88
            /* Copy characters as-is */
89
9.23M
            else {
90
9.23M
                *odata++ = ch;
91
9.23M
            }
92
9.41M
        }
93
134M
    }
94
240k
    *odata = quote;
95
240k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
8.16k
{
12
8.16k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
8.16k
    const void *idata = PyUnicode_DATA(unicode);
14
8.16k
    int ikind = PyUnicode_KIND(unicode);
15
16
8.16k
    *odata++ = quote;
17
18.2M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
18.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
18.1M
        if ((ch == quote) || (ch == '\\')) {
22
22.1k
            *odata++ = '\\';
23
22.1k
            *odata++ = ch;
24
22.1k
            continue;
25
22.1k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
18.1M
        if (ch == '\t') {
29
4.31k
            *odata++ = '\\';
30
4.31k
            *odata++ = 't';
31
4.31k
        }
32
18.1M
        else if (ch == '\n') {
33
3.02k
            *odata++ = '\\';
34
3.02k
            *odata++ = 'n';
35
3.02k
        }
36
18.1M
        else if (ch == '\r') {
37
3.05k
            *odata++ = '\\';
38
3.05k
            *odata++ = 'r';
39
3.05k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
18.1M
        else if (ch < ' ' || ch == 0x7F) {
43
16.1M
            *odata++ = '\\';
44
16.1M
            *odata++ = 'x';
45
16.1M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
16.1M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
16.1M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.05M
        else if (ch < 0x7F) {
51
1.66M
            *odata++ = ch;
52
1.66M
        }
53
54
        /* Non-ASCII characters */
55
394k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
394k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
65.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
65.0k
                if (ch <= 0xff) {
63
3.16k
                    *odata++ = 'x';
64
3.16k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.16k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.16k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
61.8k
                else if (ch <= 0xffff) {
69
28.4k
                    *odata++ = 'u';
70
28.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
28.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
28.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
28.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
28.4k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
33.4k
                else {
77
33.4k
                    *odata++ = 'U';
78
33.4k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
33.4k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
33.4k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
33.4k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
33.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
33.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
33.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
33.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
33.4k
                }
87
65.0k
            }
88
            /* Copy characters as-is */
89
329k
            else {
90
329k
                *odata++ = ch;
91
329k
            }
92
394k
        }
93
18.1M
    }
94
8.16k
    *odata = quote;
95
8.16k
}