PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/objspace/std/bytearrayobject.py

https://bitbucket.org/pypy/pypy/
Python | 1261 lines | 1249 code | 10 blank | 2 comment | 5 complexity | 3ab36ee1cac3064cc2ee029ef56536c2 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """The builtin bytearray implementation"""
  2. from rpython.rlib.objectmodel import (
  3. import_from_mixin, newlist_hint, resizelist_hint, specialize)
  4. from rpython.rlib.buffer import Buffer
  5. from rpython.rlib.rstring import StringBuilder, ByteListBuilder
  6. from rpython.rlib.debug import check_list_of_chars
  7. from rpython.rtyper.lltypesystem import rffi
  8. from rpython.rlib.rgc import (resizable_list_supporting_raw_ptr,
  9. nonmoving_raw_ptr_for_resizable_list)
  10. from pypy.interpreter.baseobjspace import W_Root
  11. from pypy.interpreter.error import OperationError, oefmt
  12. from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
  13. from pypy.interpreter.signature import Signature
  14. from pypy.interpreter.typedef import TypeDef
  15. from pypy.objspace.std.sliceobject import W_SliceObject
  16. from pypy.objspace.std.stringmethods import StringMethods, _get_buffer
  17. from pypy.objspace.std.bytesobject import W_BytesObject
  18. from pypy.objspace.std.util import get_positive_index
  19. class W_BytearrayObject(W_Root):
  20. import_from_mixin(StringMethods)
  21. def __init__(self, data):
  22. check_list_of_chars(data)
  23. self.data = resizable_list_supporting_raw_ptr(data)
  24. def __repr__(self):
  25. """representation for debugging purposes"""
  26. return "%s(%s)" % (self.__class__.__name__, ''.join(self.data))
  27. def buffer_w(self, space, flags):
  28. return BytearrayBuffer(self.data, False)
  29. def readbuf_w(self, space):
  30. return BytearrayBuffer(self.data, True)
  31. def writebuf_w(self, space):
  32. return BytearrayBuffer(self.data, False)
  33. def charbuf_w(self, space):
  34. return ''.join(self.data)
  35. def bytearray_list_of_chars_w(self, space):
  36. return self.data
  37. def nonmovable_carray(self, space):
  38. return BytearrayBuffer(self.data, False).get_raw_address()
  39. def _new(self, value):
  40. if value is self.data:
  41. value = value[:]
  42. return W_BytearrayObject(value)
  43. def _new_from_buffer(self, buffer):
  44. return W_BytearrayObject([buffer[i] for i in range(len(buffer))])
  45. def _new_from_list(self, value):
  46. return W_BytearrayObject(value)
  47. def _empty(self):
  48. return W_BytearrayObject([])
  49. def _len(self):
  50. return len(self.data)
  51. def _getitem_result(self, space, index):
  52. try:
  53. character = self.data[index]
  54. except IndexError:
  55. raise oefmt(space.w_IndexError, "bytearray index out of range")
  56. return space.wrap(ord(character))
  57. def _val(self, space):
  58. return self.data
  59. @staticmethod
  60. def _use_rstr_ops(space, w_other):
  61. return False
  62. @staticmethod
  63. def _op_val(space, w_other):
  64. return space.buffer_w(w_other, space.BUF_SIMPLE).as_str()
  65. def _chr(self, char):
  66. assert len(char) == 1
  67. return str(char)[0]
  68. def _multi_chr(self, char):
  69. return [char]
  70. @staticmethod
  71. def _builder(size=100):
  72. return ByteListBuilder(size)
  73. def _newlist_unwrapped(self, space, res):
  74. return space.newlist([W_BytearrayObject(i) for i in res])
  75. def _isupper(self, ch):
  76. return ch.isupper()
  77. def _islower(self, ch):
  78. return ch.islower()
  79. def _istitle(self, ch):
  80. return ch.isupper()
  81. def _isspace(self, ch):
  82. return ch.isspace()
  83. def _isalpha(self, ch):
  84. return ch.isalpha()
  85. def _isalnum(self, ch):
  86. return ch.isalnum()
  87. def _isdigit(self, ch):
  88. return ch.isdigit()
  89. _iscased = _isalpha
  90. def _islinebreak(self, ch):
  91. return (ch == '\n') or (ch == '\r')
  92. def _upper(self, ch):
  93. if ch.islower():
  94. o = ord(ch) - 32
  95. return chr(o)
  96. else:
  97. return ch
  98. def _lower(self, ch):
  99. if ch.isupper():
  100. o = ord(ch) + 32
  101. return chr(o)
  102. else:
  103. return ch
  104. _title = _upper
  105. def _join_return_one(self, space, w_obj):
  106. return False
  107. def _join_check_item(self, space, w_obj):
  108. if (space.isinstance_w(w_obj, space.w_str) or
  109. space.isinstance_w(w_obj, space.w_bytearray)):
  110. return 0
  111. return 1
  112. def ord(self, space):
  113. if len(self.data) != 1:
  114. raise oefmt(space.w_TypeError,
  115. "ord() expected a character, but string of length %d "
  116. "found", len(self.data))
  117. return space.wrap(ord(self.data[0]))
  118. @staticmethod
  119. def descr_new(space, w_bytearraytype, __args__):
  120. return new_bytearray(space, w_bytearraytype, [])
  121. def descr_reduce(self, space):
  122. assert isinstance(self, W_BytearrayObject)
  123. w_dict = self.getdict(space)
  124. if w_dict is None:
  125. w_dict = space.w_None
  126. return space.newtuple([
  127. space.type(self), space.newtuple([
  128. space.wrap(''.join(self.data).decode('latin-1')),
  129. space.wrap('latin-1')]),
  130. w_dict])
  131. @staticmethod
  132. def descr_fromhex(space, w_bytearraytype, w_hexstring):
  133. hexstring = space.str_w(w_hexstring)
  134. data = _hexstring_to_array(space, hexstring)
  135. # in CPython bytearray.fromhex is a staticmethod, so
  136. # we ignore w_type and always return a bytearray
  137. return new_bytearray(space, space.w_bytearray, data)
  138. @unwrap_spec(encoding='str_or_None', errors='str_or_None')
  139. def descr_init(self, space, w_source=None, encoding=None, errors=None):
  140. if w_source is None:
  141. w_source = space.wrap('')
  142. if encoding is not None:
  143. from pypy.objspace.std.unicodeobject import encode_object
  144. # if w_source is an integer this correctly raises a
  145. # TypeError the CPython error message is: "encoding or
  146. # errors without a string argument" ours is: "expected
  147. # unicode, got int object"
  148. w_source = encode_object(space, w_source, encoding, errors)
  149. # Is it an int?
  150. try:
  151. count = space.int_w(w_source)
  152. except OperationError as e:
  153. if not e.match(space, space.w_TypeError):
  154. raise
  155. else:
  156. if count < 0:
  157. raise oefmt(space.w_ValueError, "bytearray negative count")
  158. self.data = resizable_list_supporting_raw_ptr(['\0'] * count)
  159. return
  160. data = makebytearraydata_w(space, w_source)
  161. self.data = resizable_list_supporting_raw_ptr(data)
  162. def descr_repr(self, space):
  163. s = self.data
  164. # Good default if there are no replacements.
  165. buf = StringBuilder(len("bytearray(b'')") + len(s))
  166. buf.append("bytearray(b")
  167. quote = "'"
  168. for c in s:
  169. if c == '"':
  170. quote = "'"
  171. break
  172. elif c == "'":
  173. quote = '"'
  174. buf.append(quote)
  175. for i in range(len(s)):
  176. c = s[i]
  177. if c == '\\' or c == "'":
  178. buf.append('\\')
  179. buf.append(c)
  180. elif c == '\t':
  181. buf.append('\\t')
  182. elif c == '\r':
  183. buf.append('\\r')
  184. elif c == '\n':
  185. buf.append('\\n')
  186. elif not '\x20' <= c < '\x7f':
  187. n = ord(c)
  188. buf.append('\\x')
  189. buf.append("0123456789abcdef"[n >> 4])
  190. buf.append("0123456789abcdef"[n & 0xF])
  191. else:
  192. buf.append(c)
  193. buf.append(quote)
  194. buf.append(")")
  195. return space.wrap(buf.build())
  196. def descr_str(self, space):
  197. return space.wrap(''.join(self.data))
  198. def descr_eq(self, space, w_other):
  199. if isinstance(w_other, W_BytearrayObject):
  200. return space.newbool(self.data == w_other.data)
  201. try:
  202. buffer = _get_buffer(space, w_other)
  203. except OperationError as e:
  204. if e.match(space, space.w_TypeError):
  205. return space.w_NotImplemented
  206. raise
  207. value = self._val(space)
  208. buffer_len = buffer.getlength()
  209. if len(value) != buffer_len:
  210. return space.newbool(False)
  211. min_length = min(len(value), buffer_len)
  212. return space.newbool(_memcmp(value, buffer, min_length) == 0)
  213. def descr_ne(self, space, w_other):
  214. if isinstance(w_other, W_BytearrayObject):
  215. return space.newbool(self.data != w_other.data)
  216. try:
  217. buffer = _get_buffer(space, w_other)
  218. except OperationError as e:
  219. if e.match(space, space.w_TypeError):
  220. return space.w_NotImplemented
  221. raise
  222. value = self._val(space)
  223. buffer_len = buffer.getlength()
  224. if len(value) != buffer_len:
  225. return space.newbool(True)
  226. min_length = min(len(value), buffer_len)
  227. return space.newbool(_memcmp(value, buffer, min_length) != 0)
  228. def _comparison_helper(self, space, w_other):
  229. value = self._val(space)
  230. if isinstance(w_other, W_BytearrayObject):
  231. other = w_other.data
  232. other_len = len(other)
  233. cmp = _memcmp(value, other, min(len(value), len(other)))
  234. elif isinstance(w_other, W_BytesObject):
  235. other = self._op_val(space, w_other)
  236. other_len = len(other)
  237. cmp = _memcmp(value, other, min(len(value), len(other)))
  238. else:
  239. try:
  240. buffer = _get_buffer(space, w_other)
  241. except OperationError as e:
  242. if e.match(space, space.w_TypeError):
  243. return False, 0, 0
  244. raise
  245. other_len = len(buffer)
  246. cmp = _memcmp(value, buffer, min(len(value), len(buffer)))
  247. return True, cmp, other_len
  248. def descr_lt(self, space, w_other):
  249. success, cmp, other_len = self._comparison_helper(space, w_other)
  250. if not success:
  251. return space.w_NotImplemented
  252. return space.newbool(cmp < 0 or (cmp == 0 and self._len() < other_len))
  253. def descr_le(self, space, w_other):
  254. success, cmp, other_len = self._comparison_helper(space, w_other)
  255. if not success:
  256. return space.w_NotImplemented
  257. return space.newbool(cmp < 0 or (cmp == 0 and self._len() <= other_len))
  258. def descr_gt(self, space, w_other):
  259. success, cmp, other_len = self._comparison_helper(space, w_other)
  260. if not success:
  261. return space.w_NotImplemented
  262. return space.newbool(cmp > 0 or (cmp == 0 and self._len() > other_len))
  263. def descr_ge(self, space, w_other):
  264. success, cmp, other_len = self._comparison_helper(space, w_other)
  265. if not success:
  266. return space.w_NotImplemented
  267. return space.newbool(cmp > 0 or (cmp == 0 and self._len() >= other_len))
  268. def descr_iter(self, space):
  269. return space.newseqiter(self)
  270. def descr_inplace_add(self, space, w_other):
  271. if isinstance(w_other, W_BytearrayObject):
  272. self.data += w_other.data
  273. return self
  274. if isinstance(w_other, W_BytesObject):
  275. self._inplace_add(self._op_val(space, w_other))
  276. else:
  277. self._inplace_add(_get_buffer(space, w_other))
  278. return self
  279. @specialize.argtype(1)
  280. def _inplace_add(self, other):
  281. for i in range(len(other)):
  282. self.data.append(other[i])
  283. def descr_inplace_mul(self, space, w_times):
  284. try:
  285. times = space.getindex_w(w_times, space.w_OverflowError)
  286. except OperationError as e:
  287. if e.match(space, space.w_TypeError):
  288. return space.w_NotImplemented
  289. raise
  290. self.data *= times
  291. return self
  292. def descr_setitem(self, space, w_index, w_other):
  293. if isinstance(w_index, W_SliceObject):
  294. oldsize = len(self.data)
  295. start, stop, step, slicelength = w_index.indices4(space, oldsize)
  296. sequence2 = makebytearraydata_w(space, w_other)
  297. _setitem_slice_helper(space, self.data, start, step,
  298. slicelength, sequence2, empty_elem='\x00')
  299. else:
  300. idx = space.getindex_w(w_index, space.w_IndexError,
  301. "bytearray index")
  302. try:
  303. self.data[idx] = getbytevalue(space, w_other)
  304. except IndexError:
  305. raise oefmt(space.w_IndexError, "bytearray index out of range")
  306. def descr_delitem(self, space, w_idx):
  307. if isinstance(w_idx, W_SliceObject):
  308. start, stop, step, slicelength = w_idx.indices4(space,
  309. len(self.data))
  310. _delitem_slice_helper(space, self.data, start, step, slicelength)
  311. else:
  312. idx = space.getindex_w(w_idx, space.w_IndexError,
  313. "bytearray index")
  314. try:
  315. del self.data[idx]
  316. except IndexError:
  317. raise oefmt(space.w_IndexError,
  318. "bytearray deletion index out of range")
  319. def descr_append(self, space, w_item):
  320. self.data.append(getbytevalue(space, w_item))
  321. def descr_extend(self, space, w_other):
  322. if isinstance(w_other, W_BytearrayObject):
  323. self.data += w_other.data
  324. else:
  325. self.data += makebytearraydata_w(space, w_other)
  326. return self
  327. def descr_insert(self, space, w_idx, w_other):
  328. where = space.int_w(w_idx)
  329. length = len(self.data)
  330. index = get_positive_index(where, length)
  331. val = getbytevalue(space, w_other)
  332. self.data.insert(index, val)
  333. return space.w_None
  334. @unwrap_spec(w_idx=WrappedDefault(-1))
  335. def descr_pop(self, space, w_idx):
  336. index = space.int_w(w_idx)
  337. try:
  338. result = self.data.pop(index)
  339. except IndexError:
  340. if not self.data:
  341. raise oefmt(space.w_IndexError, "pop from empty bytearray")
  342. raise oefmt(space.w_IndexError, "pop index out of range")
  343. return space.wrap(ord(result))
  344. def descr_remove(self, space, w_char):
  345. char = space.int_w(space.index(w_char))
  346. try:
  347. self.data.remove(chr(char))
  348. except ValueError:
  349. raise oefmt(space.w_ValueError, "value not found in bytearray")
  350. _StringMethods_descr_contains = descr_contains
  351. def descr_contains(self, space, w_sub):
  352. if space.isinstance_w(w_sub, space.w_int):
  353. char = space.int_w(w_sub)
  354. return _descr_contains_bytearray(self.data, space, char)
  355. return self._StringMethods_descr_contains(space, w_sub)
  356. def descr_add(self, space, w_other):
  357. if isinstance(w_other, W_BytearrayObject):
  358. return self._new(self.data + w_other.data)
  359. if isinstance(w_other, W_BytesObject):
  360. return self._add(self._op_val(space, w_other))
  361. try:
  362. buffer = _get_buffer(space, w_other)
  363. except OperationError as e:
  364. if e.match(space, space.w_TypeError):
  365. return space.w_NotImplemented
  366. raise
  367. return self._add(buffer)
  368. @specialize.argtype(1)
  369. def _add(self, other):
  370. return self._new(self.data + [other[i] for i in range(len(other))])
  371. def descr_reverse(self, space):
  372. self.data.reverse()
  373. # ____________________________________________________________
  374. # helpers for slow paths, moved out because they contain loops
  375. def _make_data(s):
  376. return [s[i] for i in range(len(s))]
  377. def _descr_contains_bytearray(data, space, char):
  378. if not 0 <= char < 256:
  379. raise oefmt(space.w_ValueError, "byte must be in range(0, 256)")
  380. for c in data:
  381. if ord(c) == char:
  382. return space.w_True
  383. return space.w_False
  384. # ____________________________________________________________
  385. def getbytevalue(space, w_value):
  386. if space.isinstance_w(w_value, space.w_str):
  387. string = space.str_w(w_value)
  388. if len(string) != 1:
  389. raise oefmt(space.w_ValueError, "string must be of size 1")
  390. return string[0]
  391. value = space.getindex_w(w_value, None)
  392. if not 0 <= value < 256:
  393. # this includes the OverflowError in case the long is too large
  394. raise oefmt(space.w_ValueError, "byte must be in range(0, 256)")
  395. return chr(value)
  396. def new_bytearray(space, w_bytearraytype, data):
  397. w_obj = space.allocate_instance(W_BytearrayObject, w_bytearraytype)
  398. W_BytearrayObject.__init__(w_obj, data)
  399. return w_obj
  400. def makebytearraydata_w(space, w_source):
  401. # String-like argument
  402. try:
  403. buf = space.buffer_w(w_source, space.BUF_FULL_RO)
  404. except OperationError as e:
  405. if not e.match(space, space.w_TypeError):
  406. raise
  407. else:
  408. return list(buf.as_str())
  409. # sequence of bytes
  410. w_iter = space.iter(w_source)
  411. length_hint = space.length_hint(w_source, 0)
  412. data = newlist_hint(length_hint)
  413. extended = 0
  414. while True:
  415. try:
  416. w_item = space.next(w_iter)
  417. except OperationError as e:
  418. if not e.match(space, space.w_StopIteration):
  419. raise
  420. break
  421. value = getbytevalue(space, w_item)
  422. data.append(value)
  423. extended += 1
  424. if extended < length_hint:
  425. resizelist_hint(data, extended)
  426. return data
  427. def _hex_digit_to_int(d):
  428. val = ord(d)
  429. if 47 < val < 58:
  430. return val - 48
  431. if 64 < val < 71:
  432. return val - 55
  433. if 96 < val < 103:
  434. return val - 87
  435. return -1
  436. NON_HEX_MSG = "non-hexadecimal number found in fromhex() arg at position %d"
  437. def _hexstring_to_array(space, s):
  438. data = []
  439. length = len(s)
  440. i = 0
  441. while True:
  442. while i < length and s[i] == ' ':
  443. i += 1
  444. if i >= length:
  445. break
  446. if i + 1 == length:
  447. raise oefmt(space.w_ValueError, NON_HEX_MSG, i)
  448. top = _hex_digit_to_int(s[i])
  449. if top == -1:
  450. raise oefmt(space.w_ValueError, NON_HEX_MSG, i)
  451. bot = _hex_digit_to_int(s[i + 1])
  452. if bot == -1:
  453. raise oefmt(space.w_ValueError, NON_HEX_MSG, i + 1)
  454. data.append(chr(top * 16 + bot))
  455. i += 2
  456. return data
  457. class BytearrayDocstrings:
  458. """bytearray(iterable_of_ints) -> bytearray
  459. bytearray(string, encoding[, errors]) -> bytearray
  460. bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray
  461. bytearray(memory_view) -> bytearray
  462. Construct an mutable bytearray object from:
  463. - an iterable yielding integers in range(256)
  464. - a text string encoded using the specified encoding
  465. - a bytes or a bytearray object
  466. - any object implementing the buffer API.
  467. bytearray(int) -> bytearray.
  468. Construct a zero-initialized bytearray of the given length.
  469. """
  470. def __add__():
  471. """x.__add__(y) <==> x+y"""
  472. def __alloc__():
  473. """B.__alloc__() -> int
  474. Return the number of bytes actually allocated.
  475. """
  476. def __contains__():
  477. """x.__contains__(y) <==> y in x"""
  478. def __delitem__():
  479. """x.__delitem__(y) <==> del x[y]"""
  480. def __eq__():
  481. """x.__eq__(y) <==> x==y"""
  482. def __ge__():
  483. """x.__ge__(y) <==> x>=y"""
  484. def __getattribute__():
  485. """x.__getattribute__('name') <==> x.name"""
  486. def __getitem__():
  487. """x.__getitem__(y) <==> x[y]"""
  488. def __gt__():
  489. """x.__gt__(y) <==> x>y"""
  490. def __iadd__():
  491. """x.__iadd__(y) <==> x+=y"""
  492. def __imul__():
  493. """x.__imul__(y) <==> x*=y"""
  494. def __init__():
  495. """x.__init__(...) initializes x; see help(type(x)) for signature"""
  496. def __iter__():
  497. """x.__iter__() <==> iter(x)"""
  498. def __le__():
  499. """x.__le__(y) <==> x<=y"""
  500. def __len__():
  501. """x.__len__() <==> len(x)"""
  502. def __lt__():
  503. """x.__lt__(y) <==> x<y"""
  504. def __mul__():
  505. """x.__mul__(n) <==> x*n"""
  506. def __ne__():
  507. """x.__ne__(y) <==> x!=y"""
  508. def __reduce__():
  509. """Return state information for pickling."""
  510. def __repr__():
  511. """x.__repr__() <==> repr(x)"""
  512. def __rmul__():
  513. """x.__rmul__(n) <==> n*x"""
  514. def __setitem__():
  515. """x.__setitem__(i, y) <==> x[i]=y"""
  516. def __sizeof__():
  517. """B.__sizeof__() -> int
  518. Returns the size of B in memory, in bytes
  519. """
  520. def __str__():
  521. """x.__str__() <==> str(x)"""
  522. def append():
  523. """B.append(int) -> None
  524. Append a single item to the end of B.
  525. """
  526. def capitalize():
  527. """B.capitalize() -> copy of B
  528. Return a copy of B with only its first character capitalized (ASCII)
  529. and the rest lower-cased.
  530. """
  531. def center():
  532. """B.center(width[, fillchar]) -> copy of B
  533. Return B centered in a string of length width. Padding is
  534. done using the specified fill character (default is a space).
  535. """
  536. def count():
  537. """B.count(sub[, start[, end]]) -> int
  538. Return the number of non-overlapping occurrences of subsection sub in
  539. bytes B[start:end]. Optional arguments start and end are interpreted
  540. as in slice notation.
  541. """
  542. def decode():
  543. """B.decode(encoding=None, errors='strict') -> unicode
  544. Decode B using the codec registered for encoding. encoding defaults to
  545. the default encoding. errors may be given to set a different error
  546. handling scheme. Default is 'strict' meaning that encoding errors
  547. raise a UnicodeDecodeError. Other possible values are 'ignore' and
  548. 'replace' as well as any other name registered with
  549. codecs.register_error that is able to handle UnicodeDecodeErrors.
  550. """
  551. def endswith():
  552. """B.endswith(suffix[, start[, end]]) -> bool
  553. Return True if B ends with the specified suffix, False otherwise.
  554. With optional start, test B beginning at that position.
  555. With optional end, stop comparing B at that position.
  556. suffix can also be a tuple of strings to try.
  557. """
  558. def expandtabs():
  559. """B.expandtabs([tabsize]) -> copy of B
  560. Return a copy of B where all tab characters are expanded using spaces.
  561. If tabsize is not given, a tab size of 8 characters is assumed.
  562. """
  563. def extend():
  564. """B.extend(iterable_of_ints) -> None
  565. Append all the elements from the iterator or sequence to the
  566. end of B.
  567. """
  568. def find():
  569. """B.find(sub[, start[, end]]) -> int
  570. Return the lowest index in B where subsection sub is found,
  571. such that sub is contained within B[start,end]. Optional
  572. arguments start and end are interpreted as in slice notation.
  573. Return -1 on failure.
  574. """
  575. def fromhex():
  576. r"""bytearray.fromhex(string) -> bytearray (static method)
  577. Create a bytearray object from a string of hexadecimal numbers.
  578. Spaces between two numbers are accepted.
  579. Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\xb9\x01\xef').
  580. """
  581. def index():
  582. """B.index(sub[, start[, end]]) -> int
  583. Like B.find() but raise ValueError when the subsection is not found.
  584. """
  585. def insert():
  586. """B.insert(index, int) -> None
  587. Insert a single item into the bytearray before the given index.
  588. """
  589. def isalnum():
  590. """B.isalnum() -> bool
  591. Return True if all characters in B are alphanumeric
  592. and there is at least one character in B, False otherwise.
  593. """
  594. def isalpha():
  595. """B.isalpha() -> bool
  596. Return True if all characters in B are alphabetic
  597. and there is at least one character in B, False otherwise.
  598. """
  599. def isdigit():
  600. """B.isdigit() -> bool
  601. Return True if all characters in B are digits
  602. and there is at least one character in B, False otherwise.
  603. """
  604. def islower():
  605. """B.islower() -> bool
  606. Return True if all cased characters in B are lowercase and there is
  607. at least one cased character in B, False otherwise.
  608. """
  609. def isspace():
  610. """B.isspace() -> bool
  611. Return True if all characters in B are whitespace
  612. and there is at least one character in B, False otherwise.
  613. """
  614. def istitle():
  615. """B.istitle() -> bool
  616. Return True if B is a titlecased string and there is at least one
  617. character in B, i.e. uppercase characters may only follow uncased
  618. characters and lowercase characters only cased ones. Return False
  619. otherwise.
  620. """
  621. def isupper():
  622. """B.isupper() -> bool
  623. Return True if all cased characters in B are uppercase and there is
  624. at least one cased character in B, False otherwise.
  625. """
  626. def join():
  627. """B.join(iterable_of_bytes) -> bytearray
  628. Concatenate any number of str/bytearray objects, with B
  629. in between each pair, and return the result as a new bytearray.
  630. """
  631. def ljust():
  632. """B.ljust(width[, fillchar]) -> copy of B
  633. Return B left justified in a string of length width. Padding is
  634. done using the specified fill character (default is a space).
  635. """
  636. def lower():
  637. """B.lower() -> copy of B
  638. Return a copy of B with all ASCII characters converted to lowercase.
  639. """
  640. def lstrip():
  641. """B.lstrip([bytes]) -> bytearray
  642. Strip leading bytes contained in the argument
  643. and return the result as a new bytearray.
  644. If the argument is omitted, strip leading ASCII whitespace.
  645. """
  646. def partition():
  647. """B.partition(sep) -> (head, sep, tail)
  648. Search for the separator sep in B, and return the part before it,
  649. the separator itself, and the part after it. If the separator is not
  650. found, returns B and two empty bytearray objects.
  651. """
  652. def pop():
  653. """B.pop([index]) -> int
  654. Remove and return a single item from B. If no index
  655. argument is given, will pop the last value.
  656. """
  657. def remove():
  658. """B.remove(int) -> None
  659. Remove the first occurrence of a value in B.
  660. """
  661. def replace():
  662. """B.replace(old, new[, count]) -> bytearray
  663. Return a copy of B with all occurrences of subsection
  664. old replaced by new. If the optional argument count is
  665. given, only the first count occurrences are replaced.
  666. """
  667. def reverse():
  668. """B.reverse() -> None
  669. Reverse the order of the values in B in place.
  670. """
  671. def rfind():
  672. """B.rfind(sub[, start[, end]]) -> int
  673. Return the highest index in B where subsection sub is found,
  674. such that sub is contained within B[start,end]. Optional
  675. arguments start and end are interpreted as in slice notation.
  676. Return -1 on failure.
  677. """
  678. def rindex():
  679. """B.rindex(sub[, start[, end]]) -> int
  680. Like B.rfind() but raise ValueError when the subsection is not found.
  681. """
  682. def rjust():
  683. """B.rjust(width[, fillchar]) -> copy of B
  684. Return B right justified in a string of length width. Padding is
  685. done using the specified fill character (default is a space)
  686. """
  687. def rpartition():
  688. """B.rpartition(sep) -> (head, sep, tail)
  689. Search for the separator sep in B, starting at the end of B,
  690. and return the part before it, the separator itself, and the
  691. part after it. If the separator is not found, returns two empty
  692. bytearray objects and B.
  693. """
  694. def rsplit():
  695. """B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays
  696. Return a list of the sections in B, using sep as the delimiter,
  697. starting at the end of B and working to the front.
  698. If sep is not given, B is split on ASCII whitespace characters
  699. (space, tab, return, newline, formfeed, vertical tab).
  700. If maxsplit is given, at most maxsplit splits are done.
  701. """
  702. def rstrip():
  703. """B.rstrip([bytes]) -> bytearray
  704. Strip trailing bytes contained in the argument
  705. and return the result as a new bytearray.
  706. If the argument is omitted, strip trailing ASCII whitespace.
  707. """
  708. def split():
  709. """B.split(sep=None, maxsplit=-1) -> list of bytearrays
  710. Return a list of the sections in B, using sep as the delimiter.
  711. If sep is not given, B is split on ASCII whitespace characters
  712. (space, tab, return, newline, formfeed, vertical tab).
  713. If maxsplit is given, at most maxsplit splits are done.
  714. """
  715. def splitlines():
  716. """B.splitlines(keepends=False) -> list of lines
  717. Return a list of the lines in B, breaking at line boundaries.
  718. Line breaks are not included in the resulting list unless keepends
  719. is given and true.
  720. """
  721. def startswith():
  722. """B.startswith(prefix[, start[, end]]) -> bool
  723. Return True if B starts with the specified prefix, False otherwise.
  724. With optional start, test B beginning at that position.
  725. With optional end, stop comparing B at that position.
  726. prefix can also be a tuple of strings to try.
  727. """
  728. def strip():
  729. """B.strip([bytes]) -> bytearray
  730. Strip leading and trailing bytes contained in the argument
  731. and return the result as a new bytearray.
  732. If the argument is omitted, strip ASCII whitespace.
  733. """
  734. def swapcase():
  735. """B.swapcase() -> copy of B
  736. Return a copy of B with uppercase ASCII characters converted
  737. to lowercase ASCII and vice versa.
  738. """
  739. def title():
  740. """B.title() -> copy of B
  741. Return a titlecased version of B, i.e. ASCII words start with uppercase
  742. characters, all remaining cased characters have lowercase.
  743. """
  744. def translate():
  745. """B.translate(table[, deletechars]) -> bytearray
  746. Return a copy of B, where all characters occurring in the
  747. optional argument deletechars are removed, and the remaining
  748. characters have been mapped through the given translation
  749. table, which must be a bytes object of length 256.
  750. """
  751. def upper():
  752. """B.upper() -> copy of B
  753. Return a copy of B with all ASCII characters converted to uppercase.
  754. """
  755. def zfill():
  756. """B.zfill(width) -> copy of B
  757. Pad a numeric string B with zeros on the left, to fill a field
  758. of the specified width. B is never truncated.
  759. """
  760. W_BytearrayObject.typedef = TypeDef(
  761. "bytearray", None, None, "read-write",
  762. __doc__ = BytearrayDocstrings.__doc__,
  763. __new__ = interp2app(W_BytearrayObject.descr_new),
  764. __hash__ = None,
  765. __reduce__ = interp2app(W_BytearrayObject.descr_reduce,
  766. doc=BytearrayDocstrings.__reduce__.__doc__),
  767. fromhex = interp2app(W_BytearrayObject.descr_fromhex, as_classmethod=True,
  768. doc=BytearrayDocstrings.fromhex.__doc__),
  769. __repr__ = interp2app(W_BytearrayObject.descr_repr,
  770. doc=BytearrayDocstrings.__repr__.__doc__),
  771. __str__ = interp2app(W_BytearrayObject.descr_str,
  772. doc=BytearrayDocstrings.__str__.__doc__),
  773. __eq__ = interp2app(W_BytearrayObject.descr_eq,
  774. doc=BytearrayDocstrings.__eq__.__doc__),
  775. __ne__ = interp2app(W_BytearrayObject.descr_ne,
  776. doc=BytearrayDocstrings.__ne__.__doc__),
  777. __lt__ = interp2app(W_BytearrayObject.descr_lt,
  778. doc=BytearrayDocstrings.__lt__.__doc__),
  779. __le__ = interp2app(W_BytearrayObject.descr_le,
  780. doc=BytearrayDocstrings.__le__.__doc__),
  781. __gt__ = interp2app(W_BytearrayObject.descr_gt,
  782. doc=BytearrayDocstrings.__gt__.__doc__),
  783. __ge__ = interp2app(W_BytearrayObject.descr_ge,
  784. doc=BytearrayDocstrings.__ge__.__doc__),
  785. __iter__ = interp2app(W_BytearrayObject.descr_iter,
  786. doc=BytearrayDocstrings.__iter__.__doc__),
  787. __len__ = interp2app(W_BytearrayObject.descr_len,
  788. doc=BytearrayDocstrings.__len__.__doc__),
  789. __contains__ = interp2app(W_BytearrayObject.descr_contains,
  790. doc=BytearrayDocstrings.__contains__.__doc__),
  791. __add__ = interp2app(W_BytearrayObject.descr_add,
  792. doc=BytearrayDocstrings.__add__.__doc__),
  793. __mul__ = interp2app(W_BytearrayObject.descr_mul,
  794. doc=BytearrayDocstrings.__mul__.__doc__),
  795. __rmul__ = interp2app(W_BytearrayObject.descr_mul,
  796. doc=BytearrayDocstrings.__rmul__.__doc__),
  797. __getitem__ = interp2app(W_BytearrayObject.descr_getitem,
  798. doc=BytearrayDocstrings.__getitem__.__doc__),
  799. capitalize = interp2app(W_BytearrayObject.descr_capitalize,
  800. doc=BytearrayDocstrings.capitalize.__doc__),
  801. center = interp2app(W_BytearrayObject.descr_center,
  802. doc=BytearrayDocstrings.center.__doc__),
  803. count = interp2app(W_BytearrayObject.descr_count,
  804. doc=BytearrayDocstrings.count.__doc__),
  805. decode = interp2app(W_BytearrayObject.descr_decode,
  806. doc=BytearrayDocstrings.decode.__doc__),
  807. expandtabs = interp2app(W_BytearrayObject.descr_expandtabs,
  808. doc=BytearrayDocstrings.expandtabs.__doc__),
  809. find = interp2app(W_BytearrayObject.descr_find,
  810. doc=BytearrayDocstrings.find.__doc__),
  811. rfind = interp2app(W_BytearrayObject.descr_rfind,
  812. doc=BytearrayDocstrings.rfind.__doc__),
  813. index = interp2app(W_BytearrayObject.descr_index,
  814. doc=BytearrayDocstrings.index.__doc__),
  815. rindex = interp2app(W_BytearrayObject.descr_rindex,
  816. doc=BytearrayDocstrings.rindex.__doc__),
  817. isalnum = interp2app(W_BytearrayObject.descr_isalnum,
  818. doc=BytearrayDocstrings.isalnum.__doc__),
  819. isalpha = interp2app(W_BytearrayObject.descr_isalpha,
  820. doc=BytearrayDocstrings.isalpha.__doc__),
  821. isdigit = interp2app(W_BytearrayObject.descr_isdigit,
  822. doc=BytearrayDocstrings.isdigit.__doc__),
  823. islower = interp2app(W_BytearrayObject.descr_islower,
  824. doc=BytearrayDocstrings.islower.__doc__),
  825. isspace = interp2app(W_BytearrayObject.descr_isspace,
  826. doc=BytearrayDocstrings.isspace.__doc__),
  827. istitle = interp2app(W_BytearrayObject.descr_istitle,
  828. doc=BytearrayDocstrings.istitle.__doc__),
  829. isupper = interp2app(W_BytearrayObject.descr_isupper,
  830. doc=BytearrayDocstrings.isupper.__doc__),
  831. join = interp2app(W_BytearrayObject.descr_join,
  832. doc=BytearrayDocstrings.join.__doc__),
  833. ljust = interp2app(W_BytearrayObject.descr_ljust,
  834. doc=BytearrayDocstrings.ljust.__doc__),
  835. rjust = interp2app(W_BytearrayObject.descr_rjust,
  836. doc=BytearrayDocstrings.rjust.__doc__),
  837. lower = interp2app(W_BytearrayObject.descr_lower,
  838. doc=BytearrayDocstrings.lower.__doc__),
  839. partition = interp2app(W_BytearrayObject.descr_partition,
  840. doc=BytearrayDocstrings.partition.__doc__),
  841. rpartition = interp2app(W_BytearrayObject.descr_rpartition,
  842. doc=BytearrayDocstrings.rpartition.__doc__),
  843. replace = interp2app(W_BytearrayObject.descr_replace,
  844. doc=BytearrayDocstrings.replace.__doc__),
  845. split = interp2app(W_BytearrayObject.descr_split,
  846. doc=BytearrayDocstrings.split.__doc__),
  847. rsplit = interp2app(W_BytearrayObject.descr_rsplit,
  848. doc=BytearrayDocstrings.rsplit.__doc__),
  849. splitlines = interp2app(W_BytearrayObject.descr_splitlines,
  850. doc=BytearrayDocstrings.splitlines.__doc__),
  851. startswith = interp2app(W_BytearrayObject.descr_startswith,
  852. doc=BytearrayDocstrings.startswith.__doc__),
  853. endswith = interp2app(W_BytearrayObject.descr_endswith,
  854. doc=BytearrayDocstrings.endswith.__doc__),
  855. strip = interp2app(W_BytearrayObject.descr_strip,
  856. doc=BytearrayDocstrings.strip.__doc__),
  857. lstrip = interp2app(W_BytearrayObject.descr_lstrip,
  858. doc=BytearrayDocstrings.lstrip.__doc__),
  859. rstrip = interp2app(W_BytearrayObject.descr_rstrip,
  860. doc=BytearrayDocstrings.rstrip.__doc__),
  861. swapcase = interp2app(W_BytearrayObject.descr_swapcase,
  862. doc=BytearrayDocstrings.swapcase.__doc__),
  863. title = interp2app(W_BytearrayObject.descr_title,
  864. doc=BytearrayDocstrings.title.__doc__),
  865. translate = interp2app(W_BytearrayObject.descr_translate,
  866. doc=BytearrayDocstrings.translate.__doc__),
  867. upper = interp2app(W_BytearrayObject.descr_upper,
  868. doc=BytearrayDocstrings.upper.__doc__),
  869. zfill = interp2app(W_BytearrayObject.descr_zfill,
  870. doc=BytearrayDocstrings.zfill.__doc__),
  871. __init__ = interp2app(W_BytearrayObject.descr_init,
  872. doc=BytearrayDocstrings.__init__.__doc__),
  873. __iadd__ = interp2app(W_BytearrayObject.descr_inplace_add,
  874. doc=BytearrayDocstrings.__iadd__.__doc__),
  875. __imul__ = interp2app(W_BytearrayObject.descr_inplace_mul,
  876. doc=BytearrayDocstrings.__imul__.__doc__),
  877. __setitem__ = interp2app(W_BytearrayObject.descr_setitem,
  878. doc=BytearrayDocstrings.__setitem__.__doc__),
  879. __delitem__ = interp2app(W_BytearrayObject.descr_delitem,
  880. doc=BytearrayDocstrings.__delitem__.__doc__),
  881. append = interp2app(W_BytearrayObject.descr_append,
  882. doc=BytearrayDocstrings.append.__doc__),
  883. extend = interp2app(W_BytearrayObject.descr_extend,
  884. doc=BytearrayDocstrings.extend.__doc__),
  885. insert = interp2app(W_BytearrayObject.descr_insert,
  886. doc=BytearrayDocstrings.insert.__doc__),
  887. pop = interp2app(W_BytearrayObject.descr_pop,
  888. doc=BytearrayDocstrings.pop.__doc__),
  889. remove = interp2app(W_BytearrayObject.descr_remove,
  890. doc=BytearrayDocstrings.remove.__doc__),
  891. reverse = interp2app(W_BytearrayObject.descr_reverse,
  892. doc=BytearrayDocstrings.reverse.__doc__),
  893. )
  894. W_BytearrayObject.typedef.flag_sequence_bug_compat = True
  895. # XXX share the code again with the stuff in listobject.py
  896. def _delitem_slice_helper(space, items, start, step, slicelength):
  897. if slicelength == 0:
  898. return
  899. if step < 0:
  900. start = start + step * (slicelength-1)
  901. step = -step
  902. if step == 1:
  903. assert start >= 0
  904. if slicelength > 0:
  905. del items[start:start+slicelength]
  906. else:
  907. n = len(items)
  908. i = start
  909. for discard in range(1, slicelength):
  910. j = i+1
  911. i += step
  912. while j < i:
  913. items[j-discard] = items[j]
  914. j += 1
  915. j = i+1
  916. while j < n:
  917. items[j-slicelength] = items[j]
  918. j += 1
  919. start = n - slicelength
  920. assert start >= 0 # annotator hint
  921. del items[start:]
  922. def _setitem_slice_helper(space, items, start, step, slicelength, sequence2,
  923. empty_elem):
  924. assert slicelength >= 0
  925. oldsize = len(items)
  926. len2 = len(sequence2)
  927. if step == 1: # Support list resizing for non-extended slices
  928. delta = slicelength - len2
  929. if delta < 0:
  930. delta = -delta
  931. newsize = oldsize + delta
  932. # XXX support this in rlist!
  933. items += [empty_elem] * delta
  934. lim = start+len2
  935. i = newsize - 1
  936. while i >= lim:
  937. items[i] = items[i-delta]
  938. i -= 1
  939. elif delta == 0:
  940. pass
  941. else:
  942. assert start >= 0 # start<0 is only possible with slicelength==0
  943. del items[start:start+delta]
  944. elif len2 != slicelength: # No resize for extended slices
  945. raise oefmt(space.w_ValueError,
  946. "attempt to assign sequence of size %d to extended slice "
  947. "of size %d", len2, slicelength)
  948. if sequence2 is items:
  949. if step > 0:
  950. # Always copy starting from the right to avoid
  951. # having to make a shallow copy in the case where
  952. # the source and destination lists are the same list.
  953. i = len2 - 1
  954. start += i*step
  955. while i >= 0:
  956. items[start] = sequence2[i]
  957. start -= step
  958. i -= 1
  959. return
  960. else:
  961. # Make a shallow copy to more easily handle the reversal case
  962. sequence2 = list(sequence2)
  963. for i in range(len2):
  964. items[start] = sequence2[i]
  965. start += step
  966. class BytearrayBuffer(Buffer):
  967. _immutable_ = True
  968. def __init__(self, data, readonly):
  969. self.data = data
  970. self.readonly = readonly
  971. def getlength(self):
  972. return len(self.data)
  973. def getitem(self, index):
  974. return self.data[index]
  975. def setitem(self, index, char):
  976. self.data[index] = char
  977. def getslice(self, start, stop, step, size):
  978. if size == 0:
  979. return ""
  980. if step == 1:
  981. assert 0 <= start <= stop
  982. if start == 0 and stop == len(self.data):
  983. return "".join(self.data)
  984. return "".join(self.data[start:stop])
  985. return Buffer.getslice(self, start, stop, step, size)
  986. def setslice(self, start, string):
  987. # No bounds checks.
  988. for i in range(len(string)):
  989. self.data[start + i] = string[i]
  990. def get_raw_address(self):
  991. return nonmoving_raw_ptr_for_resizable_list(self.data)
  992. @specialize.argtype(1)
  993. def _memcmp(selfvalue, buffer, length):
  994. for i in range(length):
  995. if selfvalue[i] < buffer[i]:
  996. return -1
  997. if selfvalue[i] > buffer[i]:
  998. return 1
  999. return 0