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

2009-04-19 Thread Mart Sõmermaa
On Sun, Apr 19, 2009 at 2:06 AM, Nick Coghlan ncogh...@gmail.com wrote:
 That said, I'm starting to wonder if an even better option may be to
 just drop the kwargs support from the function and require people to
 always supply a parameters dictionary. That would simplify the signature
 to the quite straightforward:

  def add_query_params(url, params, allow_dups=True, sep='')

That's the most straightforward and I like this more than the one below.

 I agree that isn't a good option, but mapping True/False/None to those
 specific behaviours also seems rather arbitrary (specifically, it is
 difficult to remember which of allow_dups=False and allow_dups=None
 means to ignore any duplicate keys and which means to ignore only
 duplicate items).

I'd say it's less of a problem when using named arguments, i.e. you read it as:

allow_dups=True : yes
allow_dups=False : effeminately no :),
allow_dups=None : strictly no

which more or less corresponds to the behaviour.

 It also doesn't provide a clear mechanism for
 extension (e.g. what if someone wanted duplicate params to trigger an
 exception?)

 Perhaps the extra argument should just be a key/value pair filtering
 function, and we provide functions for the three existing behaviours
 (i.e. allow_duplicates(), ignore_duplicate_keys(),
 ignore_duplicate_items()) in the urllib.parse module.

This would be the most flexible and conceptually right (ye olde
strategy pattern), but would clutter the API.

 Note that your implementation and docstring currently conflict with each
 other - the docstring says pass them via a dictionary in second
 argument: but the dictionary is currently the third argument (the
 docstring also later refers to passing OrderedDictionary as the second
 argument).

It's a mistake that exemplifies once again that positional args are awkward :).

---

So, gentlemen, either

def add_query_params(url, params, allow_dups=True, sep='')

or

def allow_duplicates(...)

def remove_duplicate_values(...)

...

def add_query_params(url, params, strategy=allow_duplicates, sep='')
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-19 Thread Steven Bethard
On Sun, Apr 19, 2009 at 1:38 AM, Mart Sõmermaa mrts.py...@gmail.com wrote:
 On Sun, Apr 19, 2009 at 2:06 AM, Nick Coghlan ncogh...@gmail.com wrote:
 That said, I'm starting to wonder if an even better option may be to
 just drop the kwargs support from the function and require people to
 always supply a parameters dictionary. That would simplify the signature
 to the quite straightforward:

  def add_query_params(url, params, allow_dups=True, sep='')

 That's the most straightforward and I like this more than the one below.

 I agree that isn't a good option, but mapping True/False/None to those
 specific behaviours also seems rather arbitrary (specifically, it is
 difficult to remember which of allow_dups=False and allow_dups=None
 means to ignore any duplicate keys and which means to ignore only
 duplicate items).

 I'd say it's less of a problem when using named arguments, i.e. you read it 
 as:

 allow_dups=True : yes
 allow_dups=False : effeminately no :),
 allow_dups=None : strictly no

 which more or less corresponds to the behaviour.

 It also doesn't provide a clear mechanism for
 extension (e.g. what if someone wanted duplicate params to trigger an
 exception?)

 Perhaps the extra argument should just be a key/value pair filtering
 function, and we provide functions for the three existing behaviours
 (i.e. allow_duplicates(), ignore_duplicate_keys(),
 ignore_duplicate_items()) in the urllib.parse module.

 This would be the most flexible and conceptually right (ye olde
 strategy pattern), but would clutter the API.

 Note that your implementation and docstring currently conflict with each
 other - the docstring says pass them via a dictionary in second
 argument: but the dictionary is currently the third argument (the
 docstring also later refers to passing OrderedDictionary as the second
 argument).

 It's a mistake that exemplifies once again that positional args are awkward 
 :).

 ---

 So, gentlemen, either

 def add_query_params(url, params, allow_dups=True, sep='')

 or

 def allow_duplicates(...)

 def remove_duplicate_values(...)

 ...

 def add_query_params(url, params, strategy=allow_duplicates, sep='')

+1 for the strategy approach.

