Coverage Report

Created: 2026-10-31 06:21

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
7.06M
{
12
7.06M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.06M
    const void *idata = PyUnicode_DATA(unicode);
14
7.06M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.06M
    *odata++ = quote;
17
262M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
255M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
255M
        if ((ch == quote) || (ch == '\\')) {
22
300k
            *odata++ = '\\';
23
300k
            *odata++ = ch;
24
300k
            continue;
25
300k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
255M
        if (ch == '\t') {
29
542k
            *odata++ = '\\';
30
542k
            *odata++ = 't';
31
542k
        }
32
254M
        else if (ch == '\n') {
33
5.80M
            *odata++ = '\\';
34
5.80M
            *odata++ = 'n';
35
5.80M
        }
36
248M
        else if (ch == '\r') {
37
16.5k
            *odata++ = '\\';
38
16.5k
            *odata++ = 'r';
39
16.5k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
248M
        else if (ch < ' ' || ch == 0x7F) {
43
160M
            *odata++ = '\\';
44
160M
            *odata++ = 'x';
45
160M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
160M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
160M
        }
48
49
        /* Copy ASCII characters as-is */
50
88.0M
        else if (ch < 0x7F) {
51
73.5M
            *odata++ = ch;
52
73.5M
        }
53
54
        /* Non-ASCII characters */
55
14.5M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
14.5M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
1.80M
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
1.80M
                if (ch <= 0xff) {
63
151k
                    *odata++ = 'x';
64
151k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
151k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
151k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
1.65M
                else if (ch <= 0xffff) {
69
134k
                    *odata++ = 'u';
70
134k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
134k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
134k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
134k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
134k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.52M
                else {
77
1.52M
                    *odata++ = 'U';
78
1.52M
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.52M
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.52M
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.52M
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.52M
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.52M
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.52M
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.52M
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.52M
                }
87
1.80M
            }
88
            /* Copy characters as-is */
89
12.7M
            else {
90
12.7M
                *odata++ = ch;
91
12.7M
            }
92
14.5M
        }
93
255M
    }
94
7.06M
    *odata = quote;
95
7.06M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.74M
{
12
6.74M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.74M
    const void *idata = PyUnicode_DATA(unicode);
14
6.74M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.74M
    *odata++ = quote;
17
74.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
67.7M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
67.7M
        if ((ch == quote) || (ch == '\\')) {
22
124k
            *odata++ = '\\';
23
124k
            *odata++ = ch;
24
124k
            continue;
25
124k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
67.6M
        if (ch == '\t') {
29
465k
            *odata++ = '\\';
30
465k
            *odata++ = 't';
31
465k
        }
32
67.1M
        else if (ch == '\n') {
33
5.62M
            *odata++ = '\\';
34
5.62M
            *odata++ = 'n';
35
5.62M
        }
36
61.5M
        else if (ch == '\r') {
37
9.18k
            *odata++ = '\\';
38
9.18k
            *odata++ = 'r';
39
9.18k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
61.5M
        else if (ch < ' ' || ch == 0x7F) {
43
40.3M
            *odata++ = '\\';
44
40.3M
            *odata++ = 'x';
45
40.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
40.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
40.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
21.2M
        else if (ch < 0x7F) {
51
20.9M
            *odata++ = ch;
52
20.9M
        }
53
54
        /* Non-ASCII characters */
55
219k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
219k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
194k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
194k
                if (ch <= 0xff) {
63
103k
                    *odata++ = 'x';
64
103k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
103k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
103k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
90.8k
                else if (ch <= 0xffff) {
69
79.7k
                    *odata++ = 'u';
70
79.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
79.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
79.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
79.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
79.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
11.0k
                else {
77
11.0k
                    *odata++ = 'U';
78
11.0k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
11.0k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
11.0k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
11.0k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
11.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
11.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
11.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
11.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
11.0k
                }
87
194k
            }
88
            /* Copy characters as-is */
89
25.0k
            else {
90
25.0k
                *odata++ = ch;
91
25.0k
            }
92
219k
        }
93
67.6M
    }
94
6.74M
    *odata = quote;
95
6.74M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
311k
{
12
311k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
311k
    const void *idata = PyUnicode_DATA(unicode);
14
311k
    int ikind = PyUnicode_KIND(unicode);
15
16
311k
    *odata++ = quote;
17
166M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
165M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
165M
        if ((ch == quote) || (ch == '\\')) {
22
153k
            *odata++ = '\\';
23
153k
            *odata++ = ch;
24
153k
            continue;
25
153k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
165M
        if (ch == '\t') {
29
70.6k
            *odata++ = '\\';
30
70.6k
            *odata++ = 't';
31
70.6k
        }
32
165M
        else if (ch == '\n') {
33
148k
            *odata++ = '\\';
34
148k
            *odata++ = 'n';
35
148k
        }
36
165M
        else if (ch == '\r') {
37
4.08k
            *odata++ = '\\';
38
4.08k
            *odata++ = 'r';
39
4.08k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
165M
        else if (ch < ' ' || ch == 0x7F) {
43
101M
            *odata++ = '\\';
44
101M
            *odata++ = 'x';
45
101M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
101M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
101M
        }
48
49
        /* Copy ASCII characters as-is */
50
63.8M
        else if (ch < 0x7F) {
51
50.3M
            *odata++ = ch;
52
50.3M
        }
53
54
        /* Non-ASCII characters */
55
13.4M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
13.4M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
1.42M
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
1.42M
                if (ch <= 0xff) {
63
40.5k
                    *odata++ = 'x';
64
40.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
40.5k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
40.5k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
1.38M
                else if (ch <= 0xffff) {
69
23.6k
                    *odata++ = 'u';
70
23.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
23.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
23.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
23.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
23.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.36M
                else {
77
1.36M
                    *odata++ = 'U';
78
1.36M
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.36M
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.36M
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.36M
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.36M
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.36M
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.36M
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.36M
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.36M
                }
87
1.42M
            }
88
            /* Copy characters as-is */
89
12.0M
            else {
90
12.0M
                *odata++ = ch;
91
12.0M
            }
92
13.4M
        }
93
165M
    }
94
311k
    *odata = quote;
95
311k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
9.18k
{
12
9.18k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
9.18k
    const void *idata = PyUnicode_DATA(unicode);
14
9.18k
    int ikind = PyUnicode_KIND(unicode);
15
16
9.18k
    *odata++ = quote;
17
21.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
21.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
21.8M
        if ((ch == quote) || (ch == '\\')) {
22
22.0k
            *odata++ = '\\';
23
22.0k
            *odata++ = ch;
24
22.0k
            continue;
25
22.0k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
21.8M
        if (ch == '\t') {
29
6.20k
            *odata++ = '\\';
30
6.20k
            *odata++ = 't';
31
6.20k
        }
32
21.8M
        else if (ch == '\n') {
33
28.6k
            *odata++ = '\\';
34
28.6k
            *odata++ = 'n';
35
28.6k
        }
36
21.8M
        else if (ch == '\r') {
37
3.30k
            *odata++ = '\\';
38
3.30k
            *odata++ = 'r';
39
3.30k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
21.8M
        else if (ch < ' ' || ch == 0x7F) {
43
18.8M
            *odata++ = '\\';
44
18.8M
            *odata++ = 'x';
45
18.8M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
18.8M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
18.8M
        }
48
49
        /* Copy ASCII characters as-is */
50
3.01M
        else if (ch < 0x7F) {
51
2.17M
            *odata++ = ch;
52
2.17M
        }
53
54
        /* Non-ASCII characters */
55
833k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
833k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
189k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
189k
                if (ch <= 0xff) {
63
7.07k
                    *odata++ = 'x';
64
7.07k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
7.07k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
7.07k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
182k
                else if (ch <= 0xffff) {
69
30.8k
                    *odata++ = 'u';
70
30.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
30.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
30.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
30.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
30.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
151k
                else {
77
151k
                    *odata++ = 'U';
78
151k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
151k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
151k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
151k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
151k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
151k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
151k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
151k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
151k
                }
87
189k
            }
88
            /* Copy characters as-is */
89
644k
            else {
90
644k
                *odata++ = ch;
91
644k
            }
92
833k
        }
93
21.8M
    }
94
9.18k
    *odata = quote;
95
9.18k
}