I need to monkeypatch requests' Response class (version 1.0.4, current as of this question), to add additional methods.
I have this code:
import requests
class Response(requests.models.Response):
def hmm(self):
return 'ok'
requests.models.Response = Response
r = requests.get('http://bbc.co.uk')
print r
It fails when the original Response calls super() - https://github.com/kennethreitz/requests/blob/master/requests/models.py#L391
I think this is because it gets confused, as I have replaced the class, I feel like I'm doing something silly, any ideas? Thanks in advance.
I don’t think you can monkey-patch that type like that. When importing requests
, all these modules are initialized. And as the whole library uses from xy import Request
over and over, it will have an exact reference to the actual type. And only after that, you replace the Response type within the models module, so only subsequent imports are affected.
Unless you go through all the modules and manually replace their Response reference with your new type, they will still use the original one, making your patch useless.
Instead, you should keep the original type but expand it directly, as Martijn suggested.
You'd be better off just adding your function directly to the class:
def hmm(self):
return 'ok'
requests.models.Response.hmm = hmm
This works just fine:
>>> import requests
>>> def hmm(self):
... return 'ok'
...
>>> requests.models.Response.hmm = hmm
>>> r = requests.get('http://bbc.co.uk')
>>> print r
<Response [200]>
>>> r.hmm()
'ok'
>>> requests.__version__
'1.0.4'
Just a quick fix using setattr
, but it's a bit ugly (but semantically equivalent to @Martijn answer):
def hmm(self):
return 'OK - %s' % self.status_code
setattr(requests.models.Response, 'hmm', hmm)
r = requests.get('http://bbc.co.uk')
print r.hmm()
# prints
# OK - 200
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