prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Unclear error message running pelican.server 
  Hello,
  
  I recently upgraded from 3.7.1 to master. After building my site, I tried to run the server via `python -m pelican.server`, as previously. I got a new message:
  
      server.py: error: the following arguments are required: path
  
  Ok, cool. I don't have to cd into output/ any more to run the server. Running `python -m pelican.server outupt/`:
  
      TypeError: __init__() missing 1 required positional argument: 'RequestHandlerClass'
  
  That is... less than helpful. Googling doesn't have any pertinent info. After a little digging, I found the master branch docs already specify the new `pelican --listen` and that resolved it.
  
  It took me a little bit to figure out what was going on - I wasn't expecting the command line UI to change on a minor version, and the message ended up being totally unrelated to what had actually happened.
  
  I think it would be helpful for people upgrading from previous versions to give a clearer error message, maybe 'The pelican server should be run via `pelican --listen`'.
  
  Thanks for all the work so far!
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pelican/server.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 from __future__ import print_function, unicode_literals
  3 
  4 import argparse
  5 import logging
  6 import os
  7 import posixpath
  8 import ssl
  9 import sys
  10 
  11 try:
  12     from magic import from_file as magic_from_file
  13 except ImportError:
  14     magic_from_file = None
  15 
  16 from six.moves import BaseHTTPServer
  17 from six.moves import SimpleHTTPServer as srvmod
  18 from six.moves import urllib
  19 
  20 
  21 def parse_arguments():
  22     parser = argparse.ArgumentParser(
  23         description='Pelican Development Server',
  24         formatter_class=argparse.ArgumentDefaultsHelpFormatter
  25     )
  26     parser.add_argument("port", default=8000, type=int, nargs="?",
  27                         help="Port to Listen On")
  28     parser.add_argument("server", default="", nargs="?",
  29                         help="Interface to Listen On")
  30     parser.add_argument('--ssl', action="store_true",
  31                         help='Activate SSL listener')
  32     parser.add_argument('--cert', default="./cert.pem", nargs="?",
  33                         help='Path to certificate file. ' +
  34                         'Relative to current directory')
  35     parser.add_argument('--key', default="./key.pem", nargs="?",
  36                         help='Path to certificate key file. ' +
  37                         'Relative to current directory')
  38     parser.add_argument('path', default=".",
  39                         help='Path to pelican source directory to serve. ' +
  40                         'Relative to current directory')
  41     return parser.parse_args()
  42 
  43 
  44 class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):
  45     SUFFIXES = ['', '.html', '/index.html']
  46     RSTRIP_PATTERNS = ['', '/']
  47 
  48     def translate_path(self, path):
  49         # abandon query parameters
  50         path = path.split('?', 1)[0]
  51         path = path.split('#', 1)[0]
  52         # Don't forget explicit trailing slash when normalizing. Issue17324
  53         trailing_slash = path.rstrip().endswith('/')
  54         path = urllib.parse.unquote(path)
  55         path = posixpath.normpath(path)
  56         words = path.split('/')
  57         words = filter(None, words)
  58         path = self.base_path
  59         for word in words:
  60             if os.path.dirname(word) or word in (os.curdir, os.pardir):
  61                 # Ignore components that are not a simple file/directory name
  62                 continue
  63             path = os.path.join(path, word)
  64         if trailing_slash:
  65             path += '/'
  66         return path
  67 
  68     def do_GET(self):
  69         # cut off a query string
  70         if '?' in self.path:
  71             self.path, _ = self.path.split('?', 1)
  72 
  73         found = False
  74         # Try to detect file by applying various suffixes and stripping
  75         # patterns.
  76         for rstrip_pattern in self.RSTRIP_PATTERNS:
  77             if found:
  78                 break
  79             for suffix in self.SUFFIXES:
  80                 if not hasattr(self, 'original_path'):
  81                     self.original_path = self.path
  82 
  83                 self.path = self.original_path.rstrip(rstrip_pattern) + suffix
  84                 path = self.translate_path(self.path)
  85 
  86                 if os.path.exists(path):
  87                     srvmod.SimpleHTTPRequestHandler.do_GET(self)
  88                     logging.info("Found `%s`.", self.path)
  89                     found = True
  90                     break
  91 
  92                 logging.info("Tried to find `%s`, but it doesn't exist.", path)
  93 
  94         if not found:
  95             # Fallback if there were no matches
  96             logging.warning("Unable to find `%s` or variations.",
  97                             self.original_path)
  98 
  99     def guess_type(self, path):
  100         """Guess at the mime type for the specified file.
  101         """
  102         mimetype = srvmod.SimpleHTTPRequestHandler.guess_type(self, path)
  103 
  104         # If the default guess is too generic, try the python-magic library
  105         if mimetype == 'application/octet-stream' and magic_from_file:
  106             mimetype = magic_from_file(path, mime=True)
  107 
  108         return mimetype
  109 
  110 
  111 class RootedHTTPServer(BaseHTTPServer.HTTPServer):
  112     def __init__(self, base_path, *args, **kwargs):
  113         BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
  114         self.RequestHandlerClass.base_path = base_path
  115 
  116 
  117 if __name__ == '__main__':
  118     args = parse_arguments()
  119     RootedHTTPServer.allow_reuse_address = True
  120     try:
  121         httpd = RootedHTTPServer(
  122             (args.server, args.port),
  123             ComplexHTTPRequestHandler)
  124         if args.ssl:
  125             httpd.socket = ssl.wrap_socket(
  126                 httpd.socket, keyfile=args.key,
  127                 certfile=args.cert, server_side=True)
  128     except ssl.SSLError as e:
  129         logging.error("Couldn't open certificate file %s or key file %s",
  130                       args.cert, args.key)
  131         logging.error("Could not listen on port %s, server %s.",
  132                       args.port, args.server)
  133         sys.exit(getattr(e, 'exitcode', 1))
  134 
  135     logging.info("Serving at port %s, server %s.",
  136                  args.port, args.server)
  137     try:
  138         httpd.serve_forever()
  139     except KeyboardInterrupt as e:
  140         logging.info("Shutting down server.")
  141         httpd.socket.close()
  142
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pelican/server.py b/pelican/server.py
  --- a/pelican/server.py
  +++ b/pelican/server.py
  @@ -131,6 +131,11 @@
           logging.error("Could not listen on port %s, server %s.",
                         args.port, args.server)
           sys.exit(getattr(e, 'exitcode', 1))
  +    except TypeError as e:
  +        logging.error("'python -m pelican.server' is deprecated. The " +
  +                      "Pelican development server should be run via " +
  +                      "'pelican --listen'")
  +        sys.exit(getattr(e, 'exitcode', 1))
   
       logging.info("Serving at port %s, server %s.",
                    args.port, args.server)
  
