Make Package._metadata_exception() use unicode format strings in order
authorZac Medico <zmedico@gentoo.org>
Wed, 15 Sep 2010 05:22:15 +0000 (22:22 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 15 Sep 2010 05:22:15 +0000 (22:22 -0700)
to avoid UnicodeDecodeError in python-2.x.

This issue was reported in forum thread
http://forums.gentoo.org/viewtopic-t-844623.html where the following
traceback was posted:

  File "/usr/lib/portage/pym/_emerge/FakeVartree.py", line 195, in _pkg
    type_name="installed")
  File "/usr/lib/portage/pym/_emerge/Package.py", line 64, in __init__
    self._validate_deps()
  File "/usr/lib/portage/pym/_emerge/Package.py", line 93, in _validate_deps
    self._metadata_exception(k, e)
  File "/usr/lib/portage/pym/_emerge/Package.py", line 242, in _metadata_exception
    "%s: %s in '%s'" % (k, e, path))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 22: ordinal not in range(128)

pym/_emerge/Package.py

index cb14062ac5e40a72d3bcd42fc2abd058b93dca66..61a976530fab6a4e88b029292c04fdbbbb92a76e 100644 (file)
@@ -4,6 +4,7 @@
 import sys
 from itertools import chain
 import portage
+from portage import _unicode_decode
 from portage.cache.mappings import slot_dict_class
 from portage.const import EBUILD_PHASES
 from portage.dep import Atom, check_required_use, use_reduce, \
@@ -221,6 +222,16 @@ class Package(Task):
                return True
 
        def _metadata_exception(self, k, e):
+
+               # For unicode safety with python-2.x we need to avoid
+               # using the string format operator with a non-unicode
+               # format string, since that will result in the
+               # PortageException.__str__() method being invoked,
+               # followed by unsafe decoding that may result in a
+               # UnicodeDecodeError. Therefore, use _unicode_decode()
+               # to ensure that format strings are unicode, so that
+               # PortageException.__unicode__() is used when necessary
+               # in python-2.x.
                if not self.installed:
                        categorized_error = False
                        if e.errors:
@@ -229,11 +240,11 @@ class Package(Task):
                                                continue
                                        categorized_error = True
                                        self._invalid_metadata(error.category,
-                                               "%s: %s" % (k, error))
+                                               _unicode_decode("%s: %s") % (k, error))
 
                        if not categorized_error:
                                self._invalid_metadata(k + ".syntax",
-                                       "%s: %s" % (k, e))
+                                       _unicode_decode("%s: %s") % (k, e))
                else:
                        # For installed packages, show the path of the file
                        # containing the invalid metadata, since the user may
@@ -241,7 +252,7 @@ class Package(Task):
                        vardb = self.root_config.trees['vartree'].dbapi
                        path = vardb.getpath(self.cpv, filename=k)
                        self._invalid_metadata(k + ".syntax",
-                               "%s: %s in '%s'" % (k, e, path))
+                               _unicode_decode("%s: %s in '%s'") % (k, e, path))
 
        def _invalid_metadata(self, msg_type, msg):
                if self.invalid is None: