So, I am in the process of upgrading Web2py from version 1.67 to
1.89.5. Ouch. One of the things I encountered is that request.vars
will now include a list of duplicate values, rather than a single
value (not a list) as it previously did. For example, our url includes
a _next variable. So does the form when posting, including the Cancel
action. So now I end up with a list of 2 duplicate values when I test
set redirurl = request.vars.get('_next'). Rather than change that
umpteen times in our app, I am proposing a change to the function
'parse_get_post_vars' in main.py.
def parse_get_post_vars(request, environ):
# always parse variables in URL for GET, POST, PUT, DELETE, etc.
in get_vars
dget = cgi.parse_qsl(request.env.query_string,
keep_blank_values=1)
for (key, value) in dget:
if key in request.get_vars:
if isinstance(request.get_vars[key], list):
request.get_vars[key] += [value]
else:
request.get_vars[key] = [request.get_vars[key]] +
[value]
else:
request.get_vars[key] = value
request.vars[key] = request.get_vars[key]
# parse POST variables on POST, PUT, BOTH only in post_vars
request.body = copystream_progress(request) ### stores request
body
if (request.body and request.env.request_method in ('POST', 'PUT',
'BOTH')):
dpost =
cgi.FieldStorage(fp=request.body,environ=environ,keep_blank_values=1)
# The same detection used by FieldStorage to detect multipart
POSTs
is_multipart = dpost.type[:10] == 'multipart/'
request.body.seek(0)
isle25 = sys.version_info[1] <= 5
def listify(a):
return (not isinstance(a,list) and [a]) or a
try:
keys = sorted(dpost)
except TypeError:
keys = []
for key in keys:
dpk = dpost[key]
# if en element is not a file replace it with its value
else leave it alone
if isinstance(dpk, list):
if not dpk[0].filename:
value = [x.value for x in dpk]
else:
value = [x for x in dpk]
elif not dpk.filename:
value = dpk.value
else:
value = dpk
pvalue = listify(value)
if key in request.vars:
gvalue = listify(request.vars[key])
if isle25:
value = pvalue + gvalue
elif is_multipart:
pvalue = pvalue[len(gvalue):]
else:
pvalue = pvalue[:-len(gvalue)]
request.vars[key] = value
if len(pvalue):
request.post_vars[key] = (len(pvalue)>1 and pvalue) or
pvalue[0]
### Begin added code
for k,v in request.vars.iteritems():
if isinstance(v, list) and len(v)==2:
request.vars[k] = v[0] if v[0] == v[1] else v
### End added code
Thoughts? Comments? Any reason I shouldn't make this change?