##// END OF EJS Templates
mail: handle renamed email.Header...
Pulkit Goyal -
r30072:87b8e40e default
parent child Browse files
Show More
@@ -1,346 +1,347 b''
1 1 # mail.py - mail sending bits for mercurial
2 2 #
3 3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import, print_function
9 9
10 10 import email
11 import email.header
11 12 import os
12 13 import quopri
13 14 import smtplib
14 15 import socket
15 16 import sys
16 17 import time
17 18
18 19 from .i18n import _
19 20 from . import (
20 21 encoding,
21 22 error,
22 23 sslutil,
23 24 util,
24 25 )
25 26
26 _oldheaderinit = email.Header.Header.__init__
27 _oldheaderinit = email.header.Header.__init__
27 28 def _unifiedheaderinit(self, *args, **kw):
28 29 """
29 30 Python 2.7 introduces a backwards incompatible change
30 31 (Python issue1974, r70772) in email.Generator.Generator code:
31 32 pre-2.7 code passed "continuation_ws='\t'" to the Header
32 33 constructor, and 2.7 removed this parameter.
33 34
34 35 Default argument is continuation_ws=' ', which means that the
35 36 behavior is different in <2.7 and 2.7
36 37
37 38 We consider the 2.7 behavior to be preferable, but need
38 39 to have an unified behavior for versions 2.4 to 2.7
39 40 """
40 41 # override continuation_ws
41 42 kw['continuation_ws'] = ' '
42 43 _oldheaderinit(self, *args, **kw)
43 44
44 45 setattr(email.header.Header, '__init__', _unifiedheaderinit)
45 46
46 47 class STARTTLS(smtplib.SMTP):
47 48 '''Derived class to verify the peer certificate for STARTTLS.
48 49
49 50 This class allows to pass any keyword arguments to SSL socket creation.
50 51 '''
51 52 def __init__(self, ui, host=None, **kwargs):
52 53 smtplib.SMTP.__init__(self, **kwargs)
53 54 self._ui = ui
54 55 self._host = host
55 56
56 57 def starttls(self, keyfile=None, certfile=None):
57 58 if not self.has_extn("starttls"):
58 59 msg = "STARTTLS extension not supported by server"
59 60 raise smtplib.SMTPException(msg)
60 61 (resp, reply) = self.docmd("STARTTLS")
61 62 if resp == 220:
62 63 self.sock = sslutil.wrapsocket(self.sock, keyfile, certfile,
63 64 ui=self._ui,
64 65 serverhostname=self._host)
65 66 self.file = smtplib.SSLFakeFile(self.sock)
66 67 self.helo_resp = None
67 68 self.ehlo_resp = None
68 69 self.esmtp_features = {}
69 70 self.does_esmtp = 0
70 71 return (resp, reply)
71 72
72 73 class SMTPS(smtplib.SMTP):
73 74 '''Derived class to verify the peer certificate for SMTPS.
74 75
75 76 This class allows to pass any keyword arguments to SSL socket creation.
76 77 '''
77 78 def __init__(self, ui, keyfile=None, certfile=None, host=None,
78 79 **kwargs):
79 80 self.keyfile = keyfile
80 81 self.certfile = certfile
81 82 smtplib.SMTP.__init__(self, **kwargs)
82 83 self._host = host
83 84 self.default_port = smtplib.SMTP_SSL_PORT
84 85 self._ui = ui
85 86
86 87 def _get_socket(self, host, port, timeout):
87 88 if self.debuglevel > 0:
88 89 print('connect:', (host, port), file=sys.stderr)
89 90 new_socket = socket.create_connection((host, port), timeout)
90 91 new_socket = sslutil.wrapsocket(new_socket,
91 92 self.keyfile, self.certfile,
92 93 ui=self._ui,
93 94 serverhostname=self._host)
94 95 self.file = smtplib.SSLFakeFile(new_socket)
95 96 return new_socket
96 97
97 98 def _smtp(ui):
98 99 '''build an smtp connection and return a function to send mail'''
99 100 local_hostname = ui.config('smtp', 'local_hostname')
100 101 tls = ui.config('smtp', 'tls', 'none')
101 102 # backward compatible: when tls = true, we use starttls.
102 103 starttls = tls == 'starttls' or util.parsebool(tls)
103 104 smtps = tls == 'smtps'
104 105 if (starttls or smtps) and not util.safehasattr(socket, 'ssl'):
105 106 raise error.Abort(_("can't use TLS: Python SSL support not installed"))
106 107 mailhost = ui.config('smtp', 'host')
107 108 if not mailhost:
108 109 raise error.Abort(_('smtp.host not configured - cannot send mail'))
109 110 if smtps:
110 111 ui.note(_('(using smtps)\n'))
111 112 s = SMTPS(ui, local_hostname=local_hostname, host=mailhost)
112 113 elif starttls:
113 114 s = STARTTLS(ui, local_hostname=local_hostname, host=mailhost)
114 115 else:
115 116 s = smtplib.SMTP(local_hostname=local_hostname)
116 117 if smtps:
117 118 defaultport = 465
118 119 else:
119 120 defaultport = 25
120 121 mailport = util.getport(ui.config('smtp', 'port', defaultport))
121 122 ui.note(_('sending mail: smtp host %s, port %d\n') %
122 123 (mailhost, mailport))
123 124 s.connect(host=mailhost, port=mailport)
124 125 if starttls:
125 126 ui.note(_('(using starttls)\n'))
126 127 s.ehlo()
127 128 s.starttls()
128 129 s.ehlo()
129 130 if starttls or smtps:
130 131 ui.note(_('(verifying remote certificate)\n'))
131 132 sslutil.validatesocket(s.sock)
132 133 username = ui.config('smtp', 'username')
133 134 password = ui.config('smtp', 'password')
134 135 if username and not password:
135 136 password = ui.getpass()
136 137 if username and password:
137 138 ui.note(_('(authenticating to mail server as %s)\n') %
138 139 (username))
139 140 try:
140 141 s.login(username, password)
141 142 except smtplib.SMTPException as inst:
142 143 raise error.Abort(inst)
143 144
144 145 def send(sender, recipients, msg):
145 146 try:
146 147 return s.sendmail(sender, recipients, msg)
147 148 except smtplib.SMTPRecipientsRefused as inst:
148 149 recipients = [r[1] for r in inst.recipients.values()]
149 150 raise error.Abort('\n' + '\n'.join(recipients))
150 151 except smtplib.SMTPException as inst:
151 152 raise error.Abort(inst)
152 153
153 154 return send
154 155
155 156 def _sendmail(ui, sender, recipients, msg):
156 157 '''send mail using sendmail.'''
157 158 program = ui.config('email', 'method', 'smtp')
158 159 cmdline = '%s -f %s %s' % (program, util.email(sender),
159 160 ' '.join(map(util.email, recipients)))
160 161 ui.note(_('sending mail: %s\n') % cmdline)
161 162 fp = util.popen(cmdline, 'w')
162 163 fp.write(msg)
163 164 ret = fp.close()
164 165 if ret:
165 166 raise error.Abort('%s %s' % (
166 167 os.path.basename(program.split(None, 1)[0]),
167 168 util.explainexit(ret)[0]))
168 169
169 170 def _mbox(mbox, sender, recipients, msg):
170 171 '''write mails to mbox'''
171 172 fp = open(mbox, 'ab+')
172 173 # Should be time.asctime(), but Windows prints 2-characters day
173 174 # of month instead of one. Make them print the same thing.
174 175 date = time.strftime('%a %b %d %H:%M:%S %Y', time.localtime())
175 176 fp.write('From %s %s\n' % (sender, date))
176 177 fp.write(msg)
177 178 fp.write('\n\n')
178 179 fp.close()
179 180
180 181 def connect(ui, mbox=None):
181 182 '''make a mail connection. return a function to send mail.
182 183 call as sendmail(sender, list-of-recipients, msg).'''
183 184 if mbox:
184 185 open(mbox, 'wb').close()
185 186 return lambda s, r, m: _mbox(mbox, s, r, m)
186 187 if ui.config('email', 'method', 'smtp') == 'smtp':
187 188 return _smtp(ui)
188 189 return lambda s, r, m: _sendmail(ui, s, r, m)
189 190
190 191 def sendmail(ui, sender, recipients, msg, mbox=None):
191 192 send = connect(ui, mbox=mbox)
192 193 return send(sender, recipients, msg)
193 194
194 195 def validateconfig(ui):
195 196 '''determine if we have enough config data to try sending email.'''
196 197 method = ui.config('email', 'method', 'smtp')
197 198 if method == 'smtp':
198 199 if not ui.config('smtp', 'host'):
199 200 raise error.Abort(_('smtp specified as email transport, '
200 201 'but no smtp host configured'))
201 202 else:
202 203 if not util.findexe(method):
203 204 raise error.Abort(_('%r specified as email transport, '
204 205 'but not in PATH') % method)
205 206
206 207 def mimetextpatch(s, subtype='plain', display=False):
207 208 '''Return MIME message suitable for a patch.
208 209 Charset will be detected as utf-8 or (possibly fake) us-ascii.
209 210 Transfer encodings will be used if necessary.'''
210 211
211 212 cs = 'us-ascii'
212 213 if not display:
213 214 try:
214 215 s.decode('us-ascii')
215 216 except UnicodeDecodeError:
216 217 try:
217 218 s.decode('utf-8')
218 219 cs = 'utf-8'
219 220 except UnicodeDecodeError:
220 221 # We'll go with us-ascii as a fallback.
221 222 pass
222 223
223 224 return mimetextqp(s, subtype, cs)
224 225
225 226 def mimetextqp(body, subtype, charset):
226 227 '''Return MIME message.
227 228 Quoted-printable transfer encoding will be used if necessary.
228 229 '''
229 230 enc = None
230 231 for line in body.splitlines():
231 232 if len(line) > 950:
232 233 body = quopri.encodestring(body)
233 234 enc = "quoted-printable"
234 235 break
235 236
236 237 msg = email.MIMEText.MIMEText(body, subtype, charset)
237 238 if enc:
238 239 del msg['Content-Transfer-Encoding']
239 240 msg['Content-Transfer-Encoding'] = enc
240 241 return msg
241 242
242 243 def _charsets(ui):
243 244 '''Obtains charsets to send mail parts not containing patches.'''
244 245 charsets = [cs.lower() for cs in ui.configlist('email', 'charsets')]
245 246 fallbacks = [encoding.fallbackencoding.lower(),
246 247 encoding.encoding.lower(), 'utf-8']
247 248 for cs in fallbacks: # find unique charsets while keeping order
248 249 if cs not in charsets:
249 250 charsets.append(cs)
250 251 return [cs for cs in charsets if not cs.endswith('ascii')]
251 252
252 253 def _encode(ui, s, charsets):
253 254 '''Returns (converted) string, charset tuple.
254 255 Finds out best charset by cycling through sendcharsets in descending
255 256 order. Tries both encoding and fallbackencoding for input. Only as
256 257 last resort send as is in fake ascii.
257 258 Caveat: Do not use for mail parts containing patches!'''
258 259 try:
259 260 s.decode('ascii')
260 261 except UnicodeDecodeError:
261 262 sendcharsets = charsets or _charsets(ui)
262 263 for ics in (encoding.encoding, encoding.fallbackencoding):
263 264 try:
264 265 u = s.decode(ics)
265 266 except UnicodeDecodeError:
266 267 continue
267 268 for ocs in sendcharsets:
268 269 try:
269 270 return u.encode(ocs), ocs
270 271 except UnicodeEncodeError:
271 272 pass
272 273 except LookupError:
273 274 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs)
274 275 # if ascii, or all conversion attempts fail, send (broken) ascii
275 276 return s, 'us-ascii'
276 277
277 278 def headencode(ui, s, charsets=None, display=False):
278 279 '''Returns RFC-2047 compliant header from given string.'''
279 280 if not display:
280 281 # split into words?
281 282 s, cs = _encode(ui, s, charsets)
282 return str(email.Header.Header(s, cs))
283 return str(email.header.Header(s, cs))
283 284 return s
284 285
285 286 def _addressencode(ui, name, addr, charsets=None):
286 287 name = headencode(ui, name, charsets)
287 288 try:
288 289 acc, dom = addr.split('@')
289 290 acc = acc.encode('ascii')
290 291 dom = dom.decode(encoding.encoding).encode('idna')
291 292 addr = '%s@%s' % (acc, dom)
292 293 except UnicodeDecodeError:
293 294 raise error.Abort(_('invalid email address: %s') % addr)
294 295 except ValueError:
295 296 try:
296 297 # too strict?
297 298 addr = addr.encode('ascii')
298 299 except UnicodeDecodeError:
299 300 raise error.Abort(_('invalid local address: %s') % addr)
300 301 return email.Utils.formataddr((name, addr))
301 302
302 303 def addressencode(ui, address, charsets=None, display=False):
303 304 '''Turns address into RFC-2047 compliant header.'''
304 305 if display or not address:
305 306 return address or ''
306 307 name, addr = email.Utils.parseaddr(address)
307 308 return _addressencode(ui, name, addr, charsets)
308 309
309 310 def addrlistencode(ui, addrs, charsets=None, display=False):
310 311 '''Turns a list of addresses into a list of RFC-2047 compliant headers.
311 312 A single element of input list may contain multiple addresses, but output
312 313 always has one address per item'''
313 314 if display:
314 315 return [a.strip() for a in addrs if a.strip()]
315 316
316 317 result = []
317 318 for name, addr in email.Utils.getaddresses(addrs):
318 319 if name or addr:
319 320 result.append(_addressencode(ui, name, addr, charsets))
320 321 return result
321 322
322 323 def mimeencode(ui, s, charsets=None, display=False):
323 324 '''creates mime text object, encodes it if needed, and sets
324 325 charset and transfer-encoding accordingly.'''
325 326 cs = 'us-ascii'
326 327 if not display:
327 328 s, cs = _encode(ui, s, charsets)
328 329 return mimetextqp(s, 'plain', cs)
329 330
330 331 def headdecode(s):
331 332 '''Decodes RFC-2047 header'''
332 333 uparts = []
333 for part, charset in email.Header.decode_header(s):
334 for part, charset in email.header.decode_header(s):
334 335 if charset is not None:
335 336 try:
336 337 uparts.append(part.decode(charset))
337 338 continue
338 339 except UnicodeDecodeError:
339 340 pass
340 341 try:
341 342 uparts.append(part.decode('UTF-8'))
342 343 continue
343 344 except UnicodeDecodeError:
344 345 pass
345 346 uparts.append(part.decode('ISO-8859-1'))
346 347 return encoding.tolocal(u' '.join(uparts).encode('UTF-8'))
@@ -1,158 +1,156 b''
1 1 #require test-repo
2 2
3 3 $ . "$TESTDIR/helpers-testrepo.sh"
4 4 $ cd "$TESTDIR"/..
5 5
6 6 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
7 7 hgext/fsmonitor/pywatchman/__init__.py not using absolute_import
8 8 hgext/fsmonitor/pywatchman/__init__.py requires print_function
9 9 hgext/fsmonitor/pywatchman/capabilities.py not using absolute_import
10 10 hgext/fsmonitor/pywatchman/pybser.py not using absolute_import
11 11 i18n/check-translation.py not using absolute_import
12 12 setup.py not using absolute_import
13 13 tests/test-demandimport.py not using absolute_import
14 14
15 15 #if py3exe
16 16 $ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \
17 17 > | xargs $PYTHON3 contrib/check-py3-compat.py \
18 18 > | sed 's/[0-9][0-9]*)$/*)/'
19 19 hgext/acl.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
20 20 hgext/automv.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
21 21 hgext/blackbox.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
22 22 hgext/bugzilla.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
23 23 hgext/censor.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
24 24 hgext/chgserver.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
25 25 hgext/children.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
26 26 hgext/churn.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
27 27 hgext/clonebundles.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
28 28 hgext/color.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
29 29 hgext/convert/bzr.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *)
30 30 hgext/convert/common.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
31 31 hgext/convert/convcmd.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
32 32 hgext/convert/cvs.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
33 33 hgext/convert/cvsps.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
34 34 hgext/convert/darcs.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
35 35 hgext/convert/filemap.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *)
36 36 hgext/convert/git.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
37 37 hgext/convert/gnuarch.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
38 38 hgext/convert/hg.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
39 39 hgext/convert/monotone.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
40 40 hgext/convert/p4.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
41 41 hgext/convert/subversion.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
42 42 hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *)
43 43 hgext/eol.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
44 44 hgext/extdiff.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
45 45 hgext/factotum.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
46 46 hgext/fetch.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
47 47 hgext/fsmonitor/state.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
48 48 hgext/fsmonitor/watchmanclient.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
49 49 hgext/gpg.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
50 50 hgext/graphlog.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
51 51 hgext/hgk.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
52 52 hgext/histedit.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
53 53 hgext/journal.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
54 54 hgext/keyword.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
55 55 hgext/largefiles/basestore.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
56 56 hgext/largefiles/lfcommands.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
57 57 hgext/largefiles/lfutil.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
58 58 hgext/largefiles/localstore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *)
59 59 hgext/largefiles/overrides.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
60 60 hgext/largefiles/proto.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
61 61 hgext/largefiles/remotestore.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
62 62 hgext/largefiles/reposetup.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
63 63 hgext/largefiles/storefactory.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
64 64 hgext/largefiles/uisetup.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
65 65 hgext/largefiles/wirestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *)
66 66 hgext/mq.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
67 67 hgext/notify.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
68 68 hgext/pager.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
69 69 hgext/patchbomb.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
70 70 hgext/purge.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
71 71 hgext/rebase.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
72 72 hgext/record.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
73 73 hgext/relink.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
74 74 hgext/schemes.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
75 75 hgext/share.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
76 76 hgext/shelve.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
77 77 hgext/strip.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
78 78 hgext/transplant.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
79 79 hgext/win32text.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
80 80 mercurial/archival.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
81 81 mercurial/bookmarks.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
82 82 mercurial/branchmap.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
83 83 mercurial/bundle2.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
84 84 mercurial/bundlerepo.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
85 85 mercurial/byterange.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
86 86 mercurial/changegroup.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
87 87 mercurial/changelog.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
88 88 mercurial/cmdutil.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
89 89 mercurial/commands.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
90 90 mercurial/commandserver.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
91 91 mercurial/config.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
92 92 mercurial/context.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
93 93 mercurial/copies.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
94 94 mercurial/crecord.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
95 95 mercurial/destutil.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
96 96 mercurial/dirstate.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
97 97 mercurial/discovery.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
98 98 mercurial/dispatch.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
99 99 mercurial/encoding.py: error importing module: <TypeError> bytes expected, not str (line *)
100 100 mercurial/exchange.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
101 101 mercurial/extensions.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
102 102 mercurial/filelog.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
103 103 mercurial/filemerge.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
104 104 mercurial/fileset.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
105 105 mercurial/formatter.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
106 106 mercurial/graphmod.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
107 107 mercurial/help.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
108 108 mercurial/hg.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
109 109 mercurial/hgweb/common.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
110 110 mercurial/hgweb/hgweb_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
111 111 mercurial/hgweb/hgwebdir_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
112 112 mercurial/hgweb/protocol.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
113 113 mercurial/hgweb/request.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
114 114 mercurial/hgweb/server.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
115 115 mercurial/hgweb/webcommands.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
116 116 mercurial/hgweb/webutil.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
117 117 mercurial/hgweb/wsgicgi.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *)
118 118 mercurial/hook.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
119 119 mercurial/httpconnection.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
120 120 mercurial/httppeer.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
121 121 mercurial/i18n.py: error importing module: <TypeError> bytes expected, not str (line *)
122 122 mercurial/keepalive.py: error importing module: <AttributeError> module 'mercurial.util' has no attribute 'httplib' (line *)
123 123 mercurial/localrepo.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*)
124 mercurial/mail.py: error importing module: <AttributeError> module 'email' has no attribute 'Header' (line *)
125 mercurial/manifest.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
126 mercurial/merge.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
127 mercurial/namespaces.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
128 mercurial/patch.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
124 mercurial/manifest.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
125 mercurial/merge.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
126 mercurial/namespaces.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
127 mercurial/patch.py: error importing module: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (line *)
129 128 mercurial/pvec.py: error importing module: <NameError> name 'xrange' is not defined (line *)
130 129 mercurial/repair.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*)
131 mercurial/revlog.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
130 mercurial/revlog.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
132 131 mercurial/revset.py: error importing module: <AttributeError> 'dict' object has no attribute 'iteritems' (line *)
133 132 mercurial/scmwindows.py: error importing module: <ImportError> No module named 'winreg' (line *)
134 133 mercurial/sshpeer.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*)
135 mercurial/sshserver.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
134 mercurial/sshserver.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
136 135 mercurial/statichttprepo.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'urlerr' (error at byterange.py:*)
137 136 mercurial/store.py: error importing module: <NameError> name 'xrange' is not defined (line *)
138 137 mercurial/streamclone.py: error importing: <TypeError> can't concat bytes to str (error at store.py:*)
139 mercurial/subrepo.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
140 mercurial/templatefilters.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
141 mercurial/templatekw.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
142 mercurial/templater.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
143 mercurial/ui.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
144 mercurial/unionrepo.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
138 mercurial/subrepo.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
139 mercurial/templatefilters.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
140 mercurial/templatekw.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
141 mercurial/templater.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
142 mercurial/ui.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
143 mercurial/unionrepo.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*)
145 144 mercurial/url.py: error importing: <AttributeError> module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*)
146 mercurial/verify.py: error importing: <AttributeError> module 'email' has no attribute 'Header' (error at mail.py:*)
147 145 mercurial/win32.py: error importing module: <ImportError> No module named 'msvcrt' (line *)
148 146 mercurial/windows.py: error importing module: <ImportError> No module named 'msvcrt' (line *)
149 147 mercurial/wireproto.py: error importing: <TypeError> %b requires bytes, or an object that implements __bytes__, not 'str' (error at bundle2.py:*)
150 148
151 149 #endif
152 150
153 151 #if py3exe py3pygments
154 152 $ hg files 'set:(**.py) and grep(pygments)' | sed 's|\\|/|g' \
155 153 > | xargs $PYTHON3 contrib/check-py3-compat.py \
156 154 > | sed 's/[0-9][0-9]*)$/*)/'
157 155 hgext/highlight/highlight.py: error importing: <TypeError> Can't mix strings and bytes in path components (error at i18n.py:*)
158 156 #endif
General Comments 0
You need to be logged in to leave comments. Login now