Commit ada63e45 authored by Sébastien Luttringer's avatar Sébastien Luttringer
Browse files

string interpolation must be done in unicode

If we have to format (aka interpolatation) we need to be sure this have to be
done in unicode and not in ascii. This avoid unicode error with ascii string
encoded in utf-8.

Example of failure between a string and an object

b = Exception(u"é")
Exception("error: %s" % b)
 => Exception("error: %s" % str(b)
 => UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)
parent 675484b6
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -71,11 +71,11 @@ def get_images(patterns, repoman, local=True, min=None, max=None):
            ans += sorted(repoman.select_images([pattern]).items())
    # check selected images cound
    if min is not None and len(ans) < min:
        raise Exception("%s images found. Should be at least %s" % (
        raise Exception(u"%s images found. Should be at least %s" % (
                len(ans), min))
    # check max selected images
    if max is not None and  len(ans) > max:
        raise Exception("Too many selected images: %s. Max is %s" % (
        raise Exception(u"Too many selected images: %s. Max is %s" % (
                ", ".join([n[0] for n in ans]), max))
    for item in ans:
        if item[1] is None:
@@ -112,7 +112,7 @@ def c_build(args):
    # compute building time
    t1 = time.time()
    dt = int(t1 - t0)
    arrow("Build time: %s" % datetime.timedelta(seconds=dt))
    arrow(u"Build time: %s" % datetime.timedelta(seconds=dt))

def c_cat(args):
    '''
@@ -164,8 +164,8 @@ def c_copy(args):
    if not args.force:
        out("You will copy the following images:")
        for img, repo in todo:
            out("  %s/%s:%s" % (repo.config.name, img.name, img.version))
        out("Inside repository: #l##b#%s#R#" % dstrepo.config.name)
            out(u"  %s/%s:%s" % (repo.config.name, img.name, img.version))
        out(u"Inside repository: #l##b#%s#R#" % dstrepo.config.name)
        if not confirm():
            raise Exception("Aborted!")
    # copy it for real
@@ -192,7 +192,7 @@ def c_del(args):
    if not args.force:
        out("You will remove the following images:")
        for img, repo in todo:
            out("  %s/%s:%s" % (repo.config.name, img.name, img.version))
            out(u"  %s/%s:%s" % (repo.config.name, img.name, img.version))
        if not confirm():
            raise Exception("Aborted!")
    # delete it for real
@@ -272,7 +272,7 @@ def c_install(args):
    repoman = load_repositories(args)
    image, repo = next(get_images([args.pattern], repoman, min=1, max=1))
    # Print setup information
    arrow("Installing %s v%s" % (image.name, image.version))
    arrow(u"Installing %s v%s" % (image.name, image.version))
    # install start time
    t0 = time.time()
    # run parser scripts with parser parser argument
@@ -286,7 +286,7 @@ def c_install(args):
        # compute building time
        t1 = time.time()
        dt = int(t1 - t0)
        arrow("Install time: %s" % datetime.timedelta(seconds=dt))
        arrow(u"Install time: %s" % datetime.timedelta(seconds=dt))

def c_list(args):
    '''
@@ -318,8 +318,8 @@ def c_move(args):
    if not args.force:
        out("You will copy and remove the following images:")
        for img, repo in todo:
            out("  %s/%s:%s" % (repo.config.name, img.name, img.version))
        out("Inside repository: #l##b#%s#R#" % dstrepo.config.name)
            out(u"  %s/%s:%s" % (repo.config.name, img.name, img.version))
        out(u"Inside repository: #l##b#%s#R#" % dstrepo.config.name)
        if not confirm():
            raise Exception("Aborted!")
    # move it for real
@@ -679,7 +679,7 @@ def main():
                    proc.nice = options.nice
                    debug("Setting nice to %d" % options.nice)
                except Exception:
                    warn("Unable to nice process to %s" % options.nice)
                    warn(u"Unable to nice process to %s" % options.nice)
            if options.ionice_class is not None:
                try:
                    ioclassmap = {
@@ -688,10 +688,10 @@ def main():
                        "be": psutil.IOPRIO_CLASS_BE,
                        "idle": psutil.IOPRIO_CLASS_IDLE}
                    proc.set_ionice(ioclassmap[options.ionice_class], options.ionice_level)
                    debug("Setting ionice to class %s, level %s" %
                    debug(u"Setting ionice to class %s, level %s" %
                          (options.ionice_class, options.ionice_level))
                except Exception:
                    warn("Unable to ionice process to %s" % options.ionice_class)
                    warn(u"Unable to ionice process to %s" % options.ionice_class)
        # set timeout option
        if options.timeout is not None:
            socket.setdefaulttimeout(options.timeout)
+9 −9
Original line number Diff line number Diff line
@@ -41,8 +41,8 @@ class ConfigFile(object):
        '''
        Return path of the best config file
        '''
        for cf in [ os.path.join(os.path.expanduser("~/.config/installsystems/%s.conf" % name)),
                    "/etc/installsystems/%s.conf" % name ]:
        for cf in [ os.path.join(os.path.expanduser(u"~/.config/installsystems/%s.conf" % name)),
                    u"/etc/installsystems/%s.conf" % name ]:
            if (os.path.isfile(cf) and os.access(cf, os.R_OK)):
                return cf
        return None
@@ -82,7 +82,7 @@ class MainConfigFile(ConfigFile):
        if self.path is None:
            debug("No main config file to load")
            return
        debug("Loading main config file: %s" % self.path)
        debug(u"Loading main config file: %s" % self.path)
        try:
            cp = RawConfigParser()
            cp.read(self.path)
@@ -90,7 +90,7 @@ class MainConfigFile(ConfigFile):
            if cp.has_section(self.prefix):
                self._config.update(cp.items(self.prefix))
        except Exception as e:
            raise Exception("Unable load main config file %s: %s" % (self.path, e))
            raise Exception(u"Unable load main config file %s: %s" % (self.path, e))

    def parse(self, namespace=None):
        '''
@@ -101,11 +101,11 @@ class MainConfigFile(ConfigFile):
        for option, value in self._config.items():
            # check option is valid
            if option not in self.valid_options.keys():
                warn("Invalid option %s in %s, skipped" % (option, self.path))
                warn(u"Invalid option %s in %s, skipped" % (option, self.path))
                continue
            # we expect a string like
            if not isinstance(option, basestring):
                raise TypeError("Invalid config parser option %s type" % option)
                raise TypeError(u"Invalid config parser option %s type" % option)
            # smartly cast option's value
            if self.valid_options[option] is bool:
                value = value.strip().lower() not in ("false", "no", "0", "")
@@ -170,7 +170,7 @@ class MainConfigFile(ConfigFile):
                    os.mkdir(di)
                    break
                except Exception as e:
                    debug("Unable to create %s: %s" % (di, e))
                    debug(u"Unable to create %s: %s" % (di, e))
        return self._cache_path()


@@ -190,7 +190,7 @@ class RepoConfigFile(ConfigFile):
        if self.path is None:
            return
        # loading config file if exists
        debug("Loading repository config file: %s" % self.path)
        debug(u"Loading repository config file: %s" % self.path)
        try:
            cp = RawConfigParser()
            cp.readfp(codecs.open(self.path, "r", "utf8"))
@@ -202,7 +202,7 @@ class RepoConfigFile(ConfigFile):
                # get all options in repo
                self._repos.append(RepositoryConfig(rep, **dict(cp.items(rep))))
        except Exception as e:
            raise Exception("Unable to load repository file %s: %s" % (self.path, e))
            raise Exception(u"Unable to load repository file %s: %s" % (self.path, e))

    @property
    def repos(self):
+3 −3
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ class Database(object):
            conn.commit()
            conn.close()
        except Exception as e:
            raise Exception("Create database failed: %s" % e)
            raise Exception(u"Create database failed: %s" % e)
        return cls(path)

    def __init__(self, path):
@@ -57,13 +57,13 @@ class Database(object):
            self.version = 1.0
        # we only support database v1
        if self.version >= 2.0:
            debug("Invalid database format: %s" % self.version)
            debug(u"Invalid database format: %s" % self.version)
            raise Exception("Invalid database format")
        # we make a query to be sure format is valid
        try:
            self.ask("SELECT * FROM image")
        except:
            debug("Invalid database format: %s" % self.version)
            debug(u"Invalid database format: %s" % self.version)
            raise Exception("Invalid database format")

    def begin(self):
+107 −107

File changed.

Preview size limit exceeded, changes collapsed.

+10 −10
Original line number Diff line number Diff line
@@ -71,29 +71,29 @@ def err(message, fd=sys.stderr, endl=os.linesep):
    out(message, fd, endl)

def fatal(message, quit=True, fd=sys.stderr, endl=os.linesep):
    out("#light##red#Fatal:#reset# #red#%s#reset#" % message, fd, endl)
    out(u"#light##red#Fatal:#reset# #red#%s#reset#" % message, fd, endl)
    if sys.exc_info()[0] is not None and installsystems.verbosity > 1:
        raise
    if quit:
        os._exit(21)

def error(message, quit=True, fd=sys.stderr, endl=os.linesep):
    out("#light##red#Error:#reset# #red#%s#reset#" % message, fd, endl)
    out(u"#light##red#Error:#reset# #red#%s#reset#" % message, fd, endl)
    if sys.exc_info()[0] is not None and installsystems.verbosity > 1:
        raise
    if quit:
        exit(42)

def warn(message, fd=sys.stderr, endl=os.linesep):
    out("#light##yellow#Warning:#reset# #yellow#%s#reset#" % message, fd, endl)
    out(u"#light##yellow#Warning:#reset# #yellow#%s#reset#" % message, fd, endl)

def info(message, fd=sys.stderr, endl=os.linesep):
    if installsystems.verbosity > 0:
        out("#light#Info:#reset# %s" % message, fd, endl)
        out(u"#light#Info:#reset# %s" % message, fd, endl)

def debug(message, fd=sys.stderr, endl=os.linesep):
    if installsystems.verbosity > 1:
        out("#light##black#%s#reset#" % message, fd, endl)
        out(u"#light##black#%s#reset#" % message, fd, endl)

def arrowlevel(inc=None, level=None):
    global _arrow_level
@@ -110,13 +110,13 @@ def arrow(message, inclevel=None, level=None, fd=sys.stdout, endl=os.linesep):
    # define new level
    old_level = arrowlevel(inc=inclevel, level=level)
    if _arrow_level == 1:
        out("#light##red#=>#reset# %s" % message, fd=fd, endl=endl)
        out(u"#light##red#=>#reset# %s" % message, fd=fd, endl=endl)
    elif _arrow_level == 2:
        out(" #light##yellow#=>#reset# %s" % message, fd=fd, endl=endl)
        out(u" #light##yellow#=>#reset# %s" % message, fd=fd, endl=endl)
    elif _arrow_level == 3:
        out("  #light##blue#=>#reset# %s" % message, fd=fd, endl=endl)
        out(u"  #light##blue#=>#reset# %s" % message, fd=fd, endl=endl)
    elif _arrow_level == 4:
        out("   #light##green#=>#reset# %s" % message, fd=fd, endl=endl)
        out(u"   #light##green#=>#reset# %s" % message, fd=fd, endl=endl)
    # restore old on one shot level
    arrowlevel(level = old_level)

@@ -134,5 +134,5 @@ def confirm(message=None, ans=None, fd=sys.stdout, endl=""):
    if ans is None:
        ans = "yes"
    if message is None:
        message = "#u##l##w#Are you sure?#R# (%s) " % ans
        message = u"#u##l##w#Are you sure?#R# (%s) " % ans
    return ask(message, fd, endl) == ans
Loading