Proposed addtion to urllib.parse in 3.1 (and urlparse in 2.7)

Appending query parameters to a URL is a very common need. However, there's nothing in urllib.parse (and older urlparse) that caters for that need. Therefore, I propose adding the following to 2.7 and 3.1 in the respective libs: def add_query_params(url, **params): """ Adds additional query parameters to the given url, preserving original parameters. Usage: >>> add_query_params('http://foo.com', a='b') 'http://foo.com?a=b' >>> add_query_params('http://foo.com?a=b', b='c', d='q') 'http://foo.com?a=b&b=c&d=q' The real implementation should be more strict, e.g. raise on the following: >>> add_query_params('http://foo.com?a=b', a='b') 'http://foo.com?a=b&a=b' """ if not params: return url encoded = urllib.urlencode(params) url = urlparse.urlparse(url) return urlparse.urlunparse((url.scheme, url.netloc, url.path, url.params, (encoded if not url.query else url.query + '&' + encoded), url.fragment))

On Fri, Mar 27, 2009 at 8:56 PM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
Well, this is not 'generic' - for eg. in Django sites the above would not be applicable. -V- http://twitter.com/venkasub

On Fri, Mar 27, 2009 at 9:30 PM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
http://foo.com?a=b <http://foo.com/?a=b> != http://foo.com/a/b<http://foo.com/?a=b> . Semantically , both are same,but the framework rules are different. Not sure how you would this - by telling urllib that it is a 'pretty' django URL? (or am i missing out something?) -V-

Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
>>> add_query_params('http://foo.com?a=b', b='c', d='q')
To begin with, I wouldn't use keyword params. They're syntactically more restrictive than the rules for application/x-www-form-urlencoded allow, so you start by ruling out whole classes of URLs. Bill

On 27 Mar 2009, at 16:17, Mart Sõmermaa wrote:
Note that it's still not general enough as query fields can be repeated, e.g. http://foo.com/search/?q=spam&q=eggs -- Arnaud

As far as I can see, people tend to agree that this is useful. So, unless someone steps up to oppose this, I'll file a feature request to the Python bug tracker. Will propose an implementation based on ordered dict (that will be in 2.7/3.1 anyway). On Fri, Mar 27, 2009 at 9:29 PM, Joel Bender <jjb5@cornell.edu> wrote:

2009/3/27 Mart Sõmermaa <mrts.pydev@gmail.com>:
I hope by this you mean you'll provide a patch! -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Fri, Mar 27, 2009 at 7:36 PM, Terry Reedy <tjreedy@udel.edu> wrote:
Repeated fields can be packed together in a tuple/list: add_query_params('http://foo.com', dict(q=('spam', 'eggs'))) To which one might reply that this would exclude non-consecutive repeated fields,e g. '?q=spam&foo=bar&q=eggs. To which I would reply that for this 0.01% of cases that require this (a) do it by hand as now or (b) use the same signature as dict() (plus the host in the beginning): add_query_params(host, mapping_or_iterable=None, **params) George

There's way too much bikeshedding in this thread (not picking on you specifically). I think the originally proposed API is fine, except it should *not* reject duplicates. To add duplicates you'd just call it multiple times, e.g. add_query_params(add_query_params(url, a='x'), a='y'). It's a pretty minor use case anyways. --Guido On Fri, Mar 27, 2009 at 7:28 PM, George Sakkis <george.sakkis@gmail.com> wrote:
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Sat, Mar 28, 2009 at 5:26 AM, Guido van Rossum <guido@python.org> wrote:
So be it. I'll open a ticket and provide a patch, tests and documentation. For people concerned about ordering -- you can always use an odict for passing the kwargs: add_query_params('http://foo.com', **odict('a' = 1, 'b' = 2)) For people concerned about syntactically more restrictive rules than application/x-www-form-urlencoded allows -- pass in the kwargs via ordinary dict: add_query_params('http://foo.com', **{'|"-/': 1, 'öäü': 2}) # note that py2k allows UTF-8 in argument names anyway The latter is bad practice anyway.

On Mon, Mar 30, 2009 at 1:04 PM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
add_query_params('http://foo.com', **{'|"-/': 1, 'öäü': 2}) # note that py2k allows UTF-8 in argument names anyway
s/py2k/py3k/

