views:

147

answers:

3

This afternoon I spent several hours trying to find a bug in my custom extension to urllib2.Request. The problem was, as I found out, the usage of super(ExtendedRequest, self), since urllib2.Request is (I'm on Python 2.5) still an old style class, where the use of super() is not possible.

The most obvious way to create a new class with both features,

class ExtendedRequest(object, urllib2.Request):
    def __init__():
        super(ExtendedRequest, self).__init__(...)

doesn't work. Calling it, I'm left with AttributeError: type raised by urllib2.Request.__getattr__(). Now, before I start and copy'n paste the whole urllib2.Request class from /usr/lib/python just to rewrite it as

class Request(object):

has anyone an idea, how I could achieve this in a more elegant way? (With this being to have a new-style class based on urllib2.Request with working support for super().)

Edit: By the way: the AttributeError mentioned:

>>> class ExtendedRequest(object, urllib2.Request):
...   def __init__(self):
...     super(ExtendedRequest, self).__init__('http://stackoverflow.com')
...
>>> ABC = ExtendedRequest ()
>>> d = urllib2.urlopen(ABC)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/urllib2.py", line 124, in urlopen
    return _opener.open(url, data)
  File "/usr/lib/python2.5/urllib2.py", line 373, in open
    protocol = req.get_type()
  File "/usr/lib/python2.5/urllib2.py", line 241, in get_type
    if self.type is None:
  File "/usr/lib/python2.5/urllib2.py", line 218, in __getattr__
    raise AttributeError, attr
AttributeError: type
+1  A: 

This should work fine since the hierarchy is simple

class ExtendedRequest(urllib2.Request):
    def __init__(self,...):
        urllib2.Request.__init__(self,...)
gnibbler
Thanks for the answer, but I know that. Actually, I'm doing just this at the moment. However, I wanted to utilize the power of super() in some aspects, such as multiple inheritance.
Boldewyn
The whole hierarchy has to be new style for `super` to work correctly
gnibbler
OK, thanks. It's a pity, that it doesn't work.
Boldewyn
yes it's a pity that urllib2 isn't using newstyle classes. I wonder why they did that
gnibbler
A: 

I think you missed to pass the self parameter to definition of init in your sample. Try this one:

class ExtendedRequest(object, urllib2.Request):
    def __init__(self):
        super(ExtendedRequest, self).__init__(self)

I tested it and it seems to work okey:

>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>
Ehsan Foroughi
Yes, but when you try to call any method on the `<super>` object, it raises the AttributeError.
Boldewyn
+1  A: 
unutbu
Meanwhile I browsed through some of the related questions in the right column and found James Knight's article, too. Although I still think, that `super()` is a mighty tool, I start to get a grip on its disadvantages. Thanks for pointing it out in detail!
Boldewyn