##// END OF EJS Templates
pycompat: extract function that converts attribute or encoding name to str...
Yuya Nishihara -
r30032:2219f4f8 default
parent child Browse files
Show More
@@ -1,168 +1,182 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 def sysstr(s):
39 """Return a keyword str to be passed to Python functions such as
40 getattr() and str.encode()
41
42 This never raises UnicodeDecodeError. Non-ascii characters are
43 considered invalid and mapped to arbitrary but unique code points
44 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
45 """
46 if isinstance(s, builtins.str):
47 return s
48 return s.decode(u'latin-1')
49
38 50 def _wrapattrfunc(f):
39 51 @functools.wraps(f)
40 52 def w(object, name, *args):
41 if isinstance(name, bytes):
42 name = name.decode(u'utf-8')
43 return f(object, name, *args)
53 return f(object, sysstr(name), *args)
44 54 return w
45 55
46 56 # these wrappers are automagically imported by hgloader
47 57 delattr = _wrapattrfunc(builtins.delattr)
48 58 getattr = _wrapattrfunc(builtins.getattr)
49 59 hasattr = _wrapattrfunc(builtins.hasattr)
50 60 setattr = _wrapattrfunc(builtins.setattr)
51 61 xrange = builtins.range
52 62
63 else:
64 def sysstr(s):
65 return s
66
53 67 stringio = io.StringIO
54 68 empty = _queue.Empty
55 69 queue = _queue.Queue
56 70
57 71 class _pycompatstub(object):
58 72 def __init__(self):
59 73 self._aliases = {}
60 74
61 75 def _registeraliases(self, origin, items):
62 76 """Add items that will be populated at the first access"""
63 77 self._aliases.update((item.replace('_', '').lower(), (origin, item))
64 78 for item in items)
65 79
66 80 def __getattr__(self, name):
67 81 try:
68 82 origin, item = self._aliases[name]
69 83 except KeyError:
70 84 raise AttributeError(name)
71 85 self.__dict__[name] = obj = getattr(origin, item)
72 86 return obj
73 87
74 88 httpserver = _pycompatstub()
75 89 urlreq = _pycompatstub()
76 90 urlerr = _pycompatstub()
77 91 if not ispy3:
78 92 import BaseHTTPServer
79 93 import CGIHTTPServer
80 94 import SimpleHTTPServer
81 95 import urllib2
82 96 import urllib
83 97 urlreq._registeraliases(urllib, (
84 98 "addclosehook",
85 99 "addinfourl",
86 100 "ftpwrapper",
87 101 "pathname2url",
88 102 "quote",
89 103 "splitattr",
90 104 "splitpasswd",
91 105 "splitport",
92 106 "splituser",
93 107 "unquote",
94 108 "url2pathname",
95 109 "urlencode",
96 110 ))
97 111 urlreq._registeraliases(urllib2, (
98 112 "AbstractHTTPHandler",
99 113 "BaseHandler",
100 114 "build_opener",
101 115 "FileHandler",
102 116 "FTPHandler",
103 117 "HTTPBasicAuthHandler",
104 118 "HTTPDigestAuthHandler",
105 119 "HTTPHandler",
106 120 "HTTPPasswordMgrWithDefaultRealm",
107 121 "HTTPSHandler",
108 122 "install_opener",
109 123 "ProxyHandler",
110 124 "Request",
111 125 "urlopen",
112 126 ))
113 127 urlerr._registeraliases(urllib2, (
114 128 "HTTPError",
115 129 "URLError",
116 130 ))
117 131 httpserver._registeraliases(BaseHTTPServer, (
118 132 "HTTPServer",
119 133 "BaseHTTPRequestHandler",
120 134 ))
121 135 httpserver._registeraliases(SimpleHTTPServer, (
122 136 "SimpleHTTPRequestHandler",
123 137 ))
124 138 httpserver._registeraliases(CGIHTTPServer, (
125 139 "CGIHTTPRequestHandler",
126 140 ))
127 141
128 142 else:
129 143 import urllib.request
130 144 urlreq._registeraliases(urllib.request, (
131 145 "AbstractHTTPHandler",
132 146 "addclosehook",
133 147 "addinfourl",
134 148 "BaseHandler",
135 149 "build_opener",
136 150 "FileHandler",
137 151 "FTPHandler",
138 152 "ftpwrapper",
139 153 "HTTPHandler",
140 154 "HTTPSHandler",
141 155 "install_opener",
142 156 "pathname2url",
143 157 "HTTPBasicAuthHandler",
144 158 "HTTPDigestAuthHandler",
145 159 "HTTPPasswordMgrWithDefaultRealm",
146 160 "ProxyHandler",
147 161 "quote",
148 162 "Request",
149 163 "splitattr",
150 164 "splitpasswd",
151 165 "splitport",
152 166 "splituser",
153 167 "unquote",
154 168 "url2pathname",
155 169 "urlopen",
156 170 ))
157 171 import urllib.error
158 172 urlerr._registeraliases(urllib.error, (
159 173 "HTTPError",
160 174 "URLError",
161 175 ))
162 176 import http.server
163 177 httpserver._registeraliases(http.server, (
164 178 "HTTPServer",
165 179 "BaseHTTPRequestHandler",
166 180 "SimpleHTTPRequestHandler",
167 181 "CGIHTTPRequestHandler",
168 182 ))
General Comments 0
You need to be logged in to leave comments. Login now