Commits

Travis Shirk  committed 8ca806d

More python3'ish

  • Participants
  • Parent commits cac2ed5
  • Branches stable

Comments (0)

Files changed (12)

File src/eyed3/compat.py

 
 if PY2:
     StringTypes = types.StringTypes
-    import ConfigParser as configparser
+    UnicodeType = unicode
+    BytesType = str
+    unicode = unicode
+
+    from ConfigParser import SafeConfigParser as ConfigParser
+    from ConfigParser import Error as ConfigParserError
+
     from StringIO import StringIO
 else:
     StringTypes = (str,)
-    import configparser
+    UnicodeType = str
+    BytesType = bytes
+    unicode = str
+
+    from configparser import ConfigParser
+    from configparser import Error as ConfigParserError
+
     from io import StringIO
+
+
+def toByteString(n):
+    if PY2:
+        return chr(n)
+    else:
+        return bytes((n,))
+
+
+def byteiter(bites):
+    assert(isinstance(bites, str if PY2 else bytes))
+    for b in bites:
+        yield b if PY2 else bytes((b,))

File src/eyed3/id3/frames.py

 from .. import core
 from ..utils import requireUnicode
 from ..utils.binfuncs import *
-from ..compat import StringIO
+from ..compat import StringIO, unicode, BytesType
 from .. import Error
 from . import ID3_V2, ID3_V2_3, ID3_V2_4
 from . import (LATIN1_ENCODING, UTF_8_ENCODING, UTF_16BE_ENCODING,
             lang = DEFAULT_LANG
 
         # Test it at least looks like a valid code
-        if (lang and not re.compile("[A-Z][A-Z][A-Z]",
+        if (lang and not re.compile(b"[A-Z][A-Z][A-Z]",
                                     re.IGNORECASE).match(lang)):
             log.warning("Fixing invalid lyrics language code: %s" % lang)
             lang = DEFAULT_LANG
     @property
     def text_delim(self):
         assert(self.encoding is not None)
-        return "\x00\x00" if self.encoding in (UTF_16_ENCODING,
-                                               UTF_16BE_ENCODING) else "\x00"
+        return b"\x00\x00" if self.encoding in (UTF_16_ENCODING,
+                                                UTF_16BE_ENCODING) else b"\x00"
 
     def _initEncoding(self):
         assert(self.header.version and len(self.header.version) == 3)
 
     def render(self):
         self._initEncoding()
-        self.data = b"%s%s" % \
-                    (self.encoding,
+        self.data = (self.encoding +
                      self.text.encode(id3EncodingToString(self.encoding)))
+        assert(type(self.data) == BytesType)
         return super(TextFrame, self).render()
 
 
         self.mime_type = ""
         if frame_header.minor_version != 2:
             ch = input.read(1)
-            while ch and ch != "\x00":
+            while ch and ch != b"\x00":
                 self.mime_type += ch
                 ch = input.read(1)
         else:
         if not self.image_data and self.image_url:
             self.mime_type = self.URL_MIME_TYPE
 
-        data = (self.encoding + self.mime_type + "\x00" +
+        data = (self.encoding + self.mime_type + b"\x00" +
                 bin2bytes(dec2bin(self.picture_type, 8)) +
                 self.description.encode(id3EncodingToString(self.encoding)) +
                 self.text_delim)
         self.mime_type = ""
         if self.header.minor_version != 2:
             ch = input.read(1)
-            while ch != "\x00":
+            while ch != b"\x00":
                 self.mime_type += ch
                 ch = input.read(1)
         else:
 
     def render(self):
         self._initEncoding()
-        data = (self.encoding + self.mime_type + "\x00" +
+        data = (self.encoding + self.mime_type + b"\x00" +
                 self.filename.encode(id3EncodingToString(self.encoding)) +
                 self.text_delim +
                 self.description.encode(id3EncodingToString(self.encoding)) +
 
 
     def render(self):
-        self.data = self.owner_id + "\x00" + self.owner_data
+        self.data = self.owner_id + b"\x00" + self.owner_data
         return super(PrivateFrame, self).render()
 
 
                                            "long: %s" % self.uniq_id))
 
     def render(self):
-        self.data = self.owner_id + "\x00" + self.uniq_id
+        self.data = self.owner_id + b"\x00" + self.uniq_id
         return super(UniqueFileIDFrame, self).render()
 
 
         super(DescriptionLangTextFrame, self).parse(data, frame_header)
 
         self.encoding = encoding = self.data[0]
-        self.lang = Frame._processLang(self.data[1:4].strip("\x00"))
+        self.lang = Frame._processLang(self.data[1:4].strip(b"\x00"))
         log.debug("%s lang: %s" % (self.id, self.lang))
 
         try:
         super(TermsOfUseFrame, self).parse(data, frame_header)
 
         self.encoding = encoding = self.data[0]
-        self.lang = Frame._processLang(self.data[1:4].strip("\x00"))
+        self.lang = Frame._processLang(self.data[1:4]).strip(b"\x00")
         log.debug("%s lang: %s" % (self.id, self.lang))
         self.text = decodeUnicode(self.data[4:], encoding)
         log.debug("%s text: %s" % (self.id, self.text))
 
         # Any data remaining must be a TIT2 frame
         self.description = None
-        if data and data[:4] != "TIT2":
+        if data and data[:4] != b"TIT2":
             log.warning("Invalid toc data, TIT2 frame expected")
             return
         elif data:
     return frame
 
 
-def decodeUnicode(bytes, encoding):
+def decodeUnicode(bites, encoding):
     codec = id3EncodingToString(encoding)
     log.debug("Unicode encoding: %s" % codec)
-    return unicode(bytes, codec).rstrip("\x00")
+    return unicode(bites, codec).rstrip(b"\x00")
 
 
 def splitUnicode(data, encoding):
     try:
         if encoding == LATIN1_ENCODING or encoding == UTF_8_ENCODING:
-            (d, t) = data.split("\x00", 1)
+            (d, t) = data.split(b"\x00", 1)
         elif encoding == UTF_16_ENCODING or encoding == UTF_16BE_ENCODING:
             # Two null bytes split, but since each utf16 char is also two
             # bytes we need to ensure we found a proper boundary.
-            (d, t) = data.split("\x00\x00", 1)
+            (d, t) = data.split(b"\x00\x00", 1)
             if (len(d) % 2) != 0:
-                (d, t) = data.split("\x00\x00\x00", 1)
-                d += "\x00"
+                (d, t) = data.split(b"\x00\x00\x00", 1)
+                d += b"\x00"
     except ValueError as ex:
         log.warning("Invalid 2-tuple ID3 frame data: %s", ex)
         d, t = data, b""

File src/eyed3/id3/headers.py

             if self.update_bit:
                 data += b"\x00"
             if self.crc_bit:
-                data += "\x05"
+                data += b"\x05"
                 # XXX: Using the absolute value of the CRC. The spec is unclear
                 # about the type of this data.
                 self.crc = int(math.fabs(binascii.crc32(frame_data +
-                                                        ("\x00" * padding))))
+                                                        (b"\x00" * padding))))
                 crc_data = self._syncsafeCRC()
                 if len(crc_data) < 5:
                     # pad if necessary
-                    crc_data = ("\x00" * (5 - len(crc_data))) + crc_data
+                    crc_data = (b"\x00" * (5 - len(crc_data))) + crc_data
                 assert(len(crc_data) == 5)
                 data += crc_data
             if self.restrictions_bit:
-                data += "\x01"
+                data += b"\x01"
                 data += chr(self._restrictions)
             log.debug("Rendered extended header data (%d bytes)" % len(data))
 
             size = bin2bytes(bin2synchsafe(dec2bin(len(data) + 6, 32)))
             assert(len(size) == 4)
 
-            data = size + "\x01" + bin2bytes(dec2bin(self._flags)) + data
+            data = size + b"\x01" + bin2bytes(dec2bin(self._flags)) + data
             log.debug("Rendered extended header of size %d" % len(data))
         else:
             # Version 2.3
                 # XXX: Using the absolute value of the CRC.  The spec is unclear
                 # about the type of this value.
                 self.crc = int(math.fabs(binascii.crc32(frame_data +
-                                                        ("\x00" * padding))))
+                                                        (b"\x00" * padding))))
                 crc = bin2bytes(dec2bin(self.crc))
                 assert(len(crc) == 4)
                 size += 4
                              " is not supported.")
 
     def render(self, data_size):
