bpo-36329: Remove 'make -C Doc serve' in favour of 'make -C Doc htmlview' (GH-32354)

Also updated `make -C htmlview` so it used a full path with `file://`, because the original didn't open the page (macOS).

For example:
```sh
cd Doc

# Doesn't open anything:
python3 -c "import webbrowser; webbrowser.open('build/html/index.html')"

# Opens the docs page e.g. file:///Users/hugo/github/cpython/Doc/build/html/index.html :
python3 -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))"
```

https://bugs.python.org/issue36329
diff --git a/Doc/Makefile b/Doc/Makefile
index 61a7ce0..3a3417b 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -13,7 +13,6 @@
 SOURCES      =
 DISTVERSION  = $(shell $(PYTHON) tools/extensions/patchlevel.py)
 SPHINXERRORHANDLING = -W
-SERVE_PORT   =
 
 # Internal variables.
 PAPEROPT_a4     = -D latex_elements.papersize=a4paper
@@ -45,7 +44,6 @@
 	@echo "  dist       to create a \"dist\" directory with archived docs for download"
 	@echo "  suspicious to check for suspicious markup in output text"
 	@echo "  check      to run a check for frequent markup errors"
-	@echo "  serve      to serve the documentation on the localhost (8000)"
 
 build:
 	-mkdir -p build
@@ -141,7 +139,7 @@
 	      "cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py"
 
 htmlview: html