verification_info: {"golden_diff": "diff --git a/pelican/server.py b/pelican/server.py\n--- a/pelican/server.py\n+++ b/pelican/server.py\n@@ -131,6 +131,11 @@\n         logging.error(\"Could not listen on port %s, server %s.\",\n                       args.port, args.server)\n         sys.exit(getattr(e, 'exitcode', 1))\n+    except TypeError as e:\n+        logging.error(\"'python -m pelican.server' is deprecated. The \" +\n+                      \"Pelican development server should be run via \" +\n+                      \"'pelican --listen'\")\n+        sys.exit(getattr(e, 'exitcode', 1))\n \n     logging.info(\"Serving at port %s, server %s.\",\n                  args.port, args.server)\n", "issue": "Unclear error message running pelican.server \nHello,\r\n\r\nI recently upgraded from 3.7.1 to master. After building my site, I tried to run the server via `python -m pelican.server`, as previously. I got a new message:\r\n\r\n    server.py: error: the following arguments are required: path\r\n\r\nOk, cool. I don't have to cd into output/ any more to run the server. Running `python -m pelican.server outupt/`:\r\n\r\n    TypeError: __init__() missing 1 required positional argument: 'RequestHandlerClass'\r\n\r\nThat is... less than helpful. Googling doesn't have any pertinent info. After a little digging, I found the master branch docs already specify the new `pelican --listen` and that resolved it.\r\n\r\nIt took me a little bit to figure out what was going on - I wasn't expecting the command line UI to change on a minor version, and the message ended up being totally unrelated to what had actually happened.\r\n\r\nI think it would be helpful for people upgrading from previous versions to give a clearer error message, maybe 'The pelican server should be run via `pelican --listen`'.\r\n\r\nThanks for all the work so far!\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import print_function, unicode_literals\n\nimport argparse\nimport logging\nimport os\nimport posixpath\nimport ssl\nimport sys\n\ntry:\n    from magic import from_file as magic_from_file\nexcept ImportError:\n    magic_from_file = None\n\nfrom six.moves import BaseHTTPServer\nfrom six.moves import SimpleHTTPServer as srvmod\nfrom six.moves import urllib\n\n\ndef parse_arguments():\n    parser = argparse.ArgumentParser(\n        description='Pelican Development Server',\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"port\", default=8000, type=int, nargs=\"?\",\n                        help=\"Port to Listen On\")\n    parser.add_argument(\"server\", default=\"\", nargs=\"?\",\n                        help=\"Interface to Listen On\")\n    parser.add_argument('--ssl', action=\"store_true\",\n                        help='Activate SSL listener')\n    parser.add_argument('--cert', default=\"./cert.pem\", nargs=\"?\",\n                        help='Path to certificate file. ' +\n                        'Relative to current directory')\n    parser.add_argument('--key', default=\"./key.pem\", nargs=\"?\",\n                        help='Path to certificate key file. ' +\n                        'Relative to current directory')\n    parser.add_argument('path', default=\".\",\n                        help='Path to pelican source directory to serve. ' +\n                        'Relative to current directory')\n    return parser.parse_args()\n\n\nclass ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):\n    SUFFIXES = ['', '.html', '/index.html']\n    RSTRIP_PATTERNS = ['', '/']\n\n    def translate_path(self, path):\n        # abandon query parameters\n        path = path.split('?', 1)[0]\n        path = path.split('#', 1)[0]\n        # Don't forget explicit trailing slash when normalizing. Issue17324\n        trailing_slash = path.rstrip().endswith('/')\n        path = urllib.parse.unquote(path)\n        path = posixpath.normpath(path)\n        words = path.split('/')\n        words = filter(None, words)\n        path = self.base_path\n        for word in words:\n            if os.path.dirname(word) or word in (os.curdir, os.pardir):\n                # Ignore components that are not a simple file/directory name\n                continue\n            path = os.path.join(path, word)\n        if trailing_slash:\n            path += '/'\n        return path\n\n    def do_GET(self):\n        # cut off a query string\n        if '?' in self.path:\n            self.path, _ = self.path.split('?', 1)\n\n        found = False\n        # Try to detect file by applying various suffixes and stripping\n        # patterns.\n        for rstrip_pattern in self.RSTRIP_PATTERNS:\n            if found:\n                break\n            for suffix in self.SUFFIXES:\n                if not hasattr(self, 'original_path'):\n                    self.original_path = self.path\n\n                self.path = self.original_path.rstrip(rstrip_pattern) + suffix\n                path = self.translate_path(self.path)\n\n                if os.path.exists(path):\n                    srvmod.SimpleHTTPRequestHandler.do_GET(self)\n                    logging.info(\"Found `%s`.\", self.path)\n                    found = True\n                    break\n\n                logging.info(\"Tried to find `%s`, but it doesn't exist.\", path)\n\n        if not found:\n            # Fallback if there were no matches\n            logging.warning(\"Unable to find `%s` or variations.\",\n                            self.original_path)\n\n    def guess_type(self, path):\n        \"\"\"Guess at the mime type for the specified file.\n        \"\"\"\n        mimetype = srvmod.SimpleHTTPRequestHandler.guess_type(self, path)\n\n        # If the default guess is too generic, try the python-magic library\n        if mimetype == 'application/octet-stream' and magic_from_file:\n            mimetype = magic_from_file(path, mime=True)\n\n        return mimetype\n\n\nclass RootedHTTPServer(BaseHTTPServer.HTTPServer):\n    def __init__(self, base_path, *args, **kwargs):\n        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)\n        self.RequestHandlerClass.base_path = base_path\n\n\nif __name__ == '__main__':\n    args = parse_arguments()\n    RootedHTTPServer.allow_reuse_address = True\n    try:\n        httpd = RootedHTTPServer(\n            (args.server, args.port),\n            ComplexHTTPRequestHandler)\n        if args.ssl:\n            httpd.socket = ssl.wrap_socket(\n                httpd.socket, keyfile=args.key,\n                certfile=args.cert, server_side=True)\n    except ssl.SSLError as e:\n        logging.error(\"Couldn't open certificate file %s or key file %s\",\n                      args.cert, args.key)\n        logging.error(\"Could not listen on port %s, server %s.\",\n                      args.port, args.server)\n        sys.exit(getattr(e, 'exitcode', 1))\n\n    logging.info(\"Serving at port %s, server %s.\",\n                 args.port, args.server)\n    try:\n        httpd.serve_forever()\n    except KeyboardInterrupt as e:\n        logging.info(\"Shutting down server.\")\n        httpd.socket.close()\n", "path": "pelican/server.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import print_function, unicode_literals\n\nimport argparse\nimport logging\nimport os\nimport posixpath\nimport ssl\nimport sys\n\ntry:\n    from magic import from_file as magic_from_file\nexcept ImportError:\n    magic_from_file = None\n\nfrom six.moves import BaseHTTPServer\nfrom six.moves import SimpleHTTPServer as srvmod\nfrom six.moves import urllib\n\n\ndef parse_arguments():\n    parser = argparse.ArgumentParser(\n        description='Pelican Development Server',\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"port\", default=8000, type=int, nargs=\"?\",\n                        help=\"Port to Listen On\")\n    parser.add_argument(\"server\", default=\"\", nargs=\"?\",\n                        help=\"Interface to Listen On\")\n    parser.add_argument('--ssl', action=\"store_true\",\n                        help='Activate SSL listener')\n    parser.add_argument('--cert', default=\"./cert.pem\", nargs=\"?\",\n                        help='Path to certificate file. ' +\n                        'Relative to current directory')\n    parser.add_argument('--key', default=\"./key.pem\", nargs=\"?\",\n                        help='Path to certificate key file. ' +\n                        'Relative to current directory')\n    parser.add_argument('path', default=\".\",\n                        help='Path to pelican source directory to serve. ' +\n                        'Relative to current directory')\n    return parser.parse_args()\n\n\nclass ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):\n    SUFFIXES = ['', '.html', '/index.html']\n    RSTRIP_PATTERNS = ['', '/']\n\n    def translate_path(self, path):\n        # abandon query parameters\n        path = path.split('?', 1)[0]\n        path = path.split('#', 1)[0]\n        # Don't forget explicit trailing slash when normalizing. Issue17324\n        trailing_slash = path.rstrip().endswith('/')\n        path = urllib.parse.unquote(path)\n        path = posixpath.normpath(path)\n        words = path.split('/')\n        words = filter(None, words)\n        path = self.base_path\n        for word in words:\n            if os.path.dirname(word) or word in (os.curdir, os.pardir):\n                # Ignore components that are not a simple file/directory name\n                continue\n            path = os.path.join(path, word)\n        if trailing_slash:\n            path += '/'\n        return path\n\n    def do_GET(self):\n        # cut off a query string\n        if '?' in self.path:\n            self.path, _ = self.path.split('?', 1)\n\n        found = False\n        # Try to detect file by applying various suffixes and stripping\n        # patterns.\n        for rstrip_pattern in self.RSTRIP_PATTERNS:\n            if found:\n                break\n            for suffix in self.SUFFIXES:\n                if not hasattr(self, 'original_path'):\n                    self.original_path = self.path\n\n                self.path = self.original_path.rstrip(rstrip_pattern) + suffix\n                path = self.translate_path(self.path)\n\n                if os.path.exists(path):\n                    srvmod.SimpleHTTPRequestHandler.do_GET(self)\n                    logging.info(\"Found `%s`.\", self.path)\n                    found = True\n                    break\n\n                logging.info(\"Tried to find `%s`, but it doesn't exist.\", path)\n\n        if not found:\n            # Fallback if there were no matches\n            logging.warning(\"Unable to find `%s` or variations.\",\n                            self.original_path)\n\n    def guess_type(self, path):\n        \"\"\"Guess at the mime type for the specified file.\n        \"\"\"\n        mimetype = srvmod.SimpleHTTPRequestHandler.guess_type(self, path)\n\n        # If the default guess is too generic, try the python-magic library\n        if mimetype == 'application/octet-stream' and magic_from_file:\n            mimetype = magic_from_file(path, mime=True)\n\n        return mimetype\n\n\nclass RootedHTTPServer(BaseHTTPServer.HTTPServer):\n    def __init__(self, base_path, *args, **kwargs):\n        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)\n        self.RequestHandlerClass.base_path = base_path\n\n\nif __name__ == '__main__':\n    args = parse_arguments()\n    RootedHTTPServer.allow_reuse_address = True\n    try:\n        httpd = RootedHTTPServer(\n            (args.server, args.port),\n            ComplexHTTPRequestHandler)\n        if args.ssl:\n            httpd.socket = ssl.wrap_socket(\n                httpd.socket, keyfile=args.key,\n                certfile=args.cert, server_side=True)\n    except ssl.SSLError as e:\n        logging.error(\"Couldn't open certificate file %s or key file %s\",\n                      args.cert, args.key)\n        logging.error(\"Could not listen on port %s, server %s.\",\n                      args.port, args.server)\n        sys.exit(getattr(e, 'exitcode', 1))\n    except TypeError as e:\n        logging.error(\"'python -m pelican.server' is deprecated. The \" +\n                      \"Pelican development server should be run via \" +\n                      \"'pelican --listen'\")\n        sys.exit(getattr(e, 'exitcode', 1))\n\n    logging.info(\"Serving at port %s, server %s.\",\n                 args.port, args.server)\n    try:\n        httpd.serve_forever()\n    except KeyboardInterrupt as e:\n        logging.info(\"Shutting down server.\")\n        httpd.socket.close()\n", "path": "pelican/server.py"}]}