X Tutup
Skip to content

Commit 1ab8330

Browse files
committed
Add functions PyUnicode_Append() and PyUnicode_AppendAndDel() that mirror
PyString_Concat() and PyString_ConcatAndDel() (the name PyUnicode_Concat() was already taken). Change PyObject_Repr() to always return a unicode object. Update all repr implementations to return unicode objects. Add a function PyObject_ReprStr8() that calls PyObject_Repr() and converts the result to an 8bit string. Use PyObject_ReprStr8() where using PyObject_Repr() can't be done straightforward.
1 parent 14176a5 commit 1ab8330

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+385
-255
lines changed

Include/object.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
372372
PyAPI_FUNC(void) _Py_BreakPoint(void);
373373
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
374374
PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
375+
PyAPI_FUNC(PyObject *) PyObject_ReprStr8(PyObject *);
375376
PyAPI_FUNC(PyObject *) _PyObject_Str(PyObject *);
376377
PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *);
377378
PyAPI_FUNC(PyObject *) PyObject_Unicode(PyObject *);
@@ -418,7 +419,7 @@ PyAPI_FUNC(long) _Py_HashDouble(double);
418419
PyAPI_FUNC(long) _Py_HashPointer(void*);
419420

420421
/* Helper for passing objects to printf and the like */
421-
#define PyObject_REPR(obj) PyString_AS_STRING(PyObject_Repr(obj))
422+
#define PyObject_REPR(obj) PyString_AS_STRING(PyObject_ReprStr8(obj))
422423

423424
/* Flag bits for printing: */
424425
#define Py_PRINT_RAW 1 /* No string quotes etc. */

Include/unicodeobject.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
145145
# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar
146146
# define PyUnicode_Compare PyUnicodeUCS2_Compare
147147
# define PyUnicode_Concat PyUnicodeUCS2_Concat
148+
# define PyUnicode_Append PyUnicodeUCS2_Append
149+
# define PyUnicode_AppendAndDel PyUnicodeUCS2_AppendAndDel
148150
# define PyUnicode_Contains PyUnicodeUCS2_Contains
149151
# define PyUnicode_Count PyUnicodeUCS2_Count
150152
# define PyUnicode_Decode PyUnicodeUCS2_Decode
@@ -227,6 +229,8 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
227229
# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar
228230
# define PyUnicode_Compare PyUnicodeUCS4_Compare
229231
# define PyUnicode_Concat PyUnicodeUCS4_Concat
232+
# define PyUnicode_Append PyUnicodeUCS4_Append
233+
# define PyUnicode_AppendAndDel PyUnicodeUCS4_AppendAndDel
230234
# define PyUnicode_Contains PyUnicodeUCS4_Contains
231235
# define PyUnicode_Count PyUnicodeUCS4_Count
232236
# define PyUnicode_Decode PyUnicodeUCS4_Decode
@@ -1020,6 +1024,22 @@ PyAPI_FUNC(PyObject*) PyUnicode_Concat(
10201024
PyObject *right /* Right string */
10211025
);
10221026

