PEP 222 – Web 库增强
- 作者:
- A.M. Kuchling <amk at amk.ca>
- 状态:
- 延期
- 类型:
- 标准轨迹
- 创建:
- 2000-08-18
- Python 版本:
- 2.1
- 历史记录:
- 2000-12-22
摘要
本 PEP 提出了一套针对 Python 标准库中 CGI 开发设施的增强方案。增强可能包括新功能、用于 cookie 支持等任务的新模块,或删除过时的代码。
最初的目的是对 Python 2.1 进行改进。然而,Python 社区似乎对此兴趣不大,而且时间也不够,因此本 PEP 被推迟到未来某个 Python 版本发布。
待解决问题
本节列出了已被建议但尚未做出最终决定的变更。在本 PEP 的最终版本中,本节应为空,因为所有变更都应归类为已接受或已拒绝。
cgi.py: 我们不应该被告知去创建自己的子类,只是为了能够处理文件上传。实际上,我还没有找到时间把它做好,所以我最终把 cgi.py 的临时文件读入,充其量是另一个文件。我们的一些旧代码实际上是把它读入第二个临时文件,然后再读入最终目的地!即使我们做了,这也意味着要创建另一个对象,并调用它的 __init__
函数以及相关的开销。
cgi.py: 目前,没有 =
的查询数据被忽略。即使设置了 keep_blank_values
,像 ...?value=&...
这样的查询将返回空值,但像 ...?value&...
这样的查询将完全丢失。如果这些数据能够通过 FieldStorage
接口获得,无论是作为具有 None
值的条目,还是作为单独的列表,都会很棒。
实用函数: 从 2 元组列表构建查询字符串
与字典相关的实用类: NoKeyErrors
(返回空字符串,而不是 KeyError
),PartialStringSubstitution
(返回原始键字符串,而不是 KeyError
)
新模块
本节列出了应添加到 Python 标准库中的完整新包或模块的详细信息。
- fcgi.py: 添加对 FastCGI 协议支持的新模块。Robin Dunn 的代码需要移植到 Windows 平台。
现有模块的主要变更
本节列出了对现有模块的重大变更,无论是实现上的变更还是接口上的变更。因此,本节中的变更具有更大的风险,无论是引入 bug 还是向后不兼容。
cgi.py 模块将被弃用。(XXX 尚未选定新的模块或包名: ‘web’?‘cgilib’?)
现有模块的次要变更
本节列出了对现有模块的次要变更。这些变更的实现应该相对较小,并且几乎没有引入与先前版本的兼容性问题的风险。
被拒绝的变更
本节中列出的变更是在 Python 2.1 中提出的,但由于不适合而被拒绝。对于每个被拒绝的变更,都给出了一个理由,描述了为什么该变更被认为不合适。
- 本 PEP 中不包含 HTML 生成模块。几个这样的模块已经存在,从 HTMLgen 的纯编程接口到 ASP 风格的简单模板,再到 DTML 的复杂模板。没有任何迹象表明哪个模板模块应该被纳入标准库,这可能意味着不应该选择任何模块。
- cgi.py: 允许组合查询数据和 POST 数据。这似乎根本不是标准做法,因此是一种可疑的做法。
建议的接口
XXX 待解决问题: 命名约定(驼峰式大小写或下划线分隔?);需要查看 cgi.parse*()
函数,看看它们是否可以简化。
解析函数: 从 cgi.py 中保留大部分 parse*
函数
# The Response class borrows most of its methods from Zope's
# HTTPResponse class.
class Response:
"""
Attributes:
status: HTTP status code to return
headers: dictionary of response headers
body: string containing the body of the HTTP response
"""
def __init__(self, status=200, headers={}, body=""):
pass
def setStatus(self, status, reason=None):
"Set the numeric HTTP response code"
pass
def setHeader(self, name, value):
"Set an HTTP header"
pass
def setBody(self, body):
"Set the body of the response"
pass
def setCookie(self, name, value,
path = '/',
comment = None,
domain = None,
max-age = None,
expires = None,
secure = 0
):
"Set a cookie"
pass
def expireCookie(self, name):
"Remove a cookie from the user"
pass
def redirect(self, url):
"Redirect the browser to another URL"
pass
def __str__(self):
"Convert entire response to a string"
pass
def dump(self):
"Return a string representation useful for debugging"
pass
# XXX methods for specific classes of error:serverError,
# badRequest, etc.?
class Request:
"""
Attributes:
XXX should these be dictionaries, or dictionary-like objects?
.headers : dictionary containing HTTP headers
.cookies : dictionary of cookies
.fields : data from the form
.env : environment dictionary
"""
def __init__(self, environ=os.environ, stdin=sys.stdin,
keep_blank_values=1, strict_parsing=0):
"""Initialize the request object, using the provided environment
and standard input."""
pass
# Should people just use the dictionaries directly?
def getHeader(self, name, default=None):
pass
def getCookie(self, name, default=None):
pass
def getField(self, name, default=None):
"Return field's value as a string (even if it's an uploaded file)"
pass
def getUploadedFile(self, name):
"""Returns a file object that can be read to obtain the contents
of an uploaded file. XXX should this report an error if the
field isn't actually an uploaded file? Or should it wrap
a StringIO around simple fields for consistency?
"""
def getURL(self, n=0, query_string=0):
"""Return the URL of the current request, chopping off 'n' path
components from the right. Eg. if the URL is
"http://foo.com/bar/baz/quux", n=2 would return
"http://foo.com/bar". Does not include the query string (if
any)
"""
def getBaseURL(self, n=0):
"""Return the base URL of the current request, adding 'n' path
components to the end to recreate more of the whole URL.
Eg. if the request URL is
"http://foo.com/q/bar/baz/qux", n=0 would return
"http://foo.com/", and n=2 "http://foo.com/q/bar".
Returned URL does not include the query string, if any.
"""
def dump(self):
"String representation suitable for debugging output"
pass
# Possibilities? I don't know if these are worth doing in the
# basic objects.
def getBrowser(self):
"Returns Mozilla/IE/Lynx/Opera/whatever"
def isSecure(self):
"Return true if this is an SSLified request"
# Module-level function
def wrapper(func, logfile=sys.stderr):
"""
Calls the function 'func', passing it the arguments
(request, response, logfile). Exceptions are trapped and
sent to the file 'logfile'.
"""
# This wrapper will detect if it's being called from the command-line,
# and if so, it will run in a debugging mode; name=value pairs
# can be entered on standard input to set field values.
# (XXX how to do file uploads in this syntax?)
版权
本文件已置于公有领域。
来源: https://github.com/python/peps/blob/main/peps/pep-0222.rst
最后修改: 2023-09-09 17:39:29 GMT