summaryrefslogtreecommitdiffstats
path: root/Doc
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-05-24 09:04:53 (GMT)
committerGitHub <noreply@github.com>2023-05-24 09:04:53 (GMT)
commit08d592389603500af398d278af4842cff6f22c33 (patch)
treecc7fd2bdd678869fe361cec2eb9ca244474f5eaa /Doc
parente561c09975bf67ad8bb67c56a81e30a9165bcc84 (diff)
downloadcpython-08d592389603500af398d278af4842cff6f22c33.zip
cpython-08d592389603500af398d278af4842cff6f22c33.tar.gz
cpython-08d592389603500af398d278af4842cff6f22c33.tar.bz2
gh-104773: PEP 594: Remove cgi and cgitb modules (#104775)
* Replace "cgi" with "!cgi" in the Sphinx documentation to avoid warnings on broken references. * test_pyclbr no longer tests the cgi module.
Diffstat (limited to 'Doc')
-rw-r--r--Doc/library/cgi.rst564
-rw-r--r--Doc/library/cgitb.rst89
-rw-r--r--Doc/library/security_warnings.rst1
-rw-r--r--Doc/library/superseded.rst2
-rw-r--r--Doc/whatsnew/2.0.rst2
-rw-r--r--Doc/whatsnew/2.6.rst6
-rw-r--r--Doc/whatsnew/3.10.rst2
-rw-r--r--Doc/whatsnew/3.11.rst4
-rw-r--r--Doc/whatsnew/3.12.rst4
-rw-r--r--Doc/whatsnew/3.13.rst30
-rw-r--r--Doc/whatsnew/3.4.rst8
-rw-r--r--Doc/whatsnew/3.6.rst4
-rw-r--r--Doc/whatsnew/3.7.rst2
-rw-r--r--Doc/whatsnew/3.8.rst4
-rw-r--r--Doc/whatsnew/3.9.rst2
15 files changed, 49 insertions, 675 deletions
diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst
deleted file mode 100644
index 295a601..0000000
--- a/Doc/library/cgi.rst
+++ /dev/null
@@ -1,564 +0,0 @@
-:mod:`cgi` --- Common Gateway Interface support
-===============================================
-
-.. module:: cgi
- :synopsis: Helpers for running Python scripts via the Common Gateway Interface.
- :deprecated:
-
-**Source code:** :source:`Lib/cgi.py`
-
-.. index::
- pair: WWW; server
- pair: CGI; protocol
- pair: HTTP; protocol
- pair: MIME; headers
- single: URL
- single: Common Gateway Interface
-
-.. deprecated-removed:: 3.11 3.13
- The :mod:`cgi` module is deprecated
- (see :pep:`PEP 594 <594#cgi>` for details and alternatives).
-
- The :class:`FieldStorage` class can typically be replaced with
- :func:`urllib.parse.parse_qsl` for ``GET`` and ``HEAD`` requests,
- and the :mod:`email.message` module or
- `multipart <https://pypi.org/project/multipart/>`_ for ``POST`` and ``PUT``.
- Most :ref:`utility functions <functions-in-cgi-module>` have replacements.
-
---------------
-
-Support module for Common Gateway Interface (CGI) scripts.
-
-This module defines a number of utilities for use by CGI scripts written in
-Python.
-
-The global variable ``maxlen`` can be set to an integer indicating the maximum
-size of a POST request. POST requests larger than this size will result in a
-:exc:`ValueError` being raised during parsing. The default value of this
-variable is ``0``, meaning the request size is unlimited.
-
-.. include:: ../includes/wasm-notavail.rst
-
-Introduction
-------------
-
-.. _cgi-intro:
-
-A CGI script is invoked by an HTTP server, usually to process user input
-submitted through an HTML ``<FORM>`` or ``<ISINDEX>`` element.
-
-Most often, CGI scripts live in the server's special :file:`cgi-bin` directory.
-The HTTP server places all sorts of information about the request (such as the
-client's hostname, the requested URL, the query string, and lots of other
-goodies) in the script's shell environment, executes the script, and sends the
-script's output back to the client.
-
-The script's input is connected to the client too, and sometimes the form data
-is read this way; at other times the form data is passed via the "query string"
-part of the URL. This module is intended to take care of the different cases
-and provide a simpler interface to the Python script. It also provides a number
-of utilities that help in debugging scripts, and the latest addition is support
-for file uploads from a form (if your browser supports it).
-
-The output of a CGI script should consist of two sections, separated by a blank
-line. The first section contains a number of headers, telling the client what
-kind of data is following. Python code to generate a minimal header section
-looks like this::
-
- print("Content-Type: text/html") # HTML is following
- print() # blank line, end of headers
-
-The second section is usually HTML, which allows the client software to display
-nicely formatted text with header, in-line images, etc. Here's Python code that
-prints a simple piece of HTML::
-
- print("<TITLE>CGI script output</TITLE>")
- print("<H1>This is my first CGI script</H1>")
- print("Hello, world!")
-
-
-.. _using-the-cgi-module:
-
-Using the cgi module
---------------------
-
-Begin by writing ``import cgi``.
-
-When you write a new script, consider adding these lines::
-
- import cgitb
- cgitb.enable()
-
-This activates a special exception handler that will display detailed reports in
-the web browser if any errors occur. If you'd rather not show the guts of your
-program to users of your script, you can have the reports saved to files
-instead, with code like this::
-
- import cgitb
- cgitb.enable(display=0, logdir="/path/to/logdir")
-
-It's very helpful to use this feature during script development. The reports
-produced by :mod:`cgitb` provide information that can save you a lot of time in
-tracking down bugs. You can always remove the ``cgitb`` line later when you
-have tested your script and are confident that it works correctly.
-
-To get at submitted form data, use the :class:`FieldStorage` class. If the form
-contains non-ASCII characters, use the *encoding* keyword parameter set to the
-value of the encoding defined for the document. It is usually contained in the
-META tag in the HEAD section of the HTML document or by the
-:mailheader:`Content-Type` header. This reads the form contents from the
-standard input or the environment (depending on the value of various
-environment variables set according to the CGI standard). Since it may consume
-standard input, it should be instantiated only once.
-
-The :class:`FieldStorage` instance can be indexed like a Python dictionary.
-It allows membership testing with the :keyword:`in` operator, and also supports
-the standard dictionary method :meth:`~dict.keys` and the built-in function
-:func:`len`. Form fields containing empty strings are ignored and do not appear
-in the dictionary; to keep such values, provide a true value for the optional
-*keep_blank_values* keyword parameter when creating the :class:`FieldStorage`
-instance.
-
-For instance, the following code (which assumes that the
-:mailheader:`Content-Type` header and blank line have already been printed)
-checks that the fields ``name`` and ``addr`` are both set to a non-empty
-string::
-
- form = cgi.FieldStorage()
- if "name" not in form or "addr" not in form:
- print("<H1>Error</H1>")
- print("Please fill in the name and addr fields.")
- return
- print("<p>name:", form["name"].value)
- print("<p>addr:", form["addr"].value)
- ...further form processing here...
-
-Here the fields, accessed through ``form[key]``, are themselves instances of
-:class:`FieldStorage` (or :class:`MiniFieldStorage`, depending on the form
-encoding). The :attr:`~FieldStorage.value` attribute of the instance yields
-the string value of the field. The :meth:`~FieldStorage.getvalue` method
-returns this string value directly; it also accepts an optional second argument
-as a default to return if the requested key is not present.
-
-If the submitted form data contains more than one field with the same name, the
-object retrieved by ``form[key]`` is not a :class:`FieldStorage` or
-:class:`MiniFieldStorage` instance but a list of such instances. Similarly, in
-this situation, ``form.getvalue(key)`` would return a list of strings. If you
-expect this possibility (when your HTML form contains multiple fields with the
-same name), use the :meth:`~FieldStorage.getlist` method, which always returns
-a list of values (so that you do not need to special-case the single item
-case). For example, this code concatenates any number of username fields,
-separated by commas::
-
- value = form.getlist("username")
- usernames = ",".join(value)
-
-If a field represents an uploaded file, accessing the value via the
-:attr:`~FieldStorage.value` attribute or the :meth:`~FieldStorage.getvalue`
-method reads the entire file in memory as bytes. This may not be what you
-want. You can test for an uploaded file by testing either the
-:attr:`~FieldStorage.filename` attribute or the :attr:`~FieldStorage.file`
-attribute. You can then read the data from the :attr:`!file`
-attribute before it is automatically closed as part of the garbage collection of
-the :class:`FieldStorage` instance
-(the :func:`~io.RawIOBase.read` and :func:`~io.IOBase.readline` methods will
-return bytes)::
-
- fileitem = form["userfile"]
- if fileitem.file:
- # It's an uploaded file; count lines
- linecount = 0
- while True:
- line = fileitem.file.readline()
- if not line: break
- linecount = linecount + 1
-
-:class:`FieldStorage` objects also support being used in a :keyword:`with`
-statement, which will automatically close them when done.
-
-If an error is encountered when obtaining the contents of an uploaded file
-(for example, when the user interrupts the form submission by clicking on
-a Back or Cancel button) the :attr:`~FieldStorage.done` attribute of the
-object for the field will be set to the value -1.
-
-The file upload draft standard entertains the possibility of uploading multiple
-files from one field (using a recursive :mimetype:`multipart/\*` encoding).
-When this occurs, the item will be a dictionary-like :class:`FieldStorage` item.
-This can be determined by testing its :attr:`!type` attribute, which should be
-:mimetype:`multipart/form-data` (or perhaps another MIME type matching
-:mimetype:`multipart/\*`). In this case, it can be iterated over recursively
-just like the top-level form object.
-
-When a form is submitted in the "old" format (as the query string or as a single
-data part of type :mimetype:`application/x-www-form-urlencoded`), the items will
-actually be instances of the class :class:`MiniFieldStorage`. In this case, the
-:attr:`!list`, :attr:`!file`, and :attr:`filename` attributes are always ``None``.
-
-A form submitted via POST that also has a query string will contain both
-:class:`FieldStorage` and :class:`MiniFieldStorage` items.
-
-.. versionchanged:: 3.4
- The :attr:`~FieldStorage.file` attribute is automatically closed upon the
- garbage collection of the creating :class:`FieldStorage` instance.
-
-.. versionchanged:: 3.5
- Added support for the context management protocol to the
- :class:`FieldStorage` class.
-
-
-Higher Level Interface
-----------------------
-
-The previous section explains how to read CGI form data using the
-:class:`FieldStorage` class. This section describes a higher level interface
-which was added to this class to allow one to do it in a more readable and
-intuitive way. The interface doesn't make the techniques described in previous
-sections obsolete --- they are still useful to process file uploads efficiently,
-for example.
-
-.. XXX: Is this true ?
-
-The interface consists of two simple methods. Using the methods you can process
-form data in a generic way, without the need to worry whether only one or more
-values were posted under one name.
-
-In the previous section, you learned to write following code anytime you
-expected a user to post more than one value under one name::
-
- item = form.getvalue("item")
- if isinstance(item, list):
- # The user is requesting more than one item.
- else:
- # The user is requesting only one item.
-
-This situation is common for example when a form contains a group of multiple
-checkboxes with the same name::
-
- <input type="checkbox" name="item" value="1" />
- <input type="checkbox" name="item" value="2" />
-
-In most situations, however, there's only one form control with a particular
-name in a form and then you expect and need only one value associated with this
-name. So you write a script containing for example this code::
-
- user = form.getvalue("user").upper()
-
-The problem with the code is that you should never expect that a client will
-provide valid input to your scripts. For example, if a curious user appends
-another ``user=foo`` pair to the query string, then the script would crash,
-because in this situation the ``getvalue("user")`` method call returns a list
-instead of a string. Calling the :meth:`~str.upper` method on a list is not valid
-(since lists do not have a method of this name) and results in an
-:exc:`AttributeError` exception.
-
-Therefore, the appropriate way to read form data values was to always use the
-code which checks whether the obtained value is a single value or a list of
-values. That's annoying and leads to less readable scripts.
-
-A more convenient approach is to use the methods :meth:`~FieldStorage.getfirst`
-and :meth:`~FieldStorage.getlist` provided by this higher level interface.
-
-
-.. method:: FieldStorage.getfirst(name, default=None)
-
- This method always returns only one value associated with form field *name*.
- The method returns only the first value in case that more values were posted
- under such name. Please note that the order in which the values are received
- may vary from browser to browser and should not be counted on. [#]_ If no such
- form field or value exists then the method returns the value specified by the
- optional parameter *default*. This parameter defaults to ``None`` if not
- specified.
-
-
-.. method:: FieldStorage.getlist(name)
-
- This method always returns a list of values associated with form field *name*.
- The method returns an empty list if no such form field or value exists for
- *name*. It returns a list consisting of one item if only one such value exists.
-
-Using these methods you can write nice compact code::
-
- import cgi
- form = cgi.FieldStorage()
- user = form.getfirst("user", "").upper() # This way it's safe.
- for item in form.getlist("item"):
- do_something(item)
-
-
-.. _functions-in-cgi-module:
-
-Functions
----------
-
-These are useful if you want more control, or if you want to employ some of the
-algorithms implemented in this module in other circumstances.
-
-
-.. function:: parse(fp=None, environ=os.environ, keep_blank_values=False, strict_parsing=False, separator="&")
-
- Parse a query in the environment or from a file (the file defaults to
- ``sys.stdin``). The *keep_blank_values*, *strict_parsing* and *separator* parameters are
- passed to :func:`urllib.parse.parse_qs` unchanged.
-
- .. deprecated-removed:: 3.11 3.13
- This function, like the rest of the :mod:`cgi` module, is deprecated.
- It can be replaced by calling :func:`urllib.parse.parse_qs` directly
- on the desired query string (except for ``multipart/form-data`` input,
- which can be handled as described for :func:`parse_multipart`).
-
-
-.. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator="&")
-
- Parse input of type :mimetype:`multipart/form-data` (for file uploads).
- Arguments are *fp* for the input file, *pdict* for a dictionary containing
- other parameters in the :mailheader:`Content-Type` header, and *encoding*,
- the request encoding.
-
- Returns a dictionary just like :func:`urllib.parse.parse_qs`: keys are the
- field names, each value is a list of values for that field. For non-file
- fields, the value is a list of strings.
-
- This is easy to use but not much good if you are expecting megabytes to be
- uploaded --- in that case, use the :class:`FieldStorage` class instead
- which is much more flexible.
-
- .. versionchanged:: 3.7
- Added the *encoding* and *errors* parameters. For non-file fields, the
- value is now a list of strings, not bytes.
-
- .. versionchanged:: 3.10
- Added the *separator* parameter.
-
- .. deprecated-removed:: 3.11 3.13
- This function, like the rest of the :mod:`cgi` module, is deprecated.
- It can be replaced with the functionality in the :mod:`email` package
- (e.g. :class:`email.message.EmailMessage`/:class:`email.message.Message`)
- which implements the same MIME RFCs, or with the
- `multipart <https://pypi.org/project/multipart/>`__ PyPI project.
-
-
-.. function:: parse_header(string)
-
- Parse a MIME header (such as :mailheader:`Content-Type`) into a main value and a
- dictionary of parameters.
-
- .. deprecated-removed:: 3.11 3.13
- This function, like the rest of the :mod:`cgi` module, is deprecated.
- It can be replaced with the functionality in the :mod:`email` package,
- which implements the same MIME RFCs.
-
- For example, with :class:`email.message.EmailMessage`::
-
- from email.message import EmailMessage
- msg = EmailMessage()
- msg['content-type'] = 'application/json; charset="utf8"'
- main, params = msg.get_content_type(), msg['content-type'].params
-
-
-.. function:: test()
-
- Robust test CGI script, usable as main program. Writes minimal HTTP headers and
- formats all information provided to the script in HTML format.
-
-
-.. function:: print_environ()
-
- Format the shell environment in HTML.
-
-
-.. function:: print_form(form)
-
- Format a form in HTML.
-
-
-.. function:: print_directory()
-
- Format the current directory in HTML.
-
-
-.. function:: print_environ_usage()
-
- Print a list of useful (used by CGI) environment variables in HTML.
-
-
-.. _cgi-security:
-
-Caring about security
----------------------
-
-.. index:: pair: CGI; security
-
-There's one important rule: if you invoke an external program (via
-:func:`os.system`, :func:`os.popen` or other functions with similar
-functionality), make very sure you don't pass arbitrary strings received from
-the client to the shell. This is a well-known security hole whereby clever
-hackers anywhere on the web can exploit a gullible CGI script to invoke
-arbitrary shell commands. Even parts of the URL or field names cannot be
-trusted, since the request doesn't have to come from your form!
-
-To be on the safe side, if you must pass a string gotten from a form to a shell
-command, you should make sure the string contains only alphanumeric characters,
-dashes, underscores, and periods.
-
-
-Installing your CGI script on a Unix system
--------------------------------------------
-
-Read the documentation for your HTTP server and check with your local system
-administrator to find the directory where CGI scripts should be installed;
-usually this is in a directory :file:`cgi-bin` in the server tree.
-
-Make sure that your script is readable and executable by "others"; the Unix file
-mode should be ``0o755`` octal (use ``chmod 0755 filename``). Make sure that the
-first line of the script contains ``#!`` starting in column 1 followed by the
-pathname of the Python interpreter, for instance::
-
- #!/usr/local/bin/python
-
-Make sure the Python interpreter exists and is executable by "others".
-
-Make sure that any files your script needs to read or write are readable or
-writable, respectively, by "others" --- their mode should be ``0o644`` for
-readable and ``0o666`` for writable. This is because, for security reasons, the
-HTTP server executes your script as user "nobody", without any special
-privileges. It can only read (write, execute) files that everybody can read
-(write, execute). The current directory at execution time is also different (it
-is usually the server's cgi-bin directory) and the set of environment variables
-is also different from what you get when you log in. In particular, don't count
-on the shell's search path for executables (:envvar:`PATH`) or the Python module
-search path (:envvar:`PYTHONPATH`) to be set to anything interesting.
-
-If you need to load modules from a directory which is not on Python's default
-module search path, you can change the path in your script, before importing
-other modules. For example::
-
- import sys
- sys.path.insert(0, "/usr/home/joe/lib/python")
- sys.path.insert(0, "/usr/local/lib/python")
-
-(This way, the directory inserted last will be searched first!)
-
-Instructions for non-Unix systems will vary; check your HTTP server's
-documentation (it will usually have a section on CGI scripts).
-
-
-Testing your CGI script
------------------------
-
-Unfortunately, a CGI script will generally not run when you try it from the
-command line, and a script that works perfectly from the command line may fail
-mysteriously when run from the server. There's one reason why you should still
-test your script from the command line: if it contains a syntax error, the
-Python interpreter won't execute it at all, and the HTTP server will most likely
-send a cryptic error to the client.
-
-Assuming your script has no syntax errors, yet it does not work, you have no
-choice but to read the next section.
-
-
-Debugging CGI scripts
----------------------
-
-.. index:: pair: CGI; debugging
-
-First of all, check for trivial installation errors --- reading the section
-above on installing your CGI script carefully can save you a lot of time. If
-you wonder whether you have understood the installation procedure correctly, try
-installing a copy of this module file (:file:`cgi.py`) as a CGI script. When
-invoked as a script, the file will dump its environment and the contents of the
-form in HTML format. Give it the right mode etc., and send it a request. If it's
-installed in the standard :file:`cgi-bin` directory, it should be possible to
-send it a request by entering a URL into your browser of the form:
-
-.. code-block:: none
-
- http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home
-
-If this gives an error of type 404, the server cannot find the script -- perhaps
-you need to install it in a different directory. If it gives another error,
-there's an installation problem that you should fix before trying to go any
-further. If you get a nicely formatted listing of the environment and form
-content (in this example, the fields should be listed as "addr" with value "At
-Home" and "name" with value "Joe Blow"), the :file:`cgi.py` script has been
-installed correctly. If you follow the same procedure for your own script, you
-should now be able to debug it.
-
-The next step could be to call the :mod:`cgi` module's :func:`test` function
-from your script: replace its main code with the single statement ::
-
- cgi.test()
-
-This should produce the same results as those gotten from installing the
-:file:`cgi.py` file itself.
-
-When an ordinary Python script raises an unhandled exception (for whatever
-reason: of a typo in a module name, a file that can't be opened, etc.), the
-Python interpreter prints a nice traceback and exits. While the Python
-interpreter will still do this when your CGI script raises an exception, most
-likely the traceback will end up in one of the HTTP server's log files, or be
-discarded altogether.
-
-Fortunately, once you have managed to get your script to execute *some* code,
-you can easily send tracebacks to the web browser using the :mod:`cgitb` module.
-If you haven't done so already, just add the lines::
-
- import cgitb
- cgitb.enable()
-
-to the top of your script. Then try running it again; when a problem occurs,
-you should see a detailed report that will likely make apparent the cause of the
-crash.
-
-If you suspect that there may be a problem in importing the :mod:`cgitb` module,
-you can use an even more robust approach (which only uses built-in modules)::
-
- import sys
- sys.stderr = sys.stdout
- print("Content-Type: text/plain")
- print()
- ...your code here...
-
-This relies on the Python interpreter to print the traceback. The content type
-of the output is set to plain text, which disables all HTML processing. If your
-script works, the raw HTML will be displayed by your client. If it raises an
-exception, most likely after the first two lines have been printed, a traceback
-will be displayed. Because no HTML interpretation is going on, the traceback
-will be readable.
-
-
-Common problems and solutions
------------------------------
-
-* Most HTTP servers buffer the output from CGI scripts until the script is
- completed. This means that it is not possible to display a progress report on
- the client's display while the script is running.
-
-* Check the installation instructions above.
-
-* Check the HTTP server's log files. (``tail -f logfile`` in a separate window
- may be useful!)
-
-* Always check a script for syntax errors first, by doing something like
- ``python script.py``.
-
-* If your script does not have any syntax errors, try adding ``import cgitb;
- cgitb.enable()`` to the top of the script.
-
-* When invoking external programs, make sure they can be found. Usually, this
- means using absolute path names --- :envvar:`PATH` is usually not set to a very
- useful value in a CGI script.
-
-* When reading or writing external files, make sure they can be read or written
- by the userid under which your CGI script will be running: this is typically the
- userid under which the web server is running, or some explicitly specified
- userid for a web server's ``suexec`` feature.
-
-* Don't try to give a CGI script a set-uid mode. This doesn't work on most
- systems, and is a security liability as well.
-
-.. rubric:: Footnotes
-
-.. [#] Note that some recent versions of the HTML specification do state what
- order the field values should be supplied in, but knowing whether a request
- was received from a conforming browser, or even from a browser at all, is
- tedious and error-prone.
diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst
deleted file mode 100644
index 7f00bcd..0000000
--- a/Doc/library/cgitb.rst
+++ /dev/null
@@ -1,89 +0,0 @@
-:mod:`cgitb` --- Traceback manager for CGI scripts
-==================================================
-
-.. module:: cgitb
- :synopsis: Configurable traceback handler for CGI scripts.
- :deprecated:
-
-.. moduleauthor:: Ka-Ping Yee <ping@lfw.org>
-.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
-
-**Source code:** :source:`Lib/cgitb.py`
-
-.. index::
- single: CGI; exceptions
- single: CGI; tracebacks
- single: exceptions; in CGI scripts
- single: tracebacks; in CGI scripts
-
-.. deprecated-removed:: 3.11 3.13
- The :mod:`cgitb` module is deprecated
- (see :pep:`PEP 594 <594#cgitb>` for details).
-
---------------
-
-The :mod:`cgitb` module provides a special exception handler for Python scripts.
-(Its name is a bit misleading. It was originally designed to display extensive
-traceback information in HTML for CGI scripts. It was later generalized to also
-display this information in plain text.) After this module is activated, if an
-uncaught exception occurs, a detailed, formatted report will be displayed. The
-report includes a traceback showing excerpts of the source code for each level,
-as well as the values of the arguments and local variables to currently running
-functions, to help you debug the problem. Optionally, you can save this
-information to a file instead of sending it to the browser.
-
-To enable this feature, simply add this to the top of your CGI script::
-
- import cgitb
- cgitb.enable()
-
-The options to the :func:`enable` function control whether the report is
-displayed in the browser and whether the report is logged to a file for later
-analysis.
-
-
-.. function:: enable(display=1, logdir=None, context=5, format="html")
-
- .. index:: single: excepthook() (in module sys)
-
- This function causes the :mod:`cgitb` module to take over the interpreter's
- default handling for exceptions by setting the value of :attr:`sys.excepthook`.
-
- The optional argument *display* defaults to ``1`` and can be set to ``0`` to
- suppress sending the traceback to the browser. If the argument *logdir* is
- present, the traceback reports are written to files. The value of *logdir*
- should be a directory where these files will be placed. The optional argument
- *context* is the number of lines of context to display around the current line
- of source code in the traceback; this defaults to ``5``. If the optional
- argument *format* is ``"html"``, the output is formatted as HTML. Any other
- value forces plain text output. The default value is ``"html"``.
-
-
-.. function:: text(info, context=5)
-
- This function handles the exception described by *info* (a 3-tuple containing
- the result of :func:`sys.exc_info`), formatting its traceback as text and
- returning the result as a string. The optional argument *context* is the
- number of lines of context to display around the current line of source code
- in the traceback; this defaults to ``5``.
-
-
-.. function:: html(info, context=5)
-
- This function handles the exception described by *info* (a 3-tuple containing
- the result of :func:`sys.exc_info`), formatting its traceback as HTML and
- returning the result as a string. The optional argument *context* is the
- number of lines of context to display around the current line of source code
- in the traceback; this defaults to ``5``.
-
-
-.. function:: handler(info=None)
-
- This function handles an exception using the default settings (that is, show a
- report in the browser, but don't log to a file). This can be used when you've
- caught an exception and want to report it using :mod:`cgitb`. The optional
- *info* argument should be a 3-tuple containing an exception type, exception
- value, and traceback object, exactly like the tuple returned by
- :func:`sys.exc_info`. If the *info* argument is not supplied, the current
- exception is obtained from :func:`sys.exc_info`.
-
diff --git a/Doc/library/security_warnings.rst b/Doc/library/security_warnings.rst
index 284f365..a573c98 100644
--- a/Doc/library/security_warnings.rst
+++ b/Doc/library/security_warnings.rst
@@ -9,7 +9,6 @@ The following modules have specific security considerations:
* :mod:`base64`: :ref:`base64 security considerations <base64-security>` in
:rfc:`4648`
-* :mod:`cgi`: :ref:`CGI security considerations <cgi-security>`
* :mod:`hashlib`: :ref:`all constructors take a "usedforsecurity" keyword-only
argument disabling known insecure and blocked algorithms
<hashlib-usedforsecurity>`
diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst
index e4a473f..a96d042 100644
--- a/Doc/library/superseded.rst
+++ b/Doc/library/superseded.rst
@@ -12,8 +12,6 @@ backwards compatibility. They have been superseded by other modules.
aifc.rst
audioop.rst
- cgi.rst
- cgitb.rst
chunk.rst
crypt.rst
imghdr.rst
diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst
index 0eefefd..76094d4 100644
--- a/Doc/whatsnew/2.0.rst
+++ b/Doc/whatsnew/2.0.rst
@@ -1030,7 +1030,7 @@ Module changes
Lots of improvements and bugfixes were made to Python's extensive standard
library; some of the affected modules include :mod:`readline`,
-:mod:`ConfigParser`, :mod:`cgi`, :mod:`calendar`, :mod:`posix`, :mod:`readline`,
+:mod:`ConfigParser`, :mod:`!cgi`, :mod:`calendar`, :mod:`posix`, :mod:`readline`,
:mod:`xmllib`, :mod:`aifc`, :mod:`chunk, wave`, :mod:`random`, :mod:`shelve`,
and :mod:`nntplib`. Consult the CVS logs for the exact patch-by-patch details.
diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst
index 7236e1c..0a8bad4 100644
--- a/Doc/whatsnew/2.6.rst
+++ b/Doc/whatsnew/2.6.rst
@@ -1805,15 +1805,15 @@ changes, or look through the Subversion logs for all the details.
available, instead of restricting itself to protocol 1.
(Contributed by W. Barnes.)
-* The :mod:`cgi` module will now read variables from the query string
+* The :mod:`!cgi` module will now read variables from the query string
of an HTTP POST request. This makes it possible to use form actions
with URLs that include query strings such as
"/cgi-bin/add.py?category=1". (Contributed by Alexandre Fiori and
Nubis; :issue:`1817`.)
The :func:`parse_qs` and :func:`parse_qsl` functions have been
- relocated from the :mod:`cgi` module to the :mod:`urlparse` module.
- The versions still available in the :mod:`cgi` module will
+ relocated from the :mod:`!cgi` module to the :mod:`urlparse` module.
+ The versions still available in the :mod:`!cgi` module will
trigger :exc:`PendingDeprecationWarning` messages in 2.6
(:issue:`600362`).
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 661eeae..ab030db 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -1508,7 +1508,7 @@ query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with ``&`` as the default. This change also affects
-:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+:func:`!cgi.parse` and :func:`!cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 8aadc2a..d024b85 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -1735,9 +1735,9 @@ Modules
+---------------------+---------------------+---------------------+---------------------+---------------------+
| :mod:`audioop` | :mod:`crypt` | :mod:`nis` | :mod:`sndhdr` | :mod:`uu` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
- | :mod:`cgi` | :mod:`imghdr` | :mod:`nntplib` | :mod:`spwd` | :mod:`xdrlib` |
+ | :mod:`!cgi` | :mod:`imghdr` | :mod:`nntplib` | :mod:`spwd` | :mod:`xdrlib` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
- | :mod:`cgitb` | :mod:`mailcap` | :mod:`ossaudiodev` | :mod:`sunau` | |
+ | :mod:`!cgitb` | :mod:`mailcap` | :mod:`ossaudiodev` | :mod:`sunau` | |
+---------------------+---------------------+---------------------+---------------------+---------------------+
(Contributed by Brett Cannon in :issue:`47061` and Victor Stinner in
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 5e07a4c..417da22 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -805,8 +805,8 @@ Modules (see :pep:`594`):
* :mod:`aifc`
* :mod:`audioop`
-* :mod:`cgi`
-* :mod:`cgitb`
+* :mod:`!cgi`
+* :mod:`!cgitb`
* :mod:`chunk`
* :mod:`crypt`
* :mod:`imghdr`
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 309f26e..4bd9a73 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -118,6 +118,36 @@ Removed
* Remove support for using :class:`pathlib.Path` objects as context managers.
This functionality was deprecated and made a no-op in Python 3.9.
+* :pep:`594`: Remove the :mod:`!cgi`` and :mod:`!cgitb` modules,
+ deprecated in Python 3.11.
+
+ * ``cgi.FieldStorage`` can typically be replaced with
+ :func:`urllib.parse.parse_qsl` for ``GET`` and ``HEAD`` requests, and the
+ :mod:`email.message` module or `multipart
+ <https://pypi.org/project/multipart/>`__ PyPI project for ``POST`` and
+ ``PUT``.
+
+ * ``cgi.parse()`` can be replaced by calling :func:`urllib.parse.parse_qs`
+ directly on the desired query string, except for ``multipart/form-data``
+ input, which can be handled as described for ``cgi.parse_multipart()``.
+
+ * ``cgi.parse_multipart()`` can be replaced with the functionality in the
+ :mod:`email` package (e.g. :class:`email.message.EmailMessage` and
+ :class:`email.message.Message`) which implements the same MIME RFCs, or
+ with the `multipart <https://pypi.org/project/multipart/>`__ PyPI project.
+
+ * ``cgi.parse_header()`` can be replaced with the functionality in the
+ :mod:`email` package, which implements the same MIME RFCs. For example,
+ with :class:`email.message.EmailMessage`::
+
+ from email.message import EmailMessage
+ msg = EmailMessage()
+ msg['content-type'] = 'application/json; charset="utf8"'
+ main, params = msg.get_content_type(), msg['content-type'].params
+
+ (Contributed by Victor Stinner in :gh:`104773`.)
+
+
Porting to Python 3.13
======================
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index 45bb918..d4ed8ab 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -2371,11 +2371,11 @@ Changes in the Python API
3.3.3.
* The :attr:`~cgi.FieldStorage.file` attribute is now automatically closed when
- the creating :class:`cgi.FieldStorage` instance is garbage collected. If you
- were pulling the file object out separately from the :class:`cgi.FieldStorage`
+ the creating :class:`!cgi.FieldStorage` instance is garbage collected. If you
+ were pulling the file object out separately from the :class:`!cgi.FieldStorage`
instance and not keeping the instance alive, then you should either store the
- entire :class:`cgi.FieldStorage` instance or read the contents of the file
- before the :class:`cgi.FieldStorage` instance is garbage collected.
+ entire :class:`!cgi.FieldStorage` instance or read the contents of the file
+ before the :class:`!cgi.FieldStorage` instance is garbage collected.
* Calling ``read`` or ``write`` on a closed SSL socket now raises an
informative :exc:`ValueError` rather than the previous more mysterious
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index 1cd33df..3d8f932 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -2185,7 +2185,7 @@ Changes in the Python API
* The following modules have had missing APIs added to their :attr:`__all__`
attributes to match the documented APIs:
- :mod:`calendar`, :mod:`cgi`, :mod:`csv`,
+ :mod:`calendar`, :mod:`!cgi`, :mod:`csv`,
:mod:`~xml.etree.ElementTree`, :mod:`enum`,
:mod:`fileinput`, :mod:`ftplib`, :mod:`logging`, :mod:`mailbox`,
:mod:`mimetypes`, :mod:`optparse`, :mod:`plistlib`, :mod:`smtpd`,
@@ -2455,7 +2455,7 @@ query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with ``&`` as the default. This change also affects
-:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+:func:`!cgi.parse` and :func:`!cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 28f2283..41d7e08 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -2567,7 +2567,7 @@ query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with ``&`` as the default. This change also affects
-:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+:func:`!cgi.parse` and :func:`!cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 85e088b..1676281 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -1774,7 +1774,7 @@ The following features and APIs have been removed from Python 3.8:
to help eliminate confusion as to what Python interpreter the ``pyvenv``
script is tied to. (Contributed by Brett Cannon in :issue:`25427`.)
-* ``parse_qs``, ``parse_qsl``, and ``escape`` are removed from the :mod:`cgi`
+* ``parse_qs``, ``parse_qsl``, and ``escape`` are removed from the :mod:`!cgi`
module. They are deprecated in Python 3.2 or older. They should be imported
from the ``urllib.parse`` and ``html`` modules instead.
@@ -2251,7 +2251,7 @@ query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with ``&`` as the default. This change also affects
-:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+:func:`!cgi.parse` and :func:`!cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index 532cabd..54f5662 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -1559,7 +1559,7 @@ query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with ``&`` as the default. This change also affects
-:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
+:func:`!cgi.parse` and :func:`!cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
(Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in :issue:`42967`.)