Coverage Report

Created: 2025-11-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
709k
{
12
709k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
709k
    const void *idata = PyUnicode_DATA(unicode);
14
709k
    int ikind = PyUnicode_KIND(unicode);
15
16
709k
    *odata++ = quote;
17
109M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
108M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
108M
        if ((ch == quote) || (ch == '\\')) {
22
245k
            *odata++ = '\\';
23
245k
            *odata++ = ch;
24
245k
            continue;
25
245k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
108M
        if (ch == '\t') {
29
22.5k
            *odata++ = '\\';
30
22.5k
            *odata++ = 't';
31
22.5k
        }
32
108M
        else if (ch == '\n') {
33
1.85k
            *odata++ = '\\';
34
1.85k
            *odata++ = 'n';
35
1.85k
        }
36
108M
        else if (ch == '\r') {
37
2.08k
            *odata++ = '\\';
38
2.08k
            *odata++ = 'r';
39
2.08k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
108M
        else if (ch < ' ' || ch == 0x7F) {
43
75.9M
            *odata++ = '\\';
44
75.9M
            *odata++ = 'x';
45
75.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
75.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
75.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
32.2M
        else if (ch < 0x7F) {
51
25.5M
            *odata++ = ch;
52
25.5M
        }
53
54
        /* Non-ASCII characters */
55
6.64M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.64M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
103k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
103k
                if (ch <= 0xff) {
63
29.7k
                    *odata++ = 'x';
64
29.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
29.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
29.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
74.0k
                else if (ch <= 0xffff) {
69
51.2k
                    *odata++ = 'u';
70
51.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
51.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
51.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
51.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
51.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
22.7k
                else {
77
22.7k
                    *odata++ = 'U';
78
22.7k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
22.7k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
22.7k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
22.7k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
22.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
22.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
22.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
22.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
22.7k
                }
87
103k
            }
88
            /* Copy characters as-is */
89
6.53M
            else {
90
6.53M
                *odata++ = ch;
91
6.53M
            }
92
6.64M
        }
93
108M
    }
94
709k
    *odata = quote;
95
709k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
478k
{
12
478k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
478k
    const void *idata = PyUnicode_DATA(unicode);
14
478k
    int ikind = PyUnicode_KIND(unicode);
15
16
478k
    *odata++ = quote;
17
24.6M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
24.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
24.1M
        if ((ch == quote) || (ch == '\\')) {
22
154k
            *odata++ = '\\';
23
154k
            *odata++ = ch;
24
154k
            continue;
25
154k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
23.9M
        if (ch == '\t') {
29
13.4k
            *odata++ = '\\';
30
13.4k
            *odata++ = 't';
31
13.4k
        }
32
23.9M
        else if (ch == '\n') {
33
1.04k
            *odata++ = '\\';
34
1.04k
            *odata++ = 'n';
35
1.04k
        }
36
23.9M
        else if (ch == '\r') {
37
1.16k
            *odata++ = '\\';
38
1.16k
            *odata++ = 'r';
39
1.16k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
23.9M
        else if (ch < ' ' || ch == 0x7F) {
43
16.7M
            *odata++ = '\\';
44
16.7M
            *odata++ = 'x';
45
16.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
16.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
16.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
7.18M
        else if (ch < 0x7F) {
51
7.13M
            *odata++ = ch;
52
7.13M
        }
53
54
        /* Non-ASCII characters */
55
56.2k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
56.2k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
50.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
50.3k
                if (ch <= 0xff) {
63
15.2k
                    *odata++ = 'x';
64
15.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
15.2k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
15.2k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
35.1k
                else if (ch <= 0xffff) {
69
31.9k
                    *odata++ = 'u';
70
31.9k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
31.9k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
31.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
31.9k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
31.9k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
3.13k
                else {
77
3.13k
                    *odata++ = 'U';
78
3.13k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
3.13k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
3.13k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
3.13k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
3.13k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
3.13k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
3.13k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
3.13k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
3.13k
                }
87
50.3k
            }
88
            /* Copy characters as-is */
89
5.82k
            else {
90
5.82k
                *odata++ = ch;
91
5.82k
            }
92
56.2k
        }
93
23.9M
    }
94
478k
    *odata = quote;
95
478k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
227k
{
12
227k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
227k
    const void *idata = PyUnicode_DATA(unicode);
14
227k
    int ikind = PyUnicode_KIND(unicode);
15
16
227k
    *odata++ = quote;
17
71.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
71.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
71.2M
        if ((ch == quote) || (ch == '\\')) {
22
83.9k
            *odata++ = '\\';
23
83.9k
            *odata++ = ch;
24
83.9k
            continue;
25
83.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
71.2M
        if (ch == '\t') {
29
8.51k
            *odata++ = '\\';
30
8.51k
            *odata++ = 't';
31
8.51k
        }
32
71.1M
        else if (ch == '\n') {
33
532
            *odata++ = '\\';
34
532
            *odata++ = 'n';
35
532
        }
36
71.1M
        else if (ch == '\r') {
37
489
            *odata++ = '\\';
38
489
            *odata++ = 'r';
39
489
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
71.1M
        else if (ch < ' ' || ch == 0x7F) {
43
46.7M
            *odata++ = '\\';
44
46.7M
            *odata++ = 'x';
45
46.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
46.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
46.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
24.4M
        else if (ch < 0x7F) {
51
18.0M
            *odata++ = ch;
52
18.0M
        }
53
54
        /* Non-ASCII characters */
55
6.42M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.42M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
48.1k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
48.1k
                if (ch <= 0xff) {
63
13.1k
                    *odata++ = 'x';
64
13.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
13.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
13.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
35.0k
                else if (ch <= 0xffff) {
69
15.9k
                    *odata++ = 'u';
70
15.9k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
15.9k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
15.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
15.9k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
15.9k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
19.0k
                else {
77
19.0k
                    *odata++ = 'U';
78
19.0k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
19.0k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
19.0k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
19.0k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
19.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
19.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
19.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
19.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
19.0k
                }
87
48.1k
            }
88
            /* Copy characters as-is */
89
6.37M
            else {
90
6.37M
                *odata++ = ch;
91
6.37M
            }
92
6.42M
        }
93
71.2M
    }
94
227k
    *odata = quote;
95
227k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
3.96k
{
12
3.96k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.96k
    const void *idata = PyUnicode_DATA(unicode);
14
3.96k
    int ikind = PyUnicode_KIND(unicode);
15
16
3.96k
    *odata++ = quote;
17
12.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
12.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
12.9M
        if ((ch == quote) || (ch == '\\')) {
22
7.27k
            *odata++ = '\\';
23
7.27k
            *odata++ = ch;
24
7.27k
            continue;
25
7.27k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
12.9M
        if (ch == '\t') {
29
649
            *odata++ = '\\';
30
649
            *odata++ = 't';
31
649
        }
32
12.9M
        else if (ch == '\n') {
33
279
            *odata++ = '\\';
34
279
            *odata++ = 'n';
35
279
        }
36
12.9M
        else if (ch == '\r') {
37
430
            *odata++ = '\\';
38
430
            *odata++ = 'r';
39
430
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
12.9M
        else if (ch < ' ' || ch == 0x7F) {
43
12.4M
            *odata++ = '\\';
44
12.4M
            *odata++ = 'x';
45
12.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
544k
        else if (ch < 0x7F) {
51
382k
            *odata++ = ch;
52
382k
        }
53
54
        /* Non-ASCII characters */
55
161k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
161k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
5.24k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
5.24k
                if (ch <= 0xff) {
63
1.34k
                    *odata++ = 'x';
64
1.34k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.34k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.34k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.89k
                else if (ch <= 0xffff) {
69
3.36k
                    *odata++ = 'u';
70
3.36k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.36k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.36k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.36k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.36k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
535
                else {
77
535
                    *odata++ = 'U';
78
535
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
535
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
535
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
535
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
535
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
535
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
535
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
535
                    *odata++ = Py_hexdigits[ch & 0xF];
86
535
                }
87
5.24k
            }
88
            /* Copy characters as-is */
89
156k
            else {
90
156k
                *odata++ = ch;
91
156k
            }
92
161k
        }
93
12.9M
    }
94
3.96k
    *odata = quote;
95
3.96k
}