Coverage Report

Created: 2026-01-17 06:16

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.64M
{
12
7.64M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.64M
    const void *idata = PyUnicode_DATA(unicode);
14
7.64M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.64M
    *odata++ = quote;
17
219M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
211M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
211M
        if ((ch == quote) || (ch == '\\')) {
22
763k
            *odata++ = '\\';
23
763k
            *odata++ = ch;
24
763k
            continue;
25
763k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
211M
        if (ch == '\t') {
29
462k
            *odata++ = '\\';
30
462k
            *odata++ = 't';
31
462k
        }
32
210M
        else if (ch == '\n') {
33
5.32M
            *odata++ = '\\';
34
5.32M
            *odata++ = 'n';
35
5.32M
        }
36
205M
        else if (ch == '\r') {
37
15.7k
            *odata++ = '\\';
38
15.7k
            *odata++ = 'r';
39
15.7k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
205M
        else if (ch < ' ' || ch == 0x7F) {
43
144M
            *odata++ = '\\';
44
144M
            *odata++ = 'x';
45
144M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
144M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
144M
        }
48
49
        /* Copy ASCII characters as-is */
50
60.6M
        else if (ch < 0x7F) {
51
50.6M
            *odata++ = ch;
52
50.6M
        }
53
54
        /* Non-ASCII characters */
55
10.0M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
10.0M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
291k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
291k
                if (ch <= 0xff) {
63
69.7k
                    *odata++ = 'x';
64
69.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
69.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
69.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
221k
                else if (ch <= 0xffff) {
69
115k
                    *odata++ = 'u';
70
115k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
115k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
115k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
115k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
115k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
106k
                else {
77
106k
                    *odata++ = 'U';
78
106k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
106k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
106k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
106k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
106k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
106k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
106k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
106k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
106k
                }
87
291k
            }
88
            /* Copy characters as-is */
89
9.79M
            else {
90
9.79M
                *odata++ = ch;
91
9.79M
            }
92
10.0M
        }
93
211M
    }
94
7.64M
    *odata = quote;
95
7.64M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
7.32M
{
12
7.32M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.32M
    const void *idata = PyUnicode_DATA(unicode);
14
7.32M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.32M
    *odata++ = quote;
17
77.7M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
70.4M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
70.4M
        if ((ch == quote) || (ch == '\\')) {
22
165k
            *odata++ = '\\';
23
165k
            *odata++ = ch;
24
165k
            continue;
25
165k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
70.2M
        if (ch == '\t') {
29
432k
            *odata++ = '\\';
30
432k
            *odata++ = 't';
31
432k
        }
32
69.8M
        else if (ch == '\n') {
33
5.13M
            *odata++ = '\\';
34
5.13M
            *odata++ = 'n';
35
5.13M
        }
36
64.7M
        else if (ch == '\r') {
37
5.86k
            *odata++ = '\\';
38
5.86k
            *odata++ = 'r';
39
5.86k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
64.6M
        else if (ch < ' ' || ch == 0x7F) {
43
43.1M
            *odata++ = '\\';
44
43.1M
            *odata++ = 'x';
45
43.1M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
43.1M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
43.1M
        }
48
49
        /* Copy ASCII characters as-is */
50
21.5M
        else if (ch < 0x7F) {
51
21.4M
            *odata++ = ch;
52
21.4M
        }
53
54
        /* Non-ASCII characters */
55
92.4k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
92.4k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
79.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
79.0k
                if (ch <= 0xff) {
63
33.0k
                    *odata++ = 'x';
64
33.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
33.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
33.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
46.0k
                else if (ch <= 0xffff) {
69
39.9k
                    *odata++ = 'u';
70
39.9k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
39.9k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
39.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
39.9k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
39.9k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
6.05k
                else {
77
6.05k
                    *odata++ = 'U';
78
6.05k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
6.05k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
6.05k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
6.05k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
6.05k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
6.05k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
6.05k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
6.05k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
6.05k
                }
87
79.0k
            }
88
            /* Copy characters as-is */
89
13.3k
            else {
90
13.3k
                *odata++ = ch;
91
13.3k
            }
92
92.4k
        }
93
70.2M
    }
94
7.32M
    *odata = quote;
95
7.32M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
306k
{
12
306k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
306k
    const void *idata = PyUnicode_DATA(unicode);
14
306k
    int ikind = PyUnicode_KIND(unicode);
15
16
306k
    *odata++ = quote;
17
127M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
127M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
127M
        if ((ch == quote) || (ch == '\\')) {
22
585k
            *odata++ = '\\';
23
585k
            *odata++ = ch;
24
585k
            continue;
25
585k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
126M
        if (ch == '\t') {
29
24.6k
            *odata++ = '\\';
30
24.6k
            *odata++ = 't';
31
24.6k
        }
32
126M
        else if (ch == '\n') {
33
189k
            *odata++ = '\\';
34
189k
            *odata++ = 'n';
35
189k
        }
36
126M
        else if (ch == '\r') {
37
6.14k
            *odata++ = '\\';
38
6.14k
            *odata++ = 'r';
39
6.14k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
126M
        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
38.0M
        else if (ch < 0x7F) {
51
28.3M
            *odata++ = ch;
52
28.3M
        }
53
54
        /* Non-ASCII characters */
55
9.64M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.64M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
132k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
132k
                if (ch <= 0xff) {
63
34.3k
                    *odata++ = 'x';
64
34.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
34.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
34.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
97.9k
                else if (ch <= 0xffff) {
69
33.3k
                    *odata++ = 'u';
70
33.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
33.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
33.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
33.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
33.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
64.5k
                else {
77
64.5k
                    *odata++ = 'U';
78
64.5k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
64.5k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
64.5k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
64.5k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
64.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
64.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
64.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
64.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
64.5k
                }
87
132k
            }
88
            /* Copy characters as-is */
89
9.50M
            else {
90
9.50M
                *odata++ = ch;
91
9.50M
            }
92
9.64M
        }
93
126M
    }
94
306k
    *odata = quote;
95
306k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
7.15k
{
12
7.15k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.15k
    const void *idata = PyUnicode_DATA(unicode);
14
7.15k
    int ikind = PyUnicode_KIND(unicode);
15
16
7.15k
    *odata++ = quote;
17
13.7M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
13.7M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
13.7M
        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
13.7M
        if (ch == '\t') {
29
4.73k
            *odata++ = '\\';
30
4.73k
            *odata++ = 't';
31
4.73k
        }
32
13.7M
        else if (ch == '\n') {
33
3.16k
            *odata++ = '\\';
34
3.16k
            *odata++ = 'n';
35
3.16k
        }
36
13.7M
        else if (ch == '\r') {
37
3.71k
            *odata++ = '\\';
38
3.71k
            *odata++ = 'r';
39
3.71k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
13.7M
        else if (ch < ' ' || ch == 0x7F) {
43
12.6M
            *odata++ = '\\';
44
12.6M
            *odata++ = 'x';
45
12.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.08M
        else if (ch < 0x7F) {
51
732k
            *odata++ = ch;
52
732k
        }
53
54
        /* Non-ASCII characters */
55
353k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
353k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
79.7k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
79.7k
                if (ch <= 0xff) {
63
2.31k
                    *odata++ = 'x';
64
2.31k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.31k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.31k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
77.4k
                else if (ch <= 0xffff) {
69
41.7k
                    *odata++ = 'u';
70
41.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
41.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
41.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
41.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
41.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
35.7k
                else {
77
35.7k
                    *odata++ = 'U';
78
35.7k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
35.7k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
35.7k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
35.7k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
35.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
35.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
35.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
35.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
35.7k
                }
87
79.7k
            }
88
            /* Copy characters as-is */
89
273k
            else {
90
273k
                *odata++ = ch;
91
273k
            }
92
353k
        }
93
13.7M
    }
94
7.15k
    *odata = quote;
95
7.15k
}