classification
Title: mutable urlparse return type
Type: enhancement Stage: committed/rejected
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: works for me
Dependencies: Superseder:
Assigned To: Nosy List: eric.araujo, ezio.melotti, mastahyeti, orsenthil, r.david.murray
Priority: normal Keywords: patch

Created on 2012-08-30 18:17 by mastahyeti, last changed 2012-08-30 19:58 by eric.araujo. This issue is now closed.

Files
File name Uploaded Description Edit
urlparse_patch.patch mastahyeti, 2012-08-30 18:17 review
Messages (11)
msg169474 - (view) Author: mastahyeti (mastahyeti) Date: 2012-08-30 18:17
This patch removes the inheritance from namedtuple and attempts to add the necessary methods to make it backwards compatible.

When parsing a url with urlparse.urlparse, the return type is non-mutable (named tuple). This is really inconvenient, because one of the most common (imop) use cases for urlparse is to parse a url, make an adjustment or change and then unparse it. Currently, something like this is required:

    import urlparse

    url = list(urlparse.urlparse('http://www.example.com/foo/bar?hehe=haha'))
    url[1] = 'python.com'
    new_url = urllib.urlunparse(url)

I think this is really clunky. Moving to a mutable return type is challenging because (to my knowledge) there are no types that are mutable and compatible with tuple. This patch removes the inheritance from namedtuple and attempts to add the necessary methods to make it backwards compatible. Does any one know of a better way to do this? It would be nice if there were a namedlist type that acted like namedtuple but was mutable. 

With these updates, urlparse can be used as follows:

    import urlparse

    url = list(urlparse.urlparse('http://www.example.com/foo/bar?hehe=haha'))
    url.netloc = 'www.python.com'
    urlparse.urlunparse(url)

I think this is much better. Let me know if you disagree...

Also, I ran the script through autopep8 because it was messy.

Also, I'm not sure if I'm supposed to duplicate this patch over to Python3. I can do that if necessary
msg169475 - (view) Author: mastahyeti (mastahyeti) Date: 2012-08-30 18:21
TYPO!!!

After my patch, urlparse can be used as such:

    import urlparse

    url = urlparse.urlparse('http://www.example.com/foo/bar?hehe=haha')
    url.netloc = 'www.python.com'
    urlparse.urlunparse(url)


The difference being that the result doesn't need to be casted to a list in order to be mutated...
msg169476 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2012-08-30 18:21
This is a new feature, so it can't go in 2.7.
msg169477 - (view) Author: mastahyeti (mastahyeti) Date: 2012-08-30 18:24
This is my first patch for python. Is there a feature freeze? Does it
need to go in Python3? Thanks.

On Thu, Aug 30, 2012 at 1:22 PM, Ezio Melotti <report@bugs.python.org> wrote:
>
> Ezio Melotti added the comment:
>
> This is a new feature, so it can't go in 2.7.
>
> ----------
> nosy: +ezio.melotti, orsenthil
> stage:  -> needs patch
> versions: +Python 3.4 -Python 2.7
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue15824>
> _______________________________________
msg169478 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-30 18:25
I think the first step is probably to get consensus on whether this is desirable or not.  That might require a trip to python-idea, or it might not :)

As for the patch itself, you should definitely *not* include any changes other than the ones you are proposing.  Otherwise reviewing the patch is very difficult.

As Ezio said, as a new feature this could only go into 3.4, so the patch should be against the default branch in the mercurial repository.
msg169479 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2012-08-30 18:38
On Thu, Aug 30, 2012 at 11:17 AM, mastahyeti <report@bugs.python.org> wrote:
>
> When parsing a url with urlparse.urlparse, the return type is non-mutable (named tuple). This is really inconvenient, because one of the most common (imop) use cases for urlparse is to parse a url, make an adjustment or change and then unparse it. Currently, something like this is required:

Not actually, using the namedtuple is a convenience and working
through way may help you to be generate your target url in a more
meaningful way. Also remember that we moved to namedtuple after
understanding that it is more meaningful to use that for parsed
result.  So, my vote for this proposal is -1. And if you need discuss
the strategies of how to use it, then you can ask over at python-help
or related lists.
msg169482 - (view) Author: mastahyeti (mastahyeti) Date: 2012-08-30 18:58
Senthil,
Can you give an example of how namedtuple would be more convenient? It
is definitely more convenient than an ordinary tuple, but its
inconvenient having its items not be assignable. As I showed in my
example above, it is usable as-is, but it is clunky. As David says
above, this obviously needs to be moved to another list for discussion
of whether the current behavior is desirable.

On Thu, Aug 30, 2012 at 1:38 PM, Senthil Kumaran <report@bugs.python.org> wrote:
>
> Senthil Kumaran added the comment:
>
> On Thu, Aug 30, 2012 at 11:17 AM, mastahyeti <report@bugs.python.org> wrote:
>>
>> When parsing a url with urlparse.urlparse, the return type is non-mutable (named tuple). This is really inconvenient, because one of the most common (imop) use cases for urlparse is to parse a url, make an adjustment or change and then unparse it. Currently, something like this is required:
>
> Not actually, using the namedtuple is a convenience and working
> through way may help you to be generate your target url in a more
> meaningful way. Also remember that we moved to namedtuple after
> understanding that it is more meaningful to use that for parsed
> result.  So, my vote for this proposal is -1. And if you need discuss
> the strategies of how to use it, then you can ask over at python-help
> or related lists.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue15824>
> _______________________________________
msg169483 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-30 19:03
Actually, Senthil is right.  What you want is the _replace method of namedtuple to satisfy your use case.
msg169485 - (view) Author: mastahyeti (mastahyeti) Date: 2012-08-30 19:10
I can live with that, it just seems that ordinary item assignment is
more pythonic....

On Thu, Aug 30, 2012 at 2:03 PM, R. David Murray <report@bugs.python.org> wrote:
>
> R. David Murray added the comment:
>
> Actually, Senthil is right.  What you want is the _replace method of namedtuple to satisfy your use case.
>
> ----------
> resolution:  -> works for me
> stage:  -> committed/rejected
> status: open -> closed
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue15824>
> _______________________________________
msg169487 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-30 19:16
Not in this case.  We are treating the URL as an immutable object, so the Pythonic thing to do is create new object of the same type with the change applied.  Similar to "abcd".replace('a', 'z') returning a new string.
msg169488 - (view) Author: mastahyeti (mastahyeti) Date: 2012-08-30 19:22
Hrmm. Okay. I concede.

On Thu, Aug 30, 2012 at 2:16 PM, R. David Murray <report@bugs.python.org> wrote:
>
> R. David Murray added the comment:
>
> Not in this case.  We are treating the URL as an immutable object, so the Pythonic thing to do is create new object of the same type with the change applied.  Similar to "abcd".replace('a', 'z') returning a new string.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue15824>
> _______________________________________
History
Date User Action Args
2012-08-30 19:58:49eric.araujosetnosy: + eric.araujo
2012-08-30 19:22:39mastahyetisetmessages: + msg169488
2012-08-30 19:16:46r.david.murraysetmessages: + msg169487
2012-08-30 19:10:21mastahyetisetmessages: + msg169485
2012-08-30 19:03:40r.david.murraysetstatus: open -> closed
resolution: works for me
messages: + msg169483

stage: committed/rejected
2012-08-30 18:58:07mastahyetisetmessages: + msg169482
2012-08-30 18:38:23orsenthilsetmessages: + msg169479
2012-08-30 18:25:34r.david.murraysetnosy: + r.david.murray

messages: + msg169478
stage: needs patch -> (no value)
2012-08-30 18:24:57mastahyetisetmessages: + msg169477
2012-08-30 18:22:00ezio.melottisetversions: + Python 3.4, - Python 2.7
nosy: + ezio.melotti, orsenthil

messages: + msg169476

stage: needs patch
2012-08-30 18:21:01mastahyetisetmessages: + msg169475
2012-08-30 18:17:44mastahyeticreate