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