-	 $(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
+	$(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))"
 
 clean: clean-venv
 	-rm -rf build/*
@@ -219,7 +217,7 @@
 	$(SPHINXLINT) ../Misc/NEWS.d/next/
 
 serve:
-	$(PYTHON) ../Tools/scripts/serve.py build/html $(SERVE_PORT)
+	@echo "The serve target was removed, use htmlview instead (see bpo-36329)"
 
 # Targets for daily automated doc build
 # By default, Sphinx only rebuilds pages where the page content has changed.
diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst
index 0ca7b00..6a2d478 100644
--- a/Doc/library/wsgiref.rst
+++ b/Doc/library/wsgiref.rst
@@ -813,30 +813,76 @@
 
 This is a working "Hello World" WSGI application::
 
+   """
+   Every WSGI application must have an application object - a callable
+   object that accepts two arguments. For that purpose, we're going to
+   use a function (note that you're not limited to a function, you can
+   use a class for example). The first argument passed to the function
+   is a dictionary containing CGI-style environment variables and the
+   second variable is the callable object.
+   """
    from wsgiref.simple_server import make_server
 
-   # Every WSGI application must have an application object - a callable
-   # object that accepts two arguments. For that purpose, we're going to
-   # use a function (note that you're not limited to a function, you can
-   # use a class for example). The first argument passed to the function
-   # is a dictionary containing CGI-style environment variables and the
-   # second variable is the callable object.
+
    def hello_world_app(environ, start_response):
-       status = '200 OK'  # HTTP Status
-       headers = [('Content-type', 'text/plain; charset=utf-8')]  # HTTP Headers
+       status = "200 OK"  # HTTP Status
+       headers = [("Content-type", "text/plain; charset=utf-8")]  # HTTP Headers
        start_response(status, headers)
 
        # The returned object is going to be printed
        return [b"Hello World"]
 
-   with make_server('', 8000, hello_world_app) as httpd:
+   with make_server("", 8000, hello_world_app) as httpd:
        print("Serving on port 8000...")
 
        # Serve until process is killed
        httpd.serve_forever()
 
 
-Example of a WSGI application serving the current directory, accept optional
-directory and port number (default: 8000) on the command line:
 
-.. literalinclude:: ../../Tools/scripts/serve.py
+Example of a WSGI application serving the current directory, accept optional
+directory and port number (default: 8000) on the command line::
+
+    """
+    Small wsgiref based web server. Takes a path to serve from and an
+    optional port number (defaults to 8000), then tries to serve files.
+    MIME types are guessed from the file names, 404 errors are raised
+    if the file is not found.
+    """
+    import mimetypes
+    import os
+    import sys
+    from wsgiref import simple_server, util
+
+
+    def app(environ, respond):
+        # Get the file name and MIME type
+        fn = os.path.join(path, environ["PATH_INFO"][1:])
+        if "." not in fn.split(os.path.sep)[-1]:
+            fn = os.path.join(fn, "index.html")
+        mime_type = mimetypes.guess_type(fn)[0]
+
+        # Return 200 OK if file exists, otherwise 404 Not Found
+        if os.path.exists(fn):
+            respond("200 OK", [("Content-Type", mime_type)])
+            return util.FileWrapper(open(fn, "rb"))
+        else:
+            respond("404 Not Found", [("Content-Type", "text/plain")])
+            return [b"not found"]
+
+
+    if __name__ == "__main__":
+        # Get the path and port from command-line arguments
+        path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
+        port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
+
+        # Make and start the server until control-c
+        httpd = simple_server.make_server("", port, app)
+        print(f"Serving {path} on port {port}, control-C to stop")
+        try:
+            httpd.serve_forever()
+        except KeyboardInterrupt:
+            print("Shutting down.")
+            httpd.server_close()
+
+
diff --git a/Doc/make.bat b/Doc/make.bat
index f3e9b44..d9a7aa4 100644
--- a/Doc/make.bat
+++ b/Doc/make.bat
@@ -111,7 +111,7 @@
 echo.      html, htmlhelp, latex, text
 echo.      suspicious, linkcheck, changes, doctest
 echo.   Provided by this script:
-echo.      clean, check, serve, htmlview
+echo.      clean, check, htmlview
 echo.
 echo.All arguments past the first one are passed through to sphinx-build as
 echo.filenames to build or are ignored.  See README.rst in this directory or
@@ -184,7 +184,7 @@
 goto end
 
 :serve
-cmd /S /C "%PYTHON% ..\Tools\scripts\serve.py "%BUILDDIR%\html""
+echo.The serve target was removed, use htmlview instead (see bpo-36329)
 goto end
 
 :end
diff --git a/Misc/NEWS.d/next/Documentation/2022-04-06-11-53-41.bpo-36329.EVtAtK.rst b/Misc/NEWS.d/next/Documentation/2022-04-06-11-53-41.bpo-36329.EVtAtK.rst
new file mode 100644
index 0000000..67398de
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2022-04-06-11-53-41.bpo-36329.EVtAtK.rst
@@ -0,0 +1 @@
+Remove 'make -C Doc serve' in favour of 'make -C Doc htmlview'
diff --git a/Tools/scripts/README b/Tools/scripts/README
index ba0f662..c1d6673 100644
--- a/Tools/scripts/README
+++ b/Tools/scripts/README
@@ -57,7 +57,6 @@
 reindent-rst.py           Fix-up reStructuredText file whitespace
 rgrep.py                  Reverse grep through a file (useful for big logfiles)
 run_tests.py              Run the test suite with more sensible default options
-serve.py                  Small wsgiref-based web server, used in make serve in Doc
 stable_abi.py             Stable ABI checks and file generators.
 suff.py                   Sort a list of files by suffix
 texi2html.py              Convert GNU texinfo files into HTML
diff --git a/Tools/scripts/serve.py b/Tools/scripts/serve.py
deleted file mode 100755
index 7ac9c10..0000000
--- a/Tools/scripts/serve.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python3
-'''
-Small wsgiref based web server. Takes a path to serve from and an
-optional port number (defaults to 8000), then tries to serve files.
-Mime types are guessed from the file names, 404 errors are raised
-if the file is not found. Used for the make serve target in Doc.
-'''
-import sys
-import os
-import mimetypes
-from wsgiref import simple_server, util
-
-def app(environ, respond):
-
-    fn = os.path.join(path, environ['PATH_INFO'][1:])
-    if '.' not in fn.split(os.path.sep)[-1]:
-        fn = os.path.join(fn, 'index.html')
-    type = mimetypes.guess_type(fn)[0]
-
-    if os.path.exists(fn):
-        respond('200 OK', [('Content-Type', type)])
-        return util.FileWrapper(open(fn, "rb"))
-    else:
-        respond('404 Not Found', [('Content-Type', 'text/plain')])
-        return [b'not found']
-
-if __name__ == '__main__':
-    path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
-    port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
-    httpd = simple_server.make_server('', port, app)
-    print("Serving {} on port {}, control-C to stop".format(path, port))
-    try:
-        httpd.serve_forever()
-    except KeyboardInterrupt:
-        print("Shutting down.")
-        httpd.server_close()