Patchwork py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import

login
register
mail settings
Submitter Pulkit Goyal
Date July 3, 2016, 5:35 p.m.
Message ID <59744695fedf789adab6.1467567333@pulkit-goyal>
Download mbox | patch
Permalink /patch/15726/
State Changes Requested
Headers show

Comments

Pulkit Goyal - July 3, 2016, 5:35 p.m.
# HG changeset patch
# User Pulkit Goyal <7895pulkit@gmail.com>
# Date 1467567318 -19800
#      Sun Jul 03 23:05:18 2016 +0530
# Node ID 59744695fedf789adab649c85573c553ad750057
# Parent  59058549a611342f16e6d7e4a99b9e6ea40fa322
py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import

The BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer has been merged into http.server
 in python 3. All of them has been merged as util.httpserver to use in both python 2 and 3.
This patch adds a regex to check-code to warn against the use of BaseHTTPServer. Moreover this patch
also includes updates to lower part of test-check-py3-compat.t which used to remain unchaged.
Martijn Pieters - July 4, 2016, 12:08 p.m.
On 3 July 2016 at 18:35, Pulkit Goyal <7895pulkit@gmail.com> wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pulkit@gmail.com>
> # Date 1467567318 -19800
> #      Sun Jul 03 23:05:18 2016 +0530
> # Node ID 59744695fedf789adab649c85573c553ad750057
> # Parent  59058549a611342f16e6d7e4a99b9e6ea40fa322
> py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
>
> The BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer has been merged into http.server
>  in python 3. All of them has been merged as util.httpserver to use in both python 2 and 3.
> This patch adds a regex to check-code to warn against the use of BaseHTTPServer. Moreover this patch
> also includes updates to lower part of test-check-py3-compat.t which used to remain unchaged.

This looks very good to me!