Steve
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-19 Thread Bill Janssen
Mart Sõmermaa mrts.py...@gmail.com wrote:

 On Sun, Apr 19, 2009 at 2:06 AM, Nick Coghlan ncogh...@gmail.com wrote:
  That said, I'm starting to wonder if an even better option may be to
  just drop the kwargs support from the function and require people to
  always supply a parameters dictionary. That would simplify the signature
  to the quite straightforward:
 
   def add_query_params(url, params, allow_dups=True, sep='')

Or even better, stop trying to use a mapping, and just make the params
value a list of (name, value) pairs.  That way you can stop fiddling
around with allow_dups and just get rid of it.

Bill
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-19 Thread Steven D'Aprano
On Mon, 20 Apr 2009 05:26:59 am Bill Janssen wrote:
 Mart Sõmermaa mrts.py...@gmail.com wrote:
  On Sun, Apr 19, 2009 at 2:06 AM, Nick Coghlan ncogh...@gmail.com 
wrote:
   That said, I'm starting to wonder if an even better option may be
   to just drop the kwargs support from the function and require
   people to always supply a parameters dictionary. That would
   simplify the signature to the quite straightforward:
  
    def add_query_params(url, params, allow_dups=True, sep='')

 Or even better, stop trying to use a mapping, and just make the
 params value a list of (name, value) pairs.  That way you can stop
 fiddling around with allow_dups and just get rid of it.


Surely it should support any mapping? That's what I do in my own code. 
People will use regular dicts for convenience when they don't care 
about order or duplicates, and (name,value) pairs, or an OrderedDict, 
when they do.

I suppose you could force people to write params.items() if params is a 
dict, but it seems wrong to force an order on input data when it 
doesn't require one.


-- 
Steven D'Aprano
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-18 Thread Mart Sõmermaa
On Sat, Apr 18, 2009 at 3:41 PM, Nick Coghlan ncogh...@gmail.com wrote:
 Yep - Guido has pointed out in a few different API design discussions
 that a boolean flag that is almost always set to a literal True or False
 is a good sign that there are two functions involved rather than just
 one. There are exceptions to that guideline (e.g. the reverse argument
 for sorted and list.sort), but they aren't common, and even when they do
 crop up, making them keyword-only arguments is strongly recommended.

As you yourself previously noted -- 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 -- kwargs may cause name conflicts.

But I also agree, that the current proliferation of positional args is ugly.

add_query_params_no_dups() would be suboptimal though, as there are
currently three different ways to handle the duplicates:
* allow duplicates everywhere (True),
* remove duplicate *values* for the same key (False),
* behave like dict.update -- remove duplicate *keys*, unless
explicitly passed a list (None).

(See the documentation at
http://github.com/mrts/qparams/blob/bf1b29ad46f9d848d5609de6de0bfac1200da310/qparams.py
).

Additionally, as proposed by Antoine Pitrou, removing keys could be implemented.

It feels awkward to start a PEP for such a marginal feature, but
clearly a couple of enlightened design decisions are required.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-18 Thread Nick Coghlan
Mart Sõmermaa wrote:
 On Sat, Apr 18, 2009 at 3:41 PM, Nick Coghlan ncogh...@gmail.com wrote:
 Yep - Guido has pointed out in a few different API design discussions
 that a boolean flag that is almost always set to a literal True or False
 is a good sign that there are two functions involved rather than just
 one. There are exceptions to that guideline (e.g. the reverse argument
 for sorted and list.sort), but they aren't common, and even when they do
 crop up, making them keyword-only arguments is strongly recommended.
 
 As you yourself previously noted -- 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 -- kwargs may cause name conflicts.

Despite what I said earlier, it is probably OK to use named parameters
on the function in this case, especially since you have 3 optional
arguments that someone may want to specify independently of each other.
If someone really wants to add a query parameter to their URL that
conflicts with one of the function parameter names then they can pass
them in the same way they would pass in parameters that don't meet the
rules for a Python identifier (i.e. using the explicit params dictionary).

Something that can be done to even further reduce the chance of
conflicts is to prefix the function parameter names with underscores:

  def add_query_params(_url, _dups, _params, _sep, **kwargs)

That said, I'm starting to wonder if an even better option may be to
just drop the kwargs support from the function and require people to
always supply a parameters dictionary. That would simplify the signature
to the quite straightforward:

  def add_query_params(url, params, allow_dups=True, sep='')