1027+
/* Concat two strings and put the result in *pleft
1028+
(sets *pleft to NULL on error) */
1029+
1030+
PyAPI_FUNC(void) PyUnicode_Append(
1031+
PyObject **pleft, /* Pointer to left string */
1032+
PyObject *right /* Right string */
1033+
);
1034+
1035+
/* Concat two strings, put the result in *pleft and drop the right object
1036+
(sets *pleft to NULL on error) */
1037+
1038+
PyAPI_FUNC(void) PyUnicode_AppendAndDel(
1039+
PyObject **pleft, /* Pointer to left string */
1040+
PyObject *right /* Right string */
1041+
);
1042+
10231043
/* Split a string giving a list of Unicode strings.
10241044
10251045
If sep is NULL, splitting will be done at all whitespace

Mac/Modules/cf/_CFmodule.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ static PyObject * CFTypeRefObj_repr(CFTypeRefObject *self)
392392
{
393393
char buf[100];
394394
sprintf(buf, "<CFTypeRef type-%d object at 0x%8.8x for 0x%8.8x>", (int)CFGetTypeID(self->ob_itself), (unsigned)self, (unsigned)self->ob_itself);
395-
return PyString_FromString(buf);
395+
return PyUnicode_FromString(buf);
396396
}
397397

398398
static int CFTypeRefObj_hash(CFTypeRefObject *self)
@@ -596,7 +596,7 @@ static PyObject * CFArrayRefObj_repr(CFArrayRefObject *self)
596596
{
597597
char buf[100];
598598
sprintf(buf, "<CFArrayRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
599-
return PyString_FromString(buf);
599+
return PyUnicode_FromString(buf);
600600
}
601601

602602
static int CFArrayRefObj_hash(CFArrayRefObject *self)
@@ -836,7 +836,7 @@ static PyObject * CFMutableArrayRefObj_repr(CFMutableArrayRefObject *self)
836836
{
837837
char buf[100];
838838
sprintf(buf, "<CFMutableArrayRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
839-
return PyString_FromString(buf);
839+
return PyUnicode_FromString(buf);
840840
}
841841

842842
static int CFMutableArrayRefObj_hash(CFMutableArrayRefObject *self)
@@ -1029,7 +1029,7 @@ static PyObject * CFDictionaryRefObj_repr(CFDictionaryRefObject *self)
10291029
{
10301030
char buf[100];
10311031
sprintf(buf, "<CFDictionaryRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
1032-
return PyString_FromString(buf);
1032+
return PyUnicode_FromString(buf);
10331033
}
10341034

10351035
static int CFDictionaryRefObj_hash(CFDictionaryRefObject *self)
@@ -1206,7 +1206,7 @@ static PyObject * CFMutableDictionaryRefObj_repr(CFMutableDictionaryRefObject *s
12061206
{
12071207
char buf[100];
12081208
sprintf(buf, "<CFMutableDictionaryRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
1209-
return PyString_FromString(buf);
1209+
return PyUnicode_FromString(buf);
12101210
}
12111211

12121212
static int CFMutableDictionaryRefObj_hash(CFMutableDictionaryRefObject *self)
@@ -1437,7 +1437,7 @@ static PyObject * CFDataRefObj_repr(CFDataRefObject *self)
14371437
{
14381438
char buf[100];
14391439
sprintf(buf, "<CFDataRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
1440-
return PyString_FromString(buf);
1440+
return PyUnicode_FromString(buf);
14411441
}
14421442

14431443
static int CFDataRefObj_hash(CFDataRefObject *self)
@@ -1702,7 +1702,7 @@ static PyObject * CFMutableDataRefObj_repr(CFMutableDataRefObject *self)
17021702
{
17031703
char buf[100];
17041704
sprintf(buf, "<CFMutableDataRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
1705-
return PyString_FromString(buf);
1705+
return PyUnicode_FromString(buf);
17061706
}
17071707

17081708
static int CFMutableDataRefObj_hash(CFMutableDataRefObject *self)
@@ -2444,7 +2444,7 @@ static PyObject * CFStringRefObj_repr(CFStringRefObject *self)
24442444
{
24452445
char buf[100];
24462446
sprintf(buf, "<CFStringRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
2447-
return PyString_FromString(buf);
2447+
return PyUnicode_FromString(buf);
24482448
}
24492449

24502450
static int CFStringRefObj_hash(CFStringRefObject *self)
@@ -2832,7 +2832,7 @@ static PyObject * CFMutableStringRefObj_repr(CFMutableStringRefObject *self)
28322832
{
28332833
char buf[100];
28342834
sprintf(buf, "<CFMutableStringRef object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
2835-
return PyString_FromString(buf);
2835+
return PyUnicode_FromString(buf);
28362836
}
28372837

28382838
static int CFMutableStringRefObj_hash(CFMutableStringRefObject *self)
@@ -3484,7 +3484,7 @@ static PyObject * CFURLRefObj_repr(CFURLRefObject *self)
34843484
{
34853485
char buf[100];
34863486
sprintf(buf, "<CFURL object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
3487-
return PyString_FromString(buf);
3487+
return PyUnicode_FromString(buf);
34883488
}
34893489

34903490
static int CFURLRefObj_hash(CFURLRefObject *self)

Mac/Modules/file/_Filemodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ static PyObject * FSSpec_repr(FSSpecObject *self)
13931393
self->ob_itself.vRefNum,
13941394
self->ob_itself.parID,
13951395
self->ob_itself.name[0], self->ob_itself.name+1);
1396-
return PyString_FromString(buf);
1396+
return PyUnicode_FromString(buf);
13971397
}
13981398

13991399
#define FSSpec_hash NULL

Mac/Modules/win/_Winmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2580,7 +2580,7 @@ static PyObject * WinObj_repr(WindowObject *self)
25802580
{
25812581
char buf[100];
25822582
sprintf(buf, "<Window object at 0x%8.8x for 0x%8.8x>", (unsigned)self, (unsigned)self->ob_itself);
2583-
return PyString_FromString(buf);
2583+
return PyUnicode_FromString(buf);
25842584
}
25852585

25862586
static int WinObj_hash(WindowObject *self)

Modules/_codecsmodule.c

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,27 +161,63 @@ static PyObject *
161161
escape_encode(PyObject *self,
162162
PyObject *args)
163163
{
164+
static const char *hexdigits = "0123456789abcdef";
164165
PyObject *str;
166+
Py_ssize_t size;
167+
Py_ssize_t newsize;
165168
const char *errors = NULL;
166-
char *buf;
167-
Py_ssize_t len;
169+
PyObject *v;
168170

169171
if (!PyArg_ParseTuple(args, "O!|z:escape_encode",
170172
&PyString_Type, &str, &errors))
171173
return NULL;
172174

173-
str = PyString_Repr(str, 0);
174-
if (!str)
175-
return NULL;
175+
size = PyUnicode_GET_SIZE(str);
176+
newsize = 4*size;
177+
if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) {
178+
PyErr_SetString(PyExc_OverflowError,
179+
"string is too large to encode");
180+
return NULL;
181+
}
182+
v = PyBytes_FromStringAndSize(NULL, newsize);
176183

177-
/* The string will be quoted. Unquote, similar to unicode-escape. */
178-
buf = PyString_AS_STRING (str);
179-
len = PyString_GET_SIZE (str);
180-
memmove(buf, buf+1, len-2);
181-
if (_PyString_Resize(&str, len-2) < 0)
184+
if (v == NULL) {
182185
return NULL;
186+
}
187+
else {
188+
register Py_ssize_t i;
189+
register char c;
190+
register char *p = PyBytes_AS_STRING(v);
191+
192+
for (i = 0; i < size; i++) {
193+
/* There's at least enough room for a hex escape */
194+
assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4);
195+
c = PyString_AS_STRING(str)[i];
196+
if (c == '\'' || c == '\\')
197+
*p++ = '\\', *p++ = c;
198+
else if (c == '\t')
199+
*p++ = '\\', *p++ = 't';
200+
else if (c == '\n')
201+
*p++ = '\\', *p++ = 'n';
202+
else if (c == '\r')
203+
*p++ = '\\', *p++ = 'r';
204+
else if (c < ' ' || c >= 0x7f) {
205+
*p++ = '\\';
206+
*p++ = 'x';
207+
*p++ = hexdigits[(c & 0xf0) >> 4];
208+
*p++ = hexdigits[c & 0xf];
209+
}
210+
else
211+
*p++ = c;
212+
}
213+
*p = '\0';
214+
if (PyBytes_Resize(v, (p - PyBytes_AS_STRING(v)))) {
215+
Py_DECREF(v);
216+
return NULL;
217+
}
218+
}
183219

