diff options
Diffstat (limited to 'pym/portage/_ensure_encodings.py')
-rw-r--r-- | pym/portage/_ensure_encodings.py | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/pym/portage/_ensure_encodings.py b/pym/portage/_ensure_encodings.py new file mode 100644 index 000000000..7daf52e3b --- /dev/null +++ b/pym/portage/_ensure_encodings.py @@ -0,0 +1,133 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +import codecs + +_codec_map = None + +def _setup_encodings(default_encoding, filesystem_encoding, missing_encodings): + """ + The <python-2.6.4 that's inside stage 1 or 2 is built with a minimal + configuration which does not include the /usr/lib/pythonX.Y/encodings + directory. This results in error like the following: + + LookupError: no codec search functions registered: can't find encoding + + In order to solve this problem, detect it early and manually register + a search function for the ascii and utf_8 codecs. Starting with python-3.0 + this problem is more noticeable because of stricter handling of encoding + and decoding between strings of characters and bytes. + """ + + global _codec_map + _codec_map = _gen_missing_encodings(missing_encodings) + + default_fallback = 'utf_8' + + if default_encoding in missing_encodings and \ + default_encoding not in _codec_map: + # Make the fallback codec correspond to whatever name happens + # to be returned by sys.getfilesystemencoding(). + + try: + _codec_map[default_encoding] = codecs.lookup(default_fallback) + except LookupError: + _codec_map[default_encoding] = _codec_map[default_fallback] + + if filesystem_encoding in missing_encodings and \ + filesystem_encoding not in _codec_map: + # Make the fallback codec correspond to whatever name happens + # to be returned by sys.getdefaultencoding(). + + try: + _codec_map[filesystem_encoding] = codecs.lookup(default_fallback) + except LookupError: + _codec_map[filesystem_encoding] = _codec_map[default_fallback] + + codecs.register(_search_function) + +def _gen_missing_encodings(missing_encodings): + + codec_map = {} + + if 'ascii' in missing_encodings: + + class AsciiIncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.ascii_encode(input, self.errors)[0] + + class AsciiIncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.ascii_decode(input, self.errors)[0] + + class AsciiStreamWriter(codecs.StreamWriter): + encode = codecs.ascii_encode + + class AsciiStreamReader(codecs.StreamReader): + decode = codecs.ascii_decode + + codec_info = codecs.CodecInfo( + name='ascii', + encode=codecs.ascii_encode, + decode=codecs.ascii_decode, + incrementalencoder=AsciiIncrementalEncoder, + incrementaldecoder=AsciiIncrementalDecoder, + streamwriter=AsciiStreamWriter, + streamreader=AsciiStreamReader, + ) + + for alias in ('ascii', '646', 'ansi_x3.4_1968', 'ansi_x3_4_1968', + 'ansi_x3.4_1986', 'cp367', 'csascii', 'ibm367', 'iso646_us', + 'iso_646.irv_1991', 'iso_ir_6', 'us', 'us_ascii'): + codec_map[alias] = codec_info + + if 'utf_8' in missing_encodings: + + def utf8decode(input, errors='strict'): + return codecs.utf_8_decode(input, errors, True) + + class Utf8IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_8_encode(input, self.errors)[0] + + class Utf8IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_8_decode + + class Utf8StreamWriter(codecs.StreamWriter): + encode = codecs.utf_8_encode + + class Utf8StreamReader(codecs.StreamReader): + decode = codecs.utf_8_decode + + codec_info = codecs.CodecInfo( + name='utf-8', + encode=codecs.utf_8_encode, + decode=utf8decode, + incrementalencoder=Utf8IncrementalEncoder, + incrementaldecoder=Utf8IncrementalDecoder, + streamreader=Utf8StreamReader, + streamwriter=Utf8StreamWriter, + ) + + for alias in ('utf_8', 'u8', 'utf', 'utf8', 'utf8_ucs2', 'utf8_ucs4'): + codec_map[alias] = codec_info + + return codec_map + +def _search_function(name): + global _codec_map + name = name.lower() + name = name.replace('-', '_') + codec_info = _codec_map.get(name) + if codec_info is not None: + return codecs.CodecInfo( + name=codec_info.name, + encode=codec_info.encode, + decode=codec_info.decode, + incrementalencoder=codec_info.incrementalencoder, + incrementaldecoder=codec_info.incrementaldecoder, + streamreader=codec_info.streamreader, + streamwriter=codec_info.streamwriter, + ) + return None |