Not that I want to continue the discussion about this particular issue, but I'd like to correct this statement, since this statement is wrong (beyond the syntax of creating the odict being incorrect). "**" converts the parameters to an ordinary dict. The caller does not receive the same object you call the function with. So any ordering of the values in the odict will be lost. $ ./python.exe Python 2.7a0 (trunk:70598, Mar 25 2009, 17:30:54) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information.
Further, when an odict is created and arguments are supplied, the ordering is also lost:
3.1 works the same way (once you change the print statement and use .items instead of .iteritems: I need to run 2to3 on my example!). I just want to make sure everyone realized the limitations. odict won't solve problems like this. I think these are both "gotchas" waiting to happen. Eric.

On Mon, Mar 30, 2009 at 1:28 PM, Eric Smith <eric@trueblade.com> wrote:
Right you are, sorry for the mental blunder. So what if the signature is as follows to support passing query parameters via an ordered dict: add_query_params(url, params_dict=None, **kwargs) with the following behaviour:

Mart Sõmermaa wrote:
When setting up a dict.update style interface like that, it is often better to use *args for the two positional arguments - it avoids accidental name conflicts between the positional arguments and arbitrary keyword arguments. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------

The general consensus in python-ideas is that the following is needed, so I bring it to python-dev to final discussions before I file a feature request in bugs.python.org. Proposal: add add_query_params() for appending query parameters to an URL to urllib.parse and urlparse. Implementation: http://github.com/mrts/qparams/blob/83d1ec287ec10934b5e637455819cf796b1b421c... free to fork and comment). Behaviour (longish, guided by "simple things are simiple, complex things possible"): In the simplest form, parameters can be passed via keyword arguments: >>> add_query_params('foo', bar='baz') 'foo?bar=baz' >>> add_query_params('http://example.com/a/b/c?a=b', b='d') 'http://example.com/a/b/c?a=b&b=d' Note that '/', if given in arguments, is encoded: >>> add_query_params('http://example.com/a/b/c?a=b', b='d', foo='/bar') 'http://example.com/a/b/c?a=b&b=d&foo=%2Fbar' Duplicates are discarded: >>> add_query_params('http://example.com/a/b/c?a=b', a='b') 'http://example.com/a/b/c?a=b' >>> add_query_params('http://example.com/a/b/c?a=b&c=q', a='b', b='d', ... c='q') 'http://example.com/a/b/c?a=b&c=q&b=d' But different values for the same key are supported: >>> add_query_params('http://example.com/a/b/c?a=b', a='c', b='d') 'http://example.com/a/b/c?a=b&a=c&b=d' Pass different values for a single key in a list (again, duplicates are removed): >>> add_query_params('http://example.com/a/b/c?a=b', a=('q', 'b', 'c'), ... b='d') 'http://example.com/a/b/c?a=b&a=q&a=c&b=d' Keys with no value are respected, pass ``None`` to create one: >>> add_query_params('http://example.com/a/b/c?a', b=None) 'http://example.com/a/b/c?a&b' But if a value is given, the empty key is considered a duplicate (i.e. the case of a&a=b is considered nonsensical): >>> add_query_params('http://example.com/a/b/c?a', a='b', c=None) 'http://example.com/a/b/c?a=b&c' If you need to pass in key names that are not allowed in keyword arguments, pass them via a dictionary in second argument: >>> add_query_params('foo', {"+'|äüö": 'bar'}) 'foo?%2B%27%7C%C3%A4%C3%BC%C3%B6=bar' Order of original parameters is retained, although similar keys are grouped together. Order of keyword arguments is not (and can not be) retained: >>> add_query_params('foo?a=b&b=c&a=b&a=d', a='b') 'foo?a=b&a=d&b=c' >>> add_query_params('http://example.com/a/b/c?a=b&q=c&e=d', ... x='y', e=1, o=2) 'http://example.com/a/b/c?a=b&q=c&e=d&e=1&x=y&o=2' If you need to retain the order of the added parameters, use an :class:`OrderedDict` as the second argument (*params_dict*): >>> from collections import OrderedDict >>> od = OrderedDict() >>> od['xavier'] = 1 >>> od['abacus'] = 2 >>> od['janus'] = 3 >>> add_query_params('http://example.com/a/b/c?a=b', od) 'http://example.com/a/b/c?a=b&xavier=1&abacus=2&janus=3' If both *params_dict* and keyword arguments are provided, values from the former are used before the latter: >>> add_query_params('http://example.com/a/b/c?a=b', od, xavier=1.1, ... zorg='a', alpha='b', watt='c', borg='d') ' http://example.com/a/b/c?a=b&xavier=1&xavier=1.1&abacus=2&janus=3&zorg=a&borg=d&watt=c&alpha=b ' Do nothing with a single argument: >>> add_query_params('a') 'a' >>> add_query_params('arbitrary strange stuff?öäüõ*()+-=42') 'arbitrary strange stuff?\xc3\xb6\xc3\xa4\xc3\xbc\xc3\xb5*()+-=42'

