From c133668dc9ae95e3afbb7fb08a4f2030d9584cb4 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Mon, 10 Aug 2009 21:28:04 +0000 Subject: [PATCH] Bug #280460 - Wrap os and os.path modules with unicode encode/decode wrappers for python-2.x. svn path=/main/trunk/; revision=13978 --- pym/portage/__init__.py | 65 ++++++++++++++++++++++++++++++++++++ pym/portage/dbapi/vartree.py | 5 ++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index b26e8bd9c..358de52b7 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 24e9d0c36..6109c81b4 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -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: -- 2.26.2