[wwwsearch-commits] r32397 - wwwsearch/mechanize/trunk/mechanize
jjlee at codespeak.net
jjlee at codespeak.net
Sun Sep 17 00:09:45 CEST 2006
Author: jjlee
Date: Sun Sep 17 00:09:44 2006
New Revision: 32397
Modified:
wwwsearch/mechanize/trunk/mechanize/_mechanize.py
wwwsearch/mechanize/trunk/mechanize/_response.py
Log:
HTTPError didn't support .get_data() or .seek() -- fix that by upgrading it to a closeable_response; Don't treat any non-response HTTPErrors as responses (not sure if any of these '.fp is None' HTTPErrors are actually raised any more, but urllib2.HTTPError's c'tor knows about this case); Apply eager-read workaround to .set_response() (not just .open()); Don't multiple-.seek() wrap
Modified: wwwsearch/mechanize/trunk/mechanize/_mechanize.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_mechanize.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_mechanize.py Sun Sep 17 00:09:44 2006
@@ -155,6 +155,8 @@
response = UserAgent.open(self, self.request, data)
except urllib2.HTTPError, error:
success = False
+ if error.fp is None: # not a response
+ raise
response = error
## except (IOError, socket.error, OSError), error:
## # Yes, urllib2 really does raise all these :-((
@@ -169,16 +171,11 @@
## raise
self.set_response(response)
- # XXX
- # Temporary hack to eagerly read data (otherwise, History can contain
- # closed and partially-read responses). Proper fix is for responses to
- # know if they're partially read or not; .back() should then .reload()
- # if required.
- response.get_data()
+ response = copy.copy(self._response)
if not success:
- raise error
- return copy.copy(self._response)
+ raise response
+ return response
def __str__(self):
text = []
@@ -209,15 +206,15 @@
raise ValueError("not a response object")
self.form = None
+ self._response = _upgrade.upgrade_response(response)
- if not hasattr(response, "seek"):
- response = response_seek_wrapper(response)
- if not hasattr(response, "closeable_response"):
- response = _upgrade.upgrade_response(response)
- else:
- response = copy.copy(response)
+ # XXX
+ # Temporary hack to eagerly read data (otherwise, History can contain
+ # closed and partially-read responses). Proper fix is for responses to
+ # know if they're partially read or not; .back() should then .reload()
+ # if required.
+ self._response.get_data()
- self._response = response
self._factory.set_response(self._response)
def geturl(self):
Modified: wwwsearch/mechanize/trunk/mechanize/_response.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_response.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_response.py Sun Sep 17 00:09:44 2006
@@ -10,6 +10,7 @@
import copy, mimetools
from cStringIO import StringIO
+from urllib2 import HTTPError
# XXX Andrew Dalke kindly sent me a similar class in response to my request on
# comp.lang.python, which I then proceeded to lose. I wrote this class
@@ -218,6 +219,27 @@
self.seek(0)
+class httperror_seek_wrapper(response_seek_wrapper, HTTPError):
+
+ # this only derives from HTTPError in order to be a subclass --
+ # the HTTPError behaviour comes from delegation
+
+ def __init__(self, wrapped):
+ assert isinstance(wrapped, closeable_response), wrapped
+ response_seek_wrapper.__init__(self, wrapped)
+ # be compatible with undocumented HTTPError attributes :-(
+ self.hdrs = wrapped._headers
+ self.filename = wrapped._url
+
+ # we don't want the HTTPError implementation of these
+
+ def geturl(self):
+ return self.wrapped.geturl()
+
+ def close(self):
+ self.wrapped.close()
+
+
class eoffile:
# file-like object that always claims to be at end-of-file...
def read(self, size=-1): return ""
@@ -338,12 +360,27 @@
r = closeable_response(StringIO(data), mime_headers, url, code, msg)
return response_seek_wrapper(r)
+
# Horrible, but needed, at least until fork urllib2. Even then, may want
# to preseve urllib2 compatibility.
def upgrade_response(response):
+ """Return a copy of response that supports mechanize response interface.
+
+ Accepts responses from both mechanize and urllib2 handlers.
+ """
+ if isinstance(response, HTTPError):
+ wrapper_class = httperror_seek_wrapper
+ else:
+ wrapper_class = response_seek_wrapper
+
+ if hasattr(response, "closeable_response"):
+ if not hasattr(response, "seek"):
+ response = wrapper_class(response)
+ return copy.copy(response)
+
# a urllib2 handler constructed the response, i.e. the response is an
- # urllib.addinfourl, instead of a _Util.closeable_response as returned
- # by e.g. mechanize.HTTPHandler
+ # urllib.addinfourl or a urllib2.HTTPError, instead of a
+ # _Util.closeable_response as returned by e.g. mechanize.HTTPHandler
try:
code = response.code
except AttributeError:
@@ -361,7 +398,7 @@
response = closeable_response(
response.fp, response.info(), response.geturl(), code, msg)
- response = response_seek_wrapper(response)
+ response = wrapper_class(response)
if data:
response.set_data(data)
return response
More information about the wwwsearch-commits
mailing list