Hi Mart I haven't really followed this thread closely, so I apologize if some of my comments below have already been addressed. Mart Sõmermaa wrote:
Why discard duplicates? They are valid and have a well-defined meaning.
>>> add_query_params('http://example.com/a/b/c?a=b', a='b') 'http://example.com/a/b/c?a=b'
I would prefer: 'http://example.com/a/b/c?a=b&a=b'
I would prefer: 'http://example.com/a/b/c?a=b&c=q&a=b&b=d'
Again, it is a valid url and this will change its meaning. Why?
Why the grouping? Is it a side effect of your desire to discard duplicates? Changing the order like that changes the meaning of the url. A concrete case where the order of field names matters is the ":records" converter in http://pypi.python.org/pypi/zope.httpform/1.0.1 (a small independent package extracted from the form handling code in zope).
If you change it to keep duplicates and not unnecessarily mangle the field order I am +1, else I am -0. - Jacob

On Sun, Apr 12, 2009 at 3:23 PM, Jacob Holm <jh@improva.dk> wrote:
The bad thing about reasoning about query strings is that there is no comprehensive documentation about their meaning. Both RFC 1738 and RFC 3986 are rather vague in that matter. But I agree that duplicates actually have a meaning (an ordered list of identical values), so I'll remove the bits that prune them unless anyone opposes (which I doubt).
I'm uncertain whether a&a=b has a meaning, but don't see any harm in supporting it, so I'll add the feature.
It's also related to duplicate handling, but it mostly relates to the data structure used in the initial implementation (an OrderedDict). Re-grouping is removed now and not having to deal with duplicates simplified the code considerably (using a simple list of key-value tuples now). If you change it to keep duplicates and not unnecessarily mangle the field
order I am +1, else I am -0.
Thanks for your input! Changes pushed to github (see the updated behaviour there as well): http://github.com/mrts/qparams/blob/4f32670b55082f8d0ef01c33524145c3264c161a... MS

On 12Apr2009 16:15, Mart S?mermaa <mrts.pydev@gmail.com> wrote: | On Sun, Apr 12, 2009 at 3:23 PM, Jacob Holm <jh@improva.dk> wrote: | > Hi Mart | > >>> add_query_params('http://example.com/a/b/c?a=b', b='d', foo='/bar') | >> 'http://example.com/a/b/c?a=b&b=d&foo=%2Fbar < | >> http://example.com/a/b/c?a=b&b=d&foo=%2Fbar>' | >> | >> Duplicates are discarded: | > | > Why discard duplicates? They are valid and have a well-defined meaning. | | The bad thing about reasoning about query strings is that there is no | comprehensive documentation about their meaning. Both RFC 1738 and RFC 3986 | are rather vague in that matter. But I agree that duplicates actually have a | meaning (an ordered list of identical values), so I'll remove the bits that | prune them unless anyone opposes (which I doubt). +1 from me, with the following suggestion: it's probably worth adding the to doco that people working with dict-style query_string params should probably go make a dict or OrderedDict and use: add_query_params(..., **the_dict) just to make the other use case obvious. An alternative would be to have add_ and append_ methods with set and list behaviour. Feels a little like API bloat, though the convenience function can be nice. Cheers, -- Cameron Simpson <cs@zip.com.au> DoD#743 http://www.cskk.ezoshosting.com/cs/ The wonderous pulp and fibre of the brain had been substituted by brass and iron; he had taught wheelwork to think. - Harry Wilmot Buxton 1832, referring to Charles Babbage and his difference engine.

