summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--setup.cfg1
-rw-r--r--swiftclient/service.py2
-rwxr-xr-xswiftclient/shell.py56
-rw-r--r--tests/unit/test_service.py16
-rw-r--r--tests/unit/test_shell.py2
-rw-r--r--tox.ini6
7 files changed, 73 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 00899eb..f5e0a60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,7 @@
-2.8.0
+3.0.0
-----
-* Python 2.6 support has been removed. Also, Python 3.3 gate testing has
- been removed. Support for Python 3.3 is only best-effort. Currently
+* Python 2.6 and Python 3.3 support has been removed. Currently
supported and tested versions of Python are Python 2.7 and Python 3.4.
* Do not reveal sensitive headers in swiftclient log messages by default.
diff --git a/setup.cfg b/setup.cfg
index d745957..4c48a65 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -17,7 +17,6 @@ classifier =
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
- Programming Language :: Python :: 3.3
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
diff --git a/swiftclient/service.py b/swiftclient/service.py
index 5fa2870..f253ec8 100644
--- a/swiftclient/service.py
+++ b/swiftclient/service.py
@@ -1004,7 +1004,7 @@ class SwiftService(object):
raise
raise SwiftError('Account not found', exc=err)
- elif not objects:
+ elif objects is None:
if '/' in container:
raise SwiftError('\'/\' in container name',
container=container)
diff --git a/swiftclient/shell.py b/swiftclient/shell.py
index 68b9344..4ba71b4 100755
--- a/swiftclient/shell.py
+++ b/swiftclient/shell.py
@@ -94,11 +94,11 @@ def st_delete(parser, args, output_manager):
parser.add_option(
'', '--object-threads', type=int,
default=10, help='Number of threads to use for deleting objects. '
- 'Default is 10.')
+ 'Its value must be a positive integer. Default is 10.')
parser.add_option(
'', '--container-threads', type=int,
default=10, help='Number of threads to use for deleting containers. '
- 'Default is 10.')
+ 'Its value must be a positive integer. Default is 10.')
(options, args) = parse_args(parser, args)
args = args[1:]
if (not args and not options.yes_all) or (args and options.yes_all):
@@ -107,6 +107,22 @@ def st_delete(parser, args, output_manager):
st_delete_help)
return
+ if options.object_threads <= 0:
+ output_manager.error(
+ 'ERROR: option --object-threads should be a positive integer.'
+ '\n\nUsage: %s delete %s\n%s',
+ BASENAME, st_delete_options,
+ st_delete_help)
+ return
+
+ if options.container_threads <= 0:
+ output_manager.error(
+ 'ERROR: option --container-threads should be a positive integer.'
+ '\n\nUsage: %s delete %s\n%s',
+ BASENAME, st_delete_options,
+ st_delete_help)
+ return
+
_opts = vars(options)
_opts['object_dd_threads'] = options.object_threads
with SwiftService(options=_opts) as swift:
@@ -274,11 +290,11 @@ def st_download(parser, args, output_manager):
parser.add_option(
'', '--object-threads', type=int,
default=10, help='Number of threads to use for downloading objects. '
- 'Default is 10.')
+ 'Its value must be a positive integer. Default is 10.')
parser.add_option(
'', '--container-threads', type=int, default=10,
help='Number of threads to use for downloading containers. '
- 'Default is 10.')
+ 'Its value must be a positive integer. Default is 10.')
parser.add_option(
'', '--no-download', action='store_true',
default=False,
@@ -320,6 +336,20 @@ def st_download(parser, args, output_manager):
st_download_options, st_download_help)
return
+ if options.object_threads <= 0:
+ output_manager.error(
+ 'ERROR: option --object-threads should be a positive integer.\n\n'
+ 'Usage: %s download %s\n%s', BASENAME,
+ st_download_options, st_download_help)
+ return
+
+ if options.container_threads <= 0:
+ output_manager.error(
+ 'ERROR: option --container-threads should be a positive integer.'
+ '\n\nUsage: %s download %s\n%s', BASENAME,
+ st_download_options, st_download_help)
+ return
+
_opts = vars(options)
_opts['object_dd_threads'] = options.object_threads
with SwiftService(options=_opts) as swift:
@@ -805,11 +835,11 @@ def st_upload(parser, args, output_manager):
parser.add_option(
'', '--object-threads', type=int, default=10,
help='Number of threads to use for uploading full objects. '
- 'Default is 10.')
+ 'Its value must be a positive integer. Default is 10.')
parser.add_option(
'', '--segment-threads', type=int, default=10,
help='Number of threads to use for uploading object segments. '
- 'Default is 10.')
+ 'Its value must be a positive integer. Default is 10.')
parser.add_option(
'-H', '--header', action='append', dest='header',
default=[], help='Set request headers with the syntax header:value. '
@@ -862,6 +892,20 @@ def st_upload(parser, args, output_manager):
output_manager.error("segment-size should be positive")
return
+ if options.object_threads <= 0:
+ output_manager.error(
+ 'ERROR: option --object-threads should be a positive integer.'
+ '\n\nUsage: %s upload %s\n%s', BASENAME, st_upload_options,
+ st_upload_help)
+ return
+
+ if options.segment_threads <= 0:
+ output_manager.error(
+ 'ERROR: option --segment-threads should be a positive integer.'
+ '\n\nUsage: %s upload %s\n%s', BASENAME, st_upload_options,
+ st_upload_help)
+ return
+
_opts = vars(options)
_opts['object_uu_threads'] = options.object_threads
with SwiftService(options=_opts) as swift:
diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py
index 997d992..418ee85 100644
--- a/tests/unit/test_service.py
+++ b/tests/unit/test_service.py
@@ -1672,6 +1672,22 @@ class TestServiceDownload(_TestServiceBase):
self.assertEqual(resp['object'], 'test')
self.assertEqual(resp['path'], 'test')
+ @mock.patch('swiftclient.service.interruptable_as_completed')
+ @mock.patch('swiftclient.service.SwiftService._download_container')
+ @mock.patch('swiftclient.service.SwiftService._download_object_job')
+ def test_download_with_objects_empty(self, mock_down_obj,
+ mock_down_cont, mock_as_comp):
+ fake_future = Future()
+ fake_future.set_result(1)
+ mock_as_comp.return_value = [fake_future]
+ service = SwiftService()
+ next(service.download('c', [], self.opts), None)
+ mock_down_obj.assert_not_called()
+ mock_down_cont.assert_not_called()
+
+ next(service.download('c', options=self.opts), None)
+ self.assertEqual(True, mock_down_cont.called)
+
def test_download_with_output_dir(self):
service = SwiftService()
with mock.patch('swiftclient.service.Connection') as mock_conn:
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
index 3ea9336..36c1593 100644
--- a/tests/unit/test_shell.py
+++ b/tests/unit/test_shell.py
@@ -688,10 +688,10 @@ class TestShell(unittest.TestCase):
[None, []]
]
connection.return_value.put_object.return_value = EMPTY_ETAG
- swiftclient.shell.main(argv)
# create the delete_object child mock here in attempt to fix
# https://bugs.launchpad.net/python-swiftclient/+bug/1480223
connection.return_value.delete_object.return_value = None
+ swiftclient.shell.main(argv)
connection.return_value.put_object.assert_called_with(
'container',
self.tmpfile.lstrip('/'),
diff --git a/tox.ini b/tox.ini
index cc68d31..717128b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py27,py33,py34,py35,pypy,pep8
+envlist = py27,py34,py35,pypy,pep8
minversion = 1.6
skipsdist = True
@@ -12,9 +12,9 @@ setenv =
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-commands = sh -c 'find . -not \( -type d -name .?\* -prune \) \
+commands = sh -c '(find . -not \( -type d -name .?\* -prune \) \
\( -type d -name "__pycache__" -or -type f -name "*.py[co]" \) \
- -print0 | xargs -0 rm -rf'
+ -print0; find . -name "*.dbm*" -print0) | xargs -0 rm -rf'
python setup.py testr --testr-args="{posargs}"
whitelist_externals = sh
passenv = SWIFT_* *_proxy