Coverage Report

Created: 2026-02-26 06:53

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
6.45M
{
12
6.45M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.45M
    const void *idata = PyUnicode_DATA(unicode);
14
6.45M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.45M
    *odata++ = quote;
17
241M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
234M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
234M
        if ((ch == quote) || (ch == '\\')) {
22
276k
            *odata++ = '\\';
23
276k
            *odata++ = ch;
24
276k
            continue;
25
276k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
234M
        if (ch == '\t') {
29
462k
            *odata++ = '\\';
30
462k
            *odata++ = 't';
31
462k
        }
32
234M
        else if (ch == '\n') {
33
3.82M
            *odata++ = '\\';
34
3.82M
            *odata++ = 'n';
35
3.82M
        }
36
230M
        else if (ch == '\r') {
37
14.9k
            *odata++ = '\\';
38
14.9k
            *odata++ = 'r';
39
14.9k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
230M
        else if (ch < ' ' || ch == 0x7F) {
43
162M
            *odata++ = '\\';
44
162M
            *odata++ = 'x';
45
162M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
162M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
162M
        }
48
49
        /* Copy ASCII characters as-is */
50
67.7M
        else if (ch < 0x7F) {
51
57.6M
            *odata++ = ch;
52
57.6M
        }
53
54
        /* Non-ASCII characters */
55
10.1M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
10.1M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
356k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
356k
                if (ch <= 0xff) {
63
73.4k
                    *odata++ = 'x';
64
73.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
73.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
73.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
282k
                else if (ch <= 0xffff) {
69
90.7k
                    *odata++ = 'u';
70
90.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
90.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
90.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
90.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
90.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
191k
                else {
77
191k
                    *odata++ = 'U';
78
191k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
191k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
191k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
191k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
191k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
191k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
191k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
191k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
191k
                }
87
356k
            }
88
            /* Copy characters as-is */
89
9.78M
            else {
90
9.78M
                *odata++ = ch;
91
9.78M
            }
92
10.1M
        }
93
234M
    }
94
6.45M
    *odata = quote;
95
6.45M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.18M
{
12
6.18M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.18M
    const void *idata = PyUnicode_DATA(unicode);
14
6.18M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.18M
    *odata++ = quote;
17
88.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
82.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
82.2M
        if ((ch == quote) || (ch == '\\')) {
22
163k
            *odata++ = '\\';
23
163k
            *odata++ = ch;
24
163k
            continue;
25
163k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
82.0M
        if (ch == '\t') {
29
432k
            *odata++ = '\\';
30
432k
            *odata++ = 't';
31
432k
        }
32
81.6M
        else if (ch == '\n') {
33
3.67M
            *odata++ = '\\';
34
3.67M
            *odata++ = 'n';
35
3.67M
        }
36
77.9M
        else if (ch == '\r') {
37
5.81k
            *odata++ = '\\';
38
5.81k
            *odata++ = 'r';
39
5.81k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
77.9M
        else if (ch < ' ' || ch == 0x7F) {
43
52.4M
            *odata++ = '\\';
44
52.4M
            *odata++ = 'x';
45
52.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
52.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
52.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
25.4M
        else if (ch < 0x7F) {
51
25.3M
            *odata++ = ch;
52
25.3M
        }
53
54
        /* Non-ASCII characters */
55
111k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
111k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
72.7k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
72.7k
                if (ch <= 0xff) {
63
27.3k
                    *odata++ = 'x';
64
27.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
27.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
27.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
45.3k
                else if (ch <= 0xffff) {
69
40.4k
                    *odata++ = 'u';
70
40.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
40.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
40.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
40.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
40.4k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.85k
                else {
77
4.85k
                    *odata++ = 'U';
78
4.85k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.85k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.85k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.85k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.85k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.85k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.85k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.85k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.85k
                }
87
72.7k
            }
88
            /* Copy characters as-is */
89
38.6k
            else {
90
38.6k
                *odata++ = ch;
91
38.6k
            }
92
111k
        }
93
82.0M
    }
94
6.18M
    *odata = quote;
95
6.18M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
265k
{
12
265k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
265k
    const void *idata = PyUnicode_DATA(unicode);
14
265k
    int ikind = PyUnicode_KIND(unicode);
15
16
265k
    *odata++ = quote;
17
136M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
135M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
135M
        if ((ch == quote) || (ch == '\\')) {
22
98.7k
            *odata++ = '\\';
23
98.7k
            *odata++ = ch;
24
98.7k
            continue;
25
98.7k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
135M
        if (ch == '\t') {
29
25.9k
            *odata++ = '\\';
30
25.9k
            *odata++ = 't';
31
25.9k
        }
32
135M
        else if (ch == '\n') {
33
144k
            *odata++ = '\\';
34
144k
            *odata++ = 'n';
35
144k
        }
36
135M
        else if (ch == '\r') {
37
5.38k
            *odata++ = '\\';
38
5.38k
            *odata++ = 'r';
39
5.38k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
135M
        else if (ch < ' ' || ch == 0x7F) {
43
94.7M
            *odata++ = '\\';
44
94.7M
            *odata++ = 'x';
45
94.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
94.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
94.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
40.7M
        else if (ch < 0x7F) {
51
31.1M
            *odata++ = ch;
52
31.1M
        }
53
54
        /* Non-ASCII characters */
55
9.66M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.66M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
218k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
218k
                if (ch <= 0xff) {
63
43.3k
                    *odata++ = 'x';
64
43.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
43.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
43.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
175k
                else if (ch <= 0xffff) {
69
22.7k
                    *odata++ = 'u';
70
22.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
22.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
22.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
22.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
22.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
152k
                else {
77
152k
                    *odata++ = 'U';
78
152k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
152k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
152k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
152k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
152k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
152k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
152k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
152k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
152k
                }
87
218k
            }
88
            /* Copy characters as-is */
89
9.44M
            else {
90
9.44M
                *odata++ = ch;
91
9.44M
            }
92
9.66M
        }
93
135M
    }
94
265k
    *odata = quote;
95
265k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
8.54k
{
12
8.54k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
8.54k
    const void *idata = PyUnicode_DATA(unicode);
14
8.54k
    int ikind = PyUnicode_KIND(unicode);
15
16
8.54k
    *odata++ = quote;
17
16.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
16.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
16.9M
        if ((ch == quote) || (ch == '\\')) {
22
13.8k
            *odata++ = '\\';
23
13.8k
            *odata++ = ch;
24
13.8k
            continue;
25
13.8k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
16.9M
        if (ch == '\t') {
29
3.95k
            *odata++ = '\\';
30
3.95k
            *odata++ = 't';
31
3.95k
        }
32
16.9M
        else if (ch == '\n') {
33
4.03k
            *odata++ = '\\';
34
4.03k
            *odata++ = 'n';
35
4.03k
        }
36
16.9M
        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
16.9M
        else if (ch < ' ' || ch == 0x7F) {
43
15.4M
            *odata++ = '\\';
44
15.4M
            *odata++ = 'x';
45
15.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
15.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
15.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.52M
        else if (ch < 0x7F) {
51
1.15M
            *odata++ = ch;
52
1.15M
        }
53
54
        /* Non-ASCII characters */
55
364k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
364k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
64.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
64.9k
                if (ch <= 0xff) {
63
2.73k
                    *odata++ = 'x';
64
2.73k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.73k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.73k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
62.1k
                else if (ch <= 0xffff) {
69
27.5k
                    *odata++ = 'u';
70
27.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
27.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
27.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
27.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
27.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
34.6k
                else {
77
34.6k
                    *odata++ = 'U';
78
34.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
34.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
34.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
34.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
34.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
34.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
34.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
34.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
34.6k
                }
87
64.9k
            }
88
            /* Copy characters as-is */
89
299k
            else {
90
299k
                *odata++ = ch;
91
299k
            }
92
364k
        }
93
16.9M
    }
94
8.54k
    *odata = quote;
95
8.54k
}