Rev 2747: * ``bzrlib.transport.Transport.put_file`` now returns the number of bytes in http://people.ubuntu.com/~robertc/baz2.0/transport
Robert Collins
robertc at robertcollins.net
Mon Aug 27 05:20:14 BST 2007
At http://people.ubuntu.com/~robertc/baz2.0/transport
------------------------------------------------------------
revno: 2747
revision-id: robertc at robertcollins.net-20070827041949-br263tkuxayldxoc
parent: robertc at robertcollins.net-20070826221051-46uq33p3oqkscdd0
committer: Robert Collins <robertc at robertcollins.net>
branch nick: transport-get-file
timestamp: Mon 2007-08-27 14:19:49 +1000
message:
* ``bzrlib.transport.Transport.put_file`` now returns the number of bytes
put by the method call, to allow avoiding stat-after write or
housekeeping in callers. (Robert Collins)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
bzrlib/transport/ftp.py ftp.py-20051116161804-58dc9506548c2a53
bzrlib/transport/local.py local_transport.py-20050711165921-9b1f142bfe480c24
bzrlib/transport/memory.py memory.py-20051016101338-cd008dbdf69f04fc
bzrlib/transport/remote.py ssh.py-20060608202016-c25gvf1ob7ypbus6-1
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
=== modified file 'NEWS'
--- a/NEWS 2007-08-26 22:10:51 +0000
+++ b/NEWS 2007-08-27 04:19:49 +0000
@@ -82,6 +82,10 @@
requested data to inserted return larger ranges and in forward read order
to reduce the effect of network latency. (Robert Collins)
+ * ``bzrlib.transport.Transport.put_file`` now returns the number of bytes
+ put by the method call, to allow avoiding stat-after write or
+ housekeeping in callers. (Robert Collins)
+
bzr 0.90 2007-08-??
===================
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2007-08-21 01:32:29 +0000
+++ b/bzrlib/osutils.py 2007-08-27 04:19:49 +0000
@@ -537,13 +537,19 @@
def pumpfile(fromfile, tofile):
- """Copy contents of one file to another."""
+ """Copy contents of one file to another.
+
+ :return: The number of bytes copied.
+ """
BUFSIZE = 32768
+ length = 0
while True:
b = fromfile.read(BUFSIZE)
if not b:
break
tofile.write(b)
+ length += len(b)
+ return length
def file_iterator(input_file, readsize=32768):
=== modified file 'bzrlib/tests/test_transport_implementations.py'
--- a/bzrlib/tests/test_transport_implementations.py 2007-08-26 22:10:51 +0000
+++ b/bzrlib/tests/test_transport_implementations.py 2007-08-27 04:19:49 +0000
@@ -374,11 +374,14 @@
t.put_file, 'a', StringIO('some text for a\n'))
return
- t.put_file('a', StringIO('some text for a\n'))
+ result = t.put_file('a', StringIO('some text for a\n'))
+ # put_file returns the length of the data written
+ self.assertEqual(16, result)
self.failUnless(t.has('a'))
self.check_transport_contents('some text for a\n', t, 'a')
# Put also replaces contents
- t.put_file('a', StringIO('new\ncontents for\na\n'))
+ result = t.put_file('a', StringIO('new\ncontents for\na\n'))
+ self.assertEqual(19, result)
self.check_transport_contents('new\ncontents for\na\n', t, 'a')
self.assertRaises(NoSuchFile,
t.put_file, 'path/doesnt/exist/c',
=== modified file 'bzrlib/transport/__init__.py'
--- a/bzrlib/transport/__init__.py 2007-08-26 22:10:51 +0000
+++ b/bzrlib/transport/__init__.py 2007-08-27 04:19:49 +0000
@@ -406,7 +406,7 @@
"""
assert not isinstance(from_file, basestring), \
'_pump should only be called on files not %s' % (type(from_file,))
- osutils.pumpfile(from_file, to_file)
+ return osutils.pumpfile(from_file, to_file)
def _get_total(self, multi):
"""Try to figure out how many entries are in multi,
@@ -843,6 +843,7 @@
:param f: File-like object.
:param mode: The mode for the newly created file,
None means just use the default.
+ :return: The length of the file that was written.
"""
# We would like to mark this as NotImplemented, but most likely
# transports have defined it in terms of the old api.
=== modified file 'bzrlib/transport/ftp.py'
--- a/bzrlib/transport/ftp.py 2007-08-22 01:41:24 +0000
+++ b/bzrlib/transport/ftp.py 2007-08-27 04:19:49 +0000
@@ -271,14 +271,33 @@
abspath = self._remote_path(relpath)
tmp_abspath = '%s.tmp.%.9f.%d.%d' % (abspath, time.time(),
os.getpid(), random.randint(0,0x7FFFFFFF))
+ bytes = None
if getattr(fp, 'read', None) is None:
- fp = StringIO(fp)
+ # hand in a string IO
+ bytes = fp
+ fp = StringIO(bytes)
+ else:
+ # capture the byte count; .read() may be read only so
+ # decorate it.
+ class byte_counter(object):
+ def __init__(self, fp):
+ self.fp = fp
+ self.counted_bytes = 0
+ def read(self, count):
+ result = self.fp.read(count)
+ self.counted_bytes += len(result)
+ return result
+ fp = byte_counter(fp)
try:
mutter("FTP put: %s", abspath)
f = self._get_FTP()
try:
f.storbinary('STOR '+tmp_abspath, fp)
self._rename_and_overwrite(tmp_abspath, abspath, f)
+ if bytes is not None:
+ return len(bytes)
+ else:
+ return fp.counted_bytes
except (ftplib.error_temp,EOFError), e:
warning("Failure during ftp PUT. Deleting temporary file.")
try:
=== modified file 'bzrlib/transport/local.py'
--- a/bzrlib/transport/local.py 2007-08-22 01:41:24 +0000
+++ b/bzrlib/transport/local.py 2007-08-27 04:19:49 +0000
@@ -164,10 +164,11 @@
except (IOError, OSError),e:
self._translate_error(e, path)
try:
- self._pump(f, fp)
+ length = self._pump(f, fp)
fp.commit()
finally:
fp.close()
+ return length
def put_bytes(self, relpath, bytes, mode=None):
"""Copy the string into the location.
=== modified file 'bzrlib/transport/memory.py'
--- a/bzrlib/transport/memory.py 2007-08-15 06:53:07 +0000
+++ b/bzrlib/transport/memory.py 2007-08-27 04:19:49 +0000
@@ -158,6 +158,7 @@
'undefined', bytes, 0, 1,
'put_file must be given a file of bytes, not unicode.')
self._files[_abspath] = (bytes, mode)
+ return len(bytes)
def mkdir(self, relpath, mode=None):
"""See Transport.mkdir()."""
=== modified file 'bzrlib/transport/remote.py'
--- a/bzrlib/transport/remote.py 2007-08-26 22:10:51 +0000
+++ b/bzrlib/transport/remote.py 2007-08-27 04:19:49 +0000
@@ -234,6 +234,7 @@
(self._remote_path(relpath), self._serialise_optional_mode(mode)),
upload_contents)
self._translate_error(resp)
+ return len(upload_contents)
def put_bytes_non_atomic(self, relpath, bytes, mode=None,
create_parent_dir=False,
=== modified file 'bzrlib/transport/sftp.py'
--- a/bzrlib/transport/sftp.py 2007-08-26 22:10:51 +0000
+++ b/bzrlib/transport/sftp.py 2007-08-27 04:19:49 +0000
@@ -386,7 +386,7 @@
:param mode: The final mode for the file
"""
final_path = self._remote_path(relpath)
- self._put(final_path, f, mode=mode)
+ return self._put(final_path, f, mode=mode)
def _put(self, abspath, f, mode=None):
"""Helper function so both put() and copy_abspaths can reuse the code"""
@@ -397,7 +397,7 @@
try:
try:
fout.set_pipelined(True)
- self._pump(f, fout)
+ length = self._pump(f, fout)
except (IOError, paramiko.SSHException), e:
self._translate_io_exception(e, tmp_abspath)
# XXX: This doesn't truly help like we would like it to.
@@ -418,6 +418,7 @@
fout.close()
closed = True
self._rename_and_overwrite(tmp_abspath, abspath)
+ return length
except Exception, e:
# If we fail, try to clean up the temporary file
# before we throw the exception
More information about the bazaar-commits
mailing list