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