The keyword arguments as query parameters style would still be
supported via dict's own constructor:

 add_query_params('foo', dict(bar='baz'))
'foo?bar=baz'

 add_query_params('http://example.com/a/b/c?a=b', dict(b='d'))
'http://example.com/a/b/c?a=bb=d'

 add_query_params('http://example.com/a/b/c?a=bc=q',
... dict(a='b', b='d', c='q'))
'http://example.com/a/b/c?a=bc=qa=bc=qb=d'

 add_query_params('http://example.com/a/b/c?a=b', dict(a='c', b='d'))
'http://example.com/a/b/c?a=ba=cb=d'

This also makes the transition to a different container type (such as
OrderedDict) cleaner, since you will already be constructing a separate
object to hold the new parameters.

 But I also agree, that the current proliferation of positional args is ugly.
 
 add_query_params_no_dups() would be suboptimal though, as there are
 currently three different ways to handle the duplicates:
 * allow duplicates everywhere (True),
 * remove duplicate *values* for the same key (False),
 * behave like dict.update -- remove duplicate *keys*, unless
 explicitly passed a list (None).

So if we went the multiple functions route, we would have at least:

add_query_params_allow_duplicates()
add_query_params_ignore_duplicate_items()
add_query_params_ignore_duplicate_keys()

I agree that isn't a good option, but mapping True/False/None to those
specific behaviours also seems rather arbitrary (specifically, it is
difficult to remember which of allow_dups=False and allow_dups=None
means to ignore any duplicate keys and which means to ignore only
duplicate items). It also doesn't provide a clear mechanism for
extension (e.g. what if someone wanted duplicate params to trigger an
exception?)

Perhaps the extra argument should just be a key/value pair filtering
function, and we provide functions for the three existing behaviours
(i.e. allow_duplicates(), ignore_duplicate_keys(),
ignore_duplicate_items()) in the urllib.parse module.

 (See the documentation at
 http://github.com/mrts/qparams/blob/bf1b29ad46f9d848d5609de6de0bfac1200da310/qparams.py
 ).

Note that your implementation and docstring currently conflict with each
other - the docstring says pass them via a dictionary in second
argument: but the dictionary is currently the third argument (the
docstring also later refers to passing OrderedDictionary as the second
argument).

Phrases like second optional argument and fourth optional argument
are also ambiguous - do they refer to the second argument, which
happens to be optional or to the second of the optional arguments.
The fact that changing the function signature to disallow keyword
argument would make the optional parameters easier to refer to is a big
win in my book.

 Additionally, as proposed by Antoine Pitrou, removing keys could be 
 implemented.
 
 It feels awkward to start a PEP for such a marginal feature, but
 clearly a couple of enlightened design decisions are required.

Probably not a PEP - just a couple of documented design decisions on a
tracker item pointing to discussion on this list for the rationale.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
---

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

2009-04-13 Thread Mart Sõmermaa
On Mon, Apr 13, 2009 at 12:56 AM, Antoine Pitrou solip...@pitrou.netwrote:

 Mart Sõmermaa mrts.pydev at gmail.com writes:
 
  Proposal: add add_query_params() for appending query parameters to an URL
 to
 urllib.parse and urlparse.

 Is there anything to /remove/ a query parameter?


I'd say this is outside the scope of add_query_params().

As for the duplicate handling, I've implemented a threefold strategy that
should address all use cases raised before:

 def add_query_params(*args, **kwargs):

add_query_parms(url, [allow_dups, [args_dict, [separator]]], **kwargs)

Appends query parameters to an URL and returns the result.

:param url: the URL to update, a string.
:param allow_dups: if
* True: plainly append new parameters, allowing all duplicates
  (default),
* False: disallow duplicates in values and regroup keys so that
  different values for the same key are adjacent,
* None: disallow duplicates in keys -- each key can have a single
  value and later values override the value (like dict.update()).
:param args_dict: optional dictionary of parameters, default is {}.
:param separator: either ';' or '', the separator between key-value
pairs, default is ''.
:param kwargs: parameters as keyword arguments.

:return: original URL with updated query parameters or the original URL
unchanged if no parameters given.