> diff -r 59058549a611 -r 59744695fedf contrib/check-code.py
> --- a/contrib/check-code.py     Fri Jul 01 13:54:35 2016 +0800
> +++ b/contrib/check-code.py     Sun Jul 03 23:05:18 2016 +0530
> @@ -331,6 +331,7 @@
>      (r'^import cPickle', "don't use cPickle, use util.pickle"),
>      (r'^import pickle', "don't use pickle, use util.pickle"),
>      (r'^import httplib', "don't use httplib, use util.httplib"),
> +    (r'^import BaseHTTPServer', "use util.httpserver instead"),
>      (r'\.next\(\)', "don't use .next(), use next(...)"),
>
>      # rules depending on implementation of repquote()
> diff -r 59058549a611 -r 59744695fedf mercurial/hgweb/common.py
> --- a/mercurial/hgweb/common.py Fri Jul 01 13:54:35 2016 +0800
> +++ b/mercurial/hgweb/common.py Sun Jul 03 23:05:18 2016 +0530
> @@ -8,11 +8,14 @@
>
>  from __future__ import absolute_import
>
> -import BaseHTTPServer
>  import errno
>  import mimetypes
>  import os
>
> +from .. import util
> +
> +httpserver = util.httpserver
> +
>  HTTP_OK = 200
>  HTTP_NOT_MODIFIED = 304
>  HTTP_BAD_REQUEST = 400
> @@ -107,7 +110,7 @@
>          raise AttributeError
>
>  def _statusmessage(code):
> -    responses = BaseHTTPServer.BaseHTTPRequestHandler.responses
> +    responses = httpserver.basehttprequesthandler.responses
>      return responses.get(code, ('Error', 'Unknown error'))[0]
>
>  def statusmessage(code, message=None):
> diff -r 59058549a611 -r 59744695fedf mercurial/hgweb/server.py
> --- a/mercurial/hgweb/server.py Fri Jul 01 13:54:35 2016 +0800
> +++ b/mercurial/hgweb/server.py Sun Jul 03 23:05:18 2016 +0530
> @@ -8,7 +8,6 @@
>
>  from __future__ import absolute_import
>
> -import BaseHTTPServer
>  import errno
>  import os
>  import socket
> @@ -22,6 +21,7 @@
>      util,
>  )
>
> +http_server = util.httpserver
>  socketserver = util.socketserver
>  urlerr = util.urlerr
>  urlreq = util.urlreq
> @@ -53,7 +53,7 @@
>          for msg in seq:
>              self.handler.log_error("HG error:  %s", msg)
>
> -class _httprequesthandler(BaseHTTPServer.BaseHTTPRequestHandler):
> +class _httprequesthandler(http_server.basehttprequesthandler):
>
>      url_scheme = 'http'
>
> @@ -64,7 +64,7 @@
>
>      def __init__(self, *args, **kargs):
>          self.protocol_version = 'HTTP/1.1'
> -        BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs)
> +        http_server.basehttprequesthandler.__init__(self, *args, **kargs)
>
>      def _log_any(self, fp, format, *args):
>          fp.write("%s - - [%s] %s\n" % (self.client_address[0],
> @@ -253,14 +253,14 @@
>          return open(opt, 'a')
>      return default
>
> -class MercurialHTTPServer(object, _mixin, BaseHTTPServer.HTTPServer):
> +class MercurialHTTPServer(object, _mixin, http_server.httpserver):
>
>      # SO_REUSEADDR has broken semantics on windows
>      if os.name == 'nt':
>          allow_reuse_address = 0
>
>      def __init__(self, ui, app, addr, handler, **kwargs):
> -        BaseHTTPServer.HTTPServer.__init__(self, addr, handler, **kwargs)
> +        http_server.httpserver.__init__(self, addr, handler, **kwargs)
>          self.daemon_threads = True
>          self.application = app
>
> diff -r 59058549a611 -r 59744695fedf mercurial/pycompat.py
> --- a/mercurial/pycompat.py     Fri Jul 01 13:54:35 2016 +0800
> +++ b/mercurial/pycompat.py     Sun Jul 03 23:05:18 2016 +0530
> @@ -76,9 +76,13 @@
>          except AttributeError:
>              pass
>
> +httpserver = _pycompatstub()
>  urlreq = _pycompatstub()
>  urlerr = _pycompatstub()
>  try:
> +    import BaseHTTPServer
> +    import CGIHTTPServer
> +    import SimpleHTTPServer
>      import urllib2
>      import urllib
>      _alias(urlreq, urllib, (
> @@ -116,6 +120,16 @@
>          "HTTPError",
>          "URLError",
>      ))
> +    _alias(httpserver, BaseHTTPServer, (
> +        "HTTPServer",
> +        "BaseHTTPRequestHandler",
> +    ))
> +    _alias(httpserver, SimpleHTTPServer, (
> +        "SimpleHTTPRequestHandler",
> +    ))
> +    _alias(httpserver, CGIHTTPServer, (
> +        "CGIHTTPRequestHandler",
> +    ))
>
>  except ImportError:
>      import urllib.request
> @@ -151,6 +165,13 @@
>          "HTTPError",
>          "URLError",
>      ))
> +    import http.server
> +    _alias(httpserver, http.server, (
> +        "HTTPServer",
> +        "BaseHTTPRequestHandler",
> +        "SimpleHTTPRequestHandler",
> +        "CGIHTTPRequestHandler",
> +    ))
>
>  try:
>      xrange
> diff -r 59058549a611 -r 59744695fedf mercurial/util.py
> --- a/mercurial/util.py Fri Jul 01 13:54:35 2016 +0800
> +++ b/mercurial/util.py Sun Jul 03 23:05:18 2016 +0530
> @@ -48,6 +48,7 @@
>  for attr in (
>      'empty',
>      'httplib',
> +    'httpserver',
>      'pickle',
>      'queue',
>      'urlerr',
> diff -r 59058549a611 -r 59744695fedf tests/dumbhttp.py
> --- a/tests/dumbhttp.py Fri Jul 01 13:54:35 2016 +0800
> +++ b/tests/dumbhttp.py Sun Jul 03 23:05:18 2016 +0530
> @@ -6,24 +6,24 @@
>  Small and dumb HTTP server for use in tests.
>  """
>
> -import BaseHTTPServer
> -import SimpleHTTPServer
>  import optparse
>  import signal
>  import sys
>
>  from mercurial import (
>      cmdutil,
> +    util,
>  )
>
> +httpserver = util.httpserver
>  OptionParser = optparse.OptionParser
>
>  class simplehttpservice(object):
>      def __init__(self, host, port):
>          self.address = (host, port)
>      def init(self):
> -        self.httpd = BaseHTTPServer.HTTPServer(
> -            self.address, SimpleHTTPServer.SimpleHTTPRequestHandler)
> +        self.httpd = httpserver.httpserver(
> +            self.address, httpserver.simplehttprequesthandler)
>      def run(self):
>          self.httpd.serve_forever()
>
> diff -r 59058549a611 -r 59744695fedf tests/test-check-py3-compat.t
> --- a/tests/test-check-py3-compat.t     Fri Jul 01 13:54:35 2016 +0800
> +++ b/tests/test-check-py3-compat.t     Sun Jul 03 23:05:18 2016 +0530
> @@ -48,14 +48,14 @@
>    hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *) (glob)
>    hgext/eol.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/extdiff.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
> -  hgext/factotum.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
>    hgext/fetch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/fsmonitor/watchmanclient.py: error importing module: <SystemError> Parent module 'hgext.fsmonitor' not loaded, cannot perform relative import (line *) (glob)
>    hgext/gpg.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/graphlog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/hgk.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/histedit.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
> -  hgext/keyword.py: error importing: <ImportError> No module named 'BaseHTTPServer' (error at common.py:*) (glob)
> +  hgext/journal.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
> +  hgext/keyword.py: error importing: <SyntaxError> invalid syntax (bundle2.py, line *) (error at bundlerepo.py:*) (glob)
>    hgext/largefiles/basestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *) (glob)
>    hgext/largefiles/lfcommands.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/largefiles/lfutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
> @@ -65,7 +65,7 @@
>    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/storefactory.py: error importing: <SyntaxError> invalid syntax (bundle2.py, line *) (error at bundlerepo.py:*) (glob)
> -  hgext/largefiles/uisetup.py: error importing: <ImportError> No module named 'BaseHTTPServer' (error at common.py:*) (glob)
> +  hgext/largefiles/uisetup.py: error importing: <SyntaxError> invalid syntax (bundle2.py, line *) (error at bundlerepo.py:*) (glob)
>    hgext/largefiles/wirestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *) (glob)
>    hgext/mq.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    hgext/notify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
> @@ -103,19 +103,17 @@
>    mercurial/graphmod.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    mercurial/help.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    mercurial/hg.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
> -  mercurial/hgweb/common.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
> +  mercurial/hgweb/common.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    mercurial/hgweb/hgweb_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    mercurial/hgweb/hgwebdir_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    mercurial/hgweb/protocol.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    mercurial/hgweb/request.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
> -  mercurial/hgweb/server.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
> +  mercurial/hgweb/server.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    mercurial/hgweb/webcommands.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    mercurial/hgweb/webutil.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
>    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/httpconnection.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
>    mercurial/httppeer.py: error importing module: <SyntaxError> invalid syntax (bundle2.py, line *) (line *) (glob)
> -  mercurial/keepalive.py: error importing module: <ImportError> No module named 'thread' (line *) (glob)
>    mercurial/localrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    mercurial/mail.py: error importing module: <AttributeError> module 'email' has no attribute 'Header' (line *) (glob)
>    mercurial/manifest.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
> @@ -141,7 +139,6 @@
>    mercurial/templater.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    mercurial/ui.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    mercurial/unionrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
> -  mercurial/url.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
>    mercurial/verify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
>    mercurial/win*.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
>    mercurial/windows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
> diff -r 59058549a611 -r 59744695fedf tests/tinyproxy.py
> --- a/tests/tinyproxy.py        Fri Jul 01 13:54:35 2016 +0800
> +++ b/tests/tinyproxy.py        Sun Jul 03 23:05:18 2016 +0530
> @@ -14,7 +14,6 @@
>
>  __version__ = "0.2.1"
>
> -import BaseHTTPServer
>  import os
>  import select
>  import socket
> @@ -22,11 +21,12 @@
>
>  from mercurial import util
>
> +httpserver = util.httpserver
>  urlparse = util.urlparse
>  socketserver = util.socketserver
>
> -class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
> -    __base = BaseHTTPServer.BaseHTTPRequestHandler
> +class ProxyHandler (httpserver.basehttprequesthandler):
> +    __base = httpserver.basehttprequesthandler
>      __base_handle = __base.handle
>
>      server_version = "TinyHTTPProxy/" + __version__
> @@ -136,9 +136,9 @@
>      do_DELETE = do_GET
>
>  class ThreadingHTTPServer (socketserver.ThreadingMixIn,
> -                           BaseHTTPServer.HTTPServer):
> +                           httpserver.httpserver):
>      def __init__(self, *args, **kwargs):
> -        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
> +        httpserver.httpserver.__init__(self, *args, **kwargs)
>          a = open("proxy.pid", "w")
>          a.write(str(os.getpid()) + "\n")
>          a.close()
> @@ -158,4 +158,4 @@
>              del argv[2:]
>          else:
>              print("Any clients will be served...")
> -        BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)
> +        httpserver.test(ProxyHandler, ThreadingHTTPServer)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Yuya Nishihara - July 4, 2016, 1:35 p.m.
On Sun, 03 Jul 2016 23:05:33 +0530, Pulkit Goyal wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pulkit@gmail.com>
> # Date 1467567318 -19800
> #      Sun Jul 03 23:05:18 2016 +0530
> # Node ID 59744695fedf789adab649c85573c553ad750057
> # Parent  59058549a611342f16e6d7e4a99b9e6ea40fa322
> py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import

> --- a/mercurial/hgweb/server.py	Fri Jul 01 13:54:35 2016 +0800
> +++ b/mercurial/hgweb/server.py	Sun Jul 03 23:05:18 2016 +0530
> @@ -8,7 +8,6 @@
>  
>  from __future__ import absolute_import
>  
> -import BaseHTTPServer
>  import errno
>  import os
>  import socket
> @@ -22,6 +21,7 @@
>      util,
>  )
>  
> +http_server = util.httpserver

How about "httpservermod" ?

http_server doesn't follow our style, and it's confusing we have http_server
module and httpserver variable.
Pulkit Goyal - July 4, 2016, 1:44 p.m.
> http_server doesn't follow our style, and it's confusing we have http_server
> module and httpserver variable.

In hgweb/server we are already using httpserver as one of the
variable. To avoid conflicts I named it as http_server in this file.
Pulkit Goyal - July 4, 2016, 1:46 p.m.
> How about "httpservermod" ?

In this one only?
Yuya Nishihara - July 4, 2016, 1:58 p.m.
On Mon, 4 Jul 2016 19:16:31 +0530, Pulkit Goyal wrote:
> > How about "httpservermod" ?
> 
> In this one only?

or rename httpserver variable to server, for example. I think either way
is fine as we sometimes use nodemod to avoid name conflicts.

Patch

diff -r 59058549a611 -r 59744695fedf contrib/check-code.py
--- a/contrib/check-code.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/contrib/check-code.py	Sun Jul 03 23:05:18 2016 +0530
@@ -331,6 +331,7 @@ 
     (r'^import cPickle', "don't use cPickle, use util.pickle"),
     (r'^import pickle', "don't use pickle, use util.pickle"),
     (r'^import httplib', "don't use httplib, use util.httplib"),
+    (r'^import BaseHTTPServer', "use util.httpserver instead"),
     (r'\.next\(\)', "don't use .next(), use next(...)"),
 
     # rules depending on implementation of repquote()
diff -r 59058549a611 -r 59744695fedf mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/mercurial/hgweb/common.py	Sun Jul 03 23:05:18 2016 +0530
@@ -8,11 +8,14 @@ 
 
 from __future__ import absolute_import
 
-import BaseHTTPServer
 import errno
 import mimetypes
 import os
 
+from .. import util
+
+httpserver = util.httpserver
+
 HTTP_OK = 200
 HTTP_NOT_MODIFIED = 304
 HTTP_BAD_REQUEST = 400
@@ -107,7 +110,7 @@ 
         raise AttributeError
 
 def _statusmessage(code):
-    responses = BaseHTTPServer.BaseHTTPRequestHandler.responses
+    responses = httpserver.basehttprequesthandler.responses
     return responses.get(code, ('Error', 'Unknown error'))[0]
 
 def statusmessage(code, message=None):
diff -r 59058549a611 -r 59744695fedf mercurial/hgweb/server.py
--- a/mercurial/hgweb/server.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/mercurial/hgweb/server.py	Sun Jul 03 23:05:18 2016 +0530
@@ -8,7 +8,6 @@ 
 
 from __future__ import absolute_import
 
-import BaseHTTPServer
 import errno
 import os
 import socket
@@ -22,6 +21,7 @@ 
     util,
 )
 
+http_server = util.httpserver
 socketserver = util.socketserver
 urlerr = util.urlerr
 urlreq = util.urlreq
@@ -53,7 +53,7 @@ 
         for msg in seq:
             self.handler.log_error("HG error:  %s", msg)
 
-class _httprequesthandler(BaseHTTPServer.BaseHTTPRequestHandler):
+class _httprequesthandler(http_server.basehttprequesthandler):
 
     url_scheme = 'http'
 
@@ -64,7 +64,7 @@ 
 
     def __init__(self, *args, **kargs):
         self.protocol_version = 'HTTP/1.1'
-        BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs)
+        http_server.basehttprequesthandler.__init__(self, *args, **kargs)
 
     def _log_any(self, fp, format, *args):
         fp.write("%s - - [%s] %s\n" % (self.client_address[0],
@@ -253,14 +253,14 @@ 
         return open(opt, 'a')
     return default
 
-class MercurialHTTPServer(object, _mixin, BaseHTTPServer.HTTPServer):
+class MercurialHTTPServer(object, _mixin, http_server.httpserver):
 
     # SO_REUSEADDR has broken semantics on windows
     if os.name == 'nt':
         allow_reuse_address = 0
 
     def __init__(self, ui, app, addr, handler, **kwargs):
-        BaseHTTPServer.HTTPServer.__init__(self, addr, handler, **kwargs)
+        http_server.httpserver.__init__(self, addr, handler, **kwargs)
         self.daemon_threads = True
         self.application = app
 
diff -r 59058549a611 -r 59744695fedf mercurial/pycompat.py
--- a/mercurial/pycompat.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/mercurial/pycompat.py	Sun Jul 03 23:05:18 2016 +0530
@@ -76,9 +76,13 @@ 
         except AttributeError:
             pass
 
+httpserver = _pycompatstub()
 urlreq = _pycompatstub()
 urlerr = _pycompatstub()
 try:
+    import BaseHTTPServer
+    import CGIHTTPServer
+    import SimpleHTTPServer
     import urllib2
     import urllib
     _alias(urlreq, urllib, (
@@ -116,6 +120,16 @@ 
         "HTTPError",
         "URLError",
     ))
+    _alias(httpserver, BaseHTTPServer, (
+        "HTTPServer",
+        "BaseHTTPRequestHandler",
+    ))
+    _alias(httpserver, SimpleHTTPServer, (
+        "SimpleHTTPRequestHandler",
+    ))
+    _alias(httpserver, CGIHTTPServer, (
+        "CGIHTTPRequestHandler",
+    ))
 
 except ImportError:
     import urllib.request
@@ -151,6 +165,13 @@ 
         "HTTPError",
         "URLError",
     ))
+    import http.server
+    _alias(httpserver, http.server, (
+        "HTTPServer",
+        "BaseHTTPRequestHandler",
+        "SimpleHTTPRequestHandler",
+        "CGIHTTPRequestHandler",
+    ))
 
 try:
     xrange
diff -r 59058549a611 -r 59744695fedf mercurial/util.py
--- a/mercurial/util.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/mercurial/util.py	Sun Jul 03 23:05:18 2016 +0530
@@ -48,6 +48,7 @@ 
 for attr in (
     'empty',
     'httplib',
+    'httpserver',
     'pickle',
     'queue',
     'urlerr',
diff -r 59058549a611 -r 59744695fedf tests/dumbhttp.py
--- a/tests/dumbhttp.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/tests/dumbhttp.py	Sun Jul 03 23:05:18 2016 +0530
@@ -6,24 +6,24 @@ 
 Small and dumb HTTP server for use in tests.
 """
 
-import BaseHTTPServer
-import SimpleHTTPServer
 import optparse
 import signal
 import sys
 
 from mercurial import (
     cmdutil,
+    util,
 )
 
+httpserver = util.httpserver
 OptionParser = optparse.OptionParser
 
 class simplehttpservice(object):
     def __init__(self, host, port):
         self.address = (host, port)
     def init(self):
-        self.httpd = BaseHTTPServer.HTTPServer(
-            self.address, SimpleHTTPServer.SimpleHTTPRequestHandler)
+        self.httpd = httpserver.httpserver(
+            self.address, httpserver.simplehttprequesthandler)
     def run(self):
         self.httpd.serve_forever()
 
diff -r 59058549a611 -r 59744695fedf tests/test-check-py3-compat.t
--- a/tests/test-check-py3-compat.t	Fri Jul 01 13:54:35 2016 +0800
+++ b/tests/test-check-py3-compat.t	Sun Jul 03 23:05:18 2016 +0530
@@ -48,14 +48,14 @@ 
   hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *) (glob)
   hgext/eol.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/extdiff.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
