[PATCH 5 of 8] python3: handle urllib/urllib2 refactoring
timeless
timeless at gmail.com
Wed Mar 30 00:24:15 EDT 2016
There's a minor bug in this commit, if it's queued, could someone unqueue it?
request.urlencode should be parse.urlencode
On Tue, Mar 29, 2016 at 2:13 PM, timeless <timeless at mozdev.org> wrote:
> # HG changeset patch
> # User timeless <timeless at mozdev.org>
> # Date 1459202612 0
> # Mon Mar 28 22:03:32 2016 +0000
> # Node ID 9cc313935891c1805c271ef56ec524156eccc806
> # Parent b2205d49ee6f9a8c6ce8316bce8fd25e5d593775
> python3: handle urllib/urllib2 refactoring
>
> diff --git a/hgext/acl.py b/hgext/acl.py
> --- a/hgext/acl.py
> +++ b/hgext/acl.py
> @@ -194,7 +194,13 @@
> from __future__ import absolute_import
>
> import getpass
> -import urllib
> +
> +try:
> + import urllib
> + unquote = urllib.unquote
> +except AttributeError:
> + import urllib.request
> + unquote = urllib.request.unquote
>
> from mercurial.i18n import _
> from mercurial import (
> @@ -287,7 +293,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 = unquote(url[3])
>
> if user is None:
> user = getpass.getuser()
> diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
> --- a/hgext/convert/subversion.py
> +++ b/hgext/convert/subversion.py
> @@ -9,10 +9,25 @@
> import re
> import sys
> import tempfile
> -import urllib
> -import urllib2
> import xml.dom.minidom
>
> +try:
> + import urllib2
> + import urllib
> + httperror = urllib2.HTTPError
> + build_opener = urllib2.build_opener
> + quote = urllib.quote
> + unquote = urllib.unquote
> + url2pathname = urllib.url2pathname
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + httperror = urllib.error.HTTPError
> + build_opener = urllib.request.build_opener
> + quote = urllib.request.quote
> + unquote = urllib.request.unquote
> + url2pathname = urllib.request.url2pathname
> +
> from mercurial import (
> encoding,
> error,
> @@ -87,7 +102,7 @@
> mod = '/' + parts[1]
> return uuid, mod, revnum
>
> -def quote(s):
> +def svnquote(s):
> # As of svn 1.7, many svn calls expect "canonical" paths. In
> # theory, we should call svn.core.*canonicalize() on all paths
> # before passing them to the API. Instead, we assume the base url
> @@ -95,7 +110,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 quote(s, "!$&'()*+,-./:=@_~")
>
> def geturl(path):
> try:
> @@ -110,7 +125,7 @@
> # Module URL is later compared with the repository URL returned
> # by svn API, which is UTF-8.
> path = encoding.tolocal(path)
> - path = 'file://%s' % quote(path)
> + path = 'file://%s' % svnquote(path)
> return svn.core.svn_path_canonicalize(path)
>
> def optrev(number):
> @@ -237,7 +252,7 @@
> opener = urllib2.build_opener()
> rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path))
> data = rsp.read()
> - except urllib2.HTTPError as inst:
> + except 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 '
> @@ -261,7 +276,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 = url2pathname(path)
> except ValueError:
> proto = 'file'
> path = os.path.abspath(url)
> @@ -331,7 +346,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 = unquote(self.url[len(self.baseurl):])
> self.prevmodule = None
> self.rootmodule = self.module
> self.commits = {}
> @@ -395,7 +410,7 @@
>
> def exists(self, path, optrev):
> try:
> - svn.client.ls(self.url.rstrip('/') + '/' + quote(path),
> + svn.client.ls(self.url.rstrip('/') + '/' + svnquote(path),
> optrev, False, self.ctx)
> return True
> except svn.core.SubversionException:
> @@ -447,7 +462,7 @@
> # Check if branches bring a few more heads to the list
> if branches:
> rpath = self.url.strip('/')
> - branchnames = svn.client.ls(rpath + '/' + quote(branches),
> + branchnames = svn.client.ls(rpath + '/' + svnquote(branches),
> rev, False, self.ctx)
> for branch in sorted(branchnames):
> module = '%s/%s/%s' % (oldmodule, branches, branch)
> @@ -481,7 +496,7 @@
> if full or not parents:
> # Perform a full checkout on roots
> uuid, module, revnum = revsplit(rev)
> - entries = svn.client.ls(self.baseurl + quote(module),
> + entries = svn.client.ls(self.baseurl + svnquote(module),
> optrev(revnum), True, self.ctx)
> files = [n for n, e in entries.iteritems()
> if e.kind == svn.core.svn_node_file]
> @@ -729,7 +744,7 @@
> """Reparent the svn transport and return the previous parent."""
> if self.prevmodule == module:
> return module
> - svnurl = self.baseurl + quote(module)
> + svnurl = self.baseurl + svnquote(module)
> prevmodule = self.prevmodule
> if prevmodule is None:
> prevmodule = ''
> @@ -1012,7 +1027,7 @@
> """Enumerate all files in path at revnum, recursively."""
> path = path.strip('/')
> pool = svn.core.Pool()
> - rpath = '/'.join([self.baseurl, quote(path)]).strip('/')
> + rpath = '/'.join([self.baseurl, svnquote(path)]).strip('/')
> entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool)
> if path:
> path += '/'
> diff --git a/hgext/largefiles/proto.py b/hgext/largefiles/proto.py
> --- a/hgext/largefiles/proto.py
> +++ b/hgext/largefiles/proto.py
> @@ -4,9 +4,15 @@
> # GNU General Public License version 2 or any later version.
>
> import os
> -import urllib2
> import re
>
> +try:
> + import urllib2
> + httperror = urllib2.HTTPError
> +except ImportError:
> + import urllib.error
> + httperror = urllib.error.HTTPError
> +
> from mercurial import error, httppeer, util, wireproto
> from mercurial.i18n import _
>
> @@ -140,7 +146,7 @@
> yield result, f
> try:
> yield int(f.value)
> - except (ValueError, urllib2.HTTPError):
> + except (ValueError, 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;
> diff --git a/hgext/largefiles/remotestore.py b/hgext/largefiles/remotestore.py
> --- a/hgext/largefiles/remotestore.py
> +++ b/hgext/largefiles/remotestore.py
> @@ -6,7 +6,14 @@
>
> '''remote largefile store; the base class for wirestore'''
>
> -import urllib2
> +try:
> + import urllib2
> + httperror = urllib2.HTTPError
> + urlerror = urllib2.URLError
> +except ImportError:
> + import urllib.error
> + httperror = urllib.error.HTTPError
> + urlerror = urllib.error.URLError
>
> from mercurial import util, wireproto, error
> from mercurial.i18n import _
> @@ -49,11 +56,11 @@
> def _getfile(self, tmpfile, filename, hash):
> try:
> chunks = self._get(hash)
> - except urllib2.HTTPError as e:
> + except 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 urlerror as e:
> # This usually indicates a connection problem, so don't
> # keep trying with the other files... they will probably
> # all fail too.
> diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
> --- a/mercurial/bundle2.py
> +++ b/mercurial/bundle2.py
> @@ -152,7 +152,15 @@
> import string
> import struct
> import sys
> -import urllib
> +
> +try:
> + import urllib
> + quote = urllib.quote
> + unquote = urllib.unquote
> +except AttributeError:
> + import urllib.request
> + quote = urllib.request.quote
> + unquote = urllib.request.unquote
>
> from .i18n import _
> from . import (
> @@ -467,8 +475,8 @@
> chunks = []
> for ca in sorted(caps):
> vals = caps[ca]
> - ca = urllib.quote(ca)
> - vals = [urllib.quote(v) for v in vals]
> + ca = quote(ca)
> + vals = [quote(v) for v in vals]
> if vals:
> ca = "%s=%s" % (ca, ','.join(vals))
> chunks.append(ca)
> @@ -570,9 +578,9 @@
> """return a encoded version of all stream parameters"""
> blocks = []
> for par, value in self._params:
> - par = urllib.quote(par)
> + par = quote(par)
> if value is not None:
> - value = urllib.quote(value)
> + value = quote(value)
> par = '%s=%s' % (par, value)
> blocks.append(par)
> return ' '.join(blocks)
> diff --git a/mercurial/byterange.py b/mercurial/byterange.py
> --- a/mercurial/byterange.py
> +++ b/mercurial/byterange.py
> @@ -26,22 +26,45 @@
> import re
> import socket
> import stat
> -import urllib
> -import urllib2
>
> -addclosehook = urllib.addclosehook
> -addinfourl = urllib.addinfourl
> -splitattr = urllib.splitattr
> -splitpasswd = urllib.splitpasswd
> -splitport = urllib.splitport
> -splituser = urllib.splituser
> -unquote = urllib.unquote
> +try:
> + import urllib2
> + import urllib
> + basehandler = urllib2.BaseHandler
> + filehandler = urllib2.FileHandler
> + ftphandler = urllib2.FTPHandler
> + ftpwrapper = urllib.ftpwrapper
> + urlerror = urllib2.URLError
> + addclosehook = urllib.addclosehook
> + addinfourl = urllib.addinfourl
> + splitattr = urllib.splitattr
> + splitpasswd = urllib.splitpasswd
> + splitport = urllib.splitport
> + splituser = urllib.splituser
> + unquote = urllib.unquote
> + url2pathname = urllib.url2pathname
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + basehandler = urllib.request.BaseHandler
> + filehandler = urllib.request.FileHandler
> + ftphandler = urllib.request.FTPHandler
> + ftpwrapper = urllib.request.ftpwrapper
> + urlerror = urllib.error.URLError
> + addclosehook = urllib.request.addclosehook
> + addinfourl = urllib.request.addinfourl
> + splitattr = urllib.request.splitattr
> + splitpasswd = urllib.request.splitpasswd
> + splitport = urllib.request.splitport
> + splituser = urllib.request.splituser
> + unquote = urllib.request.unquote
> + url2pathname = urllib.request.url2pathname
>
> class RangeError(IOError):
> """Error raised when an unsatisfiable range is requested."""
> pass
>
> -class HTTPRangeHandler(urllib2.BaseHandler):
> +class HTTPRangeHandler(basehandler):
> """Handler that enables HTTP Range headers.
>
> This was extremely simple. The Range header is a HTTP feature to
> @@ -67,7 +90,7 @@
>
> def http_error_206(self, req, fp, code, msg, hdrs):
> # 206 Partial Content Response
> - r = urllib.addinfourl(fp, hdrs, req.get_full_url())
> + r = addinfourl(fp, hdrs, req.get_full_url())
> r.code = code
> r.msg = msg
> return r
> @@ -204,7 +227,7 @@
> raise RangeError('Requested Range Not Satisfiable')
> pos += bufsize
>
> -class FileRangeHandler(urllib2.FileHandler):
> +class FileRangeHandler(filehandler):
> """FileHandler subclass that adds Range support.
> This class handles Range headers exactly like an HTTP
> server would.
> @@ -212,15 +235,15 @@
> def open_local_file(self, req):
> host = req.get_host()
> file = req.get_selector()
> - localfile = urllib.url2pathname(file)
> + localfile = 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 = splitport(host)
> if port or socket.gethostbyname(host) not in self.get_names():
> - raise urllib2.URLError('file not on local host')
> + raise urlerror('file not on local host')
> fo = open(localfile,'rb')
> brange = req.headers.get('Range', None)
> brange = range_header_to_tuple(brange)
> @@ -236,7 +259,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 addinfourl(fo, headers, 'file:'+file)
>
>
> # FTP Range Support
> @@ -246,7 +269,7 @@
> # follows:
> # -- range support modifications start/end here
>
> -class FTPRangeHandler(urllib2.FTPHandler):
> +class FTPRangeHandler(ftphandler):
> def ftp_open(self, req):
> host = req.get_host()
> if not host:
> @@ -270,7 +293,7 @@
> try:
> host = socket.gethostbyname(host)
> except socket.error as msg:
> - raise urllib2.URLError(msg)
> + raise urlerror(msg)
> path, attrs = splitattr(req.get_selector())
> dirs = path.split('/')
> dirs = map(unquote, dirs)
> @@ -331,10 +354,10 @@
> raise IOError('ftp error', msg)
>
> def connect_ftp(self, user, passwd, host, port, dirs):
> - fw = ftpwrapper(user, passwd, host, port, dirs)
> + fw = ftpwrapperrest(user, passwd, host, port, dirs)
> return fw
>
> -class ftpwrapper(urllib.ftpwrapper):
> +class ftpwrapperrest(ftpwrapper):
> # range support note:
> # this ftpwrapper code is copied directly from
> # urllib. The only enhancement is to add the rest
> diff --git a/mercurial/exchange.py b/mercurial/exchange.py
> --- a/mercurial/exchange.py
> +++ b/mercurial/exchange.py
> @@ -8,8 +8,20 @@
> from __future__ import absolute_import
>
> import errno
> -import urllib
> -import urllib2
> +
> +try:
> + import urllib2
> + import urllib
> + httperror = urllib2.HTTPError
> + urlerror = urllib2.URLError
> + quote = urllib.quote
> + unquote = urllib.unquote
> +except ImportError:
> + import urllib.error
> + httperror = urllib.error.HTTPError
> + urlerror = urllib.error.URLError
> + quote = urllib.request.quote
> + unquote = urllib.request.unquote
>
> from .i18n import _
> from .node import (
> @@ -97,8 +109,8 @@
> 'missing "=" in parameter: %s') % p)
>
> key, value = p.split('=', 1)
> - key = urllib.unquote(key)
> - value = urllib.unquote(value)
> + key = unquote(key)
> + value = unquote(value)
> params[key] = value
>
> return version, params
> @@ -236,7 +248,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' % quote(params)
> else:
> raise error.Abort(_('unknown bundle type: %s') % b)
>
> @@ -1469,7 +1481,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=' + quote(capsblob))
> return caps
>
> # List of names of steps to perform for a bundle2 for getbundle, order matters.
> @@ -1535,7 +1547,7 @@
> b2caps = {}
> for bcaps in bundlecaps:
> if bcaps.startswith('bundle2='):
> - blob = urllib.unquote(bcaps[len('bundle2='):])
> + blob = unquote(bcaps[len('bundle2='):])
> b2caps.update(bundle2.decodecaps(blob))
> bundler = bundle2.bundle20(repo.ui, b2caps)
>
> @@ -1804,8 +1816,8 @@
> attrs = {'URL': fields[0]}
> for rawattr in fields[1:]:
> key, value = rawattr.split('=', 1)
> - key = urllib.unquote(key)
> - value = urllib.unquote(value)
> + key = unquote(key)
> + value = unquote(value)
> attrs[key] = value
>
> # Parse BUNDLESPEC into components. This makes client-side
> diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py
> --- a/mercurial/hgweb/protocol.py
> +++ b/mercurial/hgweb/protocol.py
> @@ -8,7 +8,6 @@
> from __future__ import absolute_import
>
> import cgi
> -import urllib
> import zlib
>
> try:
> @@ -16,6 +15,13 @@
> except ImportError:
> import io
>
> +try:
> + import urllib
> + quote = urllib.quote
> +except AttributeError:
> + import urllib.request
> + quote = urllib.request.quote
> +
> from .common import (
> HTTP_OK,
> )
> @@ -86,8 +92,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', '')))
> + quote(self.req.env.get('REMOTE_HOST', '')),
> + quote(self.req.env.get('REMOTE_USER', '')))
>
> def iscmd(cmd):
> return cmd in wireproto.commands
> diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py
> --- a/mercurial/hgweb/server.py
> +++ b/mercurial/hgweb/server.py
> @@ -15,7 +15,13 @@
> import socket
> import sys
> import traceback
> -import urllib
> +
> +try:
> + import urllib
> + unquote = urllib.unquote
> +except AttributeError:
> + import urllib.request
> + unquote = urllib.request.unquote
>
> from ..i18n import _
>
> @@ -38,7 +44,7 @@
> path, query = uri.split('?', 1)
> else:
> path, query = uri, ''
> - return urllib.unquote(path), query
> + return unquote(path), query
>
> class _error_logger(object):
> def __init__(self, handler):
> diff --git a/mercurial/httpconnection.py b/mercurial/httpconnection.py
> --- a/mercurial/httpconnection.py
> +++ b/mercurial/httpconnection.py
> @@ -13,8 +13,23 @@
> import logging
> import os
> import socket
> -import urllib
> -import urllib2
> +
> +try:
> + import urllib2
> + import urllib
> + httphandler = urllib2.HTTPHandler
> + httpshandler = urllib2.HTTPSHandler
> + abstracthttphandler = urllib2.AbstractHTTPHandler
> + addinfourl = urllib.addinfourl
> + urlerror = urllib2.URLError
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + httphandler = urllib.request.HTTPHandler
> + httpshandler = urllib.request.HTTPSHandler
> + abstracthttphandler = urllib.request.AbstractHTTPHandler
> + addinfourl = urllib.request.addinfourl
> + urlerror = urllib.error.URLError
>
> from .i18n import _
> from . import (
> @@ -123,10 +138,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(httphandler, httpshandler):
> def __init__(self, ui, pwmgr):
> global _configuredlogging
> - urllib2.AbstractHTTPHandler.__init__(self)
> + abstracthttphandler.__init__(self)
> self.ui = ui
> self.pwmgr = pwmgr
> self._connections = {}
> @@ -187,7 +202,7 @@
> proxy = None
>
> if not host:
> - raise urllib2.URLError('no host given')
> + raise urlerror('no host given')
>
> connkey = use_ssl, host, proxy
> allconns = self._connections.get(connkey, [])
> @@ -217,13 +232,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 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 = addinfourl(r, r.headers, req.get_full_url())
> resp.code = r.status
> resp.msg = r.reason
> return resp
> diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
> --- a/mercurial/httppeer.py
> +++ b/mercurial/httppeer.py
> @@ -13,10 +13,21 @@
> import os
> import socket
> import tempfile
> -import urllib
> -import urllib2
> import zlib
>
> +try:
> + import urllib2
> + import urllib
> + request = urllib2.Request
> + httperror = urllib2.HTTPError
> + urlencode = urllib.urlencode
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + request = urllib.request.Request
> + httperror = urllib.error.HTTPError
> + urlencode = urllib.request.urlencode
> +
> from .i18n import _
> from .node import nullid
> from . import (
> @@ -59,7 +70,7 @@
> self.ui.debug('using %s\n' % self._url)
>
> self.urlopener = url.opener(ui, authinfo)
> - self.requestbuilder = urllib2.Request
> + self.requestbuilder = request
>
> def __del__(self):
> if self.urlopener:
> @@ -105,7 +116,7 @@
> # object rather than a basestring
> canmungedata = not data or isinstance(data, basestring)
> if postargsok and canmungedata:
> - strargs = urllib.urlencode(sorted(args.items()))
> + strargs = urlencode(sorted(args.items()))
> if strargs:
> if not data:
> data = strargs
> @@ -119,7 +130,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 = urlencode(sorted(args.items()))
> headerfmt = 'X-HgArg-%s'
> contentlen = headersize - len(headerfmt % '000' + ': \r\n')
> headernum = 0
> @@ -132,7 +143,7 @@
> headers['Vary'] = ','.join(varyheaders)
> else:
> q += sorted(args.items())
> - qs = '?%s' % urllib.urlencode(q)
> + qs = '?%s' % urlencode(q)
> cu = "%s%s" % (self._url, qs)
> size = 0
> if util.safehasattr(data, 'length'):
> @@ -150,7 +161,7 @@
> req.add_unredirected_header('Content-Length', '%d' % size)
> try:
> resp = self.urlopener.open(req)
> - except urllib2.HTTPError as inst:
> + except httperror as inst:
> if inst.code == 401:
> raise error.Abort(_('authorization failed'))
> raise
> diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py
> --- a/mercurial/keepalive.py
> +++ b/mercurial/keepalive.py
> @@ -25,13 +25,23 @@
>
> """An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
>
> ->>> import urllib2
> +>>> try:
> +... import urllib2
> +... build_opener = urllib2.build_opener
> +... install_opener = urllib2.install_opener
> +... urlopen = urllib2.urlopen
> +... except ImportError:
> +... import urllib.request
> +... build_opener = urllib.request.build_opener
> +... install_opener = urllib.request.install_opener
> +... urlopen = urllib.request.urlopen
> +
> >>> from keepalive import HTTPHandler
> >>> keepalive_handler = HTTPHandler()
> ->>> opener = urllib2.build_opener(keepalive_handler)
> ->>> urllib2.install_opener(opener)
> +>>> opener = build_opener(keepalive_handler)
> +>>> install_opener(opener)
> >>>
> ->>> fo = urllib2.urlopen('http://www.python.org')
> +>>> fo = 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 +124,22 @@
> import socket
> import sys
> import thread
> -import urllib2
> +
> +try:
> + import urllib2
> + build_opener = urllib2.build_opener
> + install_opener = urllib2.install_opener
> + urlopen = urllib2.urlopen
> + httphandler = urllib2.HTTPHandler
> + urlerror = urllib2.URLError
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + build_opener = urllib.request.build_opener
> + install_opener = urllib.request.install_opener
> + urlopen = urllib.request.urlopen
> + httphandler = urllib.request.HTTPHandler
> + urlerror = urllib.error.URLError
>
> DEBUG = None
>
> @@ -227,7 +252,7 @@
> def do_open(self, http_class, req):
> host = req.get_host()
> if not host:
> - raise urllib2.URLError('no host given')
> + raise urlerror('no host given')
>
> try:
> h = self._cm.get_ready_conn(host)
> @@ -254,7 +279,7 @@
> self._start_transaction(h, req)
> r = h.getresponse()
> except (socket.error, httplib.HTTPException) as err:
> - raise urllib2.URLError(err)
> + raise urlerror(err)
>
> # if not a persistent connection, don't try to reuse it
> if r.will_close:
> @@ -346,14 +371,14 @@
> else:
> h.putrequest('GET', req.get_selector(), **skipheaders)
> except socket.error as err:
> - raise urllib2.URLError(err)
> + raise 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, httphandler):
> pass
>
> class HTTPResponse(httplib.HTTPResponse):
> @@ -593,14 +618,14 @@
> global HANDLE_ERRORS
> orig = HANDLE_ERRORS
> keepalive_handler = HTTPHandler()
> - opener = urllib2.build_opener(keepalive_handler)
> - urllib2.install_opener(opener)
> + opener = build_opener(keepalive_handler)
> + install_opener(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 = urlopen(url)
> fo.read()
> fo.close()
> try:
> @@ -623,25 +648,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 = build_opener()
> + install_opener(opener)
> + fo = 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 = build_opener(HTTPHandler())
> + install_opener(opener)
>
> - fo = urllib2.urlopen(url)
> + fo = urlopen(url)
> foo = fo.read()
> fo.close()
> m = md5(foo)
> print(format % ('keepalive read', m.hexdigest()))
>
> - fo = urllib2.urlopen(url)
> + fo = urlopen(url)
> foo = ''
> while True:
> f = fo.readline()
> @@ -657,15 +682,15 @@
>
> sys.stdout.write(' first using the normal urllib handlers')
> # first use normal opener
> - opener = urllib2.build_opener()
> - urllib2.install_opener(opener)
> + opener = build_opener()
> + install_opener(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 = build_opener(HTTPHandler())
> + install_opener(opener)
> t2 = fetch(N, url)
> print(' TIME: %.3f s' % t2)
> print(' improvement factor: %.2f' % (t1 / t2))
> @@ -677,7 +702,7 @@
> for i in range(N):
> if delay and i > 0:
> time.sleep(delay)
> - fo = urllib2.urlopen(url)
> + fo = urlopen(url)
> foo = fo.read()
> fo.close()
> lens.append(len(foo))
> @@ -700,7 +725,7 @@
> info = warning = error = debug
> DEBUG = FakeLogger()
> print(" fetching the file to establish a connection")
> - fo = urllib2.urlopen(url)
> + fo = urlopen(url)
> data1 = fo.read()
> fo.close()
>
> @@ -714,7 +739,7 @@
> sys.stderr.write('\r')
>
> print(" fetching the file a second time")
> - fo = urllib2.urlopen(url)
> + fo = urlopen(url)
> data2 = fo.read()
> fo.close()
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -12,9 +12,15 @@
> import os
> import random
> import time
> -import urllib
> import weakref
>
> +try:
> + import urllib
> + quote = urllib.quote
> +except AttributeError:
> + import urllib.request
> + quote = urllib.request.quote
> +
> from .i18n import _
> from .node import (
> hex,
> @@ -366,7 +372,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=' + quote(capsblob))
> return caps
>
> def _applyopenerreqs(self):
> diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
> --- a/mercurial/statichttprepo.py
> +++ b/mercurial/statichttprepo.py
> @@ -11,8 +11,21 @@
>
> import errno
> import os
> -import urllib
> -import urllib2
> +
> +try:
> + import urllib2
> + import urllib
> + request = urllib2.Request
> + httperror = urllib2.HTTPError
> + quote = urllib.quote
> + urlerror = urllib2.URLError
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + request = urllib.request.Request
> + httperror = urllib.error.HTTPError
> + quote = urllib.request.quote
> + urlerror = urllib.error.URLError
>
> from .i18n import _
> from . import (
> @@ -45,7 +58,7 @@
> def seek(self, pos):
> self.pos = pos
> def read(self, bytes=None):
> - req = urllib2.Request(self.url)
> + req = request(self.url)
> end = ''
> if bytes:
> end = self.pos + bytes - 1
> @@ -56,10 +69,10 @@
> f = self.opener.open(req)
> data = f.read()
> code = f.code
> - except urllib2.HTTPError as inst:
> + except httperror as inst:
> num = inst.code == 404 and errno.ENOENT or None
> raise IOError(num, inst)
> - except urllib2.URLError as inst:
> + except urlerror as inst:
> raise IOError(None, inst.reason[1])
>
> if code == 200:
> @@ -92,7 +105,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, quote(path)))
> return httprangereader(f, urlopener)
>
> def join(self, path):
> diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
> --- a/mercurial/templatefilters.py
> +++ b/mercurial/templatefilters.py
> @@ -11,7 +11,13 @@
> import os
> import re
> import time
> -import urllib
> +
> +try:
> + import urllib
> + quote = urllib.quote
> +except AttributeError:
> + import urllib.request
> + quote = urllib.request.quote
>
> from . import (
> encoding,
> @@ -269,7 +275,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 quote(text, safe='/@').replace('/', '%252F')
>
> def rfc3339date(text):
> """:rfc3339date: Date. Returns a date using the Internet date format
> @@ -342,7 +348,7 @@
> """:urlescape: Any text. Escapes all "special" characters. For example,
> "foo bar" becomes "foo%20bar".
> """
> - return urllib.quote(text)
> + return quote(text)
>
> def userfilter(text):
> """:user: Any text. Returns a short representation of a user name or email
> diff --git a/mercurial/url.py b/mercurial/url.py
> --- a/mercurial/url.py
> +++ b/mercurial/url.py
> @@ -13,8 +13,39 @@
> import httplib
> import os
> import socket
> -import urllib
> -import urllib2
> +
> +try:
> + import urllib2
> + import urllib
> + build_opener = urllib2.build_opener
> + pathname2url = urllib.pathname2url
> + pyhttpbasicauthhandler = urllib2.HTTPBasicAuthHandler
> + pyhttpdigestauthhandler = urllib2.HTTPDigestAuthHandler
> + pyhttppasswordmgrwithdefaultrealm = urllib2.HTTPPasswordMgrWithDefaultRealm
> + pyproxyhandler = urllib2.ProxyHandler
> +
> + try:
> + pyhttpshandler = urllib2.HTTPSHandler
> + has_https = True
> + except AttributeError:
> + has_https = False
> +
> +except ImportError:
> + import urllib.request
> + import urllib.error
> + build_opener = urllib.request.build_opener
> + pathname2url = urllib.request.pathname2url
> + pyhttpbasicauthhandler = urllib.request.HTTPBasicAuthHandler
> + pyhttpdigestauthhandler = urllib.request.HTTPDigestAuthHandler
> + pyhttppasswordmgrwithdefaultrealm = \
> + urllib.request.HTTPPasswordMgrWithDefaultRealm
> + pyproxyhandler = urllib.request.ProxyHandler
> +
> + try:
> + pyhttpshandler = urllib.request.HTTPSHandler
> + has_https = True
> + except AttributeError:
> + has_https = False
>
> try:
> import cStringIO as io
> @@ -30,13 +61,13 @@
> util,
> )
>
> -class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
> +class passwordmgr(pyhttppasswordmgrwithdefaultrealm):
> def __init__(self, ui):
> - urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
> + pyhttppasswordmgrwithdefaultrealm.__init__(self)
> self.ui = ui
>
> def find_user_password(self, realm, authuri):
> - authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
> + authinfo = pyhttppasswordmgrwithdefaultrealm.find_user_password(
> self, realm, authuri)
> user, passwd = authinfo
> if user and passwd:
> @@ -76,10 +107,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 pyhttppasswordmgrwithdefaultrealm.find_user_password(
> self, None, authuri)
>
> -class proxyhandler(urllib2.ProxyHandler):
> +class proxyhandler(pyproxyhandler):
> def __init__(self, ui):
> proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
> # XXX proxyauthinfo = None
> @@ -125,7 +156,7 @@
> except OSError:
> pass
>
> - urllib2.ProxyHandler.__init__(self, proxies)
> + pyproxyhandler.__init__(self, proxies)
> self.ui = ui
>
> def proxy_open(self, req, proxy, type_):
> @@ -138,7 +169,7 @@
> if e.startswith('.') and host.endswith(e[1:]):
> return None
>
> - return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
> + return pyproxyhandler.proxy_open(self, req, proxy, type_)
>
> def _gen_sendfile(orgsend):
> def _sendfile(self, data):
> @@ -152,7 +183,6 @@
> orgsend(self, data)
> return _sendfile
>
> -has_https = util.safehasattr(urllib2, 'HTTPSHandler')
> if has_https:
> try:
> _create_connection = socket.create_connection
> @@ -361,10 +391,10 @@
> **sslutil.sslkwargs(self.ui, host))
> sslutil.validator(self.ui, host)(self.sock)
>
> - class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
> + class httpshandler(keepalive.KeepAliveHandler, pyhttpshandler):
> def __init__(self, ui):
> keepalive.KeepAliveHandler.__init__(self)
> - urllib2.HTTPSHandler.__init__(self)
> + pyhttpshandler.__init__(self)
> self.ui = ui
> self.pwmgr = passwordmgr(self.ui)
>
> @@ -407,9 +437,9 @@
> conn.ui = self.ui
> return conn
>
> -class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
> +class httpdigestauthhandler(pyhttpdigestauthhandler):
> def __init__(self, *args, **kwargs):
> - urllib2.HTTPDigestAuthHandler.__init__(self, *args, **kwargs)
> + pyhttpdigestauthhandler.__init__(self, *args, **kwargs)
> self.retried_req = None
>
> def reset_retry_count(self):
> @@ -423,13 +453,13 @@
> if req is not self.retried_req:
> self.retried_req = req
> self.retried = 0
> - return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
> + return pyhttpdigestauthhandler.http_error_auth_reqed(
> self, auth_header, host, req, headers)
>
> -class httpbasicauthhandler(urllib2.HTTPBasicAuthHandler):
> +class httpbasicauthhandler(pyhttpbasicauthhandler):
> def __init__(self, *args, **kwargs):
> self.auth = None
> - urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
> + pyhttpbasicauthhandler.__init__(self, *args, **kwargs)
> self.retried_req = None
>
> def http_request(self, request):
> @@ -455,7 +485,7 @@
> if req is not self.retried_req:
> self.retried_req = req
> self.retried = 0
> - return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
> + return pyhttpbasicauthhandler.http_error_auth_reqed(
> self, auth_header, host, req, headers)
>
> def retry_http_basic_auth(self, host, req, realm):
> @@ -498,7 +528,7 @@
> handlers.extend((httpbasicauthhandler(passmgr),
> httpdigestauthhandler(passmgr)))
> handlers.extend([h(ui, passmgr) for h in handlerfuncs])
> - opener = urllib2.build_opener(*handlers)
> + opener = build_opener(*handlers)
>
> # 1.0 here is the _protocol_ version
> opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
> @@ -512,6 +542,6 @@
> url_, authinfo = u.authinfo()
> else:
> path = util.normpath(os.path.abspath(url_))
> - url_ = 'file://' + urllib.pathname2url(path)
> + url_ = 'file://' + pathname2url(path)
> authinfo = None
> return opener(ui, authinfo).open(url_, data)
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -34,9 +34,15 @@
> import textwrap
> import time
> import traceback
> -import urllib
> import zlib
>
> +try:
> + import urllib
> + quote = urllib.quote
> +except AttributeError:
> + import urllib.request
> + quote = urllib.request.quote
> +
> from . import (
> encoding,
> error,
> @@ -2368,30 +2374,30 @@
> if hasdriveletter(self.path):
> s += '/'
> if self.user:
> - s += urllib.quote(self.user, safe=self._safechars)
> + s += quote(self.user, safe=self._safechars)
> if self.passwd:
> - s += ':' + urllib.quote(self.passwd, safe=self._safechars)
> + s += ':' + 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 += quote(self.host)
> else:
> s += self.host
> if self.port:
> - s += ':' + urllib.quote(self.port)
> + s += ':' + 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 += 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 += '#' + quote(self.fragment, safe=self._safepchars)
> return s
>
> def authinfo(self):
> diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
> --- a/mercurial/wireproto.py
> +++ b/mercurial/wireproto.py
> @@ -11,7 +11,15 @@
> import os
> import sys
> import tempfile
> -import urllib
> +
> +try:
> + import urllib
> + quote = urllib.quote
> + unquote = urllib.unquote
> +except AttributeError:
> + import urllib.request
> + quote = urllib.request.quote
> + unquote = urllib.request.unquote
>
> from .i18n import _
> from .node import (
> @@ -287,7 +295,7 @@
> branchmap = {}
> for branchpart in d.splitlines():
> branchname, branchheads = branchpart.split(' ', 1)
> - branchname = encoding.tolocal(urllib.unquote(branchname))
> + branchname = encoding.tolocal(unquote(branchname))
> branchheads = decodelist(branchheads)
> branchmap[branchname] = branchheads
> yield branchmap
> @@ -632,7 +640,7 @@
> branchmap = repo.branchmap()
> heads = []
> for branch, nodes in branchmap.iteritems():
> - branchname = urllib.quote(encoding.fromlocal(branch))
> + branchname = quote(encoding.fromlocal(branch))
> branchnodes = encodelist(nodes)
> heads.append('%s %s' % (branchname, branchnodes))
> return '\n'.join(heads)
> @@ -684,7 +692,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=' + quote(capsblob))
> caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
> caps.append(
> 'httpheader=%d' % repo.ui.configint('server', 'maxhttpheaderlen', 1024))
> diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t
> --- a/tests/test-check-py3-compat.t
> +++ b/tests/test-check-py3-compat.t
> @@ -165,8 +165,8 @@
> hgext/largefiles/lfutil.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> hgext/largefiles/localstore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
> hgext/largefiles/overrides.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.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: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> hgext/largefiles/reposetup.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.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)
> @@ -189,7 +189,6 @@
> mercurial/branchmap.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.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> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/changelog.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/cmdutil.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> @@ -203,7 +202,7 @@
> mercurial/dirstate.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/discovery.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/dispatch.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> - mercurial/exchange.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
> + mercurial/exchange.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/extensions.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/filelog.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> mercurial/filemerge.py: error importing: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.py:*) (glob)
> @@ -223,7 +222,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> 'NullTranslations' object has no attribute 'ugettext' (error at i18n.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 module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> @@ -254,7 +253,7 @@
> mercurial/sshpeer.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> mercurial/sshserver.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> mercurial/sslutil.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> - mercurial/statichttprepo.py: error importing module: <ImportError> No module named 'urllib2' (line *) (glob)
> + mercurial/statichttprepo.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> mercurial/store.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> mercurial/streamclone.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> mercurial/subrepo.py: error importing module: <AttributeError> 'NullTranslations' object has no attribute 'ugettext' (line *) (glob)
> diff --git a/tests/test-hgweb-auth.py b/tests/test-hgweb-auth.py
> --- a/tests/test-hgweb-auth.py
> +++ b/tests/test-hgweb-auth.py
> @@ -1,5 +1,12 @@
> +try:
> + import urllib2
> + httppasswordmgrwithdefaultrealm = urllib2.HTTPPasswordMgrWithDefaultRealm
> +except AttributeError:
> + import urllib.request
> + httppasswordmgrwithdefaultrealm = \
> + urllib.request.HTTPPasswordMgrWithDefaultRealm
> +
> from mercurial import demandimport; demandimport.enable()
> -import urllib2
> from mercurial import ui, util
> from mercurial import url
> from mercurial.error import Abort
> @@ -99,7 +106,7 @@
>
> def testauthinfo(fullurl, authurl):
> print 'URIs:', fullurl, authurl
> - pm = urllib2.HTTPPasswordMgrWithDefaultRealm()
> + pm = httppasswordmgrwithdefaultrealm()
> pm.add_password(*util.url(fullurl).authinfo()[1])
> print pm.find_user_password('test', authurl)
>
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list