Coverage Report

Created: 2026-09-06 06:49

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
5.45k
{
12
5.45k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.45k
    const void *idata = PyUnicode_DATA(unicode);
14
5.45k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
5.17M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
5.16M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
5.16M
        if ((ch == quote) || (ch == '\\')) {
22
81.1k
            *odata++ = '\\';
23
81.1k
            *odata++ = ch;
24
81.1k
            continue;
25
81.1k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
5.08M
        if (ch == '\t') {
29
8.35k
            *odata++ = '\\';
30
8.35k
            *odata++ = 't';
31
8.35k
        }
32
5.07M
        else if (ch == '\n') {
33
24.7k
            *odata++ = '\\';
34
24.7k
            *odata++ = 'n';
35
24.7k
        }
36
5.05M
        else if (ch == '\r') {
37
3.60k
            *odata++ = '\\';
38
3.60k
            *odata++ = 'r';
39
3.60k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
5.04M
        else if (ch < ' ' || ch == 0x7F) {
43
1.45M
            *odata++ = '\\';
44
1.45M
            *odata++ = 'x';
45
1.45M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
1.45M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
1.45M
        }
48
49
        /* Copy ASCII characters as-is */
50
3.58M
        else if (ch < 0x7F) {
51
2.75M
            *odata++ = ch;
52
2.75M
        }
53
54
        /* Non-ASCII characters */
55
833k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
833k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
621k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
621k
                if (ch <= 0xff) {
63
610k
                    *odata++ = 'x';
64
610k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
610k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
610k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
10.7k
                else if (ch <= 0xffff) {
69
7.85k
                    *odata++ = 'u';
70
7.85k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
7.85k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
7.85k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
7.85k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
7.85k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.93k
                else {
77
2.93k
                    *odata++ = 'U';
78
2.93k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.93k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.93k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.93k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.93k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.93k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.93k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.93k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.93k
                }
87
621k
            }
88
            /* Copy characters as-is */
89
211k
            else {
90
211k
                *odata++ = ch;
91
211k
            }
92
833k
        }
93
5.08M
    }
94
5.45k
    *odata = quote;
95
5.45k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
3.49k
{
12
3.49k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.49k
    const void *idata = PyUnicode_DATA(unicode);
14
3.49k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
2.64M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
2.63M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
2.63M
        if ((ch == quote) || (ch == '\\')) {
22
21.1k
            *odata++ = '\\';
23
21.1k
            *odata++ = ch;
24
21.1k
            continue;
25
21.1k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
2.61M
        if (ch == '\t') {
29
2.72k
            *odata++ = '\\';
30
2.72k
            *odata++ = 't';
31
2.72k
        }
32
2.61M
        else if (ch == '\n') {
33
7.91k
            *odata++ = '\\';
34
7.91k
            *odata++ = 'n';
35
7.91k
        }
36
2.60M
        else if (ch == '\r') {
37
1.63k
            *odata++ = '\\';
38
1.63k
            *odata++ = 'r';
39
1.63k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
2.60M
        else if (ch < ' ' || ch == 0x7F) {
43
717k
            *odata++ = '\\';
44
717k
            *odata++ = 'x';
45
717k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
717k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
717k
        }
48
49
        /* Copy ASCII characters as-is */
50
1.88M
        else if (ch < 0x7F) {
51
1.15M
            *odata++ = ch;
52
1.15M
        }
53
54
        /* Non-ASCII characters */
55
736k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
736k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
598k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
598k
                if (ch <= 0xff) {
63
593k
                    *odata++ = 'x';
64
593k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
593k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
593k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
5.16k
                else if (ch <= 0xffff) {
69
4.31k
                    *odata++ = 'u';
70
4.31k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
4.31k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
4.31k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
4.31k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
4.31k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
855
                else {
77
855
                    *odata++ = 'U';
78
855
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
855
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
855
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
855
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
855
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
855
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
855
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
855
                    *odata++ = Py_hexdigits[ch & 0xF];
86
855
                }
87
598k
            }
88
            /* Copy characters as-is */
89
138k
            else {
90
138k
                *odata++ = ch;
91
138k
            }
92
736k
        }
93
2.61M
    }
94
3.49k
    *odata = quote;
95
3.49k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
958
{
12
958
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
958
    const void *idata = PyUnicode_DATA(unicode);
14
958
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.21M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.21M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.21M
        if ((ch == quote) || (ch == '\\')) {
22
20.9k
            *odata++ = '\\';
23
20.9k
            *odata++ = ch;
24
20.9k
            continue;
25
20.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.19M
        if (ch == '\t') {
29
1.85k
            *odata++ = '\\';
30
1.85k
            *odata++ = 't';
31
1.85k
        }
32
1.19M
        else if (ch == '\n') {
33
9.43k
            *odata++ = '\\';
34
9.43k
            *odata++ = 'n';
35
9.43k
        }
36
1.18M
        else if (ch == '\r') {
37
739
            *odata++ = '\\';
38
739
            *odata++ = 'r';
39
739
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.18M
        else if (ch < ' ' || ch == 0x7F) {
43
220k
            *odata++ = '\\';
44
220k
            *odata++ = 'x';
45
220k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
220k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
220k
        }
48
49
        /* Copy ASCII characters as-is */
50
962k
        else if (ch < 0x7F) {
51
905k
            *odata++ = ch;
52
905k
        }
53
54
        /* Non-ASCII characters */
55
57.1k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
57.1k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
14.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
14.9k
                if (ch <= 0xff) {
63
11.7k
                    *odata++ = 'x';
64
11.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
11.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
11.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.12k
                else if (ch <= 0xffff) {
69
2.19k
                    *odata++ = 'u';
70
2.19k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
2.19k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
2.19k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
2.19k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
2.19k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
927
                else {
77
927
                    *odata++ = 'U';
78
927
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
927
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
927
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
927
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
927
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
927
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
927
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
927
                    *odata++ = Py_hexdigits[ch & 0xF];
86
927
                }
87
14.9k
            }
88
            /* Copy characters as-is */
89
42.2k
            else {
90
42.2k
                *odata++ = ch;
91
42.2k
            }
92
57.1k
        }
93
1.19M
    }
94
958
    *odata = quote;
95
958
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
1.00k
{
12
1.00k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.00k
    const void *idata = PyUnicode_DATA(unicode);
14
1.00k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.31M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.30M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.30M
        if ((ch == quote) || (ch == '\\')) {
22
39.0k
            *odata++ = '\\';
23
39.0k
            *odata++ = ch;
24
39.0k
            continue;
25
39.0k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.27M
        if (ch == '\t') {
29
3.77k
            *odata++ = '\\';
30
3.77k
            *odata++ = 't';
31
3.77k
        }
32
1.26M
        else if (ch == '\n') {
33
7.35k
            *odata++ = '\\';
34
7.35k
            *odata++ = 'n';
35
7.35k
        }
36
1.25M
        else if (ch == '\r') {
37
1.22k
            *odata++ = '\\';
38
1.22k
            *odata++ = 'r';
39
1.22k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.25M
        else if (ch < ' ' || ch == 0x7F) {
43
519k
            *odata++ = '\\';
44
519k
            *odata++ = 'x';
45
519k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
519k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
519k
        }
48
49
        /* Copy ASCII characters as-is */
50
738k
        else if (ch < 0x7F) {
51
699k
            *odata++ = ch;
52
699k
        }
53
54
        /* Non-ASCII characters */
55
39.3k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
39.3k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
8.27k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
8.27k
                if (ch <= 0xff) {
63
5.76k
                    *odata++ = 'x';
64
5.76k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
5.76k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
5.76k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
2.50k
                else if (ch <= 0xffff) {
69
1.35k
                    *odata++ = 'u';
70
1.35k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.35k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.35k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.35k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.35k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.15k
                else {
77
1.15k
                    *odata++ = 'U';
78
1.15k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.15k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.15k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.15k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.15k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.15k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.15k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.15k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.15k
                }
87
8.27k
            }
88
            /* Copy characters as-is */
89
31.1k
            else {
90
31.1k
                *odata++ = ch;
91
31.1k
            }
92
39.3k
        }
93
1.27M
    }
94
1.00k
    *odata = quote;
95
1.00k
}