-        data = bytes(self.id)
+        from ..compat import BytesType
+        if type(self.id) is BytesType:
+            data = self.id
+        else:
+            data = self.id.encode("ascii")
+
         self.data_size = data_size
 
         if self.minor_version == 3:

File src/eyed3/main.py

 ################################################################################
 from __future__ import print_function
 import sys
-import exceptions
 import os.path
 import textwrap
 import eyed3
 import eyed3.utils.cli
 import eyed3.plugins
 import eyed3.info
-from eyed3.compat import configparser, StringIO
+from eyed3.compat import ConfigParser, ConfigParserError, StringIO
 
 
 DEFAULT_PLUGIN = "classic"
 
     if os.path.isfile(config_file):
         try:
-            config = configparser.SafeConfigParser()
+            config = ConfigParser()
             config.read(config_file)
-        except configparser.Error as ex:
+        except ConfigParserError as ex:
             eyed3.log.warning("User config error: " + str(ex))
             return None
     elif config_file != DEFAULT_CONFIG:
         retval = 0
     except IOError as ex:
         eyed3.utils.cli.printError(ex)
-    except exceptions.Exception as ex:
+    except Exception as ex:
         eyed3.utils.cli.printError("Uncaught exception: %s\n" % str(ex))
         eyed3.log.exception(ex)
 

