PEP 222 – Web 库增强
- 作者:
- A.M. Kuchling <amk at amk.ca>
- 状态:
- 推迟
- 类型:
- 标准跟踪
- 创建日期:
- 2000年8月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。
现有模块的主要变更
本节详细列出了现有模块(无论是实现还是接口)的主要更改。因此,本节中的更改带来更大程度的风险,可能引入错误或向后不兼容性。
cgi.py 模块将被弃用。(XXX 新模块或包名尚未选定:'web'?'cgilib'?)
现有模块的次要变更
本节列出了对现有模块的次要更改的详细信息。这些更改的实现应相对较小,并且引入与以前版本不兼容的风险较小。
被拒绝的变更
本节中列出的变更曾被提议用于 Python 2.1,但因不适用而被拒绝。对于每项被拒绝的变更,都给出了理由,说明为何该变更被认为不合适。
- HTML生成模块不属于本PEP的一部分。存在多个此类模块,范围从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