On Mon, Mar 30, 2009 at 5:04 AM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
Alas, that doesn't work -- f(**X) copies X into a real dict. But web apps that care about the order are crazy IMO.
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Fri, Mar 27, 2009 at 8:56 PM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
Well, this is not 'generic' - for eg. in Django sites the above would not be applicable. -V- http://twitter.com/venkasub

On Fri, Mar 27, 2009 at 9:30 PM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
http://foo.com?a=b <http://foo.com/?a=b> != http://foo.com/a/b<http://foo.com/?a=b> . Semantically , both are same,but the framework rules are different. Not sure how you would this - by telling urllib that it is a 'pretty' django URL? (or am i missing out something?) -V-

Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
>>> add_query_params('http://foo.com?a=b', b='c', d='q')
To begin with, I wouldn't use keyword params. They're syntactically more restrictive than the rules for application/x-www-form-urlencoded allow, so you start by ruling out whole classes of URLs. Bill

On 27 Mar 2009, at 16:17, Mart Sõmermaa wrote:
Note that it's still not general enough as query fields can be repeated, e.g. http://foo.com/search/?q=spam&q=eggs -- Arnaud

As far as I can see, people tend to agree that this is useful. So, unless someone steps up to oppose this, I'll file a feature request to the Python bug tracker. Will propose an implementation based on ordered dict (that will be in 2.7/3.1 anyway). On Fri, Mar 27, 2009 at 9:29 PM, Joel Bender <jjb5@cornell.edu> wrote:

2009/3/27 Mart Sõmermaa <mrts.pydev@gmail.com>:
I hope by this you mean you'll provide a patch! -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Fri, Mar 27, 2009 at 7:36 PM, Terry Reedy <tjreedy@udel.edu> wrote:
Repeated fields can be packed together in a tuple/list: add_query_params('http://foo.com', dict(q=('spam', 'eggs'))) To which one might reply that this would exclude non-consecutive repeated fields,e g. '?q=spam&foo=bar&q=eggs. To which I would reply that for this 0.01% of cases that require this (a) do it by hand as now or (b) use the same signature as dict() (plus the host in the beginning): add_query_params(host, mapping_or_iterable=None, **params) George

There's way too much bikeshedding in this thread (not picking on you specifically). I think the originally proposed API is fine, except it should *not* reject duplicates. To add duplicates you'd just call it multiple times, e.g. add_query_params(add_query_params(url, a='x'), a='y'). It's a pretty minor use case anyways. --Guido On Fri, Mar 27, 2009 at 7:28 PM, George Sakkis <george.sakkis@gmail.com> wrote:
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Sat, Mar 28, 2009 at 5:26 AM, Guido van Rossum <guido@python.org> wrote:
So be it. I'll open a ticket and provide a patch, tests and documentation. For people concerned about ordering -- you can always use an odict for passing the kwargs: add_query_params('http://foo.com', **odict('a' = 1, 'b' = 2)) For people concerned about syntactically more restrictive rules than application/x-www-form-urlencoded allows -- pass in the kwargs via ordinary dict: add_query_params('http://foo.com', **{'|"-/': 1, 'öäü': 2}) # note that py2k allows UTF-8 in argument names anyway The latter is bad practice anyway.

On Mon, Mar 30, 2009 at 1:04 PM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
add_query_params('http://foo.com', **{'|"-/': 1, 'öäü': 2}) # note that py2k allows UTF-8 in argument names anyway
s/py2k/py3k/

Not that I want to continue the discussion about this particular issue, but I'd like to correct this statement, since this statement is wrong (beyond the syntax of creating the odict being incorrect). "**" converts the parameters to an ordinary dict. The caller does not receive the same object you call the function with. So any ordering of the values in the odict will be lost. $ ./python.exe Python 2.7a0 (trunk:70598, Mar 25 2009, 17:30:54) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information.
Further, when an odict is created and arguments are supplied, the ordering is also lost:
3.1 works the same way (once you change the print statement and use .items instead of .iteritems: I need to run 2to3 on my example!). I just want to make sure everyone realized the limitations. odict won't solve problems like this. I think these are both "gotchas" waiting to happen. Eric.

