Skip to content

Commit 75a902d

Browse files
committed
Patch 1280, by Alexandre Vassalotti.
Make PyString's indexing and iteration return integers. (I changed a few of Alexandre's decisions -- GvR.)
1 parent 21431e8 commit 75a902d

File tree

9 files changed

+43
-51
lines changed

9 files changed

+43
-51
lines changed

Lib/dis.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ def disassemble(co, lasti=-1):
117117
extended_arg = 0
118118
free = None
119119
while i < n:
120-
c = code[i]
121-
op = ord(c)
120+
op = code[i]
122121
if i in linestarts:
123122
if i > 0:
124123
print()
@@ -134,7 +133,7 @@ def disassemble(co, lasti=-1):
134133
print(opname[op].ljust(20), end=' ')
135134
i = i+1
136135
if op >= HAVE_ARGUMENT:
137-
oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
136+
oparg = code[i] + code[i+1]*256 + extended_arg
138137
extended_arg = 0
139138
i = i+2
140139
if op == EXTENDED_ARG:
@@ -162,8 +161,7 @@ def disassemble_string(code, lasti=-1, varnames=None, names=None,
162161
n = len(code)
163162
i = 0
164163
while i < n:
165-
c = code[i]
166-
op = ord(c)
164+
op = code[i]
167165
if i == lasti: print('-->', end=' ')
168166
else: print(' ', end=' ')
169167
if i in labels: print('>>', end=' ')
@@ -172,7 +170,7 @@ def disassemble_string(code, lasti=-1, varnames=None, names=None,
172170
print(opname[op].ljust(15), end=' ')
173171
i = i+1
174172
if op >= HAVE_ARGUMENT:
175-
oparg = ord(code[i]) + ord(code[i+1])*256
173+
oparg = code[i] + code[i+1]*256
176174
i = i+2
177175
print(repr(oparg).rjust(5), end=' ')
178176
if op in hasconst:
@@ -208,11 +206,10 @@ def findlabels(code):
208206
n = len(code)
209207
i = 0
210208
while i < n:
211-
c = code[i]
212-
op = ord(c)
209+
op = code[i]
213210
i = i+1
214211
if op >= HAVE_ARGUMENT:
215-
oparg = ord(code[i]) + ord(code[i+1])*256
212+
oparg = code[i] + code[i+1]*256
216213
i = i+2
217214
label = -1
218215
if op in hasjrel:
@@ -230,8 +227,8 @@ def findlinestarts(code):
230227
Generate pairs (offset, lineno) as described in Python/compile.c.
231228
232229
"""
233-
byte_increments = [ord(c) for c in code.co_lnotab[0::2]]
234-
line_increments = [ord(c) for c in code.co_lnotab[1::2]]
230+
byte_increments = list(code.co_lnotab[0::2])
231+
line_increments = list(code.co_lnotab[1::2])
235232

236233
lastlineno = None
237234
lineno = code.co_firstlineno

Lib/encodings/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ def normalize_encoding(encoding):
5252
non-ASCII characters, these must be Latin-1 compatible.
5353
5454
"""
55+
if isinstance(encoding, str8):
56+
encoding = str(encoding, "ascii")
5557
chars = []
5658
punct = False
5759
for c in encoding:

Lib/modulefinder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ def scan_opcodes_25(self, co,
367367
consts = co.co_consts
368368
LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME
369369
while code:
370-
c = code[0]
370+
c = chr(code[0])
371371
if c in STORE_OPS:
372372
oparg, = unpack('<H', code[1:3])
373373
yield "store", (names[oparg],)

Lib/sre_parse.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,18 @@ def __next(self):
189189
if self.index >= len(self.string):
190190
self.next = None
191191
return
192-
char = self.string[self.index]
193-
if char[0] == "\\":
192+
char = self.string[self.index:self.index+1]
193+
# Special case for the str8, since indexing returns a integer
194+
# XXX This is only needed for test_bug_926075 in test_re.py
195+
if isinstance(self.string, str8):
196+
char = chr(char)
197+
if char == "\\":
194198
try:
195199
c = self.string[self.index + 1]
196200
except IndexError:
197201
raise error("bogus escape (end of line)")
202+
if isinstance(self.string, str8):
203+
char = chr(c)
198204
char = char + c
199205
self.index = self.index + len(char)
200206
self.next = char

Lib/test/string_tests.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,10 @@ def test_hash(self):
558558
a = self.type2test('DNSSEC')
559559
b = self.type2test('')
560560
for c in a:
561+
# Special case for the str8, since indexing returns a integer
562+
# XXX Maybe it would be a good idea to seperate str8's tests...
563+
if self.type2test == str8:
564+
c = chr(c)
561565
b += c
562566
hash(b)
563567
self.assertEqual(hash(a), hash(b))

Lib/test/test_bytes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def test_from_buffer(self):
348348
sample = str8("Hello world\n\x80\x81\xfe\xff")
349349
buf = memoryview(sample)
350350
b = bytes(buf)
351-
self.assertEqual(b, bytes(map(ord, sample)))
351+
self.assertEqual(b, bytes(sample))
352352

353353
def test_to_str(self):
354354
sample = "Hello world\n\x80\x81\xfe\xff"

Lib/test/test_set.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def test_union(self):
7272
self.assertEqual(type(u), self.thetype)
7373
self.assertRaises(PassThru, self.s.union, check_pass_thru())
7474
self.assertRaises(TypeError, self.s.union, [[]])
75-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
75+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
7676
self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
7777
self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
7878
self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
@@ -96,7 +96,7 @@ def test_intersection(self):
9696
self.assertEqual(self.s, self.thetype(self.word))
9797
self.assertEqual(type(i), self.thetype)
9898
self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
99-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
99+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
100100
self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
101101
self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
102102
self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
@@ -121,7 +121,7 @@ def test_difference(self):
121121
self.assertEqual(type(i), self.thetype)
122122
self.assertRaises(PassThru, self.s.difference, check_pass_thru())
123123
self.assertRaises(TypeError, self.s.difference, [[]])
124-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
124+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
125125
self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
126126
self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
127127
self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
@@ -146,7 +146,7 @@ def test_symmetric_difference(self):
146146
self.assertEqual(type(i), self.thetype)
147147
self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
148148
self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
149-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
149+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
150150
self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
151151
self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
152152
self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
@@ -390,7 +390,7 @@ def test_update(self):
390390
self.assertRaises(PassThru, self.s.update, check_pass_thru())
391391
self.assertRaises(TypeError, self.s.update, [[]])
392392
for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
393-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
393+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
394394
s = self.thetype('abcba')
395395
self.assertEqual(s.update(C(p)), None)
396396
self.assertEqual(s, set(q))
@@ -411,7 +411,7 @@ def test_intersection_update(self):
411411
self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
412412
self.assertRaises(TypeError, self.s.intersection_update, [[]])
413413
for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
414-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
414+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
415415
s = self.thetype('abcba')
416416
self.assertEqual(s.intersection_update(C(p)), None)
417417
self.assertEqual(s, set(q))
@@ -436,7 +436,7 @@ def test_difference_update(self):
436436
self.assertRaises(TypeError, self.s.difference_update, [[]])
437437
self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
438438
for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
439-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
439+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
440440
s = self.thetype('abcba')
441441
self.assertEqual(s.difference_update(C(p)), None)
442442
self.assertEqual(s, set(q))
@@ -460,7 +460,7 @@ def test_symmetric_difference_update(self):
460460
self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
461461
self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
462462
for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
463-
for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
463+
for C in set, frozenset, dict.fromkeys, str, list, tuple:
464464
s = self.thetype('abcba')
465465
self.assertEqual(s.symmetric_difference_update(C(p)), None)
466466
self.assertEqual(s, set(q))

Lib/test/test_struct.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,8 @@ def test_bool():
674674
elif not prefix and verbose:
675675
print('size of bool in native format is %i' % (len(packed)))
676676

677-
for c in str8('\x01\x7f\xff\x0f\xf0'):
678-
if struct.unpack('>t', c)[0] is not True:
677+
for c in b'\x01\x7f\xff\x0f\xf0':
678+
if struct.unpack('>t', bytes([c]))[0] is not True:
679679
raise TestFailed('%c did not unpack as True' % c)
680680

681681
test_bool()

Objects/stringobject.c

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -986,28 +986,6 @@ string_contains(PyObject *str_obj, PyObject *sub_obj)
986986
return stringlib_contains_obj(str_obj, sub_obj);
987987
}
988988

989-
static PyObject *
990-
string_item(PyStringObject *a, register Py_ssize_t i)
991-
{
992-
char pchar;
993-
PyObject *v;
994-
if (i < 0 || i >= Py_Size(a)) {
995-
PyErr_SetString(PyExc_IndexError, "string index out of range");
996-
return NULL;
997-
}
998-
pchar = a->ob_sval[i];
999-
v = (PyObject *)characters[pchar & UCHAR_MAX];
1000-
if (v == NULL)
1001-
v = PyString_FromStringAndSize(&pchar, 1);
1002-
else {
1003-
#ifdef COUNT_ALLOCS
1004-
one_strings++;
1005-
#endif
1006-
Py_INCREF(v);
1007-
}
1008-
return v;
1009-
}
1010-
1011989
static PyObject*
1012990
string_richcompare(PyStringObject *a, PyStringObject *b, int op)
1013991
{
@@ -1110,7 +1088,12 @@ string_subscript(PyStringObject* self, PyObject* item)
11101088
return NULL;
11111089
if (i < 0)
11121090
i += PyString_GET_SIZE(self);
1113-
return string_item(self, i);
1091+
if (i < 0 || i >= PyString_GET_SIZE(self)) {
1092+
PyErr_SetString(PyExc_IndexError,
1093+
"string index out of range");
1094+
return NULL;
1095+
}
1096+
return PyInt_FromLong((unsigned char)self->ob_sval[i]);
11141097
}
11151098
else if (PySlice_Check(item)) {
11161099
Py_ssize_t start, stop, step, slicelength, cur, i;
@@ -1173,7 +1156,7 @@ static PySequenceMethods string_as_sequence = {
11731156
(lenfunc)string_length, /*sq_length*/
11741157
(binaryfunc)string_concat, /*sq_concat*/
11751158
(ssizeargfunc)string_repeat, /*sq_repeat*/
1176-
(ssizeargfunc)string_item, /*sq_item*/
1159+
0, /*sq_item*/
11771160
0, /*sq_slice*/
11781161
0, /*sq_ass_item*/
11791162
0, /*sq_ass_slice*/
@@ -4147,8 +4130,8 @@ striter_next(striterobject *it)
41474130
assert(PyString_Check(seq));
41484131

41494132
if (it->it_index < PyString_GET_SIZE(seq)) {
4150-
item = PyString_FromStringAndSize(
4151-
PyString_AS_STRING(seq)+it->it_index, 1);
4133+
item = PyInt_FromLong(
4134+
(unsigned char)seq->ob_sval[it->it_index]);
41524135
if (item != NULL)
41534136
++it->it_index;
41544137
return item;

0 commit comments

Comments
 (0)