Coverage Report

Created: 2026-01-10 06:41

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.88M
{
12
7.88M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.88M
    const void *idata = PyUnicode_DATA(unicode);
14
7.88M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.88M
    *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
765k
            *odata++ = '\\';
23
765k
            *odata++ = ch;
24
765k
            continue;
25
765k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
210M
        if (ch == '\t') {
29
462k
            *odata++ = '\\';
30
462k
            *odata++ = 't';
31
462k
        }
32
210M
        else if (ch == '\n') {
33
5.56M
            *odata++ = '\\';
34
5.56M
            *odata++ = 'n';
35
5.56M
        }
36
204M
        else if (ch == '\r') {
37
13.5k
            *odata++ = '\\';
38
13.5k
            *odata++ = 'r';
39
13.5k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
204M
        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
55.0M
        else if (ch < 0x7F) {
51
47.4M
            *odata++ = ch;
52
47.4M
        }
53
54
        /* Non-ASCII characters */
55
7.59M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.59M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
342k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
342k
                if (ch <= 0xff) {
63
133k
                    *odata++ = 'x';
64
133k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
133k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
133k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
209k
                else if (ch <= 0xffff) {
69
108k
                    *odata++ = 'u';
70
108k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
108k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
108k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
108k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
108k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
100k
                else {
77
100k
                    *odata++ = 'U';
78
100k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
100k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
100k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
100k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
100k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
100k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
100k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
100k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
100k
                }
87
342k
            }
88
            /* Copy characters as-is */
89
7.25M
            else {
90
7.25M
                *odata++ = ch;
91
7.25M
            }
92
7.59M
        }
93
210M
    }
94
7.88M
    *odata = quote;
95
7.88M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
7.56M
{
12
7.56M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.56M
    const void *idata = PyUnicode_DATA(unicode);
14
7.56M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.56M
    *odata++ = quote;
17
76.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
69.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
69.2M
        if ((ch == quote) || (ch == '\\')) {
22
167k
            *odata++ = '\\';
23
167k
            *odata++ = ch;
24
167k
            continue;
25
167k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
69.0M
        if (ch == '\t') {
29
434k
            *odata++ = '\\';
30
434k
            *odata++ = 't';
31
434k
        }
32
68.6M
        else if (ch == '\n') {
33
5.31M
            *odata++ = '\\';
34
5.31M
            *odata++ = 'n';
35
5.31M
        }
36
63.3M
        else if (ch == '\r') {
37
5.40k
            *odata++ = '\\';
38
5.40k
            *odata++ = 'r';
39
5.40k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
63.3M
        else if (ch < ' ' || ch == 0x7F) {
43
42.0M
            *odata++ = '\\';
44
42.0M
            *odata++ = 'x';
45
42.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
42.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
42.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
21.3M
        else if (ch < 0x7F) {
51
21.1M
            *odata++ = ch;
52
21.1M
        }
53
54
        /* Non-ASCII characters */
55
154k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
154k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
136k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
136k
                if (ch <= 0xff) {
63
90.7k
                    *odata++ = 'x';
64
90.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
90.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
90.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
45.4k
                else if (ch <= 0xffff) {
69
39.2k
                    *odata++ = 'u';
70
39.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
39.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
39.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
39.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
39.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
6.16k
                else {
77
6.16k
                    *odata++ = 'U';
78
6.16k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
6.16k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
6.16k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
6.16k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
6.16k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
6.16k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
6.16k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
6.16k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
6.16k
                }
87
136k
            }
88
            /* Copy characters as-is */
89
17.8k
            else {
90
17.8k
                *odata++ = ch;
91
17.8k
            }
92
154k
        }
93
69.0M
    }
94
7.56M
    *odata = quote;
95
7.56M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
303k
{
12
303k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
303k
    const void *idata = PyUnicode_DATA(unicode);
14
303k
    int ikind = PyUnicode_KIND(unicode);
15
16
303k
    *odata++ = quote;
17
126M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
126M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
126M
        if ((ch == quote) || (ch == '\\')) {
22
586k
            *odata++ = '\\';
23
586k
            *odata++ = ch;
24
586k
            continue;
25
586k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
125M
        if (ch == '\t') {
29
24.7k
            *odata++ = '\\';
30
24.7k
            *odata++ = 't';
31
24.7k
        }
32
125M
        else if (ch == '\n') {
33
248k
            *odata++ = '\\';
34
248k
            *odata++ = 'n';
35
248k
        }
36
125M
        else if (ch == '\r') {
37
4.26k
            *odata++ = '\\';
38
4.26k
            *odata++ = 'r';
39
4.26k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
125M
        else if (ch < ' ' || ch == 0x7F) {
43
92.7M
            *odata++ = '\\';
44
92.7M
            *odata++ = 'x';
45
92.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
92.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
92.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
32.6M
        else if (ch < 0x7F) {
51
25.5M
            *odata++ = ch;
52
25.5M
        }
53
54
        /* Non-ASCII characters */
55
7.12M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.12M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
144k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
144k
                if (ch <= 0xff) {
63
40.1k
                    *odata++ = 'x';
64
40.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
40.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
40.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
104k
                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
67.4k
                else {
77
67.4k
                    *odata++ = 'U';
78
67.4k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
67.4k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
67.4k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
67.4k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
67.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
67.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
67.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
67.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
67.4k
                }
87
144k
            }
88
            /* Copy characters as-is */
89
6.97M
            else {
90
6.97M
                *odata++ = ch;
91
6.97M
            }
92
7.12M
        }
93
125M
    }
94
303k
    *odata = quote;
95
303k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
7.90k
{
12
7.90k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.90k
    const void *idata = PyUnicode_DATA(unicode);
14
7.90k
    int ikind = PyUnicode_KIND(unicode);
15
16
7.90k
    *odata++ = quote;
17
15.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
15.7M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
15.7M
        if ((ch == quote) || (ch == '\\')) {
22
11.7k
            *odata++ = '\\';
23
11.7k
            *odata++ = ch;
24
11.7k
            continue;
25
11.7k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
15.7M
        if (ch == '\t') {
29
3.67k
            *odata++ = '\\';
30
3.67k
            *odata++ = 't';
31
3.67k
        }
32
15.7M
        else if (ch == '\n') {
33
4.53k
            *odata++ = '\\';
34
4.53k
            *odata++ = 'n';
35
4.53k
        }
36
15.7M
        else if (ch == '\r') {
37
3.85k
            *odata++ = '\\';
38
3.85k
            *odata++ = 'r';
39
3.85k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
15.7M
        else if (ch < ' ' || ch == 0x7F) {
43
14.7M
            *odata++ = '\\';
44
14.7M
            *odata++ = 'x';
45
14.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
14.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
14.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.01M
        else if (ch < 0x7F) {
51
700k
            *odata++ = ch;
52
700k
        }
53
54
        /* Non-ASCII characters */
55
318k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
318k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
62.4k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
62.4k
                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.0k
                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.1k
                else {
77
27.1k
                    *odata++ = 'U';
78
27.1k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
27.1k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
27.1k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
27.1k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
27.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
27.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
27.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
27.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
27.1k
                }
87
62.4k
            }
88
            /* Copy characters as-is */
89
255k
            else {
90
255k
                *odata++ = ch;
91
255k
            }
92
318k
        }
93
15.7M
    }
94
7.90k
    *odata = quote;
95
7.90k
}