On Mon, Mar 30, 2009 at 1:28 PM, Eric Smith <eric@trueblade.com> wrote:
Right you are, sorry for the mental blunder. So what if the signature is as follows to support passing query parameters via an ordered dict: add_query_params(url, params_dict=None, **kwargs) with the following behaviour:

Mart Sõmermaa wrote:
When setting up a dict.update style interface like that, it is often better to use *args for the two positional arguments - it avoids accidental name conflicts between the positional arguments and arbitrary keyword arguments. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------

The general consensus in python-ideas is that the following is needed, so I bring it to python-dev to final discussions before I file a feature request in bugs.python.org. Proposal: add add_query_params() for appending query parameters to an URL to urllib.parse and urlparse. Implementation: http://github.com/mrts/qparams/blob/83d1ec287ec10934b5e637455819cf796b1b421c... free to fork and comment). Behaviour (longish, guided by "simple things are simiple, complex things possible"): In the simplest form, parameters can be passed via keyword arguments: >>> add_query_params('foo', bar='baz') 'foo?bar=baz' >>> add_query_params('http://example.com/a/b/c?a=b', b='d') 'http://example.com/a/b/c?a=b&b=d' Note that '/', if given in arguments, is encoded: >>> add_query_params('http://example.com/a/b/c?a=b', b='d', foo='/bar') 'http://example.com/a/b/c?a=b&b=d&foo=%2Fbar' Duplicates are discarded: >>> add_query_params('http://example.com/a/b/c?a=b', a='b') 'http://example.com/a/b/c?a=b' >>> add_query_params('http://example.com/a/b/c?a=b&c=q', a='b', b='d', ... c='q') 'http://example.com/a/b/c?a=b&c=q&b=d' But different values for the same key are supported: >>> add_query_params('http://example.com/a/b/c?a=b', a='c', b='d') 'http://example.com/a/b/c?a=b&a=c&b=d' Pass different values for a single key in a list (again, duplicates are removed): >>> add_query_params('http://example.com/a/b/c?a=b', a=('q', 'b', 'c'), ... b='d') 'http://example.com/a/b/c?a=b&a=q&a=c&b=d' Keys with no value are respected, pass ``None`` to create one: >>> add_query_params('http://example.com/a/b/c?a', b=None) 'http://example.com/a/b/c?a&b' But if a value is given, the empty key is considered a duplicate (i.e. the case of a&a=b is considered nonsensical): >>> add_query_params('http://example.com/a/b/c?a', a='b', c=None) 'http://example.com/a/b/c?a=b&c' If you need to pass in key names that are not allowed in keyword arguments, pass them via a dictionary in second argument: >>> add_query_params('foo', {"+'|äüö": 'bar'}) 'foo?%2B%27%7C%C3%A4%C3%BC%C3%B6=bar' Order of original parameters is retained, although similar keys are grouped together. Order of keyword arguments is not (and can not be) retained: >>> add_query_params('foo?a=b&b=c&a=b&a=d', a='b') 'foo?a=b&a=d&b=c' >>> add_query_params('http://example.com/a/b/c?a=b&q=c&e=d', ... x='y', e=1, o=2) 'http://example.com/a/b/c?a=b&q=c&e=d&e=1&x=y&o=2' If you need to retain the order of the added parameters, use an :class:`OrderedDict` as the second argument (*params_dict*): >>> from collections import OrderedDict >>> od = OrderedDict() >>> od['xavier'] = 1 >>> od['abacus'] = 2 >>> od['janus'] = 3 >>> add_query_params('http://example.com/a/b/c?a=b', od) 'http://example.com/a/b/c?a=b&xavier=1&abacus=2&janus=3' If both *params_dict* and keyword arguments are provided, values from the former are used before the latter: >>> add_query_params('http://example.com/a/b/c?a=b', od, xavier=1.1, ... zorg='a', alpha='b', watt='c', borg='d') ' http://example.com/a/b/c?a=b&xavier=1&xavier=1.1&abacus=2&janus=3&zorg=a&borg=d&watt=c&alpha=b ' Do nothing with a single argument: >>> add_query_params('a') 'a' >>> add_query_params('arbitrary strange stuff?öäüõ*()+-=42') 'arbitrary strange stuff?\xc3\xb6\xc3\xa4\xc3\xbc\xc3\xb5*()+-=42'