File src/eyed3/plugins/__init__.py

 #
 ################################################################################
 from __future__ import print_function
-import os, sys, logging, exceptions, types
+import os, sys, logging, types
 
 try:
     from collections import OrderedDict
                     log.warning("Plugin '%s' requires packages that are not "
                                 "installed: %s" % ((f, d), ex))
                     continue
-                except exceptions.Exception as ex:
+                except Exception as ex:
                     log.exception("Bad plugin '%s'", (f, d))
                     continue
 

File src/eyed3/plugins/classic.py

 ################################################################################
 from __future__ import print_function
 
-import os, stat, exceptions, re
+import os, stat, re
 from argparse import ArgumentTypeError
 from eyed3 import LOCAL_ENCODING
 from eyed3.plugins import LoaderPlugin

File src/eyed3/utils/__init__.py

 from __future__ import print_function
 import os
 import re
+from ..compat import unicode
 
 ID3_MIME_TYPE = "application/x-id3"
 ID3_MIME_TYPE_EXTENSIONS = (".id3", ".tag")

File src/eyed3/utils/binfuncs.py

 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 ################################################################################
-
+from ..compat import toByteString, BytesType, byteiter
 
 def bytes2bin(bytes, sz=8):
     '''Accepts a string of ``bytes`` (chars) and returns an array of bits
     '''
 
     retVal = []
-    for b in bytes:
+    for b in byteiter(bytes):
         bits = []
         b = ord(b)
         while b > 0:
     bits.reverse()
 
     i = 0
-    out = ''
+    out = b''
     multi = 1
     ttl = 0
     for b in bits:
         multi *= 2
         if i == 8:
             i = 0
-            out += chr(ttl)
+            out += toByteString(ttl)
             multi = 1
             ttl = 0
 
     if multi > 1:
-        out += chr(ttl)
+        out += toByteString(ttl)
 
-    out = list(out)
+    out = bytearray(out)
     out.reverse()
-    out = ''.join(out)
+    out = BytesType(out)
     return out
 
 
     elif len(x) < 8:
         return x
 
-    bites = ""
-    bites += chr((n >> 21) & 0x7f)
-    bites += chr((n >> 14) & 0x7f)
-    bites += chr((n >>  7) & 0x7f)
-    bites += chr((n >>  0) & 0x7f)
+    bites = b""
+    bites += toByteString((n >> 21) & 0x7f)
+    bites += toByteString((n >> 14) & 0x7f)
+    bites += toByteString((n >>  7) & 0x7f)
+    bites += toByteString((n >>  0) & 0x7f)
     bits = bytes2bin(bites)
     assert(len(bits) == 32)
 
     return bits
 