The commit is

http://github.com/mrts/qparams/blob/b9bdbec46bf919d142ff63e6b2b822b5d57b6f89/qparams.py

extensive description of the behaviour is in the doctests.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Michael Foord

Antoine Pitrou wrote:

Mart Sõmermaa mrts.pydev at gmail.com writes:
  

On Mon, Apr 13, 2009 at 12:56 AM, Antoine Pitrou solipsis at pitrou.net


wrote:
  

Mart Sõmermaa mrts.pydev at gmail.com writes:


Proposal: add add_query_params() for appending query parameters to an URL
  

to
  

urllib.parse and urlparse.
Is there anything to /remove/ a query parameter?

I'd say this is outside the scope of add_query_params().



Given the name of the proposed function, sure. But it sounds a bit weird to
have a function dedicated to adding parameters and nothing to remove them.

  


Weird or not, is there actually a *need* to remove query parameters?

Michael


You could e.g. rename the function to update_query_params() and decide that
every parameter whose specified value is None must atcually be removed from
the URL.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk
  



--
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Antoine Pitrou
Michael Foord fuzzyman at voidspace.org.uk writes:
 
 Weird or not, is there actually a *need* to remove query parameters?

Say you are filtering or sorting data based on some URL parameters. If the user
wants to remove one of those filters, you have to remove the corresponding query
parameter.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Senthil Kumaran
On Mon, Apr 13, 2009 at 5:31 PM, Antoine Pitrou solip...@pitrou.net wrote:
 Say you are filtering or sorting data based on some URL parameters. If the 
 user
 wants to remove one of those filters, you have to remove the corresponding 
 query
 parameter.

This is a use-case and possibly a hypothetical one which a programmer
might do under special situations.
There are lots of such use cases for which urllib.parse or urlparse
has been used for.

But my thoughts with this proposal is do we have a good RFC
specfications to implementing this?
If not and if we go by just go by the practical needs, then eventually
we will end up with bugs or feature requests in this which will take a
lot of discussions and time to get fixed.

Someone pointed out to read HTML 5.0 spec instead of RFC for this
request. I am yet to do that, but my opinion with respect to additions
to url* module is - backing of RFCs would be the best way to go and
maintain.

-- 
Senthil
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Tino Wildenhain

Hi,

Senthil Kumaran wrote:

On Mon, Apr 13, 2009 at 5:31 PM, Antoine Pitrou solip...@pitrou.net wrote:

Say you are filtering or sorting data based on some URL parameters. If the user
wants to remove one of those filters, you have to remove the corresponding query
parameter.


This is a use-case and possibly a hypothetical one which a programmer
might do under special situations.
There are lots of such use cases for which urllib.parse or urlparse
has been used for.

But my thoughts with this proposal is do we have a good RFC
specfications to implementing this?
If not and if we go by just go by the practical needs, then eventually
we will end up with bugs or feature requests in this which will take a
lot of discussions and time to get fixed.

Someone pointed out to read HTML 5.0 spec instead of RFC for this
request. I am yet to do that, but my opinion with respect to additions
to url* module is - backing of RFCs would be the best way to go and
maintain.



I'd rather like to see an ordered dict like object returned by urlparse 
for parameters this would make extra methods superfluous.


Also note that you might need to specify the encoding
of the data somewhere (most of the times its utf-8 but it depends on the
encoding used in the form page).

A nice add-on would actually be a template form object which holds all
the expected items and their type (and if optional or not) with little
wrappers for common types (int, float, string, list, ...) which
generate nice execeptions when used somewhere and not filled/no default
or actually wrong data for a type.

Otoh, this might get a bit too much in direction of a web app framework.

