summaryrefslogtreecommitdiff
blob: 5e62843f1b6e5ec9d7c38b2af6d3b4091d1a5c9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 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