-  hgext/factotum.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
   hgext/fetch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/fsmonitor/watchmanclient.py: error importing module: <SystemError> Parent module 'hgext.fsmonitor' not loaded, cannot perform relative import (line *) (glob)
   hgext/gpg.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/graphlog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/hgk.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/histedit.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
-  hgext/keyword.py: error importing: <ImportError> No module named 'BaseHTTPServer' (error at common.py:*) (glob)
+  hgext/journal.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
+  hgext/keyword.py: error importing: <SyntaxError> invalid syntax (bundle2.py, line *) (error at bundlerepo.py:*) (glob)
   hgext/largefiles/basestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *) (glob)
   hgext/largefiles/lfcommands.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/largefiles/lfutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
@@ -65,7 +65,7 @@ 
   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/storefactory.py: error importing: <SyntaxError> invalid syntax (bundle2.py, line *) (error at bundlerepo.py:*) (glob)
-  hgext/largefiles/uisetup.py: error importing: <ImportError> No module named 'BaseHTTPServer' (error at common.py:*) (glob)
+  hgext/largefiles/uisetup.py: error importing: <SyntaxError> invalid syntax (bundle2.py, line *) (error at bundlerepo.py:*) (glob)
   hgext/largefiles/wirestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *) (glob)
   hgext/mq.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   hgext/notify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
