Coverage Report

Created: 2026-03-08 06:40

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
4.32M
{
12
4.32M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.32M
    const void *idata = PyUnicode_DATA(unicode);
14
4.32M
    int ikind = PyUnicode_KIND(unicode);
15
16
4.32M
    *odata++ = quote;
17
220M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
216M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
216M
        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
216M
        if (ch == '\t') {
29
462k
            *odata++ = '\\';
30
462k
            *odata++ = 't';
31
462k
        }
32
215M
        else if (ch == '\n') {
33
3.80M
            *odata++ = '\\';
34
3.80M
            *odata++ = 'n';
35
3.80M
        }
36
211M
        else if (ch == '\r') {
37
13.0k
            *odata++ = '\\';
38
13.0k
            *odata++ = 'r';
39
13.0k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
211M
        else if (ch < ' ' || ch == 0x7F) {
43
147M
            *odata++ = '\\';
44
147M
            *odata++ = 'x';
45
147M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
147M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
147M
        }
48
49
        /* Copy ASCII characters as-is */
50
64.6M
        else if (ch < 0x7F) {
51
54.6M
            *odata++ = ch;
52
54.6M
        }
53
54
        /* Non-ASCII characters */
55
9.95M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.95M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
419k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
419k
                if (ch <= 0xff) {
63
94.3k
                    *odata++ = 'x';
64
94.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
94.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
94.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
324k
                else if (ch <= 0xffff) {
69
87.7k
                    *odata++ = 'u';
70
87.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
87.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
87.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
87.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
87.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
236k
                else {
77
236k
                    *odata++ = 'U';
78
236k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
236k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
236k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
236k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
236k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
236k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
236k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
236k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
236k
                }
87
419k
            }
88
            /* Copy characters as-is */
89
9.53M
            else {
90
9.53M
                *odata++ = ch;
91
9.53M
            }
92
9.95M
        }
93
216M
    }
94
4.32M
    *odata = quote;
95
4.32M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
4.04M
{
12
4.04M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.04M
    const void *idata = PyUnicode_DATA(unicode);
14
4.04M
    int ikind = PyUnicode_KIND(unicode);
15
16
4.04M
    *odata++ = quote;
17
67.0M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
63.0M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
63.0M
        if ((ch == quote) || (ch == '\\')) {
22
164k
            *odata++ = '\\';
23
164k
            *odata++ = ch;
24
164k
            continue;
25
164k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
62.8M
        if (ch == '\t') {
29
433k
            *odata++ = '\\';
30
433k
            *odata++ = 't';
31
433k
        }
32
62.4M
        else if (ch == '\n') {
33
3.65M
            *odata++ = '\\';
34
3.65M
            *odata++ = 'n';
35
3.65M
        }
36
58.7M
        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
58.7M
        else if (ch < ' ' || ch == 0x7F) {
43
34.7M
            *odata++ = '\\';
44
34.7M
            *odata++ = 'x';
45
34.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
34.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
34.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
23.9M
        else if (ch < 0x7F) {
51
23.8M
            *odata++ = ch;
52
23.8M
        }
53
54
        /* Non-ASCII characters */
55
144k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
144k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
93.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
93.8k
                if (ch <= 0xff) {
63
46.9k
                    *odata++ = 'x';
64
46.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
46.9k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
46.9k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
46.8k
                else if (ch <= 0xffff) {
69
35.2k
                    *odata++ = 'u';
70
35.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
35.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
35.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
35.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
35.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
11.5k
                else {
77
11.5k
                    *odata++ = 'U';
78
11.5k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
11.5k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
11.5k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
11.5k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
11.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
11.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
11.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
11.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
11.5k
                }
87
93.8k
            }
88
            /* Copy characters as-is */
89
50.1k
            else {
90
50.1k
                *odata++ = ch;
91
50.1k
            }
92
144k
        }
93
62.8M
    }
94
4.04M
    *odata = quote;
95
4.04M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
268k
{
12
268k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
268k
    const void *idata = PyUnicode_DATA(unicode);
14
268k
    int ikind = PyUnicode_KIND(unicode);
15
16
268k
    *odata++ = quote;
17
136M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
136M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
136M
        if ((ch == quote) || (ch == '\\')) {
22
97.5k
            *odata++ = '\\';
23
97.5k
            *odata++ = ch;
24
97.5k
            continue;
25
97.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
136M
        if (ch == '\t') {
29
25.1k
            *odata++ = '\\';
30
25.1k
            *odata++ = 't';
31
25.1k
        }
32
136M
        else if (ch == '\n') {
33
146k
            *odata++ = '\\';
34
146k
            *odata++ = 'n';
35
146k
        }
36
136M
        else if (ch == '\r') {
37
5.50k
            *odata++ = '\\';
38
5.50k
            *odata++ = 'r';
39
5.50k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
136M
        else if (ch < ' ' || ch == 0x7F) {
43
97.3M
            *odata++ = '\\';
44
97.3M
            *odata++ = 'x';
45
97.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
97.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
97.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
38.7M
        else if (ch < 0x7F) {
51
29.3M
            *odata++ = ch;
52
29.3M
        }
53
54
        /* Non-ASCII characters */
55
9.36M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.36M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
237k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
237k
                if (ch <= 0xff) {
63
43.9k
                    *odata++ = 'x';
64
43.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
43.9k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
43.9k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
193k
                else if (ch <= 0xffff) {
69
23.3k
                    *odata++ = 'u';
70
23.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
23.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
23.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
23.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
23.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
170k
                else {
77
170k
                    *odata++ = 'U';
78
170k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
170k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
170k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
170k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
170k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
170k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
170k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
170k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
170k
                }
87
237k
            }
88
            /* Copy characters as-is */
89
9.12M
            else {
90
9.12M
                *odata++ = ch;
91
9.12M
            }
92
9.36M
        }
93
136M
    }
94
268k
    *odata = quote;
95
268k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
9.90k
{
12
9.90k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
9.90k
    const void *idata = PyUnicode_DATA(unicode);
14
9.90k
    int ikind = PyUnicode_KIND(unicode);
15
16
9.90k
    *odata++ = quote;
17
17.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
17.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
17.1M
        if ((ch == quote) || (ch == '\\')) {
22
14.7k
            *odata++ = '\\';
23
14.7k
            *odata++ = ch;
24
14.7k
            continue;
25
14.7k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
17.1M
        if (ch == '\t') {
29
3.68k
            *odata++ = '\\';
30
3.68k
            *odata++ = 't';
31
3.68k
        }
32
17.1M
        else if (ch == '\n') {
33
4.08k
            *odata++ = '\\';
34
4.08k
            *odata++ = 'n';
35
4.08k
        }
36
17.1M
        else if (ch == '\r') {
37
3.80k
            *odata++ = '\\';
38
3.80k
            *odata++ = 'r';
39
3.80k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
17.1M
        else if (ch < ' ' || ch == 0x7F) {
43
15.2M
            *odata++ = '\\';
44
15.2M
            *odata++ = 'x';
45
15.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
15.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
15.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.87M
        else if (ch < 0x7F) {
51
1.43M
            *odata++ = ch;
52
1.43M
        }
53
54
        /* Non-ASCII characters */
55
444k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
444k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
87.7k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
87.7k
                if (ch <= 0xff) {
63
3.36k
                    *odata++ = 'x';
64
3.36k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.36k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.36k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
84.4k
                else if (ch <= 0xffff) {
69
29.1k
                    *odata++ = 'u';
70
29.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
29.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
29.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
29.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
29.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
55.3k
                else {
77
55.3k
                    *odata++ = 'U';
78
55.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
55.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
55.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
55.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
55.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
55.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
55.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
55.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
55.3k
                }
87
87.7k
            }
88
            /* Copy characters as-is */
89
356k
            else {
90
356k
                *odata++ = ch;
91
356k
            }
92
444k
        }
93
17.1M
    }
94
9.90k
    *odata = quote;
95
9.90k
}