Hi Mart I haven't really followed this thread closely, so I apologize if some of my comments below have already been addressed. Mart Sõmermaa wrote:
Why discard duplicates? They are valid and have a well-defined meaning.
>>> add_query_params('http://example.com/a/b/c?a=b', a='b') 'http://example.com/a/b/c?a=b'
I would prefer: 'http://example.com/a/b/c?a=b&a=b'
I would prefer: 'http://example.com/a/b/c?a=b&c=q&a=b&b=d'
Again, it is a valid url and this will change its meaning. Why?
Why the grouping? Is it a side effect of your desire to discard duplicates? Changing the order like that changes the meaning of the url. A concrete case where the order of field names matters is the ":records" converter in http://pypi.python.org/pypi/zope.httpform/1.0.1 (a small independent package extracted from the form handling code in zope).
If you change it to keep duplicates and not unnecessarily mangle the field order I am +1, else I am -0. - Jacob

On Sun, Apr 12, 2009 at 3:23 PM, Jacob Holm <jh@improva.dk> wrote:
The bad thing about reasoning about query strings is that there is no comprehensive documentation about their meaning. Both RFC 1738 and RFC 3986 are rather vague in that matter. But I agree that duplicates actually have a meaning (an ordered list of identical values), so I'll remove the bits that prune them unless anyone opposes (which I doubt).
I'm uncertain whether a&a=b has a meaning, but don't see any harm in supporting it, so I'll add the feature.
It's also related to duplicate handling, but it mostly relates to the data structure used in the initial implementation (an OrderedDict). Re-grouping is removed now and not having to deal with duplicates simplified the code considerably (using a simple list of key-value tuples now). If you change it to keep duplicates and not unnecessarily mangle the field
order I am +1, else I am -0.
Thanks for your input! Changes pushed to github (see the updated behaviour there as well): http://github.com/mrts/qparams/blob/4f32670b55082f8d0ef01c33524145c3264c161a... MS

On 12Apr2009 16:15, Mart S?mermaa <mrts.pydev@gmail.com> wrote: | On Sun, Apr 12, 2009 at 3:23 PM, Jacob Holm <jh@improva.dk> wrote: | > Hi Mart | > >>> add_query_params('http://example.com/a/b/c?a=b', b='d', foo='/bar') | >> 'http://example.com/a/b/c?a=b&b=d&foo=%2Fbar < | >> http://example.com/a/b/c?a=b&b=d&foo=%2Fbar>' | >> | >> Duplicates are discarded: | > | > Why discard duplicates? They are valid and have a well-defined meaning. | | The bad thing about reasoning about query strings is that there is no | comprehensive documentation about their meaning. Both RFC 1738 and RFC 3986 | are rather vague in that matter. But I agree that duplicates actually have a | meaning (an ordered list of identical values), so I'll remove the bits that | prune them unless anyone opposes (which I doubt). +1 from me, with the following suggestion: it's probably worth adding the to doco that people working with dict-style query_string params should probably go make a dict or OrderedDict and use: add_query_params(..., **the_dict) just to make the other use case obvious. An alternative would be to have add_ and append_ methods with set and list behaviour. Feels a little like API bloat, though the convenience function can be nice. Cheers, -- Cameron Simpson <cs@zip.com.au> DoD#743 http://www.cskk.ezoshosting.com/cs/ The wonderous pulp and fibre of the brain had been substituted by brass and iron; he had taught wheelwork to think. - Harry Wilmot Buxton 1832, referring to Charles Babbage and his difference engine.

On Mon, Mar 30, 2009 at 5:04 AM, Mart Sõmermaa <mrts.pydev@gmail.com> wrote:
Alas, that doesn't work -- f(**X) copies X into a real dict. But web apps that care about the order are crazy IMO.
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (12)
-
Arnaud Delobelle
-
Bill Janssen
-
Cameron Simpson
-
Eric Smith
-
George Sakkis
-
Guido van Rossum
-
Jacob Holm
-
Joel Bender
-
Mart Sõmermaa
-
Nick Coghlan
-
Terry Reedy
-
Venkatraman S