Coverage Report

Created: 2026-07-16 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/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
2.37k
{
12
2.37k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.37k
    const void *idata = PyUnicode_DATA(unicode);
14
2.37k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
4.71M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
4.71M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
4.71M
        if ((ch == quote) || (ch == '\\')) {
22
64.9k
            *odata++ = '\\';
23
64.9k
            *odata++ = ch;
24
64.9k
            continue;
25
64.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
4.64M
        if (ch == '\t') {
29
5.49k
            *odata++ = '\\';
30
5.49k
            *odata++ = 't';
31
5.49k
        }
32
4.64M
        else if (ch == '\n') {
33
26.6k
            *odata++ = '\\';
34
26.6k
            *odata++ = 'n';
35
26.6k
        }
36
4.61M
        else if (ch == '\r') {
37
2.68k
            *odata++ = '\\';
38
2.68k
            *odata++ = 'r';
39
2.68k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
4.61M
        else if (ch < ' ' || ch == 0x7F) {
43
1.48M
            *odata++ = '\\';
44
1.48M
            *odata++ = 'x';
45
1.48M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
1.48M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
1.48M
        }
48
49
        /* Copy ASCII characters as-is */
50
3.12M
        else if (ch < 0x7F) {
51
2.34M
            *odata++ = ch;
52
2.34M
        }
53
54
        /* Non-ASCII characters */
55
784k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
784k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
642k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
642k
                if (ch <= 0xff) {
63
631k
                    *odata++ = 'x';
64
631k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
631k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
631k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
11.3k
                else if (ch <= 0xffff) {
69
8.77k
                    *odata++ = 'u';
70
8.77k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
8.77k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
8.77k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
8.77k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
8.77k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.59k
                else {
77
2.59k
                    *odata++ = 'U';
78
2.59k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.59k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.59k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.59k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.59k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.59k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.59k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.59k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.59k
                }
87
642k
            }
88
            /* Copy characters as-is */
89
141k
            else {
90
141k
                *odata++ = ch;
91
141k
            }
92
784k
        }
93
4.64M
    }
94
2.37k
    *odata = quote;
95
2.37k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
1.56k
{
12
1.56k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.56k
    const void *idata = PyUnicode_DATA(unicode);
14
1.56k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
2.65M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
2.65M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
2.65M
        if ((ch == quote) || (ch == '\\')) {
22
10.7k
            *odata++ = '\\';
23
10.7k
            *odata++ = ch;
24
10.7k
            continue;
25
10.7k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
2.63M
        if (ch == '\t') {
29
2.85k
            *odata++ = '\\';
30
2.85k
            *odata++ = 't';
31
2.85k
        }
32
2.63M
        else if (ch == '\n') {
33
22.5k
            *odata++ = '\\';
34
22.5k
            *odata++ = 'n';
35
22.5k
        }
36
2.61M
        else if (ch == '\r') {
37
1.30k
            *odata++ = '\\';
38
1.30k
            *odata++ = 'r';
39
1.30k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
2.61M
        else if (ch < ' ' || ch == 0x7F) {
43
690k
            *odata++ = '\\';
44
690k
            *odata++ = 'x';
45
690k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
690k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
690k
        }
48
49
        /* Copy ASCII characters as-is */
50
1.92M
        else if (ch < 0x7F) {
51
1.15M
            *odata++ = ch;
52
1.15M
        }
53
54
        /* Non-ASCII characters */
55
769k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
769k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
632k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
632k
                if (ch <= 0xff) {
63
627k
                    *odata++ = 'x';
64
627k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
627k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
627k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
4.59k
                else if (ch <= 0xffff) {
69
3.97k
                    *odata++ = 'u';
70
3.97k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.97k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.97k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.97k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.97k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
614
                else {
77
614
                    *odata++ = 'U';
78
614
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
614
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
614
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
614
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
614
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
614
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
614
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
614
                    *odata++ = Py_hexdigits[ch & 0xF];
86
614
                }
87
632k
            }
88
            /* Copy characters as-is */
89
137k
            else {
90
137k
                *odata++ = ch;
91
137k
            }
92
769k
        }
93
2.63M
    }
94
1.56k
    *odata = quote;
95
1.56k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
466
{
12
466
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
466
    const void *idata = PyUnicode_DATA(unicode);
14
466
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
975k
    for (Py_ssize_t i = 0; i < isize; i++) {
18
975k
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
975k
        if ((ch == quote) || (ch == '\\')) {
22
28.5k
            *odata++ = '\\';
23
28.5k
            *odata++ = ch;
24
28.5k
            continue;
25
28.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
946k
        if (ch == '\t') {
29
1.95k
            *odata++ = '\\';
30
1.95k
            *odata++ = 't';
31
1.95k
        }
32
945k
        else if (ch == '\n') {
33
1.44k
            *odata++ = '\\';
34
1.44k
            *odata++ = 'n';
35
1.44k
        }
36
943k
        else if (ch == '\r') {
37
868
            *odata++ = '\\';
38
868
            *odata++ = 'r';
39
868
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
942k
        else if (ch < ' ' || ch == 0x7F) {
43
270k
            *odata++ = '\\';
44
270k
            *odata++ = 'x';
45
270k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
270k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
270k
        }
48
49
        /* Copy ASCII characters as-is */
50
672k
        else if (ch < 0x7F) {
51
665k
            *odata++ = ch;
52
665k
        }
53
54
        /* Non-ASCII characters */
55
6.98k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.98k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
4.14k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
4.14k
                if (ch <= 0xff) {
63
1.53k
                    *odata++ = 'x';
64
1.53k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.53k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.53k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
2.61k
                else if (ch <= 0xffff) {
69
1.55k
                    *odata++ = 'u';
70
1.55k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.55k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.55k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.55k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.55k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.05k
                else {
77
1.05k
                    *odata++ = 'U';
78
1.05k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.05k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.05k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.05k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.05k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.05k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.05k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.05k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.05k
                }
87
4.14k
            }
88
            /* Copy characters as-is */
89
2.84k
            else {
90
2.84k
                *odata++ = ch;
91
2.84k
            }
92
6.98k
        }
93
946k
    }
94
466
    *odata = quote;
95
466
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
345
{
12
345
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
345
    const void *idata = PyUnicode_DATA(unicode);
14
345
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.08M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.08M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.08M
        if ((ch == quote) || (ch == '\\')) {
22
25.5k
            *odata++ = '\\';
23
25.5k
            *odata++ = ch;
24
25.5k
            continue;
25
25.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.06M
        if (ch == '\t') {
29
685
            *odata++ = '\\';
30
685
            *odata++ = 't';
31
685
        }
32
1.06M
        else if (ch == '\n') {
33
2.65k
            *odata++ = '\\';
34
2.65k
            *odata++ = 'n';
35
2.65k
        }
36
1.05M
        else if (ch == '\r') {
37
507
            *odata++ = '\\';
38
507
            *odata++ = 'r';
39
507
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.05M
        else if (ch < ' ' || ch == 0x7F) {
43
526k
            *odata++ = '\\';
44
526k
            *odata++ = 'x';
45
526k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
526k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
526k
        }
48
49
        /* Copy ASCII characters as-is */
50
531k
        else if (ch < 0x7F) {
51
524k
            *odata++ = ch;
52
524k
        }
53
54
        /* Non-ASCII characters */
55
7.94k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.94k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
6.16k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
6.16k
                if (ch <= 0xff) {
63
2.00k
                    *odata++ = 'x';
64
2.00k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.00k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.00k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
4.16k
                else if (ch <= 0xffff) {
69
3.24k
                    *odata++ = 'u';
70
3.24k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.24k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.24k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.24k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.24k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
921
                else {
77
921
                    *odata++ = 'U';
78
921
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
921
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
921
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
921
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
921
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
921
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
921
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
921
                    *odata++ = Py_hexdigits[ch & 0xF];
86
921
                }
87
6.16k
            }
88
            /* Copy characters as-is */
89
1.77k
            else {
90
1.77k
                *odata++ = ch;
91
1.77k
            }
92
7.94k
        }
93
1.06M
    }
94
345
    *odata = quote;
95
345
}