py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
authorPulkit Goyal <7895pulkit@gmail.com>
Wed, 13 Jul 2016 23:38:29 +0530
changeset 29566 075146e85bb6
parent 29565 143d21a7343e
child 29567 7e2b389418da
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 unchanged.
contrib/check-code.py
mercurial/hgweb/common.py
mercurial/hgweb/server.py
mercurial/pycompat.py
mercurial/util.py
tests/dumbhttp.py
tests/test-check-py3-compat.t
tests/tinyproxy.py
--- a/contrib/check-code.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/contrib/check-code.py	Wed Jul 13 23:38:29 2016 +0530
@@ -333,6 +333,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()
--- a/mercurial/hgweb/common.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/mercurial/hgweb/common.py	Wed Jul 13 23:38:29 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):
--- a/mercurial/hgweb/server.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/mercurial/hgweb/server.py	Wed Jul 13 23:38:29 2016 +0530
@@ -8,7 +8,6 @@
 
 from __future__ import absolute_import
 
-import BaseHTTPServer
 import errno
 import os
 import socket
@@ -22,6 +21,7 @@
     util,
 )
 
+httpservermod = 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(httpservermod.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)
+        httpservermod.basehttprequesthandler.__init__(self, *args, **kargs)
 
     def _log_any(self, fp, format, *args):
         fp.write("%s - - [%s] %s\n" % (self.client_address[0],
@@ -263,14 +263,14 @@
         return open(opt, 'a')
     return default
 
-class MercurialHTTPServer(object, _mixin, BaseHTTPServer.HTTPServer):
+class MercurialHTTPServer(object, _mixin, httpservermod.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)
+        httpservermod.httpserver.__init__(self, addr, handler, **kwargs)
         self.daemon_threads = True
         self.application = app
 
--- a/mercurial/pycompat.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/mercurial/pycompat.py	Wed Jul 13 23:38:29 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
--- a/mercurial/util.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/mercurial/util.py	Wed Jul 13 23:38:29 2016 +0530
@@ -48,6 +48,7 @@
 for attr in (
     'empty',
     'httplib',
+    'httpserver',
     'pickle',
     'queue',
     'urlerr',
--- a/tests/dumbhttp.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/tests/dumbhttp.py	Wed Jul 13 23:38:29 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()
 
--- a/tests/test-check-py3-compat.t	Fri Jul 15 23:00:31 2016 +0530
+++ b/tests/test-check-py3-compat.t	Wed Jul 13 23:38:29 2016 +0530
@@ -110,12 +110,12 @@
   mercurial/hbisect.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/help.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/hg.py: error importing: <TypeError> str expected, not bytes (error at i18n.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)
@@ -136,8 +136,8 @@
   mercurial/patch.py: error importing: <TypeError> '_fields_' must be a sequence of (name, C type) pairs (error at osutil.py:*) (glob)
   mercurial/pathutil.py: error importing: <TypeError> '_fields_' must be a sequence of (name, C type) pairs (error at osutil.py:*) (glob)
   mercurial/peer.py: error importing: <TypeError> '_fields_' must be a sequence of (name, C type) pairs (error at osutil.py:*) (glob)
-  mercurial/pure/mpatch.py: error importing module: <ImportError> cannot import name 'pycompat' (line *) (glob)
-  mercurial/pure/parsers.py: error importing module: <ImportError> No module named 'mercurial.pure.node' (line *) (glob)
+  mercurial/pure/mpatch.py: error importing module: <AttributeError> 'VendorImporter' object has no attribute 'find_spec' (line *) (glob)
+  mercurial/pure/parsers.py: error importing module: <AttributeError> 'VendorImporter' object has no attribute 'find_spec' (line *) (glob)
   mercurial/pushkey.py: error importing: <TypeError> '_fields_' must be a sequence of (name, C type) pairs (error at osutil.py:*) (glob)
   mercurial/pvec.py: error importing: <TypeError> '_fields_' must be a sequence of (name, C type) pairs (error at osutil.py:*) (glob)
   mercurial/registrar.py: error importing: <TypeError> '_fields_' must be a sequence of (name, C type) pairs (error at osutil.py:*) (glob)
--- a/tests/tinyproxy.py	Fri Jul 15 23:00:31 2016 +0530
+++ b/tests/tinyproxy.py	Wed Jul 13 23:38:29 2016 +0530
@@ -14,7 +14,6 @@
 
 __version__ = "0.2.1"
 
-import BaseHTTPServer
 import optparse
 import os
 import select
@@ -23,11 +22,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__
@@ -137,9 +137,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()