##// END OF EJS Templates
pycompat: when setting attrs, ensure we use sysstr...
Augie Fackler -
r30086:f3a10896 default
parent child Browse files
Show More
@@ -1,182 +1,184 b''
1 1 # pycompat.py - portability shim for python 3
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5
6 6 """Mercurial portability shim for python 3.
7 7
8 8 This contains aliases to hide python version-specific details from the core.
9 9 """
10 10
11 11 from __future__ import absolute_import
12 12
13 13 import sys
14 14
15 15 ispy3 = (sys.version_info[0] >= 3)
16 16
17 17 if not ispy3:
18 18 import cPickle as pickle
19 19 import cStringIO as io
20 20 import httplib
21 21 import Queue as _queue
22 22 import SocketServer as socketserver
23 23 import urlparse
24 24 import xmlrpclib
25 25 else:
26 26 import http.client as httplib
27 27 import io
28 28 import pickle
29 29 import queue as _queue
30 30 import socketserver
31 31 import urllib.parse as urlparse
32 32 import xmlrpc.client as xmlrpclib
33 33
34 34 if ispy3:
35 35 import builtins
36 36 import functools
37 37
38 38 def sysstr(s):
39 39 """Return a keyword str to be passed to Python functions such as
40 40 getattr() and str.encode()
41 41
42 42 This never raises UnicodeDecodeError. Non-ascii characters are
43 43 considered invalid and mapped to arbitrary but unique code points
44 44 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
45 45 """
46 46 if isinstance(s, builtins.str):
47 47 return s
48 48 return s.decode(u'latin-1')
49 49
50 50 def _wrapattrfunc(f):
51 51 @functools.wraps(f)
52 52 def w(object, name, *args):
53 53 return f(object, sysstr(name), *args)
54 54 return w
55 55
56 56 # these wrappers are automagically imported by hgloader
57 57 delattr = _wrapattrfunc(builtins.delattr)
58 58 getattr = _wrapattrfunc(builtins.getattr)
59 59 hasattr = _wrapattrfunc(builtins.hasattr)
60 60 setattr = _wrapattrfunc(builtins.setattr)
61 61 xrange = builtins.range
62 62
63 63 else:
64 64 def sysstr(s):
65 65 return s
66 66
67 67 stringio = io.StringIO
68 68 empty = _queue.Empty
69 69 queue = _queue.Queue
70 70
71 71 class _pycompatstub(object):
72 72 def __init__(self):
73 73 self._aliases = {}
74 74
75 75 def _registeraliases(self, origin, items):
76 76 """Add items that will be populated at the first access"""
77 self._aliases.update((item.replace('_', '').lower(), (origin, item))
78 for item in items)
77 items = map(sysstr, items)
78 self._aliases.update(
79 (item.replace(sysstr('_'), sysstr('')).lower(), (origin, item))
80 for item in items)
79 81
80 82 def __getattr__(self, name):
81 83 try:
82 84 origin, item = self._aliases[name]
83 85 except KeyError:
84 86 raise AttributeError(name)
85 87 self.__dict__[name] = obj = getattr(origin, item)
86 88 return obj
87 89
88 90 httpserver = _pycompatstub()
89 91 urlreq = _pycompatstub()
90 92 urlerr = _pycompatstub()
91 93 if not ispy3:
92 94 import BaseHTTPServer
93 95 import CGIHTTPServer
94 96 import SimpleHTTPServer
95 97 import urllib2
96 98 import urllib
97 99 urlreq._registeraliases(urllib, (
98 100 "addclosehook",
99 101 "addinfourl",
100 102 "ftpwrapper",
101 103 "pathname2url",
102 104 "quote",
103 105 "splitattr",
104 106 "splitpasswd",
105 107 "splitport",
106 108 "splituser",
107 109 "unquote",
108 110 "url2pathname",
109 111 "urlencode",
110 112 ))
111 113 urlreq._registeraliases(urllib2, (
112 114 "AbstractHTTPHandler",
113 115 "BaseHandler",
114 116 "build_opener",
115 117 "FileHandler",
116 118 "FTPHandler",
117 119 "HTTPBasicAuthHandler",
118 120 "HTTPDigestAuthHandler",
119 121 "HTTPHandler",
120 122 "HTTPPasswordMgrWithDefaultRealm",
121 123 "HTTPSHandler",
122 124 "install_opener",
123 125 "ProxyHandler",
124 126 "Request",
125 127 "urlopen",
126 128 ))
127 129 urlerr._registeraliases(urllib2, (
128 130 "HTTPError",
129 131 "URLError",
130 132 ))
131 133 httpserver._registeraliases(BaseHTTPServer, (
132 134 "HTTPServer",
133 135 "BaseHTTPRequestHandler",
134 136 ))
135 137 httpserver._registeraliases(SimpleHTTPServer, (
136 138 "SimpleHTTPRequestHandler",
137 139 ))
138 140 httpserver._registeraliases(CGIHTTPServer, (
139 141 "CGIHTTPRequestHandler",
140 142 ))
141 143
142 144 else:
143 145 import urllib.request
144 146 urlreq._registeraliases(urllib.request, (
145 147 "AbstractHTTPHandler",
146 148 "addclosehook",
147 149 "addinfourl",
148 150 "BaseHandler",
149 151 "build_opener",
150 152 "FileHandler",
151 153 "FTPHandler",
152 154 "ftpwrapper",
153 155 "HTTPHandler",
154 156 "HTTPSHandler",
155 157 "install_opener",
156 158 "pathname2url",
157 159 "HTTPBasicAuthHandler",
158 160 "HTTPDigestAuthHandler",
159 161 "HTTPPasswordMgrWithDefaultRealm",
160 162 "ProxyHandler",
161 163 "quote",
162 164 "Request",
163 165 "splitattr",
164 166 "splitpasswd",
165 167 "splitport",
166 168 "splituser",
167 169 "unquote",
168 170 "url2pathname",
169 171 "urlopen",
170 172 ))
171 173 import urllib.error
172 174 urlerr._registeraliases(urllib.error, (
173 175 "HTTPError",
174 176 "URLError",
175 177 ))
176 178 import http.server
177 179 httpserver._registeraliases(http.server, (
178 180 "HTTPServer",
179 181 "BaseHTTPRequestHandler",
180 182 "SimpleHTTPRequestHandler",
181 183 "CGIHTTPRequestHandler",
182 184 ))
General Comments 0
You need to be logged in to leave comments. Login now