Coverage Report

Created: 2025-12-14 07:06

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
6.88M
{
12
6.88M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.88M
    const void *idata = PyUnicode_DATA(unicode);
14
6.88M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.88M
    *odata++ = quote;
17
199M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
192M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
192M
        if ((ch == quote) || (ch == '\\')) {
22
207k
            *odata++ = '\\';
23
207k
            *odata++ = ch;
24
207k
            continue;
25
207k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
192M
        if (ch == '\t') {
29
456k
            *odata++ = '\\';
30
456k
            *odata++ = 't';
31
456k
        }
32
191M
        else if (ch == '\n') {
33
4.74M
            *odata++ = '\\';
34
4.74M
            *odata++ = 'n';
35
4.74M
        }
36
186M
        else if (ch == '\r') {
37
10.2k
            *odata++ = '\\';
38
10.2k
            *odata++ = 'r';
39
10.2k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
186M
        else if (ch < ' ' || ch == 0x7F) {
43
132M
            *odata++ = '\\';
44
132M
            *odata++ = 'x';
45
132M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
132M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
132M
        }
48
49
        /* Copy ASCII characters as-is */
50
54.3M
        else if (ch < 0x7F) {
51
44.4M
            *odata++ = ch;
52
44.4M
        }
53
54
        /* Non-ASCII characters */
55
9.92M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.92M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
230k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
230k
                if (ch <= 0xff) {
63
61.2k
                    *odata++ = 'x';
64
61.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
61.2k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
61.2k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
169k
                else if (ch <= 0xffff) {
69
86.1k
                    *odata++ = 'u';
70
86.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
86.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
86.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
86.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
86.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
83.2k
                else {
77
83.2k
                    *odata++ = 'U';
78
83.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
83.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
83.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
83.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
83.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
83.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
83.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
83.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
83.2k
                }
87
230k
            }
88
            /* Copy characters as-is */
89
9.69M
            else {
90
9.69M
                *odata++ = ch;
91
9.69M
            }
92
9.92M
        }
93
192M
    }
94
6.88M
    *odata = quote;
95
6.88M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.61M
{
12
6.61M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.61M
    const void *idata = PyUnicode_DATA(unicode);
14
6.61M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.61M
    *odata++ = quote;
17
71.4M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
64.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
64.8M
        if ((ch == quote) || (ch == '\\')) {
22
131k
            *odata++ = '\\';
23
131k
            *odata++ = ch;
24
131k
            continue;
25
131k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
64.7M
        if (ch == '\t') {
29
433k
            *odata++ = '\\';
30
433k
            *odata++ = 't';
31
433k
        }
32
64.2M
        else if (ch == '\n') {
33
4.49M
            *odata++ = '\\';
34
4.49M
            *odata++ = 'n';
35
4.49M
        }
36
59.7M
        else if (ch == '\r') {
37
2.80k
            *odata++ = '\\';
38
2.80k
            *odata++ = 'r';
39
2.80k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
59.7M
        else if (ch < ' ' || ch == 0x7F) {
43
39.2M
            *odata++ = '\\';
44
39.2M
            *odata++ = 'x';
45
39.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
39.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
39.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
20.5M
        else if (ch < 0x7F) {
51
20.4M
            *odata++ = ch;
52
20.4M
        }
53
54
        /* Non-ASCII characters */
55
70.7k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
70.7k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
60.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
60.8k
                if (ch <= 0xff) {
63
20.7k
                    *odata++ = 'x';
64
20.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
20.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
20.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
40.1k
                else if (ch <= 0xffff) {
69
35.1k
                    *odata++ = 'u';
70
35.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
35.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
35.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
35.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
35.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.97k
                else {
77
4.97k
                    *odata++ = 'U';
78
4.97k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.97k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.97k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.97k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.97k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.97k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.97k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.97k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.97k
                }
87
60.8k
            }
88
            /* Copy characters as-is */
89
9.90k
            else {
90
9.90k
                *odata++ = ch;
91
9.90k
            }
92
70.7k
        }
93
64.7M
    }
94
6.61M
    *odata = quote;
95
6.61M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
271k
{
12
271k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
271k
    const void *idata = PyUnicode_DATA(unicode);
14
271k
    int ikind = PyUnicode_KIND(unicode);
15
16
271k
    *odata++ = quote;
17
113M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
113M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
113M
        if ((ch == quote) || (ch == '\\')) {
22
66.9k
            *odata++ = '\\';
23
66.9k
            *odata++ = ch;
24
66.9k
            continue;
25
66.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
113M
        if (ch == '\t') {
29
21.5k
            *odata++ = '\\';
30
21.5k
            *odata++ = 't';
31
21.5k
        }
32
113M
        else if (ch == '\n') {
33
244k
            *odata++ = '\\';
34
244k
            *odata++ = 'n';
35
244k
        }
36
112M
        else if (ch == '\r') {
37
4.00k
            *odata++ = '\\';
38
4.00k
            *odata++ = 'r';
39
4.00k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
112M
        else if (ch < ' ' || ch == 0x7F) {
43
79.7M
            *odata++ = '\\';
44
79.7M
            *odata++ = 'x';
45
79.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
79.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
79.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
33.0M
        else if (ch < 0x7F) {
51
23.4M
            *odata++ = ch;
52
23.4M
        }
53
54
        /* Non-ASCII characters */
55
9.61M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
9.61M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
110k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
110k
                if (ch <= 0xff) {
63
38.6k
                    *odata++ = 'x';
64
38.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
38.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
38.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
72.0k
                else if (ch <= 0xffff) {
69
21.2k
                    *odata++ = 'u';
70
21.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
21.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
21.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
21.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
21.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
50.8k
                else {
77
50.8k
                    *odata++ = 'U';
78
50.8k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
50.8k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
50.8k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
50.8k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
50.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
50.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
50.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
50.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
50.8k
                }
87
110k
            }
88
            /* Copy characters as-is */
89
9.50M
            else {
90
9.50M
                *odata++ = ch;
91
9.50M
            }
92
9.61M
        }
93
113M
    }
94
271k
    *odata = quote;
95
271k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
5.36k
{
12
5.36k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.36k
    const void *idata = PyUnicode_DATA(unicode);
14
5.36k
    int ikind = PyUnicode_KIND(unicode);
15
16
5.36k
    *odata++ = quote;
17
14.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
14.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
14.3M
        if ((ch == quote) || (ch == '\\')) {
22
8.76k
            *odata++ = '\\';
23
8.76k
            *odata++ = ch;
24
8.76k
            continue;
25
8.76k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
14.3M
        if (ch == '\t') {
29
1.59k
            *odata++ = '\\';
30
1.59k
            *odata++ = 't';
31
1.59k
        }
32
14.3M
        else if (ch == '\n') {
33
2.69k
            *odata++ = '\\';
34
2.69k
            *odata++ = 'n';
35
2.69k
        }
36
14.3M
        else if (ch == '\r') {
37
3.44k
            *odata++ = '\\';
38
3.44k
            *odata++ = 'r';
39
3.44k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
14.3M
        else if (ch < ' ' || ch == 0x7F) {
43
13.5M
            *odata++ = '\\';
44
13.5M
            *odata++ = 'x';
45
13.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
13.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
13.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
757k
        else if (ch < 0x7F) {
51
519k
            *odata++ = ch;
52
519k
        }
53
54
        /* Non-ASCII characters */
55
238k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
238k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
58.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
58.9k
                if (ch <= 0xff) {
63
1.75k
                    *odata++ = 'x';
64
1.75k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.75k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.75k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
57.1k
                else if (ch <= 0xffff) {
69
29.7k
                    *odata++ = 'u';
70
29.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
29.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
29.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
29.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
29.7k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
27.4k
                else {
77
27.4k
                    *odata++ = 'U';
78
27.4k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
27.4k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
27.4k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
27.4k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
27.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
27.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
27.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
27.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
27.4k
                }
87
58.9k
            }
88
            /* Copy characters as-is */
89
179k
            else {
90
179k
                *odata++ = ch;
91
179k
            }
92
238k
        }
93
14.3M
    }
94
5.36k
    *odata = quote;
95
5.36k
}