184-
return codec_tuple(str, PyString_Size(str));
220+
return codec_tuple(v, PyBytes_Size(v));
185221
}
186222

187223
/* --- Decoder ------------------------------------------------------------ */

Modules/_collectionsmodule.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -611,14 +611,14 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
611611
static PyObject *
612612
deque_repr(PyObject *deque)
613613
{
614-
PyObject *aslist, *result, *fmt;
614+
PyObject *aslist, *result;
615615
int i;
616616

617617
i = Py_ReprEnter(deque);
618618
if (i != 0) {
619619
if (i < 0)
620620
return NULL;
621-
return PyString_FromString("[...]");
621+
return PyUnicode_FromString("[...]");
622622
}
623623

624624
aslist = PySequence_List(deque);
@@ -627,14 +627,14 @@ deque_repr(PyObject *deque)
627627
return NULL;
628628
}
629629

630-
fmt = PyString_FromString("deque(%r)");
631-
if (fmt == NULL) {
630+
result = PyUnicode_FromString("deque(");
631+
if (result == NULL) {
632632
Py_DECREF(aslist);
633633
Py_ReprLeave(deque);
634634
return NULL;
635635
}
636-
result = PyString_Format(fmt, aslist);
637-
Py_DECREF(fmt);
636+
PyUnicode_AppendAndDel(&result, PyObject_Repr(aslist));
637+
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(")"));
638638
Py_DECREF(aslist);
639639
Py_ReprLeave(deque);
640640
return result;
@@ -1215,18 +1215,18 @@ defdict_repr(defdictobject *dd)
12151215
if (baserepr == NULL)
12161216
return NULL;
12171217
if (dd->default_factory == NULL)
1218-
defrepr = PyString_FromString("None");
1218+
defrepr = PyUnicode_FromString("None");
12191219
else
12201220
defrepr = PyObject_Repr(dd->default_factory);
12211221
if (defrepr == NULL) {
12221222
Py_DECREF(baserepr);
12231223
return NULL;
12241224
}
1225-
result = PyString_FromFormat("defaultdict(%s, %s)",
1226-
PyString_AS_STRING(defrepr),
1227-
PyString_AS_STRING(baserepr));
1228-
Py_DECREF(defrepr);
1229-
Py_DECREF(baserepr);
1225+
result = PyUnicode_FromString("defaultdict(");
1226+
PyUnicode_AppendAndDel(&result, defrepr);
1227+
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(", "));
1228+
PyUnicode_AppendAndDel(&result, baserepr);
1229+
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(")"));
12301230
return result;
12311231
}
12321232

