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