Coverage Report

Created: 2025-11-11 06:44

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
689k
{
12
689k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
689k
    const void *idata = PyUnicode_DATA(unicode);
14
689k
    int ikind = PyUnicode_KIND(unicode);
15
16
689k
    *odata++ = quote;
17
108M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
107M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
107M
        if ((ch == quote) || (ch == '\\')) {
22
232k
            *odata++ = '\\';
23
232k
            *odata++ = ch;
24
232k
            continue;
25
232k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
107M
        if (ch == '\t') {
29
20.3k
            *odata++ = '\\';
30
20.3k
            *odata++ = 't';
31
20.3k
        }
32
107M
        else if (ch == '\n') {
33
1.98k
            *odata++ = '\\';
34
1.98k
            *odata++ = 'n';
35
1.98k
        }
36
107M
        else if (ch == '\r') {
37
2.10k
            *odata++ = '\\';
38
2.10k
            *odata++ = 'r';
39
2.10k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
107M
        else if (ch < ' ' || ch == 0x7F) {
43
75.5M
            *odata++ = '\\';
44
75.5M
            *odata++ = 'x';
45
75.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
75.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
75.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
31.6M
        else if (ch < 0x7F) {
51
25.2M
            *odata++ = ch;
52
25.2M
        }
53
54
        /* Non-ASCII characters */
55
6.39M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.39M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
101k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
101k
                if (ch <= 0xff) {
63
29.3k
                    *odata++ = 'x';
64
29.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
29.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
29.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
72.3k
                else if (ch <= 0xffff) {
69
51.7k
                    *odata++ = 'u';
70
51.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
51.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
51.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
51.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
51.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
20.6k
                else {
77
20.6k
                    *odata++ = 'U';
78
20.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
20.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
20.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
20.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
20.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
20.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
20.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
20.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
20.6k
                }
87
101k
            }
88
            /* Copy characters as-is */
89
6.28M
            else {
90
6.28M
                *odata++ = ch;
91
6.28M
            }
92
6.39M
        }
93
107M
    }
94
689k
    *odata = quote;
95
689k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
463k
{
12
463k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
463k
    const void *idata = PyUnicode_DATA(unicode);
14
463k
    int ikind = PyUnicode_KIND(unicode);
15
16
463k
    *odata++ = quote;
17
24.2M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
23.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
23.8M
        if ((ch == quote) || (ch == '\\')) {
22
147k
            *odata++ = '\\';
23
147k
            *odata++ = ch;
24
147k
            continue;
25
147k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
23.6M
        if (ch == '\t') {
29
12.3k
            *odata++ = '\\';
30
12.3k
            *odata++ = 't';
31
12.3k
        }
32
23.6M
        else if (ch == '\n') {
33
1.03k
            *odata++ = '\\';
34
1.03k
            *odata++ = 'n';
35
1.03k
        }
36
23.6M
        else if (ch == '\r') {
37
1.16k
            *odata++ = '\\';
38
1.16k
            *odata++ = 'r';
39
1.16k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
23.6M
        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
7.04M
        else if (ch < 0x7F) {
51
6.99M
            *odata++ = ch;
52
6.99M
        }
53
54
        /* Non-ASCII characters */
55
56.8k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
56.8k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
50.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
50.6k
                if (ch <= 0xff) {
63
15.3k
                    *odata++ = 'x';
64
15.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
15.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
15.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
35.3k
                else if (ch <= 0xffff) {
69
32.5k
                    *odata++ = 'u';
70
32.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
32.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
32.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
32.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
32.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.76k
                else {
77
2.76k
                    *odata++ = 'U';
78
2.76k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.76k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.76k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.76k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.76k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.76k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.76k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.76k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.76k
                }
87
50.6k
            }
88
            /* Copy characters as-is */
89
6.18k
            else {
90
6.18k
                *odata++ = ch;
91
6.18k
            }
92
56.8k
        }
93
23.6M
    }
94
463k
    *odata = quote;
95
463k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
221k
{
12
221k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
221k
    const void *idata = PyUnicode_DATA(unicode);
14
221k
    int ikind = PyUnicode_KIND(unicode);
15
16
221k
    *odata++ = quote;
17
70.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
70.7M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
70.7M
        if ((ch == quote) || (ch == '\\')) {
22
77.4k
            *odata++ = '\\';
23
77.4k
            *odata++ = ch;
24
77.4k
            continue;
25
77.4k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
70.6M
        if (ch == '\t') {
29
7.34k
            *odata++ = '\\';
30
7.34k
            *odata++ = 't';
31
7.34k
        }
32
70.6M
        else if (ch == '\n') {
33
662
            *odata++ = '\\';
34
662
            *odata++ = 'n';
35
662
        }
36
70.6M
        else if (ch == '\r') {
37
510
            *odata++ = '\\';
38
510
            *odata++ = 'r';
39
510
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
70.6M
        else if (ch < ' ' || ch == 0x7F) {
43
46.5M
            *odata++ = '\\';
44
46.5M
            *odata++ = 'x';
45
46.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
46.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
46.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
24.0M
        else if (ch < 0x7F) {
51
17.8M
            *odata++ = ch;
52
17.8M
        }
53
54
        /* Non-ASCII characters */
55
6.17M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.17M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
45.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
45.8k
                if (ch <= 0xff) {
63
12.6k
                    *odata++ = 'x';
64
12.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
12.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
12.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
33.1k
                else if (ch <= 0xffff) {
69
15.8k
                    *odata++ = 'u';
70
15.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
15.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
15.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
15.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
15.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
17.3k
                else {
77
17.3k
                    *odata++ = 'U';
78
17.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
17.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
17.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
17.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
17.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
17.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
17.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
17.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
17.3k
                }
87
45.8k
            }
88
            /* Copy characters as-is */
89
6.12M
            else {
90
6.12M
                *odata++ = ch;
91
6.12M
            }
92
6.17M
        }
93
70.6M
    }
94
221k
    *odata = quote;
95
221k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
3.94k
{
12
3.94k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.94k
    const void *idata = PyUnicode_DATA(unicode);
14
3.94k
    int ikind = PyUnicode_KIND(unicode);
15
16
3.94k
    *odata++ = quote;
17
12.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
12.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
12.9M
        if ((ch == quote) || (ch == '\\')) {
22
7.22k
            *odata++ = '\\';
23
7.22k
            *odata++ = ch;
24
7.22k
            continue;
25
7.22k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
12.9M
        if (ch == '\t') {
29
651
            *odata++ = '\\';
30
651
            *odata++ = 't';
31
651
        }
32
12.9M
        else if (ch == '\n') {
33
279
            *odata++ = '\\';
34
279
            *odata++ = 'n';
35
279
        }
36
12.9M
        else if (ch == '\r') {
37
433
            *odata++ = '\\';
38
433
            *odata++ = 'r';
39
433
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
12.9M
        else if (ch < ' ' || ch == 0x7F) {
43
12.4M
            *odata++ = '\\';
44
12.4M
            *odata++ = 'x';
45
12.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
517k
        else if (ch < 0x7F) {
51
356k
            *odata++ = ch;
52
356k
        }
53
54
        /* Non-ASCII characters */
55
160k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
160k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
5.23k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
5.23k
                if (ch <= 0xff) {
63
1.33k
                    *odata++ = 'x';
64
1.33k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.33k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.33k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.89k
                else if (ch <= 0xffff) {
69
3.36k
                    *odata++ = 'u';
70
3.36k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.36k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.36k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.36k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.36k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
536
                else {
77
536
                    *odata++ = 'U';
78
536
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
536
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
536
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
536
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
536
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
536
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
536
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
536
                    *odata++ = Py_hexdigits[ch & 0xF];
86
536
                }
87
5.23k
            }
88
            /* Copy characters as-is */
89
155k
            else {
90
155k
                *odata++ = ch;
91
155k
            }
92
160k
        }
93
12.9M
    }
94
3.94k
    *odata = quote;
95
3.94k
}