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?

Reply via email to