Modules/_ctypes/_ctypes.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,12 +3446,12 @@ CFuncPtr_repr(CFuncPtrObject *self)
34463446
{
34473447
#ifdef MS_WIN32
34483448
if (self->index)
3449-
return PyString_FromFormat("<COM method offset %d: %s at %p>",
3449+
return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
34503450
self->index - 0x1000,
34513451
self->ob_type->tp_name,
34523452
self);
34533453
#endif
3454-
return PyString_FromFormat("<%s object at %p>",
3454+
return PyUnicode_FromFormat("<%s object at %p>",
34553455
self->ob_type->tp_name,
34563456
self);
34573457
}
@@ -4081,12 +4081,12 @@ Simple_repr(CDataObject *self)
40814081
static PyObject *format;
40824082

40834083
if (self->ob_type->tp_base != &Simple_Type) {
4084-
return PyString_FromFormat("<%s object at %p>",
4084+
return PyUnicode_FromFormat("<%s object at %p>",
40854085
self->ob_type->tp_name, self);
40864086
}
40874087

40884088
if (format == NULL) {
4089-
format = PyString_FromString("%s(%r)");
4089+
format = PyUnicode_FromString("%s(%r)");
40904090
if (format == NULL)
40914091
return NULL;
40924092
}
@@ -4095,7 +4095,7 @@ Simple_repr(CDataObject *self)
40954095
if (val == NULL)
40964096
return NULL;
40974097

4098-
name = PyString_FromString(self->ob_type->tp_name);
4098+
name = PyUnicode_FromString(self->ob_type->tp_name);
40994099
if (name == NULL) {
41004100
Py_DECREF(val);
41014101
return NULL;
@@ -4107,7 +4107,7 @@ Simple_repr(CDataObject *self)
41074107
if (args == NULL)
41084108
return NULL;
41094109

4110-
result = PyString_Format(format, args);
4110+
result = PyUnicode_Format(format, args);
41114111
Py_DECREF(args);
41124112
return result;
41134113
}

Modules/_ctypes/callproc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ PyCArg_repr(PyCArgObject *self)
370370
self->tag, (long)self);
371371
break;
372372
}
373-
return PyString_FromString(buffer);
373+
return PyUnicode_FromString(buffer);
374374
}
375375

376376
static PyMemberDef PyCArgType_members[] = {

Modules/_ctypes/cfield.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,15 @@ CField_repr(CFieldObject *self)
275275
name = ((PyTypeObject *)self->proto)->tp_name;
276276

277277
if (bits)
278-
result = PyString_FromFormat(
278+
result = PyUnicode_FromFormat(
279279
#if (PY_VERSION_HEX < 0x02050000)
280280
"<Field type=%s, ofs=%d:%d, bits=%d>",
281281
#else
282282
"<Field type=%s, ofs=%zd:%d, bits=%d>",
283283
#endif
284284
name, self->offset, size, bits);
285285
else
286-
result = PyString_FromFormat(
286+
result = PyUnicode_FromFormat(
287287
#if (PY_VERSION_HEX < 0x02050000)
288288
"<Field type=%s, ofs=%d, size=%d>",
289289
#else

0 commit comments

Comments
 (0)
X Tutup