Skip to content

Commit aaa8102

Browse files
author
neal.norwitz
committed
SF patch #1669633, add methods for bytes from Pete Shinners.
git-svn-id: http://svn.python.org/projects/python/branches/p3yk@54000 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 2db898f commit aaa8102

4 files changed

Lines changed: 1730 additions & 23 deletions

File tree

Include/pythonrun.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ PyAPI_FUNC(void) _PyImportHooks_Init(void);
122122
PyAPI_FUNC(int) _PyFrame_Init(void);
123123
PyAPI_FUNC(int) _PyInt_Init(void);
124124
PyAPI_FUNC(void) _PyFloat_Init(void);
125+
PyAPI_FUNC(int) PyBytes_Init(void);
125126

126127
/* Various internal finalizers */
127128
PyAPI_FUNC(void) _PyExc_Fini(void);
@@ -133,6 +134,7 @@ PyAPI_FUNC(void) PyTuple_Fini(void);
133134
PyAPI_FUNC(void) PyList_Fini(void);
134135
PyAPI_FUNC(void) PySet_Fini(void);
135136
PyAPI_FUNC(void) PyString_Fini(void);
137+
PyAPI_FUNC(void) PyBytes_Fini(void);
136138
PyAPI_FUNC(void) PyInt_Fini(void);
137139
PyAPI_FUNC(void) PyFloat_Fini(void);
138140
PyAPI_FUNC(void) PyOS_FiniInterrupts(void);

Lib/test/test_bytes.py

Lines changed: 168 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ def test_reversed(self):
145145
input.reverse()
146146
self.assertEqual(output, input)
147147

148+
def test_reverse(self):
149+
b = b'hello'
150+
self.assertEqual(b.reverse(), None)
151+
self.assertEqual(b, b'olleh')
152+
b = b'hello1' # test even number of items
153+
b.reverse()
154+
self.assertEqual(b, b'1olleh')
155+
b = bytes()
156+
b.reverse()
157+
self.assertFalse(b)
158+
148159
def test_getslice(self):
149160
def by(s):
150161
return bytes(map(ord, s))
@@ -434,36 +445,171 @@ def test_literal(self):
434445
self.assertRaises(SyntaxError, eval,
435446
'b"%s"' % chr(c))
436447

