Coverage Report

Created: 2026-06-09 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
2.08M
{
12
2.08M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.08M
    const void *idata = PyUnicode_DATA(unicode);
14
2.08M
    int ikind = PyUnicode_KIND(unicode);
15
16
2.08M
    *odata++ = quote;
17
163M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
161M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
161M
        if ((ch == quote) || (ch == '\\')) {
22
219k
            *odata++ = '\\';
23
219k
            *odata++ = ch;
24
219k
            continue;
25
219k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
161M
        if (ch == '\t') {
29
65.4k
            *odata++ = '\\';
30
65.4k
            *odata++ = 't';
31
65.4k
        }
32
161M
        else if (ch == '\n') {
33
238k
            *odata++ = '\\';
34
238k
            *odata++ = 'n';
35
238k
        }
36
161M
        else if (ch == '\r') {
37
10.5k
            *odata++ = '\\';
38
10.5k
            *odata++ = 'r';
39
10.5k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
161M
        else if (ch < ' ' || ch == 0x7F) {
43
112M
            *odata++ = '\\';
44
112M
            *odata++ = 'x';
45
112M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
112M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
112M
        }
48
49
        /* Copy ASCII characters as-is */
50
48.9M
        else if (ch < 0x7F) {
51
40.2M
            *odata++ = ch;
52
40.2M
        }
53
54
        /* Non-ASCII characters */
55
8.66M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
8.66M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
236k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
236k
                if (ch <= 0xff) {
63
69.0k
                    *odata++ = 'x';
64
69.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
69.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
69.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
167k
                else if (ch <= 0xffff) {
69
70.2k
                    *odata++ = 'u';
70
70.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
70.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
70.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
70.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
70.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
96.8k
                else {
77
96.8k
                    *odata++ = 'U';
78
96.8k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
96.8k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
96.8k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
96.8k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
96.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
96.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
96.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
96.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
96.8k
                }
87
236k
            }
88
            /* Copy characters as-is */
89
8.43M
            else {
90
8.43M
                *odata++ = ch;
91
8.43M
            }
92
8.66M
        }
93
161M
    }
94
2.08M
    *odata = quote;
95
2.08M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
1.88M
{
12
1.88M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.88M
    const void *idata = PyUnicode_DATA(unicode);
14
1.88M
    int ikind = PyUnicode_KIND(unicode);
15
16
1.88M
    *odata++ = quote;
17
50.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
48.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
48.2M
        if ((ch == quote) || (ch == '\\')) {
22
129k
            *odata++ = '\\';
23
129k
            *odata++ = ch;
24
129k
            continue;
25
129k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
48.1M
        if (ch == '\t') {
29
16.7k
            *odata++ = '\\';
30
16.7k
            *odata++ = 't';
31
16.7k
        }
32
48.1M
        else if (ch == '\n') {
33
213k
            *odata++ = '\\';
34
213k
            *odata++ = 'n';
35
213k
        }
36
47.8M
        else if (ch == '\r') {
37
5.92k
            *odata++ = '\\';
38
5.92k
            *odata++ = 'r';
39
5.92k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
47.8M
        else if (ch < ' ' || ch == 0x7F) {
43
36.9M
            *odata++ = '\\';
44
36.9M
            *odata++ = 'x';
45
36.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
36.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
36.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
10.9M
        else if (ch < 0x7F) {
51
10.8M
            *odata++ = ch;
52
10.8M
        }
53
54
        /* Non-ASCII characters */
55
88.8k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
88.8k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
73.2k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
73.2k
                if (ch <= 0xff) {
63
26.3k
                    *odata++ = 'x';
64
26.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
26.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
26.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
46.9k
                else if (ch <= 0xffff) {
69
38.6k
                    *odata++ = 'u';
70
38.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
38.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
38.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
38.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
38.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
8.36k
                else {
77
8.36k
                    *odata++ = 'U';
78
8.36k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
8.36k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
8.36k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
8.36k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
8.36k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
8.36k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
8.36k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
8.36k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
8.36k
                }
87
73.2k
            }
88
            /* Copy characters as-is */
89
15.5k
            else {
90
15.5k
                *odata++ = ch;
91
15.5k
            }
92
88.8k
        }
93
48.1M
    }
94
1.88M
    *odata = quote;
95
1.88M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
197k
{
12
197k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
197k
    const void *idata = PyUnicode_DATA(unicode);
14
197k
    int ikind = PyUnicode_KIND(unicode);
15
16
197k
    *odata++ = quote;
17
99.4M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
99.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
99.2M
        if ((ch == quote) || (ch == '\\')) {
22
68.6k
            *odata++ = '\\';
23
68.6k
            *odata++ = ch;
24
68.6k
            continue;
25
68.6k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
99.1M
        if (ch == '\t') {
29
45.7k
            *odata++ = '\\';
30
45.7k
            *odata++ = 't';
31
45.7k
        }
32
99.1M
        else if (ch == '\n') {
33
23.6k
            *odata++ = '\\';
34
23.6k
            *odata++ = 'n';
35
23.6k
        }
36
99.1M
        else if (ch == '\r') {
37
2.62k
            *odata++ = '\\';
38
2.62k
            *odata++ = 'r';
39
2.62k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
99.1M
        else if (ch < ' ' || ch == 0x7F) {
43
62.9M
            *odata++ = '\\';
44
62.9M
            *odata++ = 'x';
45
62.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
62.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
62.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
36.1M
        else if (ch < 0x7F) {
51
27.8M
            *odata++ = ch;
52
27.8M
        }
53
54
        /* Non-ASCII characters */
55
8.30M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
8.30M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
138k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
138k
                if (ch <= 0xff) {
63
39.6k
                    *odata++ = 'x';
64
39.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
39.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
39.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
99.1k
                else if (ch <= 0xffff) {
69
24.2k
                    *odata++ = 'u';
70
24.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
24.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
24.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
24.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
24.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
74.9k
                else {
77
74.9k
                    *odata++ = 'U';
78
74.9k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
74.9k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
74.9k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
74.9k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
74.9k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
74.9k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
74.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
74.9k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
74.9k
                }
87
138k
            }
88
            /* Copy characters as-is */
89
8.16M
            else {
90
8.16M
                *odata++ = ch;
91
8.16M
            }
92
8.30M
        }
93
99.1M
    }
94
197k
    *odata = quote;
95
197k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
6.22k
{
12
6.22k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.22k
    const void *idata = PyUnicode_DATA(unicode);
14
6.22k
    int ikind = PyUnicode_KIND(unicode);
15
16
6.22k
    *odata++ = quote;
17
14.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
14.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
14.3M
        if ((ch == quote) || (ch == '\\')) {
22
21.1k
            *odata++ = '\\';
23
21.1k
            *odata++ = ch;
24
21.1k
            continue;
25
21.1k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
14.3M
        if (ch == '\t') {
29
2.94k
            *odata++ = '\\';
30
2.94k
            *odata++ = 't';
31
2.94k
        }
32
14.3M
        else if (ch == '\n') {
33
1.39k
            *odata++ = '\\';
34
1.39k
            *odata++ = 'n';
35
1.39k
        }
36
14.3M
        else if (ch == '\r') {
37
2.03k
            *odata++ = '\\';
38
2.03k
            *odata++ = 'r';
39
2.03k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
14.3M
        else if (ch < ' ' || ch == 0x7F) {
43
12.4M
            *odata++ = '\\';
44
12.4M
            *odata++ = 'x';
45
12.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.83M
        else if (ch < 0x7F) {
51
1.56M
            *odata++ = ch;
52
1.56M
        }
53
54
        /* Non-ASCII characters */
55
276k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
276k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
24.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
24.0k
                if (ch <= 0xff) {
63
3.05k
                    *odata++ = 'x';
64
3.05k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.05k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.05k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
21.0k
                else if (ch <= 0xffff) {
69
7.42k
                    *odata++ = 'u';
70
7.42k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
7.42k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
7.42k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
7.42k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
7.42k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
13.6k
                else {
77
13.6k
                    *odata++ = 'U';
78
13.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
13.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
13.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
13.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
13.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
13.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
13.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
13.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
13.6k
                }
87
24.0k
            }
88
            /* Copy characters as-is */
89
251k
            else {
90
251k
                *odata++ = ch;
91
251k
            }
92
276k
        }
93
14.3M
    }
94
6.22k
    *odata = quote;
95
6.22k
}