##// END OF EJS Templates
pycompat: introduce an alias for urllib.unquote...
Augie Fackler -
r30327:e0d9b6aa default
parent child Browse files
Show More
@@ -1,210 +1,212 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 os
14 14 import sys
15 15
16 16 ispy3 = (sys.version_info[0] >= 3)
17 17
18 18 if not ispy3:
19 19 import cPickle as pickle
20 20 import cStringIO as io
21 21 import httplib
22 22 import Queue as _queue
23 23 import SocketServer as socketserver
24 24 import urlparse
25 urlunquote = urlparse.unquote
25 26 import xmlrpclib
26 27 else:
27 28 import http.client as httplib
28 29 import io
29 30 import pickle
30 31 import queue as _queue
31 32 import socketserver
32 33 import urllib.parse as urlparse
34 urlunquote = urlparse.unquote_to_bytes
33 35 import xmlrpc.client as xmlrpclib
34 36
35 37 if ispy3:
36 38 import builtins
37 39 import functools
38 40 fsencode = os.fsencode
39 41 fsdecode = os.fsdecode
40 42 # A bytes version of os.name.
41 43 osname = os.name.encode('ascii')
42 44 ospathsep = os.pathsep.encode('ascii')
43 45 ossep = os.sep.encode('ascii')
44 46
45 47 def sysstr(s):
46 48 """Return a keyword str to be passed to Python functions such as
47 49 getattr() and str.encode()
48 50
49 51 This never raises UnicodeDecodeError. Non-ascii characters are
50 52 considered invalid and mapped to arbitrary but unique code points
51 53 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
52 54 """
53 55 if isinstance(s, builtins.str):
54 56 return s
55 57 return s.decode(u'latin-1')
56 58
57 59 def _wrapattrfunc(f):
58 60 @functools.wraps(f)
59 61 def w(object, name, *args):
60 62 return f(object, sysstr(name), *args)
61 63 return w
62 64
63 65 # these wrappers are automagically imported by hgloader
64 66 delattr = _wrapattrfunc(builtins.delattr)
65 67 getattr = _wrapattrfunc(builtins.getattr)
66 68 hasattr = _wrapattrfunc(builtins.hasattr)
67 69 setattr = _wrapattrfunc(builtins.setattr)
68 70 xrange = builtins.range
69 71
70 72 else:
71 73 def sysstr(s):
72 74 return s
73 75
74 76 # Partial backport from os.py in Python 3, which only accepts bytes.
75 77 # In Python 2, our paths should only ever be bytes, a unicode path
76 78 # indicates a bug.
77 79 def fsencode(filename):
78 80 if isinstance(filename, str):
79 81 return filename
80 82 else:
81 83 raise TypeError(
82 84 "expect str, not %s" % type(filename).__name__)
83 85
84 86 # In Python 2, fsdecode() has a very chance to receive bytes. So it's
85 87 # better not to touch Python 2 part as it's already working fine.
86 88 def fsdecode(filename):
87 89 return filename
88 90
89 91 osname = os.name
90 92 ospathsep = os.pathsep
91 93 ossep = os.sep
92 94
93 95 stringio = io.StringIO
94 96 empty = _queue.Empty
95 97 queue = _queue.Queue
96 98
97 99 class _pycompatstub(object):
98 100 def __init__(self):
99 101 self._aliases = {}
100 102
101 103 def _registeraliases(self, origin, items):
102 104 """Add items that will be populated at the first access"""
103 105 items = map(sysstr, items)
104 106 self._aliases.update(
105 107 (item.replace(sysstr('_'), sysstr('')).lower(), (origin, item))
106 108 for item in items)
107 109
108 110 def __getattr__(self, name):
109 111 try:
110 112 origin, item = self._aliases[name]
111 113 except KeyError:
112 114 raise AttributeError(name)
113 115 self.__dict__[name] = obj = getattr(origin, item)
114 116 return obj
115 117
116 118 httpserver = _pycompatstub()
117 119 urlreq = _pycompatstub()
118 120 urlerr = _pycompatstub()
119 121 if not ispy3:
120 122 import BaseHTTPServer
121 123 import CGIHTTPServer
122 124 import SimpleHTTPServer
123 125 import urllib2
124 126 import urllib
125 127 urlreq._registeraliases(urllib, (
126 128 "addclosehook",
127 129 "addinfourl",
128 130 "ftpwrapper",
129 131 "pathname2url",
130 132 "quote",
131 133 "splitattr",
132 134 "splitpasswd",
133 135 "splitport",
134 136 "splituser",
135 137 "unquote",
136 138 "url2pathname",
137 139 "urlencode",
138 140 ))
139 141 urlreq._registeraliases(urllib2, (
140 142 "AbstractHTTPHandler",
141 143 "BaseHandler",
142 144 "build_opener",
143 145 "FileHandler",
144 146 "FTPHandler",
145 147 "HTTPBasicAuthHandler",
146 148 "HTTPDigestAuthHandler",
147 149 "HTTPHandler",
148 150 "HTTPPasswordMgrWithDefaultRealm",
149 151 "HTTPSHandler",
150 152 "install_opener",
151 153 "ProxyHandler",
152 154 "Request",
153 155 "urlopen",
154 156 ))
155 157 urlerr._registeraliases(urllib2, (
156 158 "HTTPError",
157 159 "URLError",
158 160 ))
159 161 httpserver._registeraliases(BaseHTTPServer, (
160 162 "HTTPServer",
161 163 "BaseHTTPRequestHandler",
162 164 ))
163 165 httpserver._registeraliases(SimpleHTTPServer, (
164 166 "SimpleHTTPRequestHandler",
165 167 ))
166 168 httpserver._registeraliases(CGIHTTPServer, (
167 169 "CGIHTTPRequestHandler",
168 170 ))
169 171
170 172 else:
171 173 import urllib.request
172 174 urlreq._registeraliases(urllib.request, (
173 175 "AbstractHTTPHandler",
174 176 "addclosehook",
175 177 "addinfourl",
176 178 "BaseHandler",
177 179 "build_opener",
178 180 "FileHandler",
179 181 "FTPHandler",
180 182 "ftpwrapper",
181 183 "HTTPHandler",
182 184 "HTTPSHandler",
183 185 "install_opener",
184 186 "pathname2url",
185 187 "HTTPBasicAuthHandler",
186 188 "HTTPDigestAuthHandler",
187 189 "HTTPPasswordMgrWithDefaultRealm",
188 190 "ProxyHandler",
189 191 "quote",
190 192 "Request",
191 193 "splitattr",
192 194 "splitpasswd",
193 195 "splitport",
194 196 "splituser",
195 197 "unquote",
196 198 "url2pathname",
197 199 "urlopen",
198 200 ))
199 201 import urllib.error
200 202 urlerr._registeraliases(urllib.error, (
201 203 "HTTPError",
202 204 "URLError",
203 205 ))
204 206 import http.server
205 207 httpserver._registeraliases(http.server, (
206 208 "HTTPServer",
207 209 "BaseHTTPRequestHandler",
208 210 "SimpleHTTPRequestHandler",
209 211 "CGIHTTPRequestHandler",
210 212 ))
General Comments 0
You need to be logged in to leave comments. Login now