Bug #280460 - Wrap os and os.path modules with unicode encode/decode
authorZac Medico <zmedico@gentoo.org>
Mon, 10 Aug 2009 21:28:04 +0000 (21:28 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 10 Aug 2009 21:28:04 +0000 (21:28 -0000)
wrappers for python-2.x.

svn path=/main/trunk/; revision=13978

pym/portage/__init__.py
pym/portage/dbapi/vartree.py

index b26e8bd9c15cb5016e2c58d263e49f36e8243c88..358de52b7ec2e7b786422993297e5f5b1746f3a2 100644 (file)
@@ -23,6 +23,7 @@ try:
        import re
        import shutil
        import time
+       import types
        try:
                import cPickle as pickle
        except ImportError:
@@ -123,6 +124,70 @@ except ImportError:
 # END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END OF IMPORTS -- END
 # ===========================================================================
 
+def _unicode_encode(s):
+       if isinstance(s, unicode):
+               s = s.encode('utf_8', 'replace')
+       return s
+
+def _unicode_decode(s):
+       if not isinstance(s, unicode) and isinstance(s, basestring):
+               s = unicode(s, encoding='utf_8', errors='replace')
+       return s
+
+class _unicode_func_wrapper(object):
+       """
+       Wraps a function, converts arguments from unicode to bytes,
+       and return values to unicode from bytes.
+       """
+       __slots__ = ('_func',)
+
+       def __init__(self, func):
+               self._func = func
+
+       def __call__(self, *args, **kwargs):
+
+               wrapped_args = [_unicode_encode(x) for x in args]
+               if kwargs:
+                       wrapped_kwargs = dict((_unicode_encode(k), _unicode_encode(v)) \
+                               for k, v in kwargs.iteritems())
+               else:
+                       wrapped_kwargs = {}
+
+               rval = self._func(*wrapped_args, **wrapped_kwargs)
+
+               if isinstance(rval, (basestring, list, tuple)):
+                       if isinstance(rval, basestring):
+                               rval = _unicode_decode(rval)
+                       elif isinstance(rval, list):
+                               rval = [_unicode_decode(x) for x in rval]
+                       elif isinstance(rval, tuple):
+                               rval = tuple(_unicode_decode(x) for x in rval)
+
+               return rval
+
+class _unicode_module_wrapper(object):
+       """
+       Wraps a module and wraps all functions with _unicode_func_wrapper.
+       """
+       __slots__ = ('_mod',)
+
+       def __init__(self, mod):
+               object.__setattr__(self, '_mod', mod)
+
+       def __getattribute__(self, attr):
+               result = getattr(object.__getattribute__(self, '_mod'), attr)
+               if isinstance(result, type):
+                       pass
+               elif type(result) is types.ModuleType:
+                       result = _unicode_module_wrapper(result)
+               elif hasattr(result, '__call__'):
+                       result = _unicode_func_wrapper(result)
+               return result
+
+if sys.hexversion >= 0x3000000:
+       def _unicode_module_wrapper(mod):
+               return mod
+
 def _shell_quote(s):
        """
        Quote a string in double-quotes and use backslashes to
index 24e9d0c36e78cfe68cc4ccbe299e2bf1272650d2..6109c81b4eb8487724bcd0ddc2586e10d40ee4c7 100644 (file)
@@ -33,7 +33,8 @@ from portage.localization import _
 
 from portage import listdir, dep_expand, digraph, flatten, key_expand, \
        doebuild_environment, doebuild, env_update, prepare_build_dirs, \
-       abssymlink, movefile, _movefile, bsd_chflags, cpv_getkey
+       abssymlink, movefile, _movefile, bsd_chflags, cpv_getkey, \
+       _unicode_module_wrapper
 
 from portage.cache.mappings import slot_dict_class
 
@@ -43,6 +44,8 @@ import logging
 import sys
 from itertools import izip
 
+os = _unicode_module_wrapper(os)
+
 try:
        import cPickle as pickle
 except ImportError: