blob: 5e62843f1b6e5ec9d7c38b2af6d3b4091d1a5c9d [file] [log] [blame]
# Copyright 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
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