summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2013-09-28 10:07:55 -0400
committerNed Batchelder <ned@nedbatchelder.com>2013-09-28 10:07:55 -0400
commit5e5cf2d5b9d7decfce16142a7cf7cc140fcbf354 (patch)
tree42126d750637ec001e5a46046ff76100284faf0b
parentf859f95e5988d88b580afdb7771f03a8ff612411 (diff)
downloadpython-coveragepy-git-5e5cf2d5b9d7decfce16142a7cf7cc140fcbf354.tar.gz
More abstractions for bytes objects. Cleans up some version checks in the real code.
-rw-r--r--coverage/backward.py26
-rw-r--r--coverage/bytecode.py12
-rw-r--r--coverage/parser.py17
-rw-r--r--tests/test_backward.py10
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])