Coverage Report

Created: 2026-07-14 06:16

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.22M
{
12
2.22M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.22M
    const void *idata = PyUnicode_DATA(unicode);
14
2.22M
    int ikind = PyUnicode_KIND(unicode);
15
16
2.22M
    *odata++ = quote;
17
186M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
184M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
184M
        if ((ch == quote) || (ch == '\\')) {
22
233k
            *odata++ = '\\';
23
233k
            *odata++ = ch;
24
233k
            continue;
25
233k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
184M
        if (ch == '\t') {
29
55.6k
            *odata++ = '\\';
30
55.6k
            *odata++ = 't';
31
55.6k
        }
32
184M
        else if (ch == '\n') {
33
225k
            *odata++ = '\\';
34
225k
            *odata++ = 'n';
35
225k
        }
36
183M
        else if (ch == '\r') {
37
8.75k
            *odata++ = '\\';
38
8.75k
            *odata++ = 'r';
39
8.75k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
183M
        else if (ch < ' ' || ch == 0x7F) {
43
132M
            *odata++ = '\\';
44
132M
            *odata++ = 'x';
45
132M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
132M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
132M
        }
48
49
        /* Copy ASCII characters as-is */
50
51.2M
        else if (ch < 0x7F) {
51
41.6M
            *odata++ = ch;
52
41.6M
        }
53
54
        /* Non-ASCII characters */
55
9.52M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.52M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
176k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
176k
                if (ch <= 0xff) {
63
70.8k
                    *odata++ = 'x';
64
70.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
70.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
70.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
105k
                else if (ch <= 0xffff) {
69
64.5k
                    *odata++ = 'u';
70
64.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
64.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
64.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
64.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
64.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
41.3k
                else {
77
41.3k
                    *odata++ = 'U';
78
41.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
41.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
41.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
41.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
41.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
41.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
41.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
41.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
41.3k
                }
87
176k
            }
88
            /* Copy characters as-is */
89
9.34M
            else {
90
9.34M
                *odata++ = ch;
91
9.34M
            }
92
9.52M
        }
93
184M
    }
94
2.22M
    *odata = quote;
95
2.22M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
2.00M
{
12
2.00M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.00M
    const void *idata = PyUnicode_DATA(unicode);
14
2.00M
    int ikind = PyUnicode_KIND(unicode);
15
16
2.00M
    *odata++ = quote;
17
52.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
50.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
50.1M
        if ((ch == quote) || (ch == '\\')) {
22
139k
            *odata++ = '\\';
23
139k
            *odata++ = ch;
24
139k
            continue;
25
139k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
50.0M
        if (ch == '\t') {
29
14.8k
            *odata++ = '\\';
30
14.8k
            *odata++ = 't';
31
14.8k
        }
32
50.0M
        else if (ch == '\n') {
33
202k
            *odata++ = '\\';
34
202k
            *odata++ = 'n';
35
202k
        }
36
49.8M
        else if (ch == '\r') {
37
6.22k
            *odata++ = '\\';
38
6.22k
            *odata++ = 'r';
39
6.22k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
49.7M
        else if (ch < ' ' || ch == 0x7F) {
43
40.0M
            *odata++ = '\\';
44
40.0M
            *odata++ = 'x';
45
40.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
40.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
40.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
9.75M
        else if (ch < 0x7F) {
51
9.66M
            *odata++ = ch;
52
9.66M
        }
53
54
        /* Non-ASCII characters */
55
86.9k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
86.9k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
72.5k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
72.5k
                if (ch <= 0xff) {
63
28.1k
                    *odata++ = 'x';
64
28.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
28.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
28.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
44.4k
                else if (ch <= 0xffff) {
69
35.9k
                    *odata++ = 'u';
70
35.9k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
35.9k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
35.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
35.9k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
35.9k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
8.45k
                else {
77
8.45k
                    *odata++ = 'U';
78
8.45k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
8.45k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
8.45k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
8.45k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
8.45k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
8.45k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
8.45k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
8.45k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
8.45k
                }
87
72.5k
            }
88
            /* Copy characters as-is */
89
14.3k
            else {
90
14.3k
                *odata++ = ch;
91
14.3k
            }
92
86.9k
        }
93
50.0M
    }
94
2.00M
    *odata = quote;
95
2.00M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
213k
{
12
213k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
213k
    const void *idata = PyUnicode_DATA(unicode);
14
213k
    int ikind = PyUnicode_KIND(unicode);
15
16
213k
    *odata++ = quote;
17
115M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
115M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
115M
        if ((ch == quote) || (ch == '\\')) {
22
74.9k
            *odata++ = '\\';
23
74.9k
            *odata++ = ch;
24
74.9k
            continue;
25
74.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
115M
        if (ch == '\t') {
29
38.9k
            *odata++ = '\\';
30
38.9k
            *odata++ = 't';
31
38.9k
        }
32
115M
        else if (ch == '\n') {
33
22.5k
            *odata++ = '\\';
34
22.5k
            *odata++ = 'n';
35
22.5k
        }
36
115M
        else if (ch == '\r') {
37
1.65k
            *odata++ = '\\';
38
1.65k
            *odata++ = 'r';
39
1.65k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
115M
        else if (ch < ' ' || ch == 0x7F) {
43
75.2M
            *odata++ = '\\';
44
75.2M
            *odata++ = 'x';
45
75.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
75.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
75.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
40.2M
        else if (ch < 0x7F) {
51
31.0M
            *odata++ = ch;
52
31.0M
        }
53
54
        /* Non-ASCII characters */
55
9.24M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.24M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
88.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
88.8k
                if (ch <= 0xff) {
63
38.2k
                    *odata++ = 'x';
64
38.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
38.2k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
38.2k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
50.6k
                else if (ch <= 0xffff) {
69
24.7k
                    *odata++ = 'u';
70
24.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
24.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
24.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
24.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
24.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
25.8k
                else {
77
25.8k
                    *odata++ = 'U';
78
25.8k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
25.8k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
25.8k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
25.8k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
25.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
25.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
25.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
25.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
25.8k
                }
87
88.8k
            }
88
            /* Copy characters as-is */
89
9.15M
            else {
90
9.15M
                *odata++ = ch;
91
9.15M
            }
92
9.24M
        }
93
115M
    }
94
213k
    *odata = quote;
95
213k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
3.97k
{
12
3.97k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.97k
    const void *idata = PyUnicode_DATA(unicode);
14
3.97k
    int ikind = PyUnicode_KIND(unicode);
15
16
3.97k
    *odata++ = quote;
17
18.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
18.5M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
18.5M
        if ((ch == quote) || (ch == '\\')) {
22
18.6k
            *odata++ = '\\';
23
18.6k
            *odata++ = ch;
24
18.6k
            continue;
25
18.6k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
18.4M
        if (ch == '\t') {
29
1.96k
            *odata++ = '\\';
30
1.96k
            *odata++ = 't';
31
1.96k
        }
32
18.4M
        else if (ch == '\n') {
33
712
            *odata++ = '\\';
34
712
            *odata++ = 'n';
35
712
        }
36
18.4M
        else if (ch == '\r') {
37
874
            *odata++ = '\\';
38
874
            *odata++ = 'r';
39
874
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
18.4M
        else if (ch < ' ' || ch == 0x7F) {
43
17.3M
            *odata++ = '\\';
44
17.3M
            *odata++ = 'x';
45
17.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
17.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
17.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.16M
        else if (ch < 0x7F) {
51
975k
            *odata++ = ch;
52
975k
        }
53
54
        /* Non-ASCII characters */
55
192k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
192k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
15.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
15.3k
                if (ch <= 0xff) {
63
4.50k
                    *odata++ = 'x';
64
4.50k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
4.50k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
4.50k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
10.8k
                else if (ch <= 0xffff) {
69
3.85k
                    *odata++ = 'u';
70
3.85k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.85k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.85k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.85k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.85k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
7.01k
                else {
77
7.01k
                    *odata++ = 'U';
78
7.01k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
7.01k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
7.01k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
7.01k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
7.01k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
7.01k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
7.01k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
7.01k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
7.01k
                }
87
15.3k
            }
88
            /* Copy characters as-is */
89
177k
            else {
90
177k
                *odata++ = ch;
91
177k
            }
92
192k
        }
93
18.4M
    }
94
3.97k
    *odata = quote;
95
3.97k
}