@@ -103,19 +103,17 @@ 
   mercurial/graphmod.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   mercurial/help.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   mercurial/hg.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
-  mercurial/hgweb/common.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
+  mercurial/hgweb/common.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   mercurial/hgweb/hgweb_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   mercurial/hgweb/hgwebdir_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   mercurial/hgweb/protocol.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   mercurial/hgweb/request.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
-  mercurial/hgweb/server.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
+  mercurial/hgweb/server.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   mercurial/hgweb/webcommands.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   mercurial/hgweb/webutil.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
   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/httpconnection.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
   mercurial/httppeer.py: error importing module: <SyntaxError> invalid syntax (bundle2.py, line *) (line *) (glob)
-  mercurial/keepalive.py: error importing module: <ImportError> No module named 'thread' (line *) (glob)
   mercurial/localrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   mercurial/mail.py: error importing module: <AttributeError> module 'email' has no attribute 'Header' (line *) (glob)
   mercurial/manifest.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
@@ -141,7 +139,6 @@ 
   mercurial/templater.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   mercurial/ui.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   mercurial/unionrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
-  mercurial/url.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
   mercurial/verify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
   mercurial/win*.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
   mercurial/windows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
diff -r 59058549a611 -r 59744695fedf tests/tinyproxy.py
--- a/tests/tinyproxy.py	Fri Jul 01 13:54:35 2016 +0800
+++ b/tests/tinyproxy.py	Sun Jul 03 23:05:18 2016 +0530
@@ -14,7 +14,6 @@ 
 
 __version__ = "0.2.1"
 
-import BaseHTTPServer
 import os
 import select
 import socket
@@ -22,11 +21,12 @@ 
 
 from mercurial import util
 
+httpserver = util.httpserver
 urlparse = util.urlparse
 socketserver = util.socketserver
 
-class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
-    __base = BaseHTTPServer.BaseHTTPRequestHandler
+class ProxyHandler (httpserver.basehttprequesthandler):
+    __base = httpserver.basehttprequesthandler
     __base_handle = __base.handle
 
     server_version = "TinyHTTPProxy/" + __version__
@@ -136,9 +136,9 @@ 
     do_DELETE = do_GET
 
 class ThreadingHTTPServer (socketserver.ThreadingMixIn,
-                           BaseHTTPServer.HTTPServer):
+                           httpserver.httpserver):
     def __init__(self, *args, **kwargs):
-        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
+        httpserver.httpserver.__init__(self, *args, **kwargs)
         a = open("proxy.pid", "w")
         a.write(str(os.getpid()) + "\n")
         a.close()
@@ -158,4 +158,4 @@ 
             del argv[2:]
         else:
             print("Any clients will be served...")
-        BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)
+        httpserver.test(ProxyHandler, ThreadingHTTPServer)