diff options
author | Zac Medico <zmedico@gentoo.org> | 2011-07-10 16:26:24 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2011-07-10 16:55:05 -0700 |
commit | 8cc8d12a674ab6271183e5c35202263a36497279 (patch) | |
tree | 22365e2c613d04151a2d2da5ff3e25e37f84c554 /pym/portage/util/__init__.py | |
parent | 906b62b24d8a845356d59abc5acd39db2174ce0f (diff) | |
download | portage-8cc8d12a674ab6271183e5c35202263a36497279.tar.gz portage-8cc8d12a674ab6271183e5c35202263a36497279.tar.bz2 portage-8cc8d12a674ab6271183e5c35202263a36497279.zip |
Migrate from codecs.open() to io.open().
The io.open() function is the same as the built-in open() function in
python3, and its implementation is optimized in python-2.7 and later.
In addition to the possible performance improvement, this also allows
us to avoid any future compatibility issues with codecs.open() that
may arise if it is delegated to the built-in open() function as
discussed in PEP 400.
The main caveat involved with io.open() is that TextIOWrapper.write()
raises TypeError if given raw bytes, unlike the streams returned from
codecs.open(). This is mainly an issue for python2 since literal
strings are raw bytes. We handle this by wrapping TextIOWrapper.write()
arguments with our _unicode_decode() function. Also, the
atomic_ofstream class overrides the write() method in python2 so that
it performs automatic coercion to unicode when necessary.
Diffstat (limited to 'pym/portage/util/__init__.py')
-rw-r--r-- | pym/portage/util/__init__.py | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/pym/portage/util/__init__.py b/pym/portage/util/__init__.py index 5468e28c9..b641d3ed2 100644 --- a/pym/portage/util/__init__.py +++ b/pym/portage/util/__init__.py @@ -11,9 +11,9 @@ __all__ = ['apply_permissions', 'apply_recursive_permissions', 'stack_dicts', 'stack_lists', 'unique_array', 'unique_everseen', 'varexpand', 'write_atomic', 'writedict', 'writemsg', 'writemsg_level', 'writemsg_stdout'] -import codecs from copy import deepcopy import errno +import io try: from itertools import filterfalse except ImportError: @@ -475,7 +475,7 @@ def grablines(myfilename, recursive=0, remember_source_file=False): os.path.join(myfilename, f), recursive, remember_source_file)) else: try: - myfile = codecs.open(_unicode_encode(myfilename, + myfile = io.open(_unicode_encode(myfilename, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['content'], errors='replace') if remember_source_file: @@ -1091,7 +1091,7 @@ class atomic_ofstream(ObjectProxy): if 'b' in mode: open_func = open else: - open_func = codecs.open + open_func = io.open kargs.setdefault('encoding', _encodings['content']) kargs.setdefault('errors', 'backslashreplace') @@ -1122,10 +1122,29 @@ class atomic_ofstream(ObjectProxy): def _get_target(self): return object.__getattribute__(self, '_file') - def __getattribute__(self, attr): - if attr in ('close', 'abort', '__del__'): - return object.__getattribute__(self, attr) - return getattr(object.__getattribute__(self, '_file'), attr) + if sys.hexversion >= 0x3000000: + + def __getattribute__(self, attr): + if attr in ('close', 'abort', '__del__'): + return object.__getattribute__(self, attr) + return getattr(object.__getattribute__(self, '_file'), attr) + + else: + + # For TextIOWrapper, automatically coerce write calls to + # unicode, in order to avoid TypeError when writing raw + # bytes with python2. + + def __getattribute__(self, attr): + if attr in ('close', 'abort', 'write', '__del__'): + return object.__getattribute__(self, attr) + return getattr(object.__getattribute__(self, '_file'), attr) + + def write(self, s): + f = object.__getattribute__(self, '_file') + if isinstance(f, io.TextIOWrapper): + s = _unicode_decode(s) + return f.write(s) def close(self): """Closes the temporary file, copies permissions (if possible), |