--- a/hgext/acl.py Thu Apr 07 00:05:48 2016 +0000
+++ b/hgext/acl.py Wed Apr 06 23:22:12 2016 +0000
@@ -194,7 +194,6 @@
from __future__ import absolute_import
import getpass
-import urllib
from mercurial.i18n import _
from mercurial import (
@@ -203,6 +202,8 @@
util,
)
+urlreq = util.urlreq
+
# Note for extension authors: ONLY specify testedwith = 'internal' for
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
@@ -287,7 +288,7 @@
if source == 'serve' and 'url' in kwargs:
url = kwargs['url'].split(':')
if url[0] == 'remote' and url[1].startswith('http'):
- user = urllib.unquote(url[3])
+ user = urlreq.unquote(url[3])
if user is None:
user = getpass.getuser()
--- a/hgext/convert/subversion.py Thu Apr 07 00:05:48 2016 +0000
+++ b/hgext/convert/subversion.py Wed Apr 06 23:22:12 2016 +0000
@@ -8,8 +8,6 @@
import re
import sys
import tempfile
-import urllib
-import urllib2
import xml.dom.minidom
from mercurial import (
@@ -25,6 +23,8 @@
stringio = util.stringio
propertycache = util.propertycache
+urlerr = util.urlerr
+urlreq = util.urlreq
commandline = common.commandline
commit = common.commit
@@ -94,7 +94,7 @@
# so we can extend it safely with new components. The "safe"
# characters were taken from the "svn_uri__char_validity" table in
# libsvn_subr/path.c.
- return urllib.quote(s, "!$&'()*+,-./:=@_~")
+ return urlreq.quote(s, "!$&'()*+,-./:=@_~")
def geturl(path):
try:
@@ -233,10 +233,10 @@
# for the svn-specific "not found" XML.
def httpcheck(ui, path, proto):
try:
- opener = urllib2.build_opener()
+ opener = urlreq.buildopener()
rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path))
data = rsp.read()
- except urllib2.HTTPError as inst:
+ except urlerr.httperror as inst:
if inst.code != 404:
# Except for 404 we cannot know for sure this is not an svn repo
ui.warn(_('svn: cannot probe remote repository, assume it could '
@@ -245,7 +245,7 @@
return True
data = inst.fp.read()
except Exception:
- # Could be urllib2.URLError if the URL is invalid or anything else.
+ # Could be urlerr.urlerror if the URL is invalid or anything else.
return False
return '<m:human-readable errcode="160013">' in data
@@ -260,7 +260,7 @@
if (os.name == 'nt' and path[:1] == '/' and path[1:2].isalpha()
and path[2:6].lower() == '%3a/'):
path = path[:2] + ':/' + path[6:]
- path = urllib.url2pathname(path)
+ path = urlreq.url2pathname(path)
except ValueError:
proto = 'file'
path = os.path.abspath(url)
@@ -330,7 +330,7 @@
self.baseurl = svn.ra.get_repos_root(self.ra)
# Module is either empty or a repository path starting with
# a slash and not ending with a slash.
- self.module = urllib.unquote(self.url[len(self.baseurl):])
+ self.module = urlreq.unquote(self.url[len(self.baseurl):])
self.prevmodule = None
self.rootmodule = self.module
self.commits = {}
--- a/hgext/largefiles/proto.py Thu Apr 07 00:05:48 2016 +0000
+++ b/hgext/largefiles/proto.py Wed Apr 06 23:22:12 2016 +0000
@@ -4,12 +4,14 @@
# GNU General Public License version 2 or any later version.
import os
-import urllib2
import re
from mercurial import error, httppeer, util, wireproto
from mercurial.i18n import _
+urlerr = util.urlerr
+urlreq = util.urlreq
+
import lfutil
LARGEFILES_REQUIRED_MSG = ('\nThis repository uses the largefiles extension.'
@@ -140,7 +142,7 @@
yield result, f
try:
yield int(f.value)
- except (ValueError, urllib2.HTTPError):
+ except (ValueError, urlerr.httperror):
# If the server returns anything but an integer followed by a
# newline, newline, it's not speaking our language; if we get
# an HTTP error, we can't be sure the largefile is present;
--- a/hgext/largefiles/remotestore.py Thu Apr 07 00:05:48 2016 +0000
+++ b/hgext/largefiles/remotestore.py Wed Apr 06 23:22:12 2016 +0000
@@ -6,11 +6,12 @@
'''remote largefile store; the base class for wirestore'''
-import urllib2
-
from mercurial import util, wireproto, error
from mercurial.i18n import _
+urlerr = util.urlerr
+urlreq = util.urlreq
+
import lfutil
import basestore
@@ -49,11 +50,11 @@
def _getfile(self, tmpfile, filename, hash):
try:
chunks = self._get(hash)
- except urllib2.HTTPError as e:
+ except urlerr.httperror as e:
# 401s get converted to error.Aborts; everything else is fine being
# turned into a StoreError
raise basestore.StoreError(filename, hash, self.url, str(e))
- except urllib2.URLError as e:
+ except urlerr.urlerror as e:
# This usually indicates a connection problem, so don't
# keep trying with the other files... they will probably
# all fail too.
--- a/mercurial/bundle2.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/bundle2.py Wed Apr 06 23:22:12 2016 +0000
@@ -152,7 +152,6 @@
import string
import struct
import sys
-import urllib
from .i18n import _
from . import (
@@ -165,6 +164,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
_pack = struct.pack
_unpack = struct.unpack
@@ -457,8 +459,8 @@
else:
key, vals = line.split('=', 1)
vals = vals.split(',')
- key = urllib.unquote(key)
- vals = [urllib.unquote(v) for v in vals]
+ key = urlreq.unquote(key)
+ vals = [urlreq.unquote(v) for v in vals]
caps[key] = vals
return caps
@@ -467,8 +469,8 @@
chunks = []
for ca in sorted(caps):
vals = caps[ca]
- ca = urllib.quote(ca)
- vals = [urllib.quote(v) for v in vals]
+ ca = urlreq.quote(ca)
+ vals = [urlreq.quote(v) for v in vals]
if vals:
ca = "%s=%s" % (ca, ','.join(vals))
chunks.append(ca)
@@ -570,9 +572,9 @@
"""return a encoded version of all stream parameters"""
blocks = []
for par, value in self._params:
- par = urllib.quote(par)
+ par = urlreq.quote(par)
if value is not None:
- value = urllib.quote(value)
+ value = urlreq.quote(value)
par = '%s=%s' % (par, value)
blocks.append(par)
return ' '.join(blocks)
@@ -691,7 +693,7 @@
params = {}
for p in paramsblock.split(' '):
p = p.split('=', 1)
- p = [urllib.unquote(i) for i in p]
+ p = [urlreq.unquote(i) for i in p]
if len(p) < 2:
p.append(None)
self._processparam(*p)
@@ -1269,7 +1271,7 @@
raw = remote.capable('bundle2')
if not raw and raw != '':
return {}
- capsblob = urllib.unquote(remote.capable('bundle2'))
+ capsblob = urlreq.unquote(remote.capable('bundle2'))
return decodecaps(capsblob)
def obsmarkersversion(caps):
--- a/mercurial/byterange.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/byterange.py Wed Apr 06 23:22:12 2016 +0000
@@ -26,22 +26,27 @@
import re
import socket
import stat
-import urllib
-import urllib2
+
+from . import (
+ util,
+)
+
+urlerr = util.urlerr
+urlreq = util.urlreq
-addclosehook = urllib.addclosehook
-addinfourl = urllib.addinfourl
-splitattr = urllib.splitattr
-splitpasswd = urllib.splitpasswd
-splitport = urllib.splitport
-splituser = urllib.splituser
-unquote = urllib.unquote
+addclosehook = urlreq.addclosehook
+addinfourl = urlreq.addinfourl
+splitattr = urlreq.splitattr
+splitpasswd = urlreq.splitpasswd
+splitport = urlreq.splitport
+splituser = urlreq.splituser
+unquote = urlreq.unquote
class RangeError(IOError):
"""Error raised when an unsatisfiable range is requested."""
pass
-class HTTPRangeHandler(urllib2.BaseHandler):
+class HTTPRangeHandler(urlreq.basehandler):
"""Handler that enables HTTP Range headers.
This was extremely simple. The Range header is a HTTP feature to
@@ -54,20 +59,20 @@
import byterange
range_handler = range.HTTPRangeHandler()
- opener = urllib2.build_opener(range_handler)
+ opener = urlreq.buildopener(range_handler)
# install it
- urllib2.install_opener(opener)
+ urlreq.installopener(opener)
# create Request and set Range header
- req = urllib2.Request('http://www.python.org/')
+ req = urlreq.request('http://www.python.org/')
req.header['Range'] = 'bytes=30-50'
- f = urllib2.urlopen(req)
+ f = urlreq.urlopen(req)
"""
def http_error_206(self, req, fp, code, msg, hdrs):
# 206 Partial Content Response
- r = urllib.addinfourl(fp, hdrs, req.get_full_url())
+ r = urlreq.addinfourl(fp, hdrs, req.get_full_url())
r.code = code
r.msg = msg
return r
@@ -204,7 +209,7 @@
raise RangeError('Requested Range Not Satisfiable')
pos += bufsize
-class FileRangeHandler(urllib2.FileHandler):
+class FileRangeHandler(urlreq.filehandler):
"""FileHandler subclass that adds Range support.
This class handles Range headers exactly like an HTTP
server would.
@@ -212,15 +217,15 @@
def open_local_file(self, req):
host = req.get_host()
file = req.get_selector()
- localfile = urllib.url2pathname(file)
+ localfile = urlreq.url2pathname(file)
stats = os.stat(localfile)
size = stats[stat.ST_SIZE]
modified = email.Utils.formatdate(stats[stat.ST_MTIME])
mtype = mimetypes.guess_type(file)[0]
if host:
- host, port = urllib.splitport(host)
+ host, port = urlreq.splitport(host)
if port or socket.gethostbyname(host) not in self.get_names():
- raise urllib2.URLError('file not on local host')
+ raise urlerr.urlerror('file not on local host')
fo = open(localfile,'rb')
brange = req.headers.get('Range', None)
brange = range_header_to_tuple(brange)
@@ -236,7 +241,7 @@
headers = email.message_from_string(
'Content-Type: %s\nContent-Length: %d\nLast-Modified: %s\n' %
(mtype or 'text/plain', size, modified))
- return urllib.addinfourl(fo, headers, 'file:'+file)
+ return urlreq.addinfourl(fo, headers, 'file:'+file)
# FTP Range Support
@@ -246,7 +251,7 @@
# follows:
# -- range support modifications start/end here
-class FTPRangeHandler(urllib2.FTPHandler):
+class FTPRangeHandler(urlreq.ftphandler):
def ftp_open(self, req):
host = req.get_host()
if not host:
@@ -270,7 +275,7 @@
try:
host = socket.gethostbyname(host)
except socket.error as msg:
- raise urllib2.URLError(msg)
+ raise urlerr.urlerror(msg)
path, attrs = splitattr(req.get_selector())
dirs = path.split('/')
dirs = map(unquote, dirs)
@@ -334,7 +339,7 @@
fw = ftpwrapper(user, passwd, host, port, dirs)
return fw
-class ftpwrapper(urllib.ftpwrapper):
+class ftpwrapper(urlreq.ftpwrapper):
# range support note:
# this ftpwrapper code is copied directly from
# urllib. The only enhancement is to add the rest
--- a/mercurial/exchange.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/exchange.py Wed Apr 06 23:22:12 2016 +0000
@@ -8,8 +8,6 @@
from __future__ import absolute_import
import errno
-import urllib
-import urllib2
from .i18n import _
from .node import (
@@ -35,6 +33,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
# Maps bundle compression human names to internal representation.
_bundlespeccompressions = {'none': None,
'bzip2': 'BZ',
@@ -97,8 +98,8 @@
'missing "=" in parameter: %s') % p)
key, value = p.split('=', 1)
- key = urllib.unquote(key)
- value = urllib.unquote(value)
+ key = urlreq.unquote(key)
+ value = urlreq.unquote(value)
params[key] = value
return version, params
@@ -236,7 +237,7 @@
elif isinstance(b, streamclone.streamcloneapplier):
requirements = streamclone.readbundle1header(fh)[2]
params = 'requirements=%s' % ','.join(sorted(requirements))
- return 'none-packed1;%s' % urllib.quote(params)
+ return 'none-packed1;%s' % urlreq.quote(params)
else:
raise error.Abort(_('unknown bundle type: %s') % b)
@@ -1465,7 +1466,7 @@
"""return a set with appropriate options to use bundle20 during getbundle"""
caps = set(['HG20'])
capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
- caps.add('bundle2=' + urllib.quote(capsblob))
+ caps.add('bundle2=' + urlreq.quote(capsblob))
return caps
# List of names of steps to perform for a bundle2 for getbundle, order matters.
@@ -1531,7 +1532,7 @@
b2caps = {}
for bcaps in bundlecaps:
if bcaps.startswith('bundle2='):
- blob = urllib.unquote(bcaps[len('bundle2='):])
+ blob = urlreq.unquote(bcaps[len('bundle2='):])
b2caps.update(bundle2.decodecaps(blob))
bundler = bundle2.bundle20(repo.ui, b2caps)
@@ -1800,8 +1801,8 @@
attrs = {'URL': fields[0]}
for rawattr in fields[1:]:
key, value = rawattr.split('=', 1)
- key = urllib.unquote(key)
- value = urllib.unquote(value)
+ key = urlreq.unquote(key)
+ value = urlreq.unquote(value)
attrs[key] = value
# Parse BUNDLESPEC into components. This makes client-side
@@ -1917,9 +1918,9 @@
cg.apply(repo, 'clonebundles', url)
tr.close()
return True
- except urllib2.HTTPError as e:
+ except urlerr.httperror as e:
ui.warn(_('HTTP error fetching bundle: %s\n') % str(e))
- except urllib2.URLError as e:
+ except urlerr.urlerror as e:
ui.warn(_('error fetching bundle: %s\n') % e.reason[1])
return False
--- a/mercurial/hgweb/protocol.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/hgweb/protocol.py Wed Apr 06 23:22:12 2016 +0000
@@ -8,7 +8,6 @@
from __future__ import absolute_import
import cgi
-import urllib
import zlib
from .common import (
@@ -21,6 +20,9 @@
)
stringio = util.stringio
+urlerr = util.urlerr
+urlreq = util.urlreq
+
HGTYPE = 'application/mercurial-0.1'
HGERRTYPE = 'application/hg-error'
@@ -82,8 +84,8 @@
def _client(self):
return 'remote:%s:%s:%s' % (
self.req.env.get('wsgi.url_scheme') or 'http',
- urllib.quote(self.req.env.get('REMOTE_HOST', '')),
- urllib.quote(self.req.env.get('REMOTE_USER', '')))
+ urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
+ urlreq.quote(self.req.env.get('REMOTE_USER', '')))
def iscmd(cmd):
return cmd in wireproto.commands
--- a/mercurial/hgweb/server.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/hgweb/server.py Wed Apr 06 23:22:12 2016 +0000
@@ -15,7 +15,6 @@
import socket
import sys
import traceback
-import urllib
from ..i18n import _
@@ -24,6 +23,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
from . import (
common,
)
@@ -38,7 +40,7 @@
path, query = uri.split('?', 1)
else:
path, query = uri, ''
- return urllib.unquote(path), query
+ return urlreq.unquote(path), query
class _error_logger(object):
def __init__(self, handler):
--- a/mercurial/httpconnection.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/httpconnection.py Wed Apr 06 23:22:12 2016 +0000
@@ -13,8 +13,6 @@
import logging
import os
import socket
-import urllib
-import urllib2
from .i18n import _
from . import (
@@ -23,6 +21,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
# moved here from url.py to avoid a cycle
class httpsendfile(object):
"""This is a wrapper around the objects returned by python's "open".
@@ -123,10 +124,10 @@
# Subclass BOTH of these because otherwise urllib2 "helpfully"
# reinserts them since it notices we don't include any subclasses of
# them.
-class http2handler(urllib2.HTTPHandler, urllib2.HTTPSHandler):
+class http2handler(urlreq.httphandler, urlreq.httpshandler):
def __init__(self, ui, pwmgr):
global _configuredlogging
- urllib2.AbstractHTTPHandler.__init__(self)
+ urlreq.abstracthttphandler.__init__(self)
self.ui = ui
self.pwmgr = pwmgr
self._connections = {}
@@ -187,7 +188,7 @@
proxy = None
if not host:
- raise urllib2.URLError('no host given')
+ raise urlerr.urlerror('no host given')
connkey = use_ssl, host, proxy
allconns = self._connections.get(connkey, [])
@@ -217,13 +218,13 @@
h.request(req.get_method(), path, req.data, headers)
r = h.getresponse()
except socket.error as err: # XXX what error?
- raise urllib2.URLError(err)
+ raise urlerr.urlerror(err)
# Pick apart the HTTPResponse object to get the addinfourl
# object initialized properly.
r.recv = r.read
- resp = urllib.addinfourl(r, r.headers, req.get_full_url())
+ resp = urlreq.addinfourl(r, r.headers, req.get_full_url())
resp.code = r.status
resp.msg = r.reason
return resp
--- a/mercurial/httppeer.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/httppeer.py Wed Apr 06 23:22:12 2016 +0000
@@ -13,8 +13,6 @@
import os
import socket
import tempfile
-import urllib
-import urllib2
import zlib
from .i18n import _
@@ -29,6 +27,9 @@
wireproto,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
def zgenerator(f):
zd = zlib.decompressobj()
try:
@@ -59,7 +60,7 @@
self.ui.debug('using %s\n' % self._url)
self.urlopener = url.opener(ui, authinfo)
- self.requestbuilder = urllib2.Request
+ self.requestbuilder = urlreq.request
def __del__(self):
if self.urlopener:
@@ -105,7 +106,7 @@
# object rather than a basestring
canmungedata = not data or isinstance(data, basestring)
if postargsok and canmungedata:
- strargs = urllib.urlencode(sorted(args.items()))
+ strargs = urlreq.urlencode(sorted(args.items()))
if strargs:
if not data:
data = strargs
@@ -119,7 +120,7 @@
headersize = int(httpheader.split(',', 1)[0])
if headersize > 0:
# The headers can typically carry more data than the URL.
- encargs = urllib.urlencode(sorted(args.items()))
+ encargs = urlreq.urlencode(sorted(args.items()))
headerfmt = 'X-HgArg-%s'
contentlen = headersize - len(headerfmt % '000' + ': \r\n')
headernum = 0
@@ -132,7 +133,7 @@
headers['Vary'] = ','.join(varyheaders)
else:
q += sorted(args.items())
- qs = '?%s' % urllib.urlencode(q)
+ qs = '?%s' % urlreq.urlencode(q)
cu = "%s%s" % (self._url, qs)
size = 0
if util.safehasattr(data, 'length'):
@@ -150,7 +151,7 @@
req.add_unredirected_header('Content-Length', '%d' % size)
try:
resp = self.urlopener.open(req)
- except urllib2.HTTPError as inst:
+ except urlerr.httperror as inst:
if inst.code == 401:
raise error.Abort(_('authorization failed'))
raise
--- a/mercurial/keepalive.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/keepalive.py Wed Apr 06 23:22:12 2016 +0000
@@ -28,10 +28,10 @@
>>> import urllib2
>>> from keepalive import HTTPHandler
>>> keepalive_handler = HTTPHandler()
->>> opener = urllib2.build_opener(keepalive_handler)
->>> urllib2.install_opener(opener)
+>>> opener = urlreq.buildopener(keepalive_handler)
+>>> urlreq.installopener(opener)
>>>
->>> fo = urllib2.urlopen('http://www.python.org')
+>>> fo = urlreq.urlopen('http://www.python.org')
If a connection to a given host is requested, and all of the existing
connections are still in use, another connection will be opened. If
@@ -114,7 +114,13 @@
import socket
import sys
import thread
-import urllib2
+
+from . import (
+ util,
+)
+
+urlerr = util.urlerr
+urlreq = util.urlreq
DEBUG = None
@@ -227,7 +233,7 @@
def do_open(self, http_class, req):
host = req.get_host()
if not host:
- raise urllib2.URLError('no host given')
+ raise urlerr.urlerror('no host given')
try:
h = self._cm.get_ready_conn(host)
@@ -254,7 +260,7 @@
self._start_transaction(h, req)
r = h.getresponse()
except (socket.error, httplib.HTTPException) as err:
- raise urllib2.URLError(err)
+ raise urlerr.urlerror(err)
# if not a persistent connection, don't try to reuse it
if r.will_close:
@@ -346,14 +352,14 @@
else:
h.putrequest('GET', req.get_selector(), **skipheaders)
except socket.error as err:
- raise urllib2.URLError(err)
+ raise urlerr.urlerror(err)
for k, v in headers.items():
h.putheader(k, v)
h.endheaders()
if req.has_data():
h.send(data)
-class HTTPHandler(KeepAliveHandler, urllib2.HTTPHandler):
+class HTTPHandler(KeepAliveHandler, urlreq.httphandler):
pass
class HTTPResponse(httplib.HTTPResponse):
@@ -593,14 +599,14 @@
global HANDLE_ERRORS
orig = HANDLE_ERRORS
keepalive_handler = HTTPHandler()
- opener = urllib2.build_opener(keepalive_handler)
- urllib2.install_opener(opener)
+ opener = urlreq.buildopener(keepalive_handler)
+ urlreq.installopener(opener)
pos = {0: 'off', 1: 'on'}
for i in (0, 1):
print(" fancy error handling %s (HANDLE_ERRORS = %i)" % (pos[i], i))
HANDLE_ERRORS = i
try:
- fo = urllib2.urlopen(url)
+ fo = urlreq.urlopen(url)
fo.read()
fo.close()
try:
@@ -623,25 +629,25 @@
format = '%25s: %s'
# first fetch the file with the normal http handler
- opener = urllib2.build_opener()
- urllib2.install_opener(opener)
- fo = urllib2.urlopen(url)
+ opener = urlreq.buildopener()
+ urlreq.installopener(opener)
+ fo = urlreq.urlopen(url)
foo = fo.read()
fo.close()
m = md5(foo)
print(format % ('normal urllib', m.hexdigest()))
# now install the keepalive handler and try again
- opener = urllib2.build_opener(HTTPHandler())
- urllib2.install_opener(opener)
+ opener = urlreq.buildopener(HTTPHandler())
+ urlreq.installopener(opener)
- fo = urllib2.urlopen(url)
+ fo = urlreq.urlopen(url)
foo = fo.read()
fo.close()
m = md5(foo)
print(format % ('keepalive read', m.hexdigest()))
- fo = urllib2.urlopen(url)
+ fo = urlreq.urlopen(url)
foo = ''
while True:
f = fo.readline()
@@ -657,15 +663,15 @@
sys.stdout.write(' first using the normal urllib handlers')
# first use normal opener
- opener = urllib2.build_opener()
- urllib2.install_opener(opener)
+ opener = urlreq.buildopener()
+ urlreq.installopener(opener)
t1 = fetch(N, url)
print(' TIME: %.3f s' % t1)
sys.stdout.write(' now using the keepalive handler ')
# now install the keepalive handler and try again
- opener = urllib2.build_opener(HTTPHandler())
- urllib2.install_opener(opener)
+ opener = urlreq.buildopener(HTTPHandler())
+ urlreq.installopener(opener)
t2 = fetch(N, url)
print(' TIME: %.3f s' % t2)
print(' improvement factor: %.2f' % (t1 / t2))
@@ -677,7 +683,7 @@
for i in range(N):
if delay and i > 0:
time.sleep(delay)
- fo = urllib2.urlopen(url)
+ fo = urlreq.urlopen(url)
foo = fo.read()
fo.close()
lens.append(len(foo))
@@ -700,7 +706,7 @@
info = warning = error = debug
DEBUG = FakeLogger()
print(" fetching the file to establish a connection")
- fo = urllib2.urlopen(url)
+ fo = urlreq.urlopen(url)
data1 = fo.read()
fo.close()
@@ -714,7 +720,7 @@
sys.stderr.write('\r')
print(" fetching the file a second time")
- fo = urllib2.urlopen(url)
+ fo = urlreq.urlopen(url)
data2 = fo.read()
fo.close()
--- a/mercurial/localrepo.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/localrepo.py Wed Apr 06 23:22:12 2016 +0000
@@ -12,7 +12,6 @@
import os
import random
import time
-import urllib
import weakref
from .i18n import _
@@ -59,6 +58,8 @@
release = lockmod.release
propertycache = util.propertycache
+urlerr = util.urlerr
+urlreq = util.urlreq
filecache = scmutil.filecache
class repofilecache(filecache):
@@ -366,7 +367,7 @@
if self.ui.configbool('experimental', 'bundle2-advertise', True):
caps = set(caps)
capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
- caps.add('bundle2=' + urllib.quote(capsblob))
+ caps.add('bundle2=' + urlreq.quote(capsblob))
return caps
def _applyopenerreqs(self):
--- a/mercurial/statichttprepo.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/statichttprepo.py Wed Apr 06 23:22:12 2016 +0000
@@ -11,8 +11,6 @@
import errno
import os
-import urllib
-import urllib2
from .i18n import _
from . import (
@@ -28,6 +26,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
class httprangereader(object):
def __init__(self, url, opener):
# we assume opener has HTTPRangeHandler
@@ -45,7 +46,7 @@
def seek(self, pos):
self.pos = pos
def read(self, bytes=None):
- req = urllib2.Request(self.url)
+ req = urlreq.request(self.url)
end = ''
if bytes:
end = self.pos + bytes - 1
@@ -56,10 +57,10 @@
f = self.opener.open(req)
data = f.read()
code = f.code
- except urllib2.HTTPError as inst:
+ except urlerr.httperror as inst:
num = inst.code == 404 and errno.ENOENT or None
raise IOError(num, inst)
- except urllib2.URLError as inst:
+ except urlerr.urlerror as inst:
raise IOError(None, inst.reason[1])
if code == 200:
@@ -92,7 +93,7 @@
def __call__(self, path, mode='r', *args, **kw):
if mode not in ('r', 'rb'):
raise IOError('Permission denied')
- f = "/".join((self.base, urllib.quote(path)))
+ f = "/".join((self.base, urlreq.quote(path)))
return httprangereader(f, urlopener)
def join(self, path):
--- a/mercurial/templatefilters.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/templatefilters.py Wed Apr 06 23:22:12 2016 +0000
@@ -11,7 +11,6 @@
import os
import re
import time
-import urllib
from . import (
encoding,
@@ -22,6 +21,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
# filters are callables like:
# fn(obj)
# with:
@@ -299,7 +301,7 @@
Forward slashes are escaped twice to prevent web servers from prematurely
unescaping them. For example, "@foo bar/baz" becomes "@foo%20bar%252Fbaz".
"""
- return urllib.quote(text, safe='/@').replace('/', '%252F')
+ return urlreq.quote(text, safe='/@').replace('/', '%252F')
@templatefilter('rfc3339date')
def rfc3339date(text):
@@ -384,7 +386,7 @@
"""Any text. Escapes all "special" characters. For example,
"foo bar" becomes "foo%20bar".
"""
- return urllib.quote(text)
+ return urlreq.quote(text)
@templatefilter('user')
def userfilter(text):
--- a/mercurial/url.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/url.py Wed Apr 06 23:22:12 2016 +0000
@@ -13,8 +13,6 @@
import httplib
import os
import socket
-import urllib
-import urllib2
from .i18n import _
from . import (
@@ -26,13 +24,16 @@
)
stringio = util.stringio
-class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
+urlerr = util.urlerr
+urlreq = util.urlreq
+
+class passwordmgr(urlreq.httppasswordmgrwithdefaultrealm):
def __init__(self, ui):
- urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
+ urlreq.httppasswordmgrwithdefaultrealm.__init__(self)
self.ui = ui
def find_user_password(self, realm, authuri):
- authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
+ authinfo = urlreq.httppasswordmgrwithdefaultrealm.find_user_password(
self, realm, authuri)
user, passwd = authinfo
if user and passwd:
@@ -72,10 +73,10 @@
self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set'))
def find_stored_password(self, authuri):
- return urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
+ return urlreq.httppasswordmgrwithdefaultrealm.find_user_password(
self, None, authuri)
-class proxyhandler(urllib2.ProxyHandler):
+class proxyhandler(urlreq.proxyhandler):
def __init__(self, ui):
proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
# XXX proxyauthinfo = None
@@ -121,7 +122,7 @@
except OSError:
pass
- urllib2.ProxyHandler.__init__(self, proxies)
+ urlreq.proxyhandler.__init__(self, proxies)
self.ui = ui
def proxy_open(self, req, proxy, type_):
@@ -134,7 +135,7 @@
if e.startswith('.') and host.endswith(e[1:]):
return None
- return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
+ return urlreq.proxyhandler.proxy_open(self, req, proxy, type_)
def _gen_sendfile(orgsend):
def _sendfile(self, data):
@@ -148,7 +149,7 @@
orgsend(self, data)
return _sendfile
-has_https = util.safehasattr(urllib2, 'HTTPSHandler')
+has_https = util.safehasattr(urlreq, 'httpshandler')
if has_https:
try:
_create_connection = socket.create_connection
@@ -357,10 +358,10 @@
**sslutil.sslkwargs(self.ui, host))
sslutil.validator(self.ui, host)(self.sock)
- class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
+ class httpshandler(keepalive.KeepAliveHandler, urlreq.httpshandler):
def __init__(self, ui):
keepalive.KeepAliveHandler.__init__(self)
- urllib2.HTTPSHandler.__init__(self)
+ urlreq.httpshandler.__init__(self)
self.ui = ui
self.pwmgr = passwordmgr(self.ui)
@@ -403,9 +404,9 @@
conn.ui = self.ui
return conn
-class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
+class httpdigestauthhandler(urlreq.httpdigestauthhandler):
def __init__(self, *args, **kwargs):
- urllib2.HTTPDigestAuthHandler.__init__(self, *args, **kwargs)
+ urlreq.httpdigestauthhandler.__init__(self, *args, **kwargs)
self.retried_req = None
def reset_retry_count(self):
@@ -419,13 +420,13 @@
if req is not self.retried_req:
self.retried_req = req
self.retried = 0
- return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
+ return urlreq.httpdigestauthhandler.http_error_auth_reqed(
self, auth_header, host, req, headers)
-class httpbasicauthhandler(urllib2.HTTPBasicAuthHandler):
+class httpbasicauthhandler(urlreq.httpbasicauthhandler):
def __init__(self, *args, **kwargs):
self.auth = None
- urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
+ urlreq.httpbasicauthhandler.__init__(self, *args, **kwargs)
self.retried_req = None
def http_request(self, request):
@@ -451,7 +452,7 @@
if req is not self.retried_req:
self.retried_req = req
self.retried = 0
- return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
+ return urlreq.httpbasicauthhandler.http_error_auth_reqed(
self, auth_header, host, req, headers)
def retry_http_basic_auth(self, host, req, realm):
@@ -494,7 +495,7 @@
handlers.extend((httpbasicauthhandler(passmgr),
httpdigestauthhandler(passmgr)))
handlers.extend([h(ui, passmgr) for h in handlerfuncs])
- opener = urllib2.build_opener(*handlers)
+ opener = urlreq.buildopener(*handlers)
# 1.0 here is the _protocol_ version
opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
@@ -508,6 +509,6 @@
url_, authinfo = u.authinfo()
else:
path = util.normpath(os.path.abspath(url_))
- url_ = 'file://' + urllib.pathname2url(path)
+ url_ = 'file://' + urlreq.pathname2url(path)
authinfo = None
return opener(ui, authinfo).open(url_, data)
--- a/mercurial/util.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/util.py Wed Apr 06 23:22:12 2016 +0000
@@ -34,7 +34,6 @@
import textwrap
import time
import traceback
-import urllib
import zlib
from . import (
@@ -50,11 +49,15 @@
'empty',
'queue',
'urlerr',
- 'urlreq',
+ # we do import urlreq, but we do it outside the loop
+ #'urlreq',
'stringio',
):
globals()[attr] = getattr(pycompat, attr)
+# This line is to make pyflakes happy:
+urlreq = pycompat.urlreq
+
if os.name == 'nt':
from . import windows as platform
else:
@@ -2388,30 +2391,30 @@
if hasdriveletter(self.path):
s += '/'
if self.user:
- s += urllib.quote(self.user, safe=self._safechars)
+ s += urlreq.quote(self.user, safe=self._safechars)
if self.passwd:
- s += ':' + urllib.quote(self.passwd, safe=self._safechars)
+ s += ':' + urlreq.quote(self.passwd, safe=self._safechars)
if self.user or self.passwd:
s += '@'
if self.host:
if not (self.host.startswith('[') and self.host.endswith(']')):
- s += urllib.quote(self.host)
+ s += urlreq.quote(self.host)
else:
s += self.host
if self.port:
- s += ':' + urllib.quote(self.port)
+ s += ':' + urlreq.quote(self.port)
if self.host:
s += '/'
if self.path:
# TODO: similar to the query string, we should not unescape the
# path when we store it, the path might contain '%2f' = '/',
# which we should *not* escape.
- s += urllib.quote(self.path, safe=self._safepchars)
+ s += urlreq.quote(self.path, safe=self._safepchars)
if self.query:
# we store the query in escaped form.
s += '?' + self.query
if self.fragment is not None:
- s += '#' + urllib.quote(self.fragment, safe=self._safepchars)
+ s += '#' + urlreq.quote(self.fragment, safe=self._safepchars)
return s
def authinfo(self):
--- a/mercurial/wireproto.py Thu Apr 07 00:05:48 2016 +0000
+++ b/mercurial/wireproto.py Wed Apr 06 23:22:12 2016 +0000
@@ -11,7 +11,6 @@
import os
import sys
import tempfile
-import urllib
from .i18n import _
from .node import (
@@ -31,6 +30,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
bundle2required = _(
'incompatible Mercurial client; bundle2 required\n'
'(see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n')
@@ -287,7 +289,7 @@
branchmap = {}
for branchpart in d.splitlines():
branchname, branchheads = branchpart.split(' ', 1)
- branchname = encoding.tolocal(urllib.unquote(branchname))
+ branchname = encoding.tolocal(urlreq.unquote(branchname))
branchheads = decodelist(branchheads)
branchmap[branchname] = branchheads
yield branchmap
@@ -632,7 +634,7 @@
branchmap = repo.branchmap()
heads = []
for branch, nodes in branchmap.iteritems():
- branchname = urllib.quote(encoding.fromlocal(branch))
+ branchname = urlreq.quote(encoding.fromlocal(branch))
branchnodes = encodelist(nodes)
heads.append('%s %s' % (branchname, branchnodes))
return '\n'.join(heads)
@@ -684,7 +686,7 @@
caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
if repo.ui.configbool('experimental', 'bundle2-advertise', True):
capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
- caps.append('bundle2=' + urllib.quote(capsblob))
+ caps.append('bundle2=' + urlreq.quote(capsblob))
caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
caps.append(
'httpheader=%d' % repo.ui.configint('server', 'maxhttpheaderlen', 1024))
--- a/tests/test-check-py3-compat.t Thu Apr 07 00:05:48 2016 +0000
+++ b/tests/test-check-py3-compat.t Wed Apr 06 23:22:12 2016 +0000
@@ -113,8 +113,8 @@
hgext/largefiles/lfutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
hgext/largefiles/localstore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
hgext/largefiles/overrides.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
- hgext/largefiles/proto.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
- hgext/largefiles/remotestore.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
+ hgext/largefiles/proto.py: error importing: <ImportError> No module named 'httplib' (error at httppeer.py:*) (glob)
+ hgext/largefiles/remotestore.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at wireproto.py:*) (glob)
hgext/largefiles/reposetup.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
hgext/largefiles/uisetup.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
hgext/largefiles/wirestore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
@@ -135,7 +135,6 @@
mercurial/branchmap.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/bundle*.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
mercurial/bundlerepo.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
- mercurial/byterange.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
mercurial/changegroup.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/changelog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/cmdutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
@@ -147,7 +146,7 @@
mercurial/dirstate.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/discovery.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/dispatch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
- mercurial/exchange.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
+ mercurial/exchange.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
mercurial/extensions.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/filelog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/filemerge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
@@ -167,7 +166,7 @@
mercurial/hgweb/wsgicgi.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
mercurial/hook.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/httpclient/_readers.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
- mercurial/httpconnection.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
+ mercurial/httpconnection.py: error importing: <ImportError> No module named 'httplib' (error at __init__.py:*) (glob)
mercurial/httppeer.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
mercurial/keepalive.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
mercurial/localrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
@@ -186,7 +185,7 @@
mercurial/simplemerge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/sshpeer.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at wireproto.py:*) (glob)
mercurial/sshserver.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
- mercurial/statichttprepo.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
+ mercurial/statichttprepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/store.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/streamclone.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
mercurial/subrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
--- a/tests/test-hgweb-auth.py Thu Apr 07 00:05:48 2016 +0000
+++ b/tests/test-hgweb-auth.py Wed Apr 06 23:22:12 2016 +0000
@@ -1,7 +1,6 @@
from __future__ import absolute_import, print_function
from mercurial import demandimport; demandimport.enable()
-import urllib2
from mercurial import (
error,
ui as uimod,
@@ -9,6 +8,9 @@
util,
)
+urlerr = util.urlerr
+urlreq = util.urlreq
+
class myui(uimod.ui):
def interactive(self):
return False
@@ -104,7 +106,7 @@
def testauthinfo(fullurl, authurl):
print('URIs:', fullurl, authurl)
- pm = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ pm = urlreq.httppasswordmgrwithdefaultrealm()
pm.add_password(*util.url(fullurl).authinfo()[1])
print(pm.find_user_password('test', authurl))