448+
def test_extend(self):
449+
orig = b'hello'
450+
a = bytes(orig)
451+
a.extend(a)
452+
self.assertEqual(a, orig + orig)
453+
self.assertEqual(a[5:], orig)
454+
455+
def test_remove(self):
456+
b = b'hello'
457+
b.remove(ord('l'))
458+
self.assertEqual(b, b'helo')
459+
b.remove(ord('l'))
460+
self.assertEqual(b, b'heo')
461+
self.assertRaises(ValueError, lambda: b.remove(ord('l')))
462+
self.assertRaises(ValueError, lambda: b.remove(400))
463+
self.assertRaises(ValueError, lambda: b.remove('e'))
464+
# remove first and last
465+
b.remove(ord('o'))
466+
b.remove(ord('h'))
467+
self.assertEqual(b, b'e')
468+
469+
def test_pop(self):
470+
b = b'world'
471+
self.assertEqual(b.pop(), ord('d'))
472+
self.assertEqual(b.pop(0), ord('w'))
473+
self.assertEqual(b.pop(-2), ord('r'))
474+
self.assertRaises(IndexError, lambda: b.pop(10))
475+
self.assertRaises(OverflowError, lambda: bytes().pop())
476+
477+
def test_nosort(self):
478+
self.assertRaises(AttributeError, lambda: bytes().sort())
479+
480+
def test_index(self):
481+
b = b'parrot'
482+
self.assertEqual(b.index('p'), 0)
483+
self.assertEqual(b.index('rr'), 2)
484+
self.assertEqual(b.index('t'), 5)
485+
self.assertRaises(ValueError, lambda: b.index('w'))
486+
487+
def test_count(self):
488+
b = b'mississippi'
489+
self.assertEqual(b.count('i'), 4)
490+
self.assertEqual(b.count('ss'), 2)
491+
self.assertEqual(b.count('w'), 0)
492+
493+
def test_append(self):
494+
b = b'hell'
495+
b.append(ord('o'))
496+
self.assertEqual(b, b'hello')
497+
self.assertEqual(b.append(100), None)
498+
b = bytes()
499+
b.append(ord('A'))
500+
self.assertEqual(len(b), 1)
501+
502+
def test_insert(self):
503+
b = b'msssspp'
504+
b.insert(1, ord('i'))
505+
b.insert(4, ord('i'))
506+
b.insert(-2, ord('i'))
507+
b.insert(1000, ord('i'))
508+
self.assertEqual(b, b'mississippi')
509+
510+
def test_startswith(self):
511+
b = b'hello'
512+
self.assertFalse(bytes().startswith("anything"))
513+
self.assertTrue(b.startswith("hello"))
514+
self.assertTrue(b.startswith("hel"))
515+
self.assertTrue(b.startswith("h"))
516+
self.assertFalse(b.startswith("hellow"))
517+
self.assertFalse(b.startswith("ha"))
518+
519+
def test_endswith(self):
520+
b = b'hello'
521+
self.assertFalse(bytes().endswith("anything"))
522+
self.assertTrue(b.endswith("hello"))
523+
self.assertTrue(b.endswith("llo"))
524+
self.assertTrue(b.endswith("o"))
525+
self.assertFalse(b.endswith("whello"))
526+
self.assertFalse(b.endswith("no"))
527+
528+
def test_find(self):
529+
b = b'mississippi'
530+
self.assertEqual(b.find('ss'), 2)
531+
self.assertEqual(b.find('ss', 3), 5)
532+
self.assertEqual(b.find('ss', 1, 7), 2)
533+
self.assertEqual(b.find('ss', 1, 3), -1)
534+
self.assertEqual(b.find('w'), -1)
535+
self.assertEqual(b.find('mississippian'), -1)
536+
537+
def test_rfind(self):
538+
b = b'mississippi'
539+
self.assertEqual(b.rfind('ss'), 5)
540+
self.assertEqual(b.rfind('ss', 3), 5)
541+
self.assertEqual(b.rfind('ss', 0, 6), 2)
542+
self.assertEqual(b.rfind('w'), -1)
543+
self.assertEqual(b.rfind('mississippian'), -1)
544+
545+
def test_index(self):
546+
b = b'world'
547+
self.assertEqual(b.index('w'), 0)
548+
self.assertEqual(b.index('orl'), 1)
549+
self.assertRaises(ValueError, lambda: b.index('worm'))
550+
self.assertRaises(ValueError, lambda: b.index('ldo'))
551+
552+
def test_rindex(self):
553+
# XXX could be more rigorous
554+
b = b'world'
555+
self.assertEqual(b.rindex('w'), 0)
556+
self.assertEqual(b.rindex('orl'), 1)
557+
self.assertRaises(ValueError, lambda: b.rindex('worm'))
558+
self.assertRaises(ValueError, lambda: b.rindex('ldo'))
559+
560+
def test_replace(self):
561+
b = b'mississippi'
562+
self.assertEqual(b.replace('i', 'a'), b'massassappa')
563+
self.assertEqual(b.replace('ss', 'x'), b'mixixippi')
564+
565+
def test_translate(self):
566+
b = b'hello'
567+
rosetta = bytes(range(0, 256))
568+
rosetta[ord('o')] = ord('e')
569+
c = b.translate(rosetta, b'l')
570+
self.assertEqual(b, b'hello')
571+
self.assertEqual(c, b'hee')
572+
573+
def test_split(self):
574+
b = b'mississippi'
575+
self.assertEqual(b.split('i'), [b'm', b'ss', b'ss', b'pp', b''])
576+
self.assertEqual(b.split('ss'), [b'mi', b'i', b'ippi'])
577+
self.assertEqual(b.split('w'), [b])
578+
# require an arg (no magic whitespace split)
579+
self.assertRaises(TypeError, lambda: b.split())
580+
581+
def test_rsplit(self):
582+
b = b'mississippi'
583+
self.assertEqual(b.rsplit('i'), [b'm', b'ss', b'ss', b'pp', b''])
584+
self.assertEqual(b.rsplit('ss'), [b'mi', b'i', b'ippi'])
585+
self.assertEqual(b.rsplit('w'), [b])
586+
# require an arg (no magic whitespace split)
587+
self.assertRaises(TypeError, lambda: b.rsplit())
588+
589+
def test_partition(self):
590+
b = b'mississippi'
591+
self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi'))
592+
self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
593+
594+
def test_rpartition(self):
595+
b = b'mississippi'
596+
self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi'))
597+
self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
598+
437599
# Optimizations:
438600
# __iter__? (optimization)
439601
# __reversed__? (optimization)
440602

441-
# XXX Some list methods?
442-
# extended slicing
443-
# extended slice assignment
444-
# extend (same as b[len(b):] = src)
445-
# reverse (in-place)
446-
# remove
447-
# pop
448-
# NOT sort!
449-
# With int arg:
450-
# index
451-
# count
452-
# append
453-
# insert
454-
455603
# XXX Some string methods? (Those that don't use character properties)
456-
# startswith
457-
# endswidth
458-
# find, rfind
459-
# index, rindex (bytes arg)
604+
# lstrip, rstrip, strip?? (currently un-pepped)
460605
# join
461-
# replace
462-
# translate
463-
# split, rsplit
464-
# lstrip, rstrip, strip??
465606

466607
# XXX pickle and marshal support?
608+
609+
# There are tests in string_tests.py that are more
610+
# comprehensive for things like split, partition, etc.
611+
# Unfortunately they are all bundled with tests that
612+
# are not appropriate for bytes
467613

468614

469615
def test_main():

0 commit comments

Comments
 (0)