diff options
Diffstat (limited to 'coverage/backward.py')
-rw-r--r-- | coverage/backward.py | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/coverage/backward.py b/coverage/backward.py index 425bcc6e..6347501a 100644 --- a/coverage/backward.py +++ b/coverage/backward.py @@ -1,12 +1,12 @@ """Add things to old Pythons so I can pretend they are newer.""" # This file does lots of tricky stuff, so disable a bunch of lintisms. -# pylint: disable-msg=F0401,W0611,W0622 +# pylint: disable=F0401,W0611,W0622 # F0401: Unable to import blah # W0611: Unused import blah # W0622: Redefining built-in blah -import os, sys +import os, re, sys # Python 2.3 doesn't have `set` try: @@ -49,6 +49,16 @@ try: except NameError: range = range +# A function to iterate listlessly over a dict's items. +if "iteritems" in dir({}): + def iitems(d): + """Produce the items from dict `d`.""" + return d.iteritems() +else: + def iitems(d): + """Produce the items from dict `d`.""" + return d.items() + # Exec is a statement in Py2, a function in Py3 if sys.version_info >= (3, 0): def exec_code_object(code, global_map): @@ -66,8 +76,56 @@ else: ) ) -# ConfigParser was renamed to the more-standard configparser +# Reading Python source and interpreting the coding comment is a big deal. +if sys.version_info >= (3, 0): + # Python 3.2 provides `tokenize.open`, the best way to open source files. + import tokenize + try: + open_source = tokenize.open # pylint: disable=E1101 + except AttributeError: + from io import TextIOWrapper + detect_encoding = tokenize.detect_encoding # pylint: disable=E1101 + # Copied from the 3.2 stdlib: + def open_source(fname): + """Open a file in read only mode using the encoding detected by + detect_encoding(). + """ + buffer = open(fname, 'rb') + encoding, _ = detect_encoding(buffer.readline) + buffer.seek(0) + text = TextIOWrapper(buffer, encoding, line_buffering=True) + text.mode = 'r' + return text +else: + def open_source(fname): + """Open a source file the best way.""" + return open(fname, "rU") + + +# Python 3.x is picky about bytes and strings, so provide methods to +# get them right, and make them no-ops in 2.x +if sys.version_info >= (3, 0): + def to_bytes(s): + """Convert string `s` to bytes.""" + return s.encode('utf8') + + def to_string(b): + """Convert bytes `b` to a string.""" + return b.decode('utf8') + +else: + def to_bytes(s): + """Convert string `s` to bytes (no-op in 2.x).""" + return s + + def to_string(b): + """Convert bytes `b` to a string (no-op in 2.x).""" + return b + +# Md5 is available in different places. try: - import configparser + import hashlib + md5 = hashlib.md5 except ImportError: - import ConfigParser as configparser + import md5 + md5 = md5.new |