diff options
| author | Matt Odden <mrodden@us.ibm.com> | 2013-06-24 07:15:28 +0000 |
|---|---|---|
| committer | Matt Odden <mrodden@us.ibm.com> | 2013-07-16 07:11:31 +0000 |
| commit | 79ee3672d46ea324d5c1fca6e9f97876e3c267f2 (patch) | |
| tree | 1a9306b1b383afb2a7b203f5b1735a3d64997d0e /openstack | |
| parent | ba32f8ecb33403885ea521e3c2dcc4b49a81bd71 (diff) | |
| download | oslo-79ee3672d46ea324d5c1fca6e9f97876e3c267f2.tar.gz oslo-79ee3672d46ea324d5c1fca6e9f97876e3c267f2.tar.xz oslo-79ee3672d46ea324d5c1fca6e9f97876e3c267f2.zip | |
Add more robust gettext interpolation handling
While integrating the new delayed messaging gettextutils
functionality into Nova, there were issues with handling
the string interpolation operations. This change adds some
paths for dealing with these cases, such as non-deep-copyable
parameters, and python code-like objects. Also, adds some
much needed test coverage.
Change-Id: I65879875adf7a12fa0d1873167c2efadfc23a54b
Diffstat (limited to 'openstack')
| -rw-r--r-- | openstack/common/gettextutils.py | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/openstack/common/gettextutils.py b/openstack/common/gettextutils.py index 0e27425..011ddb6 100644 --- a/openstack/common/gettextutils.py +++ b/openstack/common/gettextutils.py @@ -28,6 +28,7 @@ import copy import gettext import logging.handlers import os +import re import UserString _localedir = os.environ.get('oslo'.upper() + '_LOCALEDIR') @@ -122,14 +123,44 @@ class Message(UserString.UserString, object): return unicode(full_msg) + def _save_dictionary_parameter(self, dict_param): + full_msg = self.data + # look for %(blah) fields in string; + # ignore %% and deal with the + # case where % is first character on the line + keys = re.findall('(?:[^%]|^)%\((\w*)\)[a-z]', full_msg) + + # if we don't find any %(blah) blocks but have a %s + if not keys and re.findall('(?:[^%]|^)%[a-z]', full_msg): + # apparently the full dictionary is the parameter + params = copy.deepcopy(dict_param) + else: + params = {} + for key in keys: + try: + params[key] = copy.deepcopy(dict_param[key]) + except TypeError: + # cast uncopyable thing to unicode string + params[key] = unicode(dict_param[key]) + + return params + def _save_parameters(self, other): # we check for None later to see if # we actually have parameters to inject, # so encapsulate if our parameter is actually None if other is None: self.params = (other, ) + elif isinstance(other, dict): + self.params = self._save_dictionary_parameter(other) else: - self.params = copy.deepcopy(other) + # fallback to casting to unicode, + # this will handle the problematic python code-like + # objects that cannot be deep-copied + try: + self.params = copy.deepcopy(other) + except TypeError: + self.params = unicode(other) return self |
