Coverage Report

Created: 2026-05-30 06:18

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
5.67M
{
12
5.67M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.67M
    const void *idata = PyUnicode_DATA(unicode);
14
5.67M
    int ikind = PyUnicode_KIND(unicode);
15
16
5.67M
    *odata++ = quote;
17
256M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
250M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
250M
        if ((ch == quote) || (ch == '\\')) {
22
214k
            *odata++ = '\\';
23
214k
            *odata++ = ch;
24
214k
            continue;
25
214k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
250M
        if (ch == '\t') {
29
477k
            *odata++ = '\\';
30
477k
            *odata++ = 't';
31
477k
        }
32
249M
        else if (ch == '\n') {
33
3.83M
            *odata++ = '\\';
34
3.83M
            *odata++ = 'n';
35
3.83M
        }
36
246M
        else if (ch == '\r') {
37
12.9k
            *odata++ = '\\';
38
12.9k
            *odata++ = 'r';
39
12.9k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
246M
        else if (ch < ' ' || ch == 0x7F) {
43
170M
            *odata++ = '\\';
44
170M
            *odata++ = 'x';
45
170M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
170M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
170M
        }
48
49
        /* Copy ASCII characters as-is */
50
75.9M
        else if (ch < 0x7F) {
51
63.6M
            *odata++ = ch;
52
63.6M
        }
53
54
        /* Non-ASCII characters */
55
12.3M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
12.3M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
334k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
334k
                if (ch <= 0xff) {
63
67.4k
                    *odata++ = 'x';
64
67.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
67.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
67.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
267k
                else if (ch <= 0xffff) {
69
89.8k
                    *odata++ = 'u';
70
89.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
89.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
89.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
89.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
89.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
177k
                else {
77
177k
                    *odata++ = 'U';
78
177k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
177k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
177k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
177k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
177k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
177k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
177k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
177k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
177k
                }
87
334k
            }
88
            /* Copy characters as-is */
89
11.9M
            else {
90
11.9M
                *odata++ = ch;
91
11.9M
            }
92
12.3M
        }
93
250M
    }
94
5.67M
    *odata = quote;
95
5.67M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
5.39M
{
12
5.39M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.39M
    const void *idata = PyUnicode_DATA(unicode);
14
5.39M
    int ikind = PyUnicode_KIND(unicode);
15
16
5.39M
    *odata++ = quote;
17
80.7M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
75.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
75.3M
        if ((ch == quote) || (ch == '\\')) {
22
121k
            *odata++ = '\\';
23
121k
            *odata++ = ch;
24
121k
            continue;
25
121k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
75.1M
        if (ch == '\t') {
29
432k
            *odata++ = '\\';
30
432k
            *odata++ = 't';
31
432k
        }
32
74.7M
        else if (ch == '\n') {
33
3.75M
            *odata++ = '\\';
34
3.75M
            *odata++ = 'n';
35
3.75M
        }
36
70.9M
        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
70.9M
        else if (ch < ' ' || ch == 0x7F) {
43
48.3M
            *odata++ = '\\';
44
48.3M
            *odata++ = 'x';
45
48.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
48.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
48.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
22.6M
        else if (ch < 0x7F) {
51
22.5M
            *odata++ = ch;
52
22.5M
        }
53
54
        /* Non-ASCII characters */
55
91.9k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
91.9k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
73.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
73.8k
                if (ch <= 0xff) {
63
27.5k
                    *odata++ = 'x';
64
27.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
27.5k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
27.5k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
46.2k
                else if (ch <= 0xffff) {
69
36.0k
                    *odata++ = 'u';
70
36.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
36.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
36.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
36.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
36.0k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
10.2k
                else {
77
10.2k
                    *odata++ = 'U';
78
10.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
10.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
10.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
10.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
10.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
10.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
10.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
10.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
10.2k
                }
87
73.8k
            }
88
            /* Copy characters as-is */
89
18.0k
            else {
90
18.0k
                *odata++ = ch;
91
18.0k
            }
92
91.9k
        }
93
75.1M
    }
94
5.39M
    *odata = quote;
95
5.39M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
267k
{
12
267k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
267k
    const void *idata = PyUnicode_DATA(unicode);
14
267k
    int ikind = PyUnicode_KIND(unicode);
15
16
267k
    *odata++ = quote;
17
156M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
156M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
156M
        if ((ch == quote) || (ch == '\\')) {
22
73.3k
            *odata++ = '\\';
23
73.3k
            *odata++ = ch;
24
73.3k
            continue;
25
73.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
155M
        if (ch == '\t') {
29
41.3k
            *odata++ = '\\';
30
41.3k
            *odata++ = 't';
31
41.3k
        }
32
155M
        else if (ch == '\n') {
33
78.5k
            *odata++ = '\\';
34
78.5k
            *odata++ = 'n';
35
78.5k
        }
36
155M
        else if (ch == '\r') {
37
3.69k
            *odata++ = '\\';
38
3.69k
            *odata++ = 'r';
39
3.69k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
155M
        else if (ch < ' ' || ch == 0x7F) {
43
104M
            *odata++ = '\\';
44
104M
            *odata++ = 'x';
45
104M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
104M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
104M
        }
48
49
        /* Copy ASCII characters as-is */
50
51.1M
        else if (ch < 0x7F) {
51
39.2M
            *odata++ = ch;
52
39.2M
        }
53
54
        /* Non-ASCII characters */
55
11.8M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
11.8M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
194k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
194k
                if (ch <= 0xff) {
63
36.4k
                    *odata++ = 'x';
64
36.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
36.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
36.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
158k
                else if (ch <= 0xffff) {
69
25.1k
                    *odata++ = 'u';
70
25.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
25.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
25.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
25.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
25.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
133k
                else {
77
133k
                    *odata++ = 'U';
78
133k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
133k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
133k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
133k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
133k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
133k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
133k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
133k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
133k
                }
87
194k
            }
88
            /* Copy characters as-is */
89
11.6M
            else {
90
11.6M
                *odata++ = ch;
91
11.6M
            }
92
11.8M
        }
93
155M
    }
94
267k
    *odata = quote;
95
267k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
8.10k
{
12
8.10k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
8.10k
    const void *idata = PyUnicode_DATA(unicode);
14
8.10k
    int ikind = PyUnicode_KIND(unicode);
15
16
8.10k
    *odata++ = quote;
17
19.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
19.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
19.3M
        if ((ch == quote) || (ch == '\\')) {
22
20.5k
            *odata++ = '\\';
23
20.5k
            *odata++ = ch;
24
20.5k
            continue;
25
20.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
19.3M
        if (ch == '\t') {
29
3.64k
            *odata++ = '\\';
30
3.64k
            *odata++ = 't';
31
3.64k
        }
32
19.3M
        else if (ch == '\n') {
33
2.79k
            *odata++ = '\\';
34
2.79k
            *odata++ = 'n';
35
2.79k
        }
36
19.3M
        else if (ch == '\r') {
37
3.01k
            *odata++ = '\\';
38
3.01k
            *odata++ = 'r';
39
3.01k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
19.3M
        else if (ch < ' ' || ch == 0x7F) {
43
17.1M
            *odata++ = '\\';
44
17.1M
            *odata++ = 'x';
45
17.1M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
17.1M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
17.1M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.22M
        else if (ch < 0x7F) {
51
1.82M
            *odata++ = ch;
52
1.82M
        }
53
54
        /* Non-ASCII characters */
55
396k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
396k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
66.1k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
66.1k
                if (ch <= 0xff) {
63
3.36k
                    *odata++ = 'x';
64
3.36k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.36k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.36k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
62.7k
                else if (ch <= 0xffff) {
69
28.6k
                    *odata++ = 'u';
70
28.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
28.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
28.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
28.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
28.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
34.1k
                else {
77
34.1k
                    *odata++ = 'U';
78
34.1k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
34.1k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
34.1k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
34.1k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
34.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
34.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
34.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
34.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
34.1k
                }
87
66.1k
            }
88
            /* Copy characters as-is */
89
330k
            else {
90
330k
                *odata++ = ch;
91
330k
            }
92
396k
        }
93
19.3M
    }
94
8.10k
    *odata = quote;
95
8.10k
}