I was poking around at the source of the requests
module, and noticed this code:
class Response(object):
"""The :class:`Response <Response>` object, which contains a
server's response to an HTTP request.
"""
def __init__(self):
super(Response, self).__init__()
... more init method...
My understanding of super()
suggests this call wouldn't do anything at all. I've found quite a few questions about superclass calling, but all work from subclasses of other classes, not object
itself. The python docs, too, don't mention this construction.
It occurred to me this might simply be a mistake, and if you git blame
that file to the commit that introduced that line, you'll see that at the time of authorship, Response
was a subclass of BaseResponse
. Is the line just a holdover from a class refactoring, or does it this super() call do anything at all?
This code might actually do something if Response becomes part of a multiple inheritance tree. The next class in the "MRO" list could be something other than object! In that case, the call to super could be very much necessary.
For example,
class NewerClass(A, Response):
def __init__(self):
... do stuff ...
super(NewerClass, self).__init__()
From that class definition and without knowing what the hierarchy of A is, you can not determine what the next class that super(Response, self).__init__()
calls will be. It might be object or it might be a base class of A.
I think one problem is that the name super causes confusion. It does not act like Smalltalk's super variable unless you only use single inheritance, and it does not return a "super class" object. Instead what it is doing is figuring out the "next" class to be used according to MRO order.
Classic articles on the subject are: Python's Super Considered Super and Python's Super Considered Harmful.
As mentioned in Corley Brigman's comment, it's unnecessary but harmless.
For some background, the BaseResponse
class was added during Kenneth's sprint on Requests 1.0. The 1.0 code change introduced transport adapters, which make it possible to define specific behaviour for some HTTP endpoints (or indeed non-HTTP endpoints). An important part of the Transport Adapter interface is the HTTPAdapter.build_response()
method, which takes the returned raw response from HTTPAdapter.send()
and builds a Requests Response
object from it.
It is clear that Kenneth saw potential utility in having some form of abstract base class for Response
s, which would allow transport adapters to return Response
s with very different behaviours to the standard HTTP Response
object. For this reason, the refactor into an ABC with the bulk of the logic in the subclass seemed to make sense.
Later in the refactor this got yanked out again as unnecessary complexity. The reality is that people wanting to define specialised Response
objects can simply subclass Response
, rather than having an ABC that does nothing much. This makes the mainline use case (vanilla Requests) much cleaner in the code, and takes away almost no utility.
When the BaseRequest
class got pulled out, this line got overlooked, but since it causes no problems there's never been need to remove it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With