def testSeekable(self): from mechanize._response import seek_wrapper text = self.text for ii in range(1, 6): fh = TestUnSeekable(text) sfh = seek_wrapper(fh) test = getattr(self, "_test%d" % ii) test(sfh) # copies have independent seek positions fh = TestUnSeekable(text) sfh = seek_wrapper(fh) self._testCopy(sfh)
def test_upgrade_response(self): def is_response(r): names = "get_data read readline readlines close seek code msg".split( ) for name in names: self.assertTrue(hasattr(r, name), 'No attr named: {}'.format(name)) self.assertEqual(r.get_data(), b"test data") from mechanize._response import upgrade_response, make_headers, make_response, closeable_response, seek_wrapper data = b"test data" url = "http://example.com/" code = 200 msg = "OK" # Normal response (closeable_response wrapped with seek_wrapper): return a copy r1 = make_response(data, [], url, code, msg) r2 = upgrade_response(r1) is_response(r2) self.assertIsNot(r1, r2) self.assertIs(r1.wrapped, r2.wrapped) # closeable_response with no seek_wrapper: wrap with seek_wrapper r1 = closeable_response(BytesIO(data), make_headers([]), url, code, msg) self.assertRaises(AssertionError, is_response, r1) r2 = upgrade_response(r1) is_response(r2) self.assertIsNot(r1, r2) self.assertIs(r1, r2.wrapped) # addinfourl: extract .fp and wrap it with closeable_response and seek_wrapper from mechanize.polyglot import addinfourl r1 = addinfourl(BytesIO(data), make_headers([]), url) self.assertRaises(AssertionError, is_response, r1) r2 = upgrade_response(r1) is_response(r2) self.assertIsNot(r1, r2) self.assertIsNot(r1, r2.wrapped) self.assertIs(r1.fp, r2.wrapped.fp) # addinfourl with code, msg r1 = addinfourl(BytesIO(data), make_headers([]), url) r1.code = 206 r1.msg = "cool" r2 = upgrade_response(r1) is_response(r2) self.assertEqual(r2.code, r1.code) self.assertEqual(r2.msg, r1.msg) # addinfourl with seek wrapper: cached data is not lost r1 = addinfourl(BytesIO(data), make_headers([]), url) r1 = seek_wrapper(r1) self.assertEqual(r1.read(4), b'test') r2 = upgrade_response(r1) is_response(r2) # addinfourl wrapped with HTTPError -- remains an HTTPError of the same subclass (through horrible trickery) hdrs = make_headers([]) r1 = addinfourl(BytesIO(data), hdrs, url) class MyHTTPError(mechanize.HTTPError): pass r1 = MyHTTPError(url, code, msg, hdrs, r1) self.assertRaises(AssertionError, is_response, r1) r2 = upgrade_response(r1) is_response(r2) self.assertIsInstance(r2, MyHTTPError) name = MyHTTPError.__module__ + '.' + MyHTTPError.__name__ self.assertTrue( repr(r2).startswith( '<httperror_seek_wrapper ({} instance) at'.format(name))) # The trickery does not cause double-wrapping r3 = upgrade_response(r2) is_response(r3) self.assertIsNot(r3, r2) self.assertIs(r3.wrapped, r2.wrapped) # Test dynamically-created class __repr__ for case where we have the module name r4 = addinfourl(BytesIO(data), hdrs, url) r4 = mechanize.HTTPError(url, code, msg, hdrs, r4) r4 = upgrade_response(r4) q = '<httperror_seek_wrapper (urllib2.HTTPError instance) at' if not mechanize.polyglot.is_py2: q = q.replace('urllib2', 'urllib.error') self.assertTrue(repr(r4).startswith(q))
def get_wrapper(): from mechanize._response import seek_wrapper f = BytesIO(text) wr = seek_wrapper(f) return wr