Regards
Tino

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Steven Bethard
On Mon, Apr 13, 2009 at 2:29 AM, Mart Sõmermaa mrts.py...@gmail.com wrote:


 On Mon, Apr 13, 2009 at 12:56 AM, Antoine Pitrou solip...@pitrou.net
 wrote:

 Mart Sõmermaa mrts.pydev at gmail.com writes:
 
  Proposal: add add_query_params() for appending query parameters to an
  URL to
 urllib.parse and urlparse.

 Is there anything to /remove/ a query parameter?

 I'd say this is outside the scope of add_query_params().

 As for the duplicate handling, I've implemented a threefold strategy that
 should address all use cases raised before:

  def add_query_params(*args, **kwargs):
     
     add_query_parms(url, [allow_dups, [args_dict, [separator]]], **kwargs)

     Appends query parameters to an URL and returns the result.

     :param url: the URL to update, a string.
     :param allow_dups: if
     * True: plainly append new parameters, allowing all duplicates
   (default),
     * False: disallow duplicates in values and regroup keys so that
   different values for the same key are adjacent,
     * None: disallow duplicates in keys -- each key can have a single
   value and later values override the value (like dict.update()).

Unnamed flag parameters are unfriendly to the reader. If I see something like:

  add_query_params(url, True, dict(a=b, c=d))

I can pretty much guess what the first and third arguments are, but I
have no clue for the second. Even if I have read the documentation
before, I may not remember whether the middle argument is allow_dups
or keep_dups.

Steve

     :param args_dict: optional dictionary of parameters, default is {}.
     :param separator: either ';' or '', the separator between key-value
     pairs, default is ''.
     :param kwargs: parameters as keyword arguments.

     :return: original URL with updated query parameters or the original URL
     unchanged if no parameters given.
     

 The commit is

 http://github.com/mrts/qparams/blob/b9bdbec46bf919d142ff63e6b2b822b5d57b6f89/qparams.py

 extensive description of the behaviour is in the doctests.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Mart Sõmermaa
On Mon, Apr 13, 2009 at 8:23 PM, Steven Bethard
steven.beth...@gmail.com wrote:

 On Mon, Apr 13, 2009 at 2:29 AM, Mart Sõmermaa mrts.py...@gmail.com wrote:
 
 
  On Mon, Apr 13, 2009 at 12:56 AM, Antoine Pitrou solip...@pitrou.net
  wrote:
 
  Mart Sõmermaa mrts.pydev at gmail.com writes:
  
   Proposal: add add_query_params() for appending query parameters to an
   URL to
  urllib.parse and urlparse.
 
  Is there anything to /remove/ a query parameter?
 
  I'd say this is outside the scope of add_query_params().
 
  As for the duplicate handling, I've implemented a threefold strategy that
  should address all use cases raised before:
 
   def add_query_params(*args, **kwargs):
  
  add_query_parms(url, [allow_dups, [args_dict, [separator]]], **kwargs)
 
  Appends query parameters to an URL and returns the result.
 
  :param url: the URL to update, a string.
  :param allow_dups: if
  * True: plainly append new parameters, allowing all duplicates
(default),
  * False: disallow duplicates in values and regroup keys so that
different values for the same key are adjacent,
  * None: disallow duplicates in keys -- each key can have a single
value and later values override the value (like dict.update()).

 Unnamed flag parameters are unfriendly to the reader. If I see something like:

  add_query_params(url, True, dict(a=b, c=d))

 I can pretty much guess what the first and third arguments are, but I
 have no clue for the second. Even if I have read the documentation
 before, I may not remember whether the middle argument is allow_dups
 or keep_dups.

Keyword arguments are already used for specifying the arguments to the
query, so naming can't be used. Someone may need an 'allow_dups' key
in their query and forget to pass it in params_dict.

A default behaviour should be found that works according to most
user's expectations so that they don't need to use the positional
arguments generally.

Antoine Pitrou wrote:
 You could e.g. rename the function to update_query_params() and decide that
 every parameter whose specified value is None must atcually be removed from
 the URL.

I agree that removing parameters is useful. Currently, None is used
for signifying a key with no value. Instead, booleans could be used:
if a key is True (but obviously not any other value that evaluates to
True), it is a key with no value, if False (under the same evaluation
restriction), it should be removed from the query if present. None
should not be treated specially under that scheme. As an example:

 update_query_params('http://example.com/?q=foo', q=False, a=True, b='c', 
 d=None)
'http://example.com/?ab=cd=None'

However,
1) I'm not sure about the implications of 'foo is True', I have never
used it and PEP 8 explicitly warns against it -- does it work
consistently across different Python implementations? (Assuming on the
grounds that True should be a singleton no different from None that it
should work.)
2) the API gets overly complicated -- as per the complaint above, it's
usability-challenged already.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Greg Ewing

