Rev 3737: Don't use multiple inheritance for http smart medium since we in file:///v/home/vila/src/bzr/experimental/bzr-py26-compat/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Sep 25 17:03:24 BST 2008


At file:///v/home/vila/src/bzr/experimental/bzr-py26-compat/

------------------------------------------------------------
revno: 3737
revision-id: v.ladeuil+lp at free.fr-20080925160322-omrugnbgkcwp9eo2
parent: v.ladeuil+lp at free.fr-20080925160234-7o5qhh48re61njn6
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: no-params-for-new-init
timestamp: Thu 2008-09-25 18:03:22 +0200
message:
  Don't use multiple inheritance for http smart medium since we
  can't pass parameters to object.__init__ (and bzr used that trick
  prior to python-2.6 to implement it).
  
  * bzrlib/tests/test_http.py:
  (TestHTTPConnections.test_get_smart_medium): Deleted.
  
  * bzrlib/transport/http/__init__.py:
  (HttpTransportBase): Get rid of multiple inheritance from
  medium.SmartClientMedium.
  (HttpTransportBase.get_smart_medium): Build the medium on demand
  but cache it to avoid probing for smart server repeatedly.
  (SmartClientHTTPMedium): New class. Transfer get_request,
  should_probe and send_http_smart_request from
  HttpTransportBase. Keep a weak reference on the http transport to
  avoid circular references.
  (SmartClientHTTPMedium.send_http_smart_request): Handle the weak
  reference.
  
  * bzrlib/transport/remote.py:
  (RemoteTransport): Doesn't inherit from SmartClientMedium anymore.
  
  * bzrlib/transport/__init__.py:
  (Transport.__init__): Don't pass parameters to object.__init__.
-------------- next part --------------
=== modified file 'bzrlib/tests/test_http.py'
--- a/bzrlib/tests/test_http.py	2008-08-14 02:15:31 +0000
+++ b/bzrlib/tests/test_http.py	2008-09-25 16:03:22 +0000
@@ -449,13 +449,6 @@
             '"GET /foo/bar HTTP/1.1" 200 - "-" "bzr/%s'
             % bzrlib.__version__) > -1)
 
-    def test_get_smart_medium(self):
-        # For HTTP, get_smart_medium should return the transport object.
-        server = self.get_readonly_server()
-        http_transport = self._transport(server.get_url())
-        medium = http_transport.get_smart_medium()
-        self.assertIs(medium, http_transport)
-
     def test_has_on_bogus_host(self):
         # Get a free address and don't 'accept' on it, so that we
         # can be sure there is no http handler there, but set a

=== modified file 'bzrlib/transport/__init__.py'
--- a/bzrlib/transport/__init__.py	2008-09-10 19:14:43 +0000
+++ b/bzrlib/transport/__init__.py	2008-09-25 16:03:22 +0000
@@ -293,7 +293,7 @@
     _bytes_to_read_before_seek = 0
 
     def __init__(self, base):
-        super(Transport, self).__init__(base=base)
+        super(Transport, self).__init__()
         self.base = base
 
     def _translate_error(self, e, path, raise_generic=True):

=== modified file 'bzrlib/transport/http/__init__.py'
--- a/bzrlib/transport/http/__init__.py	2008-09-02 04:34:23 +0000
+++ b/bzrlib/transport/http/__init__.py	2008-09-25 16:03:22 +0000
@@ -25,6 +25,7 @@
 import urlparse
 import urllib
 import sys
+import weakref
 
 from bzrlib import (
     debug,
@@ -79,7 +80,7 @@
     return url
 
 
-class HttpTransportBase(ConnectedTransport, medium.SmartClientMedium):
+class HttpTransportBase(ConnectedTransport):
     """Base class for http implementations.
 
     Does URL parsing, etc, but not any network IO.
@@ -161,16 +162,16 @@
                     path=self._path)
         return auth
 
-    def get_request(self):
-        return SmartClientHTTPMediumRequest(self)
-
     def get_smart_medium(self):
-        """See Transport.get_smart_medium.
+        """See Transport.get_smart_medium."""
+        if self._medium is None:
+            # Since medium holds some state (smart server probing at least), we
+            # need to keep it around. Note that this is needed because medium
+            # has the same 'base' attribute as the transport so it can't be
+            # shared between transports having different bases.
+            self._medium = SmartClientHTTPMedium(self)
+        return self._medium
 
-        HttpTransportBase directly implements the minimal interface of
-        SmartMediumClient, so this returns self.
-        """
-        return self
 
     def _degrade_range_hint(self, relpath, ranges, exc_info):
         if self._range_hint == 'multi':
@@ -515,16 +516,21 @@
 
         return ','.join(strings)
 
-    def send_http_smart_request(self, bytes):
-        try:
-            code, body_filelike = self._post(bytes)
-            if code != 200:
-                raise InvalidHttpResponse(
-                    self._remote_path('.bzr/smart'),
-                    'Expected 200 response code, got %r' % (code,))
-        except errors.InvalidHttpResponse, e:
-            raise errors.SmartProtocolError(str(e))
-        return body_filelike
+
+# TODO: May be better located in smart/medium.py with the other
+# SmartMedium classes
+class SmartClientHTTPMedium(medium.SmartClientMedium):
+
+    def __init__(self, http_transport):
+        super(SmartClientHTTPMedium, self).__init__(http_transport.base)
+        # We don't want to create a circular reference between the http
+        # transport and its associated medium. Since the transport will live
+        # longer than the medium, the medium keep only a weak reference to its
+        # transport.
+        self._http_transport_ref = weakref.ref(http_transport)
+
+    def get_request(self):
+        return SmartClientHTTPMediumRequest(self)
 
     def should_probe(self):
         return True
@@ -538,7 +544,22 @@
         rel_url = urlutils.relative_url(self.base, transport_base)
         return urllib.unquote(rel_url)
 
-
+    def send_http_smart_request(self, bytes):
+        try:
+            # Get back the http_transport hold by the weak reference
+            t = self._http_transport_ref()
+            code, body_filelike = t._post(bytes)
+            if code != 200:
+                raise InvalidHttpResponse(
+                    t._remote_path('.bzr/smart'),
+                    'Expected 200 response code, got %r' % (code,))
+        except errors.InvalidHttpResponse, e:
+            raise errors.SmartProtocolError(str(e))
+        return body_filelike
+
+
+# TODO: May be better located in smart/medium.py with the other
+# SmartMediumRequest classes
 class SmartClientHTTPMediumRequest(medium.SmartClientMediumRequest):
     """A SmartClientMediumRequest that works with an HTTP medium."""
 

=== modified file 'bzrlib/transport/remote.py'
--- a/bzrlib/transport/remote.py	2008-08-29 19:33:35 +0000
+++ b/bzrlib/transport/remote.py	2008-09-25 16:03:22 +0000
@@ -43,7 +43,7 @@
         self.st_mode = mode
 
 
-class RemoteTransport(transport.ConnectedTransport, medium.SmartClientMedium):
+class RemoteTransport(transport.ConnectedTransport):
     """Connection to a smart server.
 
     The connection holds references to the medium that can be used to send



More information about the bazaar-commits mailing list