mirror of
https://github.com/python/cpython.git
synced 2025-10-15 03:10:29 +00:00
Remove old backwards-compatibility classes from the cgi module.
This commit is contained in:
parent
fb16cf1d9b
commit
49d1b4f919
3 changed files with 11 additions and 190 deletions
|
@ -63,9 +63,7 @@ prints a simple piece of HTML::
|
||||||
Using the cgi module
|
Using the cgi module
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Begin by writing ``import cgi``. Do not use ``from cgi import *`` --- the
|
Begin by writing ``import cgi``.
|
||||||
module defines all sorts of names for its own use or for backward compatibility
|
|
||||||
that you don't want in your namespace.
|
|
||||||
|
|
||||||
When you write a new script, consider adding the line::
|
When you write a new script, consider adding the line::
|
||||||
|
|
||||||
|
@ -83,12 +81,11 @@ 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
|
tracking down bugs. You can always remove the ``cgitb`` line later when you
|
||||||
have tested your script and are confident that it works correctly.
|
have tested your script and are confident that it works correctly.
|
||||||
|
|
||||||
To get at submitted form data, it's best to use the :class:`FieldStorage` class.
|
To get at submitted form data, use the :class:`FieldStorage` class. Instantiate
|
||||||
The other classes defined in this module are provided mostly for backward
|
it exactly once, without arguments. This reads the form contents from standard
|
||||||
compatibility. Instantiate it exactly once, without arguments. This reads the
|
input or the environment (depending on the value of various environment
|
||||||
form contents from standard input or the environment (depending on the value of
|
variables set according to the CGI standard). Since it may consume standard
|
||||||
various environment variables set according to the CGI standard). Since it may
|
input, it should be instantiated only once.
|
||||||
consume standard input, it should be instantiated only once.
|
|
||||||
|
|
||||||
The :class:`FieldStorage` instance can be indexed like a Python dictionary, and
|
The :class:`FieldStorage` instance can be indexed like a Python dictionary, and
|
||||||
also supports the standard dictionary methods :meth:`__contains__` and
|
also supports the standard dictionary methods :meth:`__contains__` and
|
||||||
|
@ -245,26 +242,6 @@ Using these methods you can write nice compact code::
|
||||||
do_something(item)
|
do_something(item)
|
||||||
|
|
||||||
|
|
||||||
Old classes
|
|
||||||
-----------
|
|
||||||
|
|
||||||
These classes, present in earlier versions of the :mod:`cgi` module, are still
|
|
||||||
supported for backward compatibility. New applications should use the
|
|
||||||
:class:`FieldStorage` class.
|
|
||||||
|
|
||||||
:class:`SvFormContentDict` stores single value form content as dictionary; it
|
|
||||||
assumes each field name occurs in the form only once.
|
|
||||||
|
|
||||||
:class:`FormContentDict` stores multiple value form content as a dictionary (the
|
|
||||||
form items are lists of values). Useful if your form contains multiple fields
|
|
||||||
with the same name.
|
|
||||||
|
|
||||||
Other classes (:class:`FormContent`, :class:`InterpFormContentDict`) are present
|
|
||||||
for backwards compatibility with really old applications only. If you still use
|
|
||||||
these and would be inconvenienced when they disappeared from a next version of
|
|
||||||
this module, drop me a note.
|
|
||||||
|
|
||||||
|
|
||||||
.. _functions-in-cgi-module:
|
.. _functions-in-cgi-module:
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
|
|
124
Lib/cgi.py
124
Lib/cgi.py
|
@ -15,9 +15,6 @@ This module defines a number of utilities for use by CGI scripts
|
||||||
written in Python.
|
written in Python.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# XXX Perhaps there should be a slimmed version that doesn't contain
|
|
||||||
# all those backwards compatible and debugging classes and functions?
|
|
||||||
|
|
||||||
# History
|
# History
|
||||||
# -------
|
# -------
|
||||||
#
|
#
|
||||||
|
@ -43,8 +40,7 @@ import rfc822
|
||||||
import collections
|
import collections
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict",
|
__all__ = ["MiniFieldStorage", "FieldStorage",
|
||||||
"SvFormContentDict", "InterpFormContentDict", "FormContent",
|
|
||||||
"parse", "parse_qs", "parse_qsl", "parse_multipart",
|
"parse", "parse_qs", "parse_qsl", "parse_multipart",
|
||||||
"parse_header", "print_exception", "print_environ",
|
"parse_header", "print_exception", "print_environ",
|
||||||
"print_form", "print_directory", "print_arguments",
|
"print_form", "print_directory", "print_arguments",
|
||||||
|
@ -777,124 +773,6 @@ class FieldStorage:
|
||||||
return tempfile.TemporaryFile("w+", encoding="utf-8", newline="\n")
|
return tempfile.TemporaryFile("w+", encoding="utf-8", newline="\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Backwards Compatibility Classes
|
|
||||||
# ===============================
|
|
||||||
|
|
||||||
class FormContentDict(collections.Mapping):
|
|
||||||
"""Form content as dictionary with a list of values per field.
|
|
||||||
|
|
||||||
form = FormContentDict()
|
|
||||||
|
|
||||||
form[key] -> [value, value, ...]
|
|
||||||
key in form -> Boolean
|
|
||||||
form.keys() -> [key, key, ...]
|
|
||||||
form.values() -> [[val, val, ...], [val, val, ...], ...]
|
|
||||||
form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...]
|
|
||||||
form.dict == {key: [val, val, ...], ...}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
|
|
||||||
self.dict = self.data = parse(environ=environ,
|
|
||||||
keep_blank_values=keep_blank_values,
|
|
||||||
strict_parsing=strict_parsing)
|
|
||||||
self.query_string = environ['QUERY_STRING']
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self.dict)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return iter(self.dict)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return self.dict[key]
|
|
||||||
|
|
||||||
|
|
||||||
class SvFormContentDict(FormContentDict):
|
|
||||||
"""Form content as dictionary expecting a single value per field.
|
|
||||||
|
|
||||||
If you only expect a single value for each field, then form[key]
|
|
||||||
will return that single value. It will raise an IndexError if
|
|
||||||
that expectation is not true. If you expect a field to have
|
|
||||||
possible multiple values, than you can use form.getlist(key) to
|
|
||||||
get all of the values. values() and items() are a compromise:
|
|
||||||
they return single strings where there is a single value, and
|
|
||||||
lists of strings otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
def __getitem__(self, key):
|
|
||||||
if len(self.dict[key]) > 1:
|
|
||||||
raise IndexError('expecting a single value')
|
|
||||||
return self.dict[key][0]
|
|
||||||
def getlist(self, key):
|
|
||||||
return self.dict[key]
|
|
||||||
def values(self):
|
|
||||||
result = []
|
|
||||||
for value in self.dict.values():
|
|
||||||
if len(value) == 1:
|
|
||||||
result.append(value[0])
|
|
||||||
else: result.append(value)
|
|
||||||
return result
|
|
||||||
def items(self):
|
|
||||||
result = []
|
|
||||||
for key, value in self.dict.items():
|
|
||||||
if len(value) == 1:
|
|
||||||
result.append((key, value[0]))
|
|
||||||
else: result.append((key, value))
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class InterpFormContentDict(SvFormContentDict):
|
|
||||||
"""This class is present for backwards compatibility only."""
|
|
||||||
def __getitem__(self, key):
|
|
||||||
v = SvFormContentDict.__getitem__(self, key)
|
|
||||||
if v[0] in '0123456789+-.':
|
|
||||||
try: return int(v)
|
|
||||||
except ValueError:
|
|
||||||
try: return float(v)
|
|
||||||
except ValueError: pass
|
|
||||||
return v.strip()
|
|
||||||
def values(self):
|
|
||||||
result = []
|
|
||||||
for key in self.keys():
|
|
||||||
try:
|
|
||||||
result.append(self[key])
|
|
||||||
except IndexError:
|
|
||||||
result.append(self.dict[key])
|
|
||||||
return result
|
|
||||||
def items(self):
|
|
||||||
result = []
|
|
||||||
for key in self.keys():
|
|
||||||
try:
|
|
||||||
result.append((key, self[key]))
|
|
||||||
except IndexError:
|
|
||||||
result.append((key, self.dict[key]))
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class FormContent(FormContentDict):
|
|
||||||
"""This class is present for backwards compatibility only."""
|
|
||||||
def values(self, key):
|
|
||||||
if key in self.dict :return self.dict[key]
|
|
||||||
else: return None
|
|
||||||
def indexed_value(self, key, location):
|
|
||||||
if key in self.dict:
|
|
||||||
if len(self.dict[key]) > location:
|
|
||||||
return self.dict[key][location]
|
|
||||||
else: return None
|
|
||||||
else: return None
|
|
||||||
def value(self, key):
|
|
||||||
if key in self.dict: return self.dict[key][0]
|
|
||||||
else: return None
|
|
||||||
def length(self, key):
|
|
||||||
return len(self.dict[key])
|
|
||||||
def stripped(self, key):
|
|
||||||
if key in self.dict: return self.dict[key][0].strip()
|
|
||||||
else: return None
|
|
||||||
def pars(self):
|
|
||||||
return self.dict
|
|
||||||
|
|
||||||
|
|
||||||
# Test/debug code
|
# Test/debug code
|
||||||
# ===============
|
# ===============
|
||||||
|
|
||||||
|
|
|
@ -143,56 +143,22 @@ class CgiTests(unittest.TestCase):
|
||||||
self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
|
self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
|
||||||
|
|
||||||
env = {'QUERY_STRING': orig}
|
env = {'QUERY_STRING': orig}
|
||||||
fcd = cgi.FormContentDict(env)
|
|
||||||
sd = cgi.SvFormContentDict(env)
|
|
||||||
fs = cgi.FieldStorage(environ=env)
|
fs = cgi.FieldStorage(environ=env)
|
||||||
if type(expect) == type({}):
|
if type(expect) == type({}):
|
||||||
# test dict interface
|
# test dict interface
|
||||||
self.assertEqual(len(expect), len(fcd))
|
self.assertEqual(len(expect), len(fs))
|
||||||
self.assertEqual(norm(expect.keys()), norm(fcd.keys()))
|
self.assertEqual(norm(expect.keys()), norm(fs.keys()))
|
||||||
self.assertEqual(norm(expect.values()), norm(fcd.values()))
|
##self.assertEqual(norm(expect.values()), norm(fs.values()))
|
||||||
self.assertEqual(norm(expect.items()), norm(fcd.items()))
|
##self.assertEqual(norm(expect.items()), norm(fs.items()))
|
||||||
self.assertEqual(fcd.get("nonexistent field", "default"), "default")
|
|
||||||
self.assertEqual(len(sd), len(fs))
|
|
||||||
self.assertEqual(norm(sd.keys()), norm(fs.keys()))
|
|
||||||
self.assertEqual(fs.getvalue("nonexistent field", "default"), "default")
|
self.assertEqual(fs.getvalue("nonexistent field", "default"), "default")
|
||||||
# test individual fields
|
# test individual fields
|
||||||
for key in expect.keys():
|
for key in expect.keys():
|
||||||
expect_val = expect[key]
|
expect_val = expect[key]
|
||||||
self.assert_(key in fcd)
|
|
||||||
self.assertEqual(norm(fcd[key]), norm(expect[key]))
|
|
||||||
self.assertEqual(fcd.get(key, "default"), fcd[key])
|
|
||||||
self.assert_(key in fs)
|
self.assert_(key in fs)
|
||||||
if len(expect_val) > 1:
|
if len(expect_val) > 1:
|
||||||
single_value = 0
|
|
||||||
else:
|
|
||||||
single_value = 1
|
|
||||||
try:
|
|
||||||
val = sd[key]
|
|
||||||
except IndexError:
|
|
||||||
self.failIf(single_value)
|
|
||||||
self.assertEqual(fs.getvalue(key), expect_val)
|
self.assertEqual(fs.getvalue(key), expect_val)
|
||||||
else:
|
else:
|
||||||
self.assert_(single_value)
|
|
||||||
self.assertEqual(val, expect_val[0])
|
|
||||||
self.assertEqual(fs.getvalue(key), expect_val[0])
|
self.assertEqual(fs.getvalue(key), expect_val[0])
|
||||||
self.assertEqual(norm(sd.getlist(key)), norm(expect_val))
|
|
||||||
if single_value:
|
|
||||||
self.assertEqual(norm(sd.values()),
|
|
||||||
first_elts(norm(expect.values())))
|
|
||||||
self.assertEqual(norm(sd.items()),
|
|
||||||
first_second_elts(norm(expect.items())))
|
|
||||||
|
|
||||||
def test_weird_formcontentdict(self):
|
|
||||||
# Test the weird FormContentDict classes
|
|
||||||
env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
|
|
||||||
expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
|
|
||||||
d = cgi.InterpFormContentDict(env)
|
|
||||||
for k, v in expect.items():
|
|
||||||
self.assertEqual(d[k], v)
|
|
||||||
for k, v in d.items():
|
|
||||||
self.assertEqual(expect[k], v)
|
|
||||||
self.assertEqual(norm(expect.values()), norm(d.values()))
|
|
||||||
|
|
||||||
def test_log(self):
|
def test_log(self):
|
||||||
cgi.log("Testing")
|
cgi.log("Testing")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue