[Python-ideas] Proposed addtion to urllib.parse in 3.1 (and urlparse in 2.7)

Eric Smith eric at trueblade.com
Mon Mar 30 12:28:31 CEST 2009


> For people concerned about ordering -- you can always use an odict for 
> passing the kwargs:
> 
> add_query_params('http://foo.com <http://foo.com/>', **odict('a' = 1, 
> 'b' = 2))

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.
 >>> from collections import OrderedDict as odict
 >>> def foo(**kwargs):
...   print type(kwargs)
...   for k, v in kwargs.iteritems():
...     print k, v
...
 >>> o1=odict(); o1['a']=1; o1['b']=2
 >>> o1
OrderedDict([('a', 1), ('b', 2)])
 >>> o2=odict(); o2['b']=2; o2['a']=1
 >>> o2
OrderedDict([('b', 2), ('a', 1)])
 >>> foo(**o1)
<type 'dict'>
a 1
b 2
 >>> foo(**o2)
<type 'dict'>
a 1
b 2
 >>>

Further, when an odict is created and arguments are supplied, the 
ordering is also lost:
 >>> odict(a=1, b=2)
OrderedDict([('a', 1), ('b', 2)])
 >>> odict(b=2, a=1)
OrderedDict([('a', 1), ('b', 2)])
 >>>

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.



More information about the Python-ideas mailing list