Coverage Report

Created: 2026-06-21 06:15

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.60M
{
12
2.60M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.60M
    const void *idata = PyUnicode_DATA(unicode);
14
2.60M
    int ikind = PyUnicode_KIND(unicode);
15
16
2.60M
    *odata++ = quote;
17
160M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
157M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
157M
        if ((ch == quote) || (ch == '\\')) {
22
225k
            *odata++ = '\\';
23
225k
            *odata++ = ch;
24
225k
            continue;
25
225k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
157M
        if (ch == '\t') {
29
63.5k
            *odata++ = '\\';
30
63.5k
            *odata++ = 't';
31
63.5k
        }
32
157M
        else if (ch == '\n') {
33
232k
            *odata++ = '\\';
34
232k
            *odata++ = 'n';
35
232k
        }
36
157M
        else if (ch == '\r') {
37
11.4k
            *odata++ = '\\';
38
11.4k
            *odata++ = 'r';
39
11.4k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
157M
        else if (ch < ' ' || ch == 0x7F) {
43
109M
            *odata++ = '\\';
44
109M
            *odata++ = 'x';
45
109M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
109M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
109M
        }
48
49
        /* Copy ASCII characters as-is */
50
47.4M
        else if (ch < 0x7F) {
51
38.4M
            *odata++ = ch;
52
38.4M
        }
53
54
        /* Non-ASCII characters */
55
8.99M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
8.99M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
225k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
225k
                if (ch <= 0xff) {
63
70.0k
                    *odata++ = 'x';
64
70.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
70.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
70.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
155k
                else if (ch <= 0xffff) {
69
64.7k
                    *odata++ = 'u';
70
64.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
64.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
64.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
64.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
64.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
90.7k
                else {
77
90.7k
                    *odata++ = 'U';
78
90.7k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
90.7k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
90.7k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
90.7k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
90.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
90.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
90.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
90.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
90.7k
                }
87
225k
            }
88
            /* Copy characters as-is */
89
8.77M
            else {
90
8.77M
                *odata++ = ch;
91
8.77M
            }
92
8.99M
        }
93
157M
    }
94
2.60M
    *odata = quote;
95
2.60M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
2.40M
{
12
2.40M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.40M
    const void *idata = PyUnicode_DATA(unicode);
14
2.40M
    int ikind = PyUnicode_KIND(unicode);
15
16
2.40M
    *odata++ = quote;
17
54.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
51.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
51.9M
        if ((ch == quote) || (ch == '\\')) {
22
130k
            *odata++ = '\\';
23
130k
            *odata++ = ch;
24
130k
            continue;
25
130k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
51.7M
        if (ch == '\t') {
29
16.0k
            *odata++ = '\\';
30
16.0k
            *odata++ = 't';
31
16.0k
        }
32
51.7M
        else if (ch == '\n') {
33
207k
            *odata++ = '\\';
34
207k
            *odata++ = 'n';
35
207k
        }
36
51.5M
        else if (ch == '\r') {
37
7.09k
            *odata++ = '\\';
38
7.09k
            *odata++ = 'r';
39
7.09k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
51.5M
        else if (ch < ' ' || ch == 0x7F) {
43
41.5M
            *odata++ = '\\';
44
41.5M
            *odata++ = 'x';
45
41.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
41.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
41.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
10.0M
        else if (ch < 0x7F) {
51
9.93M
            *odata++ = ch;
52
9.93M
        }
53
54
        /* Non-ASCII characters */
55
83.2k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
83.2k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
68.7k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
68.7k
                if (ch <= 0xff) {
63
26.1k
                    *odata++ = 'x';
64
26.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
26.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
26.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
42.5k
                else if (ch <= 0xffff) {
69
33.6k
                    *odata++ = 'u';
70
33.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
33.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
33.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
33.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
33.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
8.91k
                else {
77
8.91k
                    *odata++ = 'U';
78
8.91k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
8.91k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
8.91k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
8.91k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
8.91k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
8.91k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
8.91k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
8.91k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
8.91k
                }
87
68.7k
            }
88
            /* Copy characters as-is */
89
14.5k
            else {
90
14.5k
                *odata++ = ch;
91
14.5k
            }
92
83.2k
        }
93
51.7M
    }
94
2.40M
    *odata = quote;
95
2.40M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
195k
{
12
195k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
195k
    const void *idata = PyUnicode_DATA(unicode);
14
195k
    int ikind = PyUnicode_KIND(unicode);
15
16
195k
    *odata++ = quote;
17
93.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
93.6M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
93.6M
        if ((ch == quote) || (ch == '\\')) {
22
72.2k
            *odata++ = '\\';
23
72.2k
            *odata++ = ch;
24
72.2k
            continue;
25
72.2k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
93.5M
        if (ch == '\t') {
29
43.4k
            *odata++ = '\\';
30
43.4k
            *odata++ = 't';
31
43.4k
        }
32
93.5M
        else if (ch == '\n') {
33
23.5k
            *odata++ = '\\';
34
23.5k
            *odata++ = 'n';
35
23.5k
        }
36
93.5M
        else if (ch == '\r') {
37
2.64k
            *odata++ = '\\';
38
2.64k
            *odata++ = 'r';
39
2.64k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
93.5M
        else if (ch < ' ' || ch == 0x7F) {
43
57.7M
            *odata++ = '\\';
44
57.7M
            *odata++ = 'x';
45
57.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
57.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
57.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
35.7M
        else if (ch < 0x7F) {
51
27.0M
            *odata++ = ch;
52
27.0M
        }
53
54
        /* Non-ASCII characters */
55
8.65M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
8.65M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
135k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
135k
                if (ch <= 0xff) {
63
41.2k
                    *odata++ = 'x';
64
41.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
41.2k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
41.2k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
94.6k
                else if (ch <= 0xffff) {
69
26.0k
                    *odata++ = 'u';
70
26.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
26.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
26.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
26.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
26.0k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
68.6k
                else {
77
68.6k
                    *odata++ = 'U';
78
68.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
68.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
68.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
68.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
68.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
68.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
68.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
68.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
68.6k
                }
87
135k
            }
88
            /* Copy characters as-is */
89
8.52M
            else {
90
8.52M
                *odata++ = ch;
91
8.52M
            }
92
8.65M
        }
93
93.5M
    }
94
195k
    *odata = quote;
95
195k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
5.45k
{
12
5.45k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.45k
    const void *idata = PyUnicode_DATA(unicode);
14
5.45k
    int ikind = PyUnicode_KIND(unicode);
15
16
5.45k
    *odata++ = quote;
17
12.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
12.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
12.1M
        if ((ch == quote) || (ch == '\\')) {
22
22.6k
            *odata++ = '\\';
23
22.6k
            *odata++ = ch;
24
22.6k
            continue;
25
22.6k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
12.1M
        if (ch == '\t') {
29
4.05k
            *odata++ = '\\';
30
4.05k
            *odata++ = 't';
31
4.05k
        }
32
12.1M
        else if (ch == '\n') {
33
1.43k
            *odata++ = '\\';
34
1.43k
            *odata++ = 'n';
35
1.43k
        }
36
12.1M
        else if (ch == '\r') {
37
1.75k
            *odata++ = '\\';
38
1.75k
            *odata++ = 'r';
39
1.75k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
12.1M
        else if (ch < ' ' || ch == 0x7F) {
43
10.4M
            *odata++ = '\\';
44
10.4M
            *odata++ = 'x';
45
10.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
10.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
10.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.72M
        else if (ch < 0x7F) {
51
1.46M
            *odata++ = ch;
52
1.46M
        }
53
54
        /* Non-ASCII characters */
55
256k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
256k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
20.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
20.9k
                if (ch <= 0xff) {
63
2.63k
                    *odata++ = 'x';
64
2.63k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.63k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.63k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
18.2k
                else if (ch <= 0xffff) {
69
5.01k
                    *odata++ = 'u';
70
5.01k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
5.01k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
5.01k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
5.01k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
5.01k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
13.2k
                else {
77
13.2k
                    *odata++ = 'U';
78
13.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
13.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
13.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
13.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
13.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
13.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
13.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
13.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
13.2k
                }
87
20.9k
            }
88
            /* Copy characters as-is */
89
235k
            else {
90
235k
                *odata++ = ch;
91
235k
            }
92
256k
        }
93
12.1M
    }
94
5.45k
    *odata = quote;
95
5.45k
}