+'''
+XXX: appears unused. Needs porting to python3
+'''
 def bytes2str(bites):
-    s = bytes("")
-    for b in bites:
+    s = ""
+    for b in byteiter(bites):
         s += ("\\x%02x" % ord(b))
     return s
-
-

File src/test/id3/test_frames.py

                        UTF_16BE_ENCODING)
 from eyed3.id3 import ID3_V1_0, ID3_V1_1, ID3_V2_2, ID3_V2_3, ID3_V2_4
 from eyed3.id3.frames import *
+from eyed3.compat import unicode
 from ..compat import *
 
 

File src/test/id3/test_id3.py

 import unittest
 from nose.tools import *
 from eyed3.id3 import *
+from eyed3.compat import unicode
 
 class GenreTests(unittest.TestCase):
     def testEmptyGenre(self):

File src/test/id3/test_tag.py

 from eyed3.core import Date
 from eyed3.id3 import Tag, ID3_DEFAULT_VERSION, ID3_V2_3, ID3_V2_4
 from eyed3.id3 import frames
+from eyed3.compat import unicode
 from ..compat import *
 from .. import ExternalDataTestCase, DATA_D
 

File src/test/test_binfuncs.py

 def test_bytes2bin():
     # test ones and zeros, sz==8
     for i in range(1, 11):
-        zeros = bytes2bin(bytes("\x00") * i)
-        ones = bytes2bin(bytes("\xFF") * i)
+        zeros = bytes2bin(b"\x00" * i)
+        ones = bytes2bin(b"\xFF" * i)
         assert_true(len(zeros) == (8 * i) and len(zeros) == len(ones))
         for i in range(len(zeros)):
             assert_true(zeros[i] == 0)
             assert_true(ones[i] == 1)
 
     # test 'sz' bounds checking
-    assert_raises(ValueError, bytes2bin, bytes("a"), -1)
-    assert_raises(ValueError, bytes2bin, bytes("a"), 0)
-    assert_raises(ValueError, bytes2bin, bytes("a"), 9)
+    assert_raises(ValueError, bytes2bin, b"a", -1)
+    assert_raises(ValueError, bytes2bin, b"a", 0)
+    assert_raises(ValueError, bytes2bin, b"a", 9)
 
     # Test 'sz'
     for sz in range(1, 9):
-        res = bytes2bin(bytes("\x00\xFF"), sz=sz)
+        res = bytes2bin(b"\x00\xFF", sz=sz)
         assert_true(len(res) == 2 * sz)
         assert_true(res[:sz] == [0] * sz)
         assert_true(res[sz:] == [1] * sz)
     assert_equal(bin2dec([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]), 2730)
 
 def test_bytes2dec():
-    assert_equal(bytes2dec(bytes("\x00\x11\x22\x33")), 1122867)
+    assert_equal(bytes2dec(b"\x00\x11\x22\x33"), 1122867)
 
 def test_dec2bin():
     assert_equal(dec2bin(3036790792), [1, 0, 1, 1, 0, 1, 0, 1,
     assert_equal(dec2bin(1, p=8), [0, 0, 0, 0, 0, 0, 0, 1])
 
 def test_dec2bytes():
-    assert_equal(dec2bytes(ord("a")), "\x61")
+    assert_equal(dec2bytes(ord(b"a")), b"\x61")
 
 def test_bin2syncsafe():
-    assert_raises(ValueError, bin2synchsafe, bytes2bin("\xff\xff\xff\xff"))
+    assert_raises(ValueError, bin2synchsafe, bytes2bin(b"\xff\xff\xff\xff"))
     assert_raises(ValueError, bin2synchsafe, [0] * 33)
     assert_equal(bin2synchsafe([1] * 7), [1] * 7)
     assert_equal(bin2synchsafe(dec2bin(255)), [0, 0, 0, 0, 0, 0, 0, 0,
                                                0, 0, 0, 0, 0, 0, 0, 0,
                                                0, 0, 0, 0, 0, 0, 0, 1,
                                                0, 1, 1, 1, 1, 1, 1, 1])
-
-def test_bytes2str():
-    assert_equal(bytes2str("\xfe"), "\\xfe")