Coverage Report

Created: 2026-04-20 06:11

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.27M
{
12
6.27M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.27M
    const void *idata = PyUnicode_DATA(unicode);
14
6.27M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.27M
    *odata++ = quote;
17
237M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
230M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
230M
        if ((ch == quote) || (ch == '\\')) {
22
236k
            *odata++ = '\\';
23
236k
            *odata++ = ch;
24
236k
            continue;
25
236k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
230M
        if (ch == '\t') {
29
484k
            *odata++ = '\\';
30
484k
            *odata++ = 't';
31
484k
        }
32
230M
        else if (ch == '\n') {
33
3.80M
            *odata++ = '\\';
34
3.80M
            *odata++ = 'n';
35
3.80M
        }
36
226M
        else if (ch == '\r') {
37
14.3k
            *odata++ = '\\';
38
14.3k
            *odata++ = 'r';
39
14.3k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
226M
        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
64.4M
        else if (ch < 0x7F) {
51
54.5M
            *odata++ = ch;
52
54.5M
        }
53
54
        /* Non-ASCII characters */
55
9.92M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.92M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
373k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
373k
                if (ch <= 0xff) {
63
85.3k
                    *odata++ = 'x';
64
85.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
85.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
85.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
288k
                else if (ch <= 0xffff) {
69
84.8k
                    *odata++ = 'u';
70
84.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
84.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
84.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
84.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
84.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
203k
                else {
77
203k
                    *odata++ = 'U';
78
203k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
203k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
203k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
203k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
203k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
203k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
203k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
203k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
203k
                }
87
373k
            }
88
            /* Copy characters as-is */
89
9.55M
            else {
90
9.55M
                *odata++ = ch;
91
9.55M
            }
92
9.92M
        }
93
230M
    }
94
6.27M
    *odata = quote;
95
6.27M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.01M
{
12
6.01M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.01M
    const void *idata = PyUnicode_DATA(unicode);
14
6.01M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.01M
    *odata++ = quote;
17
82.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
76.5M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
76.5M
        if ((ch == quote) || (ch == '\\')) {
22
140k
            *odata++ = '\\';
23
140k
            *odata++ = ch;
24
140k
            continue;
25
140k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
76.4M
        if (ch == '\t') {
29
430k
            *odata++ = '\\';
30
430k
            *odata++ = 't';
31
430k
        }
32
76.0M
        else if (ch == '\n') {
33
3.71M
            *odata++ = '\\';
34
3.71M
            *odata++ = 'n';
35
3.71M
        }
36
72.2M
        else if (ch == '\r') {
37
6.26k
            *odata++ = '\\';
38
6.26k
            *odata++ = 'r';
39
6.26k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
72.2M
        else if (ch < ' ' || ch == 0x7F) {
43
52.0M
            *odata++ = '\\';
44
52.0M
            *odata++ = 'x';
45
52.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
52.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
52.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
20.2M
        else if (ch < 0x7F) {
51
20.1M
            *odata++ = ch;
52
20.1M
        }
53
54
        /* Non-ASCII characters */
55
144k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
144k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
68.2k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
68.2k
                if (ch <= 0xff) {
63
28.4k
                    *odata++ = 'x';
64
28.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
28.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
28.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
39.7k
                else if (ch <= 0xffff) {
69
31.1k
                    *odata++ = 'u';
70
31.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
31.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
31.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
31.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
31.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
8.59k
                else {
77
8.59k
                    *odata++ = 'U';
78
8.59k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
8.59k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
8.59k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
8.59k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
8.59k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
8.59k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
8.59k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
8.59k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
8.59k
                }
87
68.2k
            }
88
            /* Copy characters as-is */
89
75.9k
            else {
90
75.9k
                *odata++ = ch;
91
75.9k
            }
92
144k
        }
93
76.4M
    }
94
6.01M
    *odata = quote;
95
6.01M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
251k
{
12
251k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
251k
    const void *idata = PyUnicode_DATA(unicode);
14
251k
    int ikind = PyUnicode_KIND(unicode);
15
16
251k
    *odata++ = quote;
17
135M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
135M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
135M
        if ((ch == quote) || (ch == '\\')) {
22
83.3k
            *odata++ = '\\';
23
83.3k
            *odata++ = ch;
24
83.3k
            continue;
25
83.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
135M
        if (ch == '\t') {
29
50.7k
            *odata++ = '\\';
30
50.7k
            *odata++ = 't';
31
50.7k
        }
32
135M
        else if (ch == '\n') {
33
93.7k
            *odata++ = '\\';
34
93.7k
            *odata++ = 'n';
35
93.7k
        }
36
135M
        else if (ch == '\r') {
37
4.77k
            *odata++ = '\\';
38
4.77k
            *odata++ = 'r';
39
4.77k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
135M
        else if (ch < ' ' || ch == 0x7F) {
43
93.1M
            *odata++ = '\\';
44
93.1M
            *odata++ = 'x';
45
93.1M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
93.1M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
93.1M
        }
48
49
        /* Copy ASCII characters as-is */
50
41.9M
        else if (ch < 0x7F) {
51
32.6M
            *odata++ = ch;
52
32.6M
        }
53
54
        /* Non-ASCII characters */
55
9.32M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.32M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
219k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
219k
                if (ch <= 0xff) {
63
53.8k
                    *odata++ = 'x';
64
53.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
53.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
53.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
166k
                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
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
219k
            }
88
            /* Copy characters as-is */
89
9.10M
            else {
90
9.10M
                *odata++ = ch;
91
9.10M
            }
92
9.32M
        }
93
135M
    }
94
251k
    *odata = quote;
95
251k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
9.35k
{
12
9.35k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
9.35k
    const void *idata = PyUnicode_DATA(unicode);
14
9.35k
    int ikind = PyUnicode_KIND(unicode);
15
16
9.35k
    *odata++ = quote;
17
18.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
18.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
18.8M
        if ((ch == quote) || (ch == '\\')) {
22
12.9k
            *odata++ = '\\';
23
12.9k
            *odata++ = ch;
24
12.9k
            continue;
25
12.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
18.8M
        if (ch == '\t') {
29
3.56k
            *odata++ = '\\';
30
3.56k
            *odata++ = 't';
31
3.56k
        }
32
18.8M
        else if (ch == '\n') {
33
2.98k
            *odata++ = '\\';
34
2.98k
            *odata++ = 'n';
35
2.98k
        }
36
18.8M
        else if (ch == '\r') {
37
3.32k
            *odata++ = '\\';
38
3.32k
            *odata++ = 'r';
39
3.32k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
18.8M
        else if (ch < ' ' || ch == 0x7F) {
43
16.6M
            *odata++ = '\\';
44
16.6M
            *odata++ = 'x';
45
16.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
16.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
16.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.25M
        else if (ch < 0x7F) {
51
1.79M
            *odata++ = ch;
52
1.79M
        }
53
54
        /* Non-ASCII characters */
55
456k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
456k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
85.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
85.6k
                if (ch <= 0xff) {
63
3.04k
                    *odata++ = 'x';
64
3.04k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.04k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.04k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
82.6k
                else if (ch <= 0xffff) {
69
28.8k
                    *odata++ = 'u';
70
28.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
28.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
28.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
28.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
28.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
53.7k
                else {
77
53.7k
                    *odata++ = 'U';
78
53.7k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
53.7k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
53.7k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
53.7k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
53.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
53.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
53.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
53.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
53.7k
                }
87
85.6k
            }
88
            /* Copy characters as-is */
89
371k
            else {
90
371k
                *odata++ = ch;
91
371k
            }
92
456k
        }
93
18.8M
    }
94
9.35k
    *odata = quote;
95
9.35k
}