Coverage Report

Created: 2026-03-23 06:45

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.39M
{
12
6.39M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.39M
    const void *idata = PyUnicode_DATA(unicode);
14
6.39M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.39M
    *odata++ = quote;
17
239M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
232M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
232M
        if ((ch == quote) || (ch == '\\')) {
22
254k
            *odata++ = '\\';
23
254k
            *odata++ = ch;
24
254k
            continue;
25
254k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
232M
        if (ch == '\t') {
29
451k
            *odata++ = '\\';
30
451k
            *odata++ = 't';
31
451k
        }
32
232M
        else if (ch == '\n') {
33
3.86M
            *odata++ = '\\';
34
3.86M
            *odata++ = 'n';
35
3.86M
        }
36
228M
        else if (ch == '\r') {
37
15.3k
            *odata++ = '\\';
38
15.3k
            *odata++ = 'r';
39
15.3k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
228M
        else if (ch < ' ' || ch == 0x7F) {
43
161M
            *odata++ = '\\';
44
161M
            *odata++ = 'x';
45
161M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
161M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
161M
        }
48
49
        /* Copy ASCII characters as-is */
50
66.1M
        else if (ch < 0x7F) {
51
56.2M
            *odata++ = ch;
52
56.2M
        }
53
54
        /* Non-ASCII characters */
55
9.94M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.94M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
363k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
363k
                if (ch <= 0xff) {
63
71.5k
                    *odata++ = 'x';
64
71.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
71.5k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
71.5k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
292k
                else if (ch <= 0xffff) {
69
91.1k
                    *odata++ = 'u';
70
91.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
91.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
91.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
91.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
91.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
201k
                else {
77
201k
                    *odata++ = 'U';
78
201k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
201k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
201k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
201k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
201k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
201k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
201k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
201k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
201k
                }
87
363k
            }
88
            /* Copy characters as-is */
89
9.58M
            else {
90
9.58M
                *odata++ = ch;
91
9.58M
            }
92
9.94M
        }
93
232M
    }
94
6.39M
    *odata = quote;
95
6.39M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.11M
{
12
6.11M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.11M
    const void *idata = PyUnicode_DATA(unicode);
14
6.11M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.11M
    *odata++ = quote;
17
89.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
83.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
83.2M
        if ((ch == quote) || (ch == '\\')) {
22
138k
            *odata++ = '\\';
23
138k
            *odata++ = ch;
24
138k
            continue;
25
138k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
83.1M
        if (ch == '\t') {
29
429k
            *odata++ = '\\';
30
429k
            *odata++ = 't';
31
429k
        }
32
82.7M
        else if (ch == '\n') {
33
3.73M
            *odata++ = '\\';
34
3.73M
            *odata++ = 'n';
35
3.73M
        }
36
78.9M
        else if (ch == '\r') {
37
6.93k
            *odata++ = '\\';
38
6.93k
            *odata++ = 'r';
39
6.93k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
78.9M
        else if (ch < ' ' || ch == 0x7F) {
43
54.3M
            *odata++ = '\\';
44
54.3M
            *odata++ = 'x';
45
54.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
54.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
54.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
24.5M
        else if (ch < 0x7F) {
51
24.4M
            *odata++ = ch;
52
24.4M
        }
53
54
        /* Non-ASCII characters */
55
146k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
146k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
71.4k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
71.4k
                if (ch <= 0xff) {
63
27.4k
                    *odata++ = 'x';
64
27.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
27.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
27.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
43.9k
                else if (ch <= 0xffff) {
69
35.5k
                    *odata++ = 'u';
70
35.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
35.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
35.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
35.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
35.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
8.40k
                else {
77
8.40k
                    *odata++ = 'U';
78
8.40k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
8.40k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
8.40k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
8.40k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
8.40k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
8.40k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
8.40k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
8.40k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
8.40k
                }
87
71.4k
            }
88
            /* Copy characters as-is */
89
75.0k
            else {
90
75.0k
                *odata++ = ch;
91
75.0k
            }
92
146k
        }
93
83.1M
    }
94
6.11M
    *odata = quote;
95
6.11M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
264k
{
12
264k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
264k
    const void *idata = PyUnicode_DATA(unicode);
14
264k
    int ikind = PyUnicode_KIND(unicode);
15
16
264k
    *odata++ = quote;
17
132M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
131M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
131M
        if ((ch == quote) || (ch == '\\')) {
22
99.3k
            *odata++ = '\\';
23
99.3k
            *odata++ = ch;
24
99.3k
            continue;
25
99.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
131M
        if (ch == '\t') {
29
18.5k
            *odata++ = '\\';
30
18.5k
            *odata++ = 't';
31
18.5k
        }
32
131M
        else if (ch == '\n') {
33
125k
            *odata++ = '\\';
34
125k
            *odata++ = 'n';
35
125k
        }
36
131M
        else if (ch == '\r') {
37
4.24k
            *odata++ = '\\';
38
4.24k
            *odata++ = 'r';
39
4.24k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
131M
        else if (ch < ' ' || ch == 0x7F) {
43
92.0M
            *odata++ = '\\';
44
92.0M
            *odata++ = 'x';
45
92.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
92.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
92.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
39.6M
        else if (ch < 0x7F) {
51
30.2M
            *odata++ = ch;
52
30.2M
        }
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
207k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
207k
                if (ch <= 0xff) {
63
40.8k
                    *odata++ = 'x';
64
40.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
40.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
40.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
166k
                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
141k
                else {
77
141k
                    *odata++ = 'U';
78
141k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
141k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
141k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
141k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
141k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
141k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
141k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
141k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
141k
                }
87
207k
            }
88
            /* Copy characters as-is */
89
9.15M
            else {
90
9.15M
                *odata++ = ch;
91
9.15M
            }
92
9.36M
        }
93
131M
    }
94
264k
    *odata = quote;
95
264k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
9.83k
{
12
9.83k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
9.83k
    const void *idata = PyUnicode_DATA(unicode);
14
9.83k
    int ikind = PyUnicode_KIND(unicode);
15
16
9.83k
    *odata++ = quote;
17
17.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
17.5M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
17.5M
        if ((ch == quote) || (ch == '\\')) {
22
16.9k
            *odata++ = '\\';
23
16.9k
            *odata++ = ch;
24
16.9k
            continue;
25
16.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
17.5M
        if (ch == '\t') {
29
3.74k
            *odata++ = '\\';
30
3.74k
            *odata++ = 't';
31
3.74k
        }
32
17.5M
        else if (ch == '\n') {
33
3.37k
            *odata++ = '\\';
34
3.37k
            *odata++ = 'n';
35
3.37k
        }
36
17.5M
        else if (ch == '\r') {
37
4.19k
            *odata++ = '\\';
38
4.19k
            *odata++ = 'r';
39
4.19k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
17.5M
        else if (ch < ' ' || ch == 0x7F) {
43
15.5M
            *odata++ = '\\';
44
15.5M
            *odata++ = 'x';
45
15.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
15.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
15.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.00M
        else if (ch < 0x7F) {
51
1.57M
            *odata++ = ch;
52
1.57M
        }
53
54
        /* Non-ASCII characters */
55
432k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
432k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
84.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
84.6k
                if (ch <= 0xff) {
63
3.22k
                    *odata++ = 'x';
64
3.22k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.22k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.22k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
81.3k
                else if (ch <= 0xffff) {
69
29.8k
                    *odata++ = 'u';
70
29.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
29.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
29.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
29.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
29.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
51.4k
                else {
77
51.4k
                    *odata++ = 'U';
78
51.4k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
51.4k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
51.4k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
51.4k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
51.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
51.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
51.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
51.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
51.4k
                }
87
84.6k
            }
88
            /* Copy characters as-is */
89
347k
            else {
90
347k
                *odata++ = ch;
91
347k
            }
92
432k
        }
93
17.5M
    }
94
9.83k
    *odata = quote;
95
9.83k
}