Coverage Report

Created: 2026-02-09 07:07

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.74M
{
12
4.74M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.74M
    const void *idata = PyUnicode_DATA(unicode);
14
4.74M
    int ikind = PyUnicode_KIND(unicode);
15
16
4.74M
    *odata++ = quote;
17
200M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
195M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
195M
        if ((ch == quote) || (ch == '\\')) {
22
467k
            *odata++ = '\\';
23
467k
            *odata++ = ch;
24
467k
            continue;
25
467k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
194M
        if (ch == '\t') {
29
452k
            *odata++ = '\\';
30
452k
            *odata++ = 't';
31
452k
        }
32
194M
        else if (ch == '\n') {
33
3.35M
            *odata++ = '\\';
34
3.35M
            *odata++ = 'n';
35
3.35M
        }
36
191M
        else if (ch == '\r') {
37
17.0k
            *odata++ = '\\';
38
17.0k
            *odata++ = 'r';
39
17.0k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
191M
        else if (ch < ' ' || ch == 0x7F) {
43
136M
            *odata++ = '\\';
44
136M
            *odata++ = 'x';
45
136M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
136M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
136M
        }
48
49
        /* Copy ASCII characters as-is */
50
54.5M
        else if (ch < 0x7F) {
51
44.7M
            *odata++ = ch;
52
44.7M
        }
53
54
        /* Non-ASCII characters */
55
9.83M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.83M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
295k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
295k
                if (ch <= 0xff) {
63
73.8k
                    *odata++ = 'x';
64
73.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
73.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
73.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
221k
                else if (ch <= 0xffff) {
69
84.7k
                    *odata++ = 'u';
70
84.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
84.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
84.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
84.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
84.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
136k
                else {
77
136k
                    *odata++ = 'U';
78
136k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
136k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
136k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
136k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
136k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
136k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
136k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
136k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
136k
                }
87
295k
            }
88
            /* Copy characters as-is */
89
9.53M
            else {
90
9.53M
                *odata++ = ch;
91
9.53M
            }
92
9.83M
        }
93
194M
    }
94
4.74M
    *odata = quote;
95
4.74M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
4.52M
{
12
4.52M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.52M
    const void *idata = PyUnicode_DATA(unicode);
14
4.52M
    int ikind = PyUnicode_KIND(unicode);
15
16
4.52M
    *odata++ = quote;
17
64.6M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
60.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
60.1M
        if ((ch == quote) || (ch == '\\')) {
22
117k
            *odata++ = '\\';
23
117k
            *odata++ = ch;
24
117k
            continue;
25
117k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
60.0M
        if (ch == '\t') {
29
428k
            *odata++ = '\\';
30
428k
            *odata++ = 't';
31
428k
        }
32
59.5M
        else if (ch == '\n') {
33
3.22M
            *odata++ = '\\';
34
3.22M
            *odata++ = 'n';
35
3.22M
        }
36
56.3M
        else if (ch == '\r') {
37
9.48k
            *odata++ = '\\';
38
9.48k
            *odata++ = 'r';
39
9.48k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
56.3M
        else if (ch < ' ' || ch == 0x7F) {
43
40.4M
            *odata++ = '\\';
44
40.4M
            *odata++ = 'x';
45
40.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
40.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
40.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
15.8M
        else if (ch < 0x7F) {
51
15.7M
            *odata++ = ch;
52
15.7M
        }
53
54
        /* Non-ASCII characters */
55
124k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
124k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
66.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
66.0k
                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
38.6k
                else if (ch <= 0xffff) {
69
34.1k
                    *odata++ = 'u';
70
34.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
34.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
34.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
34.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
34.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.50k
                else {
77
4.50k
                    *odata++ = 'U';
78
4.50k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.50k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.50k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.50k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.50k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.50k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.50k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.50k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.50k
                }
87
66.0k
            }
88
            /* Copy characters as-is */
89
58.8k
            else {
90
58.8k
                *odata++ = ch;
91
58.8k
            }
92
124k
        }
93
60.0M
    }
94
4.52M
    *odata = quote;
95
4.52M
}
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
121M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
120M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
120M
        if ((ch == quote) || (ch == '\\')) {
22
338k
            *odata++ = '\\';
23
338k
            *odata++ = ch;
24
338k
            continue;
25
338k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
120M
        if (ch == '\t') {
29
19.7k
            *odata++ = '\\';
30
19.7k
            *odata++ = 't';
31
19.7k
        }
32
120M
        else if (ch == '\n') {
33
126k
            *odata++ = '\\';
34
126k
            *odata++ = 'n';
35
126k
        }
36
120M
        else if (ch == '\r') {
37
4.80k
            *odata++ = '\\';
38
4.80k
            *odata++ = 'r';
39
4.80k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
120M
        else if (ch < ' ' || ch == 0x7F) {
43
83.0M
            *odata++ = '\\';
44
83.0M
            *odata++ = 'x';
45
83.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
83.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
83.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
37.2M
        else if (ch < 0x7F) {
51
27.8M
            *odata++ = ch;
52
27.8M
        }
53
54
        /* Non-ASCII characters */
55
9.41M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.41M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
175k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
175k
                if (ch <= 0xff) {
63
44.0k
                    *odata++ = 'x';
64
44.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
44.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
44.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
131k
                else if (ch <= 0xffff) {
69
22.7k
                    *odata++ = 'u';
70
22.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
22.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
22.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
22.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
22.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
108k
                else {
77
108k
                    *odata++ = 'U';
78
108k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
108k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
108k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
108k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
108k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
108k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
108k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
108k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
108k
                }
87
175k
            }
88
            /* Copy characters as-is */
89
9.24M
            else {
90
9.24M
                *odata++ = ch;
91
9.24M
            }
92
9.41M
        }
93
120M
    }
94
213k
    *odata = quote;
95
213k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
7.12k
{
12
7.12k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.12k
    const void *idata = PyUnicode_DATA(unicode);
14
7.12k
    int ikind = PyUnicode_KIND(unicode);
15
16
7.12k
    *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
11.2k
            *odata++ = '\\';
23
11.2k
            *odata++ = ch;
24
11.2k
            continue;
25
11.2k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
14.3M
        if (ch == '\t') {
29
3.89k
            *odata++ = '\\';
30
3.89k
            *odata++ = 't';
31
3.89k
        }
32
14.3M
        else if (ch == '\n') {
33
3.26k
            *odata++ = '\\';
34
3.26k
            *odata++ = 'n';
35
3.26k
        }
36
14.3M
        else if (ch == '\r') {
37
2.74k
            *odata++ = '\\';
38
2.74k
            *odata++ = 'r';
39
2.74k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
14.3M
        else if (ch < ' ' || ch == 0x7F) {
43
12.9M
            *odata++ = '\\';
44
12.9M
            *odata++ = 'x';
45
12.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.43M
        else if (ch < 0x7F) {
51
1.13M
            *odata++ = ch;
52
1.13M
        }
53
54
        /* Non-ASCII characters */
55
292k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
292k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
53.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
53.3k
                if (ch <= 0xff) {
63
2.30k
                    *odata++ = 'x';
64
2.30k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.30k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.30k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
51.0k
                else if (ch <= 0xffff) {
69
27.8k
                    *odata++ = 'u';
70
27.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
27.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
27.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
27.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
27.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
23.2k
                else {
77
23.2k
                    *odata++ = 'U';
78
23.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
23.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
23.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
23.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
23.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
23.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
23.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
23.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
23.2k
                }
87
53.3k
            }
88
            /* Copy characters as-is */
89
239k
            else {
90
239k
                *odata++ = ch;
91
239k
            }
92
292k
        }
93
14.3M
    }
94
7.12k
    *odata = quote;
95
7.12k
}