diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2013-09-28 10:07:55 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2013-09-28 10:07:55 -0400 |
commit | 5e5cf2d5b9d7decfce16142a7cf7cc140fcbf354 (patch) | |
tree | 42126d750637ec001e5a46046ff76100284faf0b | |
parent | f859f95e5988d88b580afdb7771f03a8ff612411 (diff) | |
download | python-coveragepy-git-5e5cf2d5b9d7decfce16142a7cf7cc140fcbf354.tar.gz |
More abstractions for bytes objects. Cleans up some version checks in the real code.
-rw-r--r-- | coverage/backward.py | 26 | ||||
-rw-r--r-- | coverage/bytecode.py | 12 | ||||
-rw-r--r-- | coverage/parser.py | 17 | ||||
-rw-r--r-- | tests/test_backward.py | 10 |
4 files changed, 42 insertions, 23 deletions
diff --git a/coverage/backward.py b/coverage/backward.py index 4894bac0..e782284a 100644 --- a/coverage/backward.py +++ b/coverage/backward.py @@ -140,6 +140,19 @@ if sys.version_info >= (3, 0): """Convert bytes `b` to a string.""" return b.decode('utf8') + def binary_bytes(byte_values): + """Produce a byte string with the ints from `byte_values`.""" + return bytes(byte_values) + + def byte_to_int(byte_value): + """Turn an element of a bytes object into an int.""" + return byte_value + + def bytes_to_ints(bytes_value): + """Turn a bytes object into a sequence of ints.""" + # In Py3, iterating bytes gives ints. + return bytes_value + else: def to_bytes(s): """Convert string `s` to bytes (no-op in 2.x).""" @@ -149,6 +162,19 @@ else: """Convert bytes `b` to a string (no-op in 2.x).""" return b + def binary_bytes(byte_values): + """Produce a byte string with the ints from `byte_values`.""" + return "".join(chr(b) for b in byte_values) + + def byte_to_int(byte_value): + """Turn an element of a bytes object into an int.""" + return ord(byte_value) + + def bytes_to_ints(bytes_value): + """Turn a bytes object into a sequence of ints.""" + for byte in bytes_value: + yield ord(byte) + # Md5 is available in different places. try: import hashlib diff --git a/coverage/bytecode.py b/coverage/bytecode.py index 06bc1dfd..85360638 100644 --- a/coverage/bytecode.py +++ b/coverage/bytecode.py @@ -1,6 +1,8 @@ """Bytecode manipulation for coverage.py""" -import opcode, sys, types +import opcode, types + +from coverage.backward import byte_to_int class ByteCode(object): """A single bytecode.""" @@ -31,12 +33,8 @@ class ByteCodes(object): def __init__(self, code): self.code = code - if sys.version_info >= (3, 0): - def __getitem__(self, i): - return self.code[i] - else: - def __getitem__(self, i): - return ord(self.code[i]) + def __getitem__(self, i): + return byte_to_int(self.code[i]) def __iter__(self): offset = 0 diff --git a/coverage/parser.py b/coverage/parser.py index 2d777a5d..d531d128 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -5,6 +5,7 @@ import dis, re, sys, token, tokenize from coverage.backward import set, sorted, StringIO # pylint: disable=W0622 from coverage.backward import open_source, range # pylint: disable=W0622 from coverage.backward import reversed # pylint: disable=W0622 +from coverage.backward import bytes_to_ints from coverage.bytecode import ByteCodes, CodeObjects from coverage.misc import nice_pair, expensive, join_regex from coverage.misc import CoverageException, NoSource, NotPython @@ -367,18 +368,6 @@ class ByteParser(object): children = CodeObjects(self.code) return [ByteParser(code=c, text=self.text) for c in children] - # Getting numbers from the lnotab value changed in Py3.0. - if sys.version_info >= (3, 0): - def _lnotab_increments(self, lnotab): - """Produce ints from the lnotab bytes in 3.x""" - # co_lnotab is a bytes object, which iterates as ints. - return lnotab - else: - def _lnotab_increments(self, lnotab): - """Produce ints from the lnotab string in 2.x""" - for c in lnotab: - yield ord(c) - def _bytes_lines(self): """Map byte offsets to line numbers in `code`. @@ -390,8 +379,8 @@ class ByteParser(object): """ # Adapted from dis.py in the standard library. - byte_increments = self._lnotab_increments(self.code.co_lnotab[0::2]) - line_increments = self._lnotab_increments(self.code.co_lnotab[1::2]) + byte_increments = bytes_to_ints(self.code.co_lnotab[0::2]) + line_increments = bytes_to_ints(self.code.co_lnotab[1::2]) last_line_num = None line_num = self.code.co_firstlineno diff --git a/tests/test_backward.py b/tests/test_backward.py index 63ee20d0..e98017ae 100644 --- a/tests/test_backward.py +++ b/tests/test_backward.py @@ -1,7 +1,6 @@ -# -*- coding: utf-8 -*- """Tests that our version shims in backward.py are working.""" -from coverage.backward import iitems +from coverage.backward import iitems, binary_bytes, byte_to_int, bytes_to_ints from tests.backunittest import TestCase @@ -14,3 +13,10 @@ class BackwardTest(TestCase): d = {'a': 1, 'b': 2, 'c': 3} items = [('a', 1), ('b', 2), ('c', 3)] self.assertSameElements(list(iitems(d)), items) + + def test_binary_bytes(self): + byte_values = [0, 255, 17, 23, 42, 57] + bb = binary_bytes(byte_values) + self.assertEqual(len(bb), len(byte_values)) + self.assertEqual(byte_values, list(bytes_to_ints(bb))) + self.assertEqual(byte_values, [byte_to_int(b) for b in bb]) |