Coverage Report

Created: 2026-10-17 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
7.10M
{
12
7.10M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.10M
    const void *idata = PyUnicode_DATA(unicode);
14
7.10M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.10M
    *odata++ = quote;
17
244M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
237M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
237M
        if ((ch == quote) || (ch == '\\')) {
22
388k
            *odata++ = '\\';
23
388k
            *odata++ = ch;
24
388k
            continue;
25
388k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
236M
        if (ch == '\t') {
29
475k
            *odata++ = '\\';
30
475k
            *odata++ = 't';
31
475k
        }
32
236M
        else if (ch == '\n') {
33
5.80M
            *odata++ = '\\';
34
5.80M
            *odata++ = 'n';
35
5.80M
        }
36
230M
        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
230M
        else if (ch < ' ' || ch == 0x7F) {
43
149M
            *odata++ = '\\';
44
149M
            *odata++ = 'x';
45
149M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
149M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
149M
        }
48
49
        /* Copy ASCII characters as-is */
50
80.6M
        else if (ch < 0x7F) {
51
68.8M
            *odata++ = ch;
52
68.8M
        }
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
1.14M
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
1.14M
                if (ch <= 0xff) {
63
81.5k
                    *odata++ = 'x';
64
81.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
81.5k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
81.5k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
1.06M
                else if (ch <= 0xffff) {
69
98.8k
                    *odata++ = 'u';
70
98.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
98.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
98.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
98.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
98.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
966k
                else {
77
966k
                    *odata++ = 'U';
78
966k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
966k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
966k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
966k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
966k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
966k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
966k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
966k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
966k
                }
87
1.14M
            }
88
            /* Copy characters as-is */
89
10.7M
            else {
90
10.7M
                *odata++ = ch;
91
10.7M
            }
92
11.8M
        }
93
236M
    }
94
7.10M
    *odata = quote;
95
7.10M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.79M
{
12
6.79M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.79M
    const void *idata = PyUnicode_DATA(unicode);
14
6.79M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.79M
    *odata++ = quote;
17
75.6M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
68.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
68.8M
        if ((ch == quote) || (ch == '\\')) {
22
129k
            *odata++ = '\\';
23
129k
            *odata++ = ch;
24
129k
            continue;
25
129k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
68.7M
        if (ch == '\t') {
29
456k
            *odata++ = '\\';
30
456k
            *odata++ = 't';
31
456k
        }
32
68.3M
        else if (ch == '\n') {
33
5.66M
            *odata++ = '\\';
34
5.66M
            *odata++ = 'n';
35
5.66M
        }
36
62.6M
        else if (ch == '\r') {
37
8.62k
            *odata++ = '\\';
38
8.62k
            *odata++ = 'r';
39
8.62k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
62.6M
        else if (ch < ' ' || ch == 0x7F) {
43
41.2M
            *odata++ = '\\';
44
41.2M
            *odata++ = 'x';
45
41.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
41.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
41.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
21.3M
        else if (ch < 0x7F) {
51
21.2M
            *odata++ = ch;
52
21.2M
        }
53
54
        /* Non-ASCII characters */
55
94.6k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
94.6k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
79.5k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
79.5k
                if (ch <= 0xff) {
63
31.0k
                    *odata++ = 'x';
64
31.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
31.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
31.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
48.5k
                else if (ch <= 0xffff) {
69
36.2k
                    *odata++ = 'u';
70
36.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
36.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
36.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
36.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
36.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
12.3k
                else {
77
12.3k
                    *odata++ = 'U';
78
12.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
12.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
12.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
12.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
12.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
12.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
12.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
12.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
12.3k
                }
87
79.5k
            }
88
            /* Copy characters as-is */
89
15.0k
            else {
90
15.0k
                *odata++ = ch;
91
15.0k
            }
92
94.6k
        }
93
68.7M
    }
94
6.79M
    *odata = quote;
95
6.79M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
294k
{
12
294k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
294k
    const void *idata = PyUnicode_DATA(unicode);
14
294k
    int ikind = PyUnicode_KIND(unicode);
15
16
294k
    *odata++ = quote;
17
146M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
146M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
146M
        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
146M
        if (ch == '\t') {
29
16.1k
            *odata++ = '\\';
30
16.1k
            *odata++ = 't';
31
16.1k
        }
32
146M
        else if (ch == '\n') {
33
141k
            *odata++ = '\\';
34
141k
            *odata++ = 'n';
35
141k
        }
36
145M
        else if (ch == '\r') {
37
4.88k
            *odata++ = '\\';
38
4.88k
            *odata++ = 'r';
39
4.88k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
145M
        else if (ch < ' ' || ch == 0x7F) {
43
88.7M
            *odata++ = '\\';
44
88.7M
            *odata++ = 'x';
45
88.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
88.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
88.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
57.2M
        else if (ch < 0x7F) {
51
46.0M
            *odata++ = ch;
52
46.0M
        }
53
54
        /* Non-ASCII characters */
55
11.1M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
11.1M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
938k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
938k
                if (ch <= 0xff) {
63
46.8k
                    *odata++ = 'x';
64
46.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
46.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
46.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
891k
                else if (ch <= 0xffff) {
69
31.8k
                    *odata++ = 'u';
70
31.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
31.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
31.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
31.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
31.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
859k
                else {
77
859k
                    *odata++ = 'U';
78
859k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
859k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
859k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
859k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
859k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
859k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
859k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
859k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
859k
                }
87
938k
            }
88
            /* Copy characters as-is */
89
10.1M
            else {
90
10.1M
                *odata++ = ch;
91
10.1M
            }
92
11.1M
        }
93
146M
    }
94
294k
    *odata = quote;
95
294k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
8.06k
{
12
8.06k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
8.06k
    const void *idata = PyUnicode_DATA(unicode);
14
8.06k
    int ikind = PyUnicode_KIND(unicode);
15
16
8.06k
    *odata++ = quote;
17
21.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
21.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
21.9M
        if ((ch == quote) || (ch == '\\')) {
22
25.1k
            *odata++ = '\\';
23
25.1k
            *odata++ = ch;
24
25.1k
            continue;
25
25.1k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
21.8M
        if (ch == '\t') {
29
3.46k
            *odata++ = '\\';
30
3.46k
            *odata++ = 't';
31
3.46k
        }
32
21.8M
        else if (ch == '\n') {
33
6.72k
            *odata++ = '\\';
34
6.72k
            *odata++ = 'n';
35
6.72k
        }
36
21.8M
        else if (ch == '\r') {
37
3.56k
            *odata++ = '\\';
38
3.56k
            *odata++ = 'r';
39
3.56k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
21.8M
        else if (ch < ' ' || ch == 0x7F) {
43
19.7M
            *odata++ = '\\';
44
19.7M
            *odata++ = 'x';
45
19.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
19.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
19.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.11M
        else if (ch < 0x7F) {
51
1.46M
            *odata++ = ch;
52
1.46M
        }
53
54
        /* Non-ASCII characters */
55
650k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
650k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
128k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
128k
                if (ch <= 0xff) {
63
3.64k
                    *odata++ = 'x';
64
3.64k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.64k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.64k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
125k
                else if (ch <= 0xffff) {
69
30.7k
                    *odata++ = 'u';
70
30.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
30.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
30.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
30.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
30.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
94.3k
                else {
77
94.3k
                    *odata++ = 'U';
78
94.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
94.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
94.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
94.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
94.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
94.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
94.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
94.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
94.3k
                }
87
128k
            }
88
            /* Copy characters as-is */
89
521k
            else {
90
521k
                *odata++ = ch;
91
521k
            }
92
650k
        }
93
21.8M
    }
94
8.06k
    *odata = quote;
95
8.06k
}