Coverage Report

Created: 2026-06-07 06:26

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.42k
{
12
2.42k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
2.42k
    const void *idata = PyUnicode_DATA(unicode);
14
2.42k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
3.80M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
3.80M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
3.80M
        if ((ch == quote) || (ch == '\\')) {
22
63.3k
            *odata++ = '\\';
23
63.3k
            *odata++ = ch;
24
63.3k
            continue;
25
63.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
3.74M
        if (ch == '\t') {
29
4.11k
            *odata++ = '\\';
30
4.11k
            *odata++ = 't';
31
4.11k
        }
32
3.73M
        else if (ch == '\n') {
33
7.61k
            *odata++ = '\\';
34
7.61k
            *odata++ = 'n';
35
7.61k
        }
36
3.73M
        else if (ch == '\r') {
37
2.04k
            *odata++ = '\\';
38
2.04k
            *odata++ = 'r';
39
2.04k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
3.72M
        else if (ch < ' ' || ch == 0x7F) {
43
1.39M
            *odata++ = '\\';
44
1.39M
            *odata++ = 'x';
45
1.39M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
1.39M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
1.39M
        }
48
49
        /* Copy ASCII characters as-is */
50
2.33M
        else if (ch < 0x7F) {
51
2.29M
            *odata++ = ch;
52
2.29M
        }
53
54
        /* Non-ASCII characters */
55
45.5k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
45.5k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
20.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
20.9k
                if (ch <= 0xff) {
63
9.15k
                    *odata++ = 'x';
64
9.15k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
9.15k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
9.15k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
11.7k
                else if (ch <= 0xffff) {
69
9.43k
                    *odata++ = 'u';
70
9.43k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
9.43k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
9.43k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
9.43k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
9.43k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.31k
                else {
77
2.31k
                    *odata++ = 'U';
78
2.31k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.31k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.31k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.31k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.31k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.31k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.31k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.31k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.31k
                }
87
20.9k
            }
88
            /* Copy characters as-is */
89
24.6k
            else {
90
24.6k
                *odata++ = ch;
91
24.6k
            }
92
45.5k
        }
93
3.74M
    }
94
2.42k
    *odata = quote;
95
2.42k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
1.48k
{
12
1.48k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.48k
    const void *idata = PyUnicode_DATA(unicode);
14
1.48k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.59M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.59M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.59M
        if ((ch == quote) || (ch == '\\')) {
22
6.56k
            *odata++ = '\\';
23
6.56k
            *odata++ = ch;
24
6.56k
            continue;
25
6.56k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.58M
        if (ch == '\t') {
29
2.10k
            *odata++ = '\\';
30
2.10k
            *odata++ = 't';
31
2.10k
        }
32
1.58M
        else if (ch == '\n') {
33
1.99k
            *odata++ = '\\';
34
1.99k
            *odata++ = 'n';
35
1.99k
        }
36
1.58M
        else if (ch == '\r') {
37
705
            *odata++ = '\\';
38
705
            *odata++ = 'r';
39
705
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.57M
        else if (ch < ' ' || ch == 0x7F) {
43
448k
            *odata++ = '\\';
44
448k
            *odata++ = 'x';
45
448k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
448k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
448k
        }
48
49
        /* Copy ASCII characters as-is */
50
1.13M
        else if (ch < 0x7F) {
51
1.11M
            *odata++ = ch;
52
1.11M
        }
53
54
        /* Non-ASCII characters */
55
15.8k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
15.8k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
9.67k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
9.67k
                if (ch <= 0xff) {
63
3.68k
                    *odata++ = 'x';
64
3.68k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.68k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.68k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
5.98k
                else if (ch <= 0xffff) {
69
5.44k
                    *odata++ = 'u';
70
5.44k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
5.44k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
5.44k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
5.44k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
5.44k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
538
                else {
77
538
                    *odata++ = 'U';
78
538
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
538
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
538
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
538
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
538
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
538
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
538
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
538
                    *odata++ = Py_hexdigits[ch & 0xF];
86
538
                }
87
9.67k
            }
88
            /* Copy characters as-is */
89
6.14k
            else {
90
6.14k
                *odata++ = ch;
91
6.14k
            }
92
15.8k
        }
93
1.58M
    }
94
1.48k
    *odata = quote;
95
1.48k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
562
{
12
562
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
562
    const void *idata = PyUnicode_DATA(unicode);
14
562
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.15M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.15M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.15M
        if ((ch == quote) || (ch == '\\')) {
22
54.0k
            *odata++ = '\\';
23
54.0k
            *odata++ = ch;
24
54.0k
            continue;
25
54.0k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.10M
        if (ch == '\t') {
29
1.45k
            *odata++ = '\\';
30
1.45k
            *odata++ = 't';
31
1.45k
        }
32
1.10M
        else if (ch == '\n') {
33
1.95k
            *odata++ = '\\';
34
1.95k
            *odata++ = 'n';
35
1.95k
        }
36
1.10M
        else if (ch == '\r') {
37
997
            *odata++ = '\\';
38
997
            *odata++ = 'r';
39
997
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.09M
        else if (ch < ' ' || ch == 0x7F) {
43
323k
            *odata++ = '\\';
44
323k
            *odata++ = 'x';
45
323k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
323k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
323k
        }
48
49
        /* Copy ASCII characters as-is */
50
775k
        else if (ch < 0x7F) {
51
752k
            *odata++ = ch;
52
752k
        }
53
54
        /* Non-ASCII characters */
55
22.8k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
22.8k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
6.78k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
6.78k
                if (ch <= 0xff) {
63
3.43k
                    *odata++ = 'x';
64
3.43k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
3.43k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
3.43k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.35k
                else if (ch <= 0xffff) {
69
2.34k
                    *odata++ = 'u';
70
2.34k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
2.34k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
2.34k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
2.34k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
2.34k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.00k
                else {
77
1.00k
                    *odata++ = 'U';
78
1.00k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.00k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.00k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.00k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.00k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.00k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.00k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.00k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.00k
                }
87
6.78k
            }
88
            /* Copy characters as-is */
89
16.0k
            else {
90
16.0k
                *odata++ = ch;
91
16.0k
            }
92
22.8k
        }
93
1.10M
    }
94
562
    *odata = quote;
95
562
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
370
{
12
370
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
370
    const void *idata = PyUnicode_DATA(unicode);
14
370
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.05M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.05M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.05M
        if ((ch == quote) || (ch == '\\')) {
22
2.81k
            *odata++ = '\\';
23
2.81k
            *odata++ = ch;
24
2.81k
            continue;
25
2.81k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.05M
        if (ch == '\t') {
29
559
            *odata++ = '\\';
30
559
            *odata++ = 't';
31
559
        }
32
1.05M
        else if (ch == '\n') {
33
3.66k
            *odata++ = '\\';
34
3.66k
            *odata++ = 'n';
35
3.66k
        }
36
1.05M
        else if (ch == '\r') {
37
345
            *odata++ = '\\';
38
345
            *odata++ = 'r';
39
345
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.05M
        else if (ch < ' ' || ch == 0x7F) {
43
619k
            *odata++ = '\\';
44
619k
            *odata++ = 'x';
45
619k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
619k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
619k
        }
48
49
        /* Copy ASCII characters as-is */
50
430k
        else if (ch < 0x7F) {
51
423k
            *odata++ = ch;
52
423k
        }
53
54
        /* Non-ASCII characters */
55
6.95k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.95k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
4.45k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
4.45k
                if (ch <= 0xff) {
63
2.04k
                    *odata++ = 'x';
64
2.04k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
2.04k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
2.04k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
2.41k
                else if (ch <= 0xffff) {
69
1.64k
                    *odata++ = 'u';
70
1.64k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.64k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.64k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.64k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.64k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
771
                else {
77
771
                    *odata++ = 'U';
78
771
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
771
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
771
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
771
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
771
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
771
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
771
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
771
                    *odata++ = Py_hexdigits[ch & 0xF];
86
771
                }
87
4.45k
            }
88
            /* Copy characters as-is */
89
2.50k
            else {
90
2.50k
                *odata++ = ch;
91
2.50k
            }
92
6.95k
        }
93
1.05M
    }
94
370
    *odata = quote;
95
370
}