Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of git://github.com/fabric/fabric

Conflicts:
	docs/changelog.rst
  • Loading branch information...
commit bfcbb2b12b117e2cfda685efeed50572ccc7819e 2 parents c521c7f + e12300b
@jawnb jawnb authored
View
2  docs/changelog.rst
@@ -25,6 +25,8 @@ would have also been included in the 1.2 line.
Changelog
=========
+* :feature:`699` Allow `name` attribute on file-like objects for get/put. Thanks
+ to Peter Lyons for the pull request.
* :bug:`711` `~fabric.sftp.get` would fail when filenames had % in their path.
Thanks to John Begeman
* :bug:`702` `~fabric.operations.require` failed to test for "empty" values in
View
13 fabric/operations.py
@@ -318,6 +318,10 @@ def put(local_path=None, remote_path=None, use_sudo=False,
put('*.py', 'cgi-bin/')
put('index.html', 'index.html', mode=0755)
+ .. note::
+ If a file-like object such as StringIO has a ``name`` attribute, that
+ will be used in Fabric's printed output instead of the default
+ ``<file obj>``
.. versionchanged:: 1.0
Now honors the remote working directory as manipulated by
`~fabric.context_managers.cd`, and the local working directory as
@@ -330,6 +334,8 @@ def put(local_path=None, remote_path=None, use_sudo=False,
.. versionchanged:: 1.0
Return value is now an iterable of uploaded remote file paths which
also exhibits the ``.failed`` and ``.succeeded`` attributes.
+ .. versionchanged:: 1.5
+ Allow a ``name`` attribute on file-like objects for log output
"""
# Handle empty local path
local_path = local_path or os.getcwd()
@@ -490,6 +496,11 @@ def get(remote_path, local_path=None):
transfers. (We hope to patch our SSH layer in the future to enable true
straight-to-memory downloads.)
+ .. note::
+ If a file-like object such as StringIO has a ``name`` attribute, that
+ will be used in Fabric's printed output instead of the default
+ ``<file obj>``
+
.. versionchanged:: 1.0
Now honors the remote working directory as manipulated by
`~fabric.context_managers.cd`, and the local working directory as
@@ -505,6 +516,8 @@ def get(remote_path, local_path=None):
.. versionchanged:: 1.0
Return value is now an iterable of downloaded local file paths, which
also exhibits the ``.failed`` and ``.succeeded`` attributes.
+ .. versionchanged:: 1.5
+ Allow a ``name`` attribute on file-like objects for log output
"""
# Handle empty local path / default kwarg value
local_path = local_path or "%(host)s/%(path)s"
View
14 fabric/sftp.py
@@ -13,6 +13,16 @@
from fabric.context_managers import settings
+def _format_local(local_path, local_is_path):
+ """Format a path for log output"""
+ if local_is_path:
+ return local_path
+ else:
+ # This allows users to set a name attr on their StringIO objects
+ # just like an open file object would have
+ return getattr(local_path, 'name', '<file obj>')
+
+
class SFTP(object):
"""
SFTP helper class, which is also a facade for ssh.SFTPClient.
@@ -129,7 +139,7 @@ def get(self, remote_path, local_path, local_is_path, rremote=None):
if output.running:
print("[%s] download: %s <- %s" % (
env.host_string,
- local_path if local_is_path else "<file obj>",
+ _format_local(local_path, local_is_path),
remote_path
))
# Warn about overwrites, but keep going
@@ -204,7 +214,7 @@ def put(self, local_path, remote_path, use_sudo, mirror_local_mode, mode,
if output.running:
print("[%s] put: %s -> %s" % (
env.host_string,
- local_path if local_is_path else '<file obj>',
+ _format_local(local_path, local_is_path),
posixpath.join(pre, remote_path)
))
# When using sudo, "bounce" the file through a guaranteed-unique file
View
16 tests/test_operations.py
@@ -843,6 +843,22 @@ def test_lcd_should_apply_to_get(self):
get(f, f)
assert self.exists_locally(os.path.join(d, f))
+ @server()
+ @mock_streams('stdout')
+ def test_stringio_without_name(self):
+ file_obj = StringIO(u'test data')
+ put(file_obj, '/')
+ assert re.search('<file obj>', sys.stdout.getvalue())
+
+ @server()
+ @mock_streams('stdout')
+ def test_stringio_with_name(self):
+ """If a file object (StringIO) has a name attribute, use that in output"""
+ file_obj = StringIO(u'test data')
+ file_obj.name = 'Test StringIO Object'
+ put(file_obj, '/')
+ assert re.search(file_obj.name, sys.stdout.getvalue())
+
#
# local()
Please sign in to comment.
Something went wrong with that request. Please try again.