/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transport/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2007-07-11 23:45:20 UTC
  • mfrom: (2601 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2643.
  • Revision ID: john@arbash-meinel.com-20070711234520-do3h7zw8skbathpz
[merge] bzr.dev 2601

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
lazy_import(globals(), """
35
35
import errno
36
36
from collections import deque
37
 
from copy import deepcopy
38
37
from stat import S_ISDIR
39
38
import unittest
40
39
import urllib
215
214
                   (other.start, other.length, other.ranges))
216
215
 
217
216
 
 
217
class LateReadError(object):
 
218
    """A helper for transports which pretends to be a readable file.
 
219
 
 
220
    When read() is called, errors.ReadError is raised.
 
221
    """
 
222
 
 
223
    def __init__(self, path):
 
224
        self._path = path
 
225
 
 
226
    def close(self):
 
227
        """a no-op - do nothing."""
 
228
 
 
229
    def _fail(self):
 
230
        """Raise ReadError."""
 
231
        raise errors.ReadError(self._path)
 
232
 
 
233
    def __iter__(self):
 
234
        self._fail()
 
235
 
 
236
    def read(self, count=-1):
 
237
        self._fail()
 
238
 
 
239
    def readlines(self):
 
240
        self._fail()
 
241
 
 
242
 
218
243
class Transport(object):
219
244
    """This class encapsulates methods for retrieving or putting a file
220
245
    from/to a storage location.
292
317
        else:
293
318
            return True
294
319
 
 
320
    def external_url(self):
 
321
        """Return a URL for self that can be given to an external process.
 
322
 
 
323
        There is no guarantee that the URL can be accessed from a different
 
324
        machine - e.g. file:/// urls are only usable on the local machine,
 
325
        sftp:/// urls when the server is only bound to localhost are only
 
326
        usable from localhost etc.
 
327
 
 
328
        NOTE: This method may remove security wrappers (e.g. on chroot
 
329
        transports) and thus should *only* be used when the result will not
 
330
        be used to obtain a new transport within bzrlib. Ideally chroot
 
331
        transports would know enough to cause the external url to be the exact
 
332
        one used that caused the chrooting in the first place, but that is not
 
333
        currently the case.
 
334
 
 
335
        :return: A URL that can be given to another process.
 
336
        :raises InProcessTransport: If the transport is one that cannot be
 
337
            accessed out of the current process (e.g. a MemoryTransport)
 
338
            then InProcessTransport is raised.
 
339
        """
 
340
        raise NotImplementedError(self.external_url)
 
341
 
295
342
    def should_cache(self):
296
343
        """Return True if the data pulled across should be cached locally.
297
344
        """
473
520
    def get(self, relpath):
474
521
        """Get the file at the given relative path.
475
522
 
 
523
        This may fail in a number of ways:
 
524
         - HTTP servers may return content for a directory. (unexpected
 
525
           content failure)
 
526
         - FTP servers may indicate NoSuchFile for a directory.
 
527
         - SFTP servers may give a file handle for a directory that will
 
528
           fail on read().
 
529
 
 
530
        For correct use of the interface, be sure to catch errors.PathError
 
531
        when calling it and catch errors.ReadError when reading from the
 
532
        returned object.
 
533
 
476
534
        :param relpath: The relative path to the file
477
535
        :rtype: File-like object.
478
536
        """
575
633
        :param fudge_factor: All transports have some level of 'it is
576
634
                better to read some more data and throw it away rather 
577
635
                than seek', so collapse if we are 'close enough'
578
 
        :return: yield _CoalescedOffset objects, which have members for wher
 
636
        :return: yield _CoalescedOffset objects, which have members for where
579
637
                to start, how much to read, and how to split those 
580
638
                chunks back up
581
639
        """
1177
1235
        raise NotImplementedError
1178
1236
 
1179
1237
 
1180
 
class TransportTestProviderAdapter(object):
1181
 
    """A tool to generate a suite testing all transports for a single test.
1182
 
 
1183
 
    This is done by copying the test once for each transport and injecting
1184
 
    the transport_class and transport_server classes into each copy. Each copy
1185
 
    is also given a new id() to make it easy to identify.
1186
 
    """
1187
 
 
1188
 
    def adapt(self, test):
1189
 
        result = unittest.TestSuite()
1190
 
        for klass, server_factory in self._test_permutations():
1191
 
            new_test = deepcopy(test)
1192
 
            new_test.transport_class = klass
1193
 
            new_test.transport_server = server_factory
1194
 
            def make_new_test_id():
1195
 
                new_id = "%s(%s)" % (new_test.id(), server_factory.__name__)
1196
 
                return lambda: new_id
1197
 
            new_test.id = make_new_test_id()
1198
 
            result.addTest(new_test)
1199
 
        return result
1200
 
 
1201
 
    def get_transport_test_permutations(self, module):
1202
 
        """Get the permutations module wants to have tested."""
1203
 
        if getattr(module, 'get_test_permutations', None) is None:
1204
 
            warning("transport module %s doesn't provide get_test_permutations()"
1205
 
                    % module.__name__)
1206
 
            return []
1207
 
        return module.get_test_permutations()
1208
 
 
1209
 
    def _test_permutations(self):
1210
 
        """Return a list of the klass, server_factory pairs to test."""
1211
 
        result = []
1212
 
        for module in _get_transport_modules():
1213
 
            try:
1214
 
                result.extend(self.get_transport_test_permutations(reduce(getattr, 
1215
 
                    (module).split('.')[1:],
1216
 
                     __import__(module))))
1217
 
            except errors.DependencyNotPresent, e:
1218
 
                # Continue even if a dependency prevents us 
1219
 
                # from running this test
1220
 
                pass
1221
 
        return result
1222
 
 
1223
 
 
1224
1238
class TransportLogger(object):
1225
1239
    """Adapt a transport to get clear logging data on api calls.
1226
1240
    
1302
1316
#              help="This modifier converts any transport to be readonly."
1303
1317
            )
1304
1318
register_lazy_transport('readonly+', 'bzrlib.transport.readonly', 'ReadonlyTransportDecorator')
 
1319
 
1305
1320
register_transport_proto('fakenfs+')
1306
1321
register_lazy_transport('fakenfs+', 'bzrlib.transport.fakenfs', 'FakeNFSTransportDecorator')
 
1322
 
 
1323
register_transport_proto('brokenrename+')
 
1324
register_lazy_transport('brokenrename+', 'bzrlib.transport.brokenrename',
 
1325
        'BrokenRenameTransportDecorator')
 
1326
 
1307
1327
register_transport_proto('vfat+')
1308
1328
register_lazy_transport('vfat+',
1309
1329
                        'bzrlib.transport.fakevfat',