views:

33

answers:

1

In the following example from wsgi.org is cur_named copied:

def __call__(self, environ, start_response):
    script_name = environ.get('SCRIPT_NAME', '')
    path_info = environ.get('PATH_INFO', '')
    for regex, application in self.patterns:
        match = regex.match(path_info)
        if not match:
            continue
        extra_path_info = path_info[match.end():]
        if extra_path_info and not extra_path_info.startswith('/'):
            # Not a very good match
            continue
        pos_args = match.groups()
        named_args = match.groupdict()
        cur_pos, cur_named = environ.get('wsgiorg.routing_args', ((), {}))
        new_pos = list(cur_pos) + list(pos_args)
        new_named = cur_named.copy() # Why copy()?
        new_named.update(named_args)
        environ['wsgiorg.routing_args'] = (new_pos, new_named)
        environ['SCRIPT_NAME'] = script_name + path_info[:match.end()]
        environ['PATH_INFO'] = extra_path_info
        return application(environ, start_response)
    return self.not_found(environ, start_response)

Why not to call ur_named.update(named_args) directly?

+1  A: 

Do you know where cur_named dict came from? Just imaging something like the following:

SOME_CONFIG = {
    'some_key': ((..., ...), {...}),
    ...
}

environ['wsgiorg.routing_args'] = SOME_CONFIG['some_key']

Now when you update new_named in-place you are actually updating inner dictionary inside SOME_CONFIG which will bring your data to other requests. The safe way is to copy dictionary unless you are sure it's not needed.

Denis Otkidach
Ok, but `routing_args` are per request and a cannot imagine a case, where inplace modification would be critical. Even if there were another middleware modifying this dict, it wouldn't make sense to copy the dict, because in the end only one single dict with routing_args can be passed to the application.
deamon
SOME_CONFIG in my example is not created for each request. Some environments like FastCGI handle more than one request during process lifetime. Since the first request indirectly modifies this variable, you'll get modified data for subsequent requests.
Denis Otkidach