Antoine Pitrou wrote:


Say you are filtering or sorting data based on some URL parameters. If the user
wants to remove one of those filters, you have to remove the corresponding query
parameter.


For an application like that, I would be keeping the
parameters as a list or some other structured way and
only converting them to a URL when needed.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-13 Thread Steven Bethard
On Mon, Apr 13, 2009 at 1:14 PM, Mart Sõmermaa mrts.py...@gmail.com wrote:
 On Mon, Apr 13, 2009 at 8:23 PM, Steven Bethard steven.beth...@gmail.com 
 wrote:
 On Mon, Apr 13, 2009 at 2:29 AM, Mart Sõmermaa mrts.py...@gmail.com wrote:
  As for the duplicate handling, I've implemented a threefold strategy that
  should address all use cases raised before:
 
   def add_query_params(*args, **kwargs):
      
      add_query_parms(url, [allow_dups, [args_dict, [separator]]], **kwargs)
 
      Appends query parameters to an URL and returns the result.
 
      :param url: the URL to update, a string.
      :param allow_dups: if
          * True: plainly append new parameters, allowing all duplicates
            (default),
          * False: disallow duplicates in values and regroup keys so that
            different values for the same key are adjacent,
          * None: disallow duplicates in keys -- each key can have a single
            value and later values override the value (like dict.update()).

 Unnamed flag parameters are unfriendly to the reader. If I see something 
 like:

  add_query_params(url, True, dict(a=b, c=d))

 I can pretty much guess what the first and third arguments are, but I
 have no clue for the second. Even if I have read the documentation
 before, I may not remember whether the middle argument is allow_dups
 or keep_dups.

 Keyword arguments are already used for specifying the arguments to the
 query, so naming can't be used. Someone may need an 'allow_dups' key
 in their query and forget to pass it in params_dict.

 A default behaviour should be found that works according to most
 user's expectations so that they don't need to use the positional
 arguments generally.

I believe the usual Python approach here is to have two variants of
the function, add_query_params and add_query_params_no_dups (or
whatever you want to name them). That way the flag parameter is
named right in the function name.

Steve
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-12 Thread Mart Sõmermaa
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/qparams.py(feel
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=bb=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=bb=dfoo=%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=bc=q', a='b', b='d',
...  c='q')
'http://example.com/a/b/c?a=bc=qb=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=ba=cb=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=ba=qa=cb=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?ab'

But if a value is given, the empty key is considered a duplicate (i.e. the
case of aa=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=bc'

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=bb=ca=ba=d', a='b')
'foo?a=ba=db=c'

 add_query_params('http://example.com/a/b/c?a=bq=ce=d',
... x='y', e=1, o=2)
'http://example.com/a/b/c?a=bq=ce=de=1x=yo=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=bxavier=1abacus=2janus=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=bxavier=1xavier=1.1abacus=2janus=3zorg=aborg=dwatt=calpha=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'
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-12 Thread Mart Sõmermaa
On Sun, Apr 12, 2009 at 3:23 PM, Jacob Holm j...@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=bb=dfoo=%2Fbar 
 http://example.com/a/b/c?a=bb=dfoo=%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).


 But if a value is given, the empty key is considered a duplicate (i.e. the
 case of aa=b is considered nonsensical):


 Again, it is a valid url and this will change its meaning.  Why?


I'm uncertain whether aa=b has a meaning, but don't see any harm in
supporting it, so I'll add the feature.


 add_query_params('http://example.com/a/b/c?a', a='b', c=None)
'http://example.com/a/b/c?a=bc http://example.com/a/b/c?a=bc'

 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.


 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).


 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/qparams.py

MS
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-04-12 Thread Lino Mastrodomenico
2009/4/12 Mart Sõmermaa mrts.py...@gmail.com:
 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.

FYI the HTML5 spec (http://whatwg.org/html5 ) may have a better
contact with reality than the RFCs.

From a quick scan, two sections that may be relevant are 4.10.16.3
Form submission algorithm:

http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#form-submission-algorithm

and 4.10.16.4 URL-encoded form data:

http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#url-encoded-form-data

-- 
Lino Mastrodomenico
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com