Coverage Report

Created: 2026-01-09 06:26

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.63M
{
12
7.63M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.63M
    const void *idata = PyUnicode_DATA(unicode);
14
7.63M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.63M
    *odata++ = quote;
17
207M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
199M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
199M
        if ((ch == quote) || (ch == '\\')) {
22
778k
            *odata++ = '\\';
23
778k
            *odata++ = ch;
24
778k
            continue;
25
778k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
198M
        if (ch == '\t') {
29
458k
            *odata++ = '\\';
30
458k
            *odata++ = 't';
31
458k
        }
32
198M
        else if (ch == '\n') {
33
5.55M
            *odata++ = '\\';
34
5.55M
            *odata++ = 'n';
35
5.55M
        }
36
192M
        else if (ch == '\r') {
37
13.4k
            *odata++ = '\\';
38
13.4k
            *odata++ = 'r';
39
13.4k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
192M
        else if (ch < ' ' || ch == 0x7F) {
43
138M
            *odata++ = '\\';
44
138M
            *odata++ = 'x';
45
138M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
138M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
138M
        }
48
49
        /* Copy ASCII characters as-is */
50
54.3M
        else if (ch < 0x7F) {
51
46.6M
            *odata++ = ch;
52
46.6M
        }
53
54
        /* Non-ASCII characters */
55
7.67M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.67M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
293k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
293k
                if (ch <= 0xff) {
63
79.9k
                    *odata++ = 'x';
64
79.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
79.9k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
79.9k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
213k
                else if (ch <= 0xffff) {
69
109k
                    *odata++ = 'u';
70
109k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
109k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
109k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
109k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
109k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
103k
                else {
77
103k
                    *odata++ = 'U';
78
103k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
103k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
103k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
103k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
103k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
103k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
103k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
103k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
103k
                }
87
293k
            }
88
            /* Copy characters as-is */
89
7.38M
            else {
90
7.38M
                *odata++ = ch;
91
7.38M
            }
92
7.67M
        }
93
198M
    }
94
7.63M
    *odata = quote;
95
7.63M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
7.31M
{
12
7.31M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.31M
    const void *idata = PyUnicode_DATA(unicode);
14
7.31M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.31M
    *odata++ = quote;
17
74.2M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
66.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
66.9M
        if ((ch == quote) || (ch == '\\')) {
22
173k
            *odata++ = '\\';
23
173k
            *odata++ = ch;
24
173k
            continue;
25
173k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
66.7M
        if (ch == '\t') {
29
434k
            *odata++ = '\\';
30
434k
            *odata++ = 't';
31
434k
        }
32
66.3M
        else if (ch == '\n') {
33
5.31M
            *odata++ = '\\';
34
5.31M
            *odata++ = 'n';
35
5.31M
        }
36
61.0M
        else if (ch == '\r') {
37
5.32k
            *odata++ = '\\';
38
5.32k
            *odata++ = 'r';
39
5.32k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
61.0M
        else if (ch < ' ' || ch == 0x7F) {
43
39.6M
            *odata++ = '\\';
44
39.6M
            *odata++ = 'x';
45
39.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
39.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
39.6M
        }
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
104k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
104k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
83.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
83.0k
                if (ch <= 0xff) {
63
36.7k
                    *odata++ = 'x';
64
36.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
36.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
36.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
46.2k
                else if (ch <= 0xffff) {
69
40.0k
                    *odata++ = 'u';
70
40.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
40.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
40.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
40.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
40.0k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
6.24k
                else {
77
6.24k
                    *odata++ = 'U';
78
6.24k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
6.24k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
6.24k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
6.24k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
6.24k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
6.24k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
6.24k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
6.24k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
6.24k
                }
87
83.0k
            }
88
            /* Copy characters as-is */
89
21.9k
            else {
90
21.9k
                *odata++ = ch;
91
21.9k
            }
92
104k
        }
93
66.7M
    }
94
7.31M
    *odata = quote;
95
7.31M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
309k
{
12
309k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
309k
    const void *idata = PyUnicode_DATA(unicode);
14
309k
    int ikind = PyUnicode_KIND(unicode);
15
16
309k
    *odata++ = quote;
17
119M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
119M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
119M
        if ((ch == quote) || (ch == '\\')) {
22
592k
            *odata++ = '\\';
23
592k
            *odata++ = ch;
24
592k
            continue;
25
592k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
118M
        if (ch == '\t') {
29
19.8k
            *odata++ = '\\';
30
19.8k
            *odata++ = 't';
31
19.8k
        }
32
118M
        else if (ch == '\n') {
33
228k
            *odata++ = '\\';
34
228k
            *odata++ = 'n';
35
228k
        }
36
118M
        else if (ch == '\r') {
37
4.37k
            *odata++ = '\\';
38
4.37k
            *odata++ = 'r';
39
4.37k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
118M
        else if (ch < ' ' || ch == 0x7F) {
43
86.6M
            *odata++ = '\\';
44
86.6M
            *odata++ = 'x';
45
86.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
86.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
86.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
31.9M
        else if (ch < 0x7F) {
51
24.6M
            *odata++ = ch;
52
24.6M
        }
53
54
        /* Non-ASCII characters */
55
7.26M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.26M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
147k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
147k
                if (ch <= 0xff) {
63
40.6k
                    *odata++ = 'x';
64
40.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
40.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
40.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
106k
                else if (ch <= 0xffff) {
69
36.6k
                    *odata++ = 'u';
70
36.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
36.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
36.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
36.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
36.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
70.2k
                else {
77
70.2k
                    *odata++ = 'U';
78
70.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
70.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
70.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
70.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
70.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
70.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
70.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
70.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
70.2k
                }
87
147k
            }
88
            /* Copy characters as-is */
89
7.11M
            else {
90
7.11M
                *odata++ = ch;
91
7.11M
            }
92
7.26M
        }
93
118M
    }
94
309k
    *odata = quote;
95
309k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
7.83k
{
12
7.83k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.83k
    const void *idata = PyUnicode_DATA(unicode);
14
7.83k
    int ikind = PyUnicode_KIND(unicode);
15
16
7.83k
    *odata++ = quote;
17
13.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
13.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
13.1M
        if ((ch == quote) || (ch == '\\')) {
22
11.8k
            *odata++ = '\\';
23
11.8k
            *odata++ = ch;
24
11.8k
            continue;
25
11.8k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
13.1M
        if (ch == '\t') {
29
3.37k
            *odata++ = '\\';
30
3.37k
            *odata++ = 't';
31
3.37k
        }
32
13.1M
        else if (ch == '\n') {
33
4.23k
            *odata++ = '\\';
34
4.23k
            *odata++ = 'n';
35
4.23k
        }
36
13.0M
        else if (ch == '\r') {
37
3.77k
            *odata++ = '\\';
38
3.77k
            *odata++ = 'r';
39
3.77k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
13.0M
        else if (ch < ' ' || ch == 0x7F) {
43
12.0M
            *odata++ = '\\';
44
12.0M
            *odata++ = 'x';
45
12.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.01M
        else if (ch < 0x7F) {
51
702k
            *odata++ = ch;
52
702k
        }
53
54
        /* Non-ASCII characters */
55
309k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
309k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
62.5k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
62.5k
                if (ch <= 0xff) {
63
2.43k
                    *odata++ = 'x';
64
2.43k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.43k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.43k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
60.1k
                else if (ch <= 0xffff) {
69
32.9k
                    *odata++ = 'u';
70
32.9k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
32.9k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
32.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
32.9k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
32.9k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
27.2k
                else {
77
27.2k
                    *odata++ = 'U';
78
27.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
27.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
27.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
27.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
27.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
27.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
27.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
27.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
27.2k
                }
87
62.5k
            }
88
            /* Copy characters as-is */
89
247k
            else {
90
247k
                *odata++ = ch;
91
247k
            }
92
309k
        }
93
13.1M
    }
94
7.83k
    *odata = quote;
95
7.83k
}