Hello community,

here is the log from the commit of package python-swiftclient for 
openSUSE:Factory checked in at 2019-05-03 22:43:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-swiftclient (Old)
 and      /work/SRC/openSUSE:Factory/.python-swiftclient.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-swiftclient"

Fri May  3 22:43:20 2019 rev:26 rq:692880 version:3.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-swiftclient/python-swiftclient.changes    
2018-09-07 15:39:38.198521161 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-swiftclient.new.5148/python-swiftclient.changes
  2019-05-03 22:43:21.907360024 +0200
@@ -1,0 +2,28 @@
+Mon Apr  8 12:33:46 UTC 2019 - [email protected]
+
+- update to version 3.7.0
+  - Stop leaking quite so many connections
+  - authors/changelog updates for release
+  - Switch to stestr
+  - Add .idea into .gitignore
+  - Make py36 unit test job voting
+  - Use template for lower-constraints
+  - Update reno for stable/rocky
+  - Add python 3.6 unit test job
+  - import zuul job settings from project-config
+  - Add release note link in README
+  - Change openstack-dev to openstack-discuss
+  - update .functests to run stestr
+  - Add py37 check/gate jobs; add py37 to default tox env list
+  - Stop lazy importing keystoneclient
+  - add python 3.6 unit test job
+  - Add Python 3.6 classifier to setup.cfg
+  - switch documentation job to new PTI
+  - Add delimiter to get_account().
+  - fix tox python3 overrides
+  - Update release to 3.7.0
+  - Use Swift's in-tree DSVM test
+  - Update hacking version
+  - py2 functional testing
+
+-------------------------------------------------------------------

Old:
----
  python-swiftclient-3.6.0.tar.gz

New:
----
  python-swiftclient-3.7.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-swiftclient.spec ++++++
--- /var/tmp/diff_new_pack.WGUReQ/_old  2019-05-03 22:43:22.531361338 +0200
+++ /var/tmp/diff_new_pack.WGUReQ/_new  2019-05-03 22:43:22.531361338 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-swiftclient
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,32 +12,30 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           python-swiftclient
-Version:        3.6.0
+Version:        3.7.0
 Release:        0
 Summary:        OpenStack Object Storage API Client Library
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://launchpad.net/python-swiftclient
-Source0:        
https://files.pythonhosted.org/packages/source/p/python-swiftclient/python-swiftclient-3.6.0.tar.gz
+Source0:        
https://files.pythonhosted.org/packages/source/p/python-swiftclient/python-swiftclient-3.7.0.tar.gz
 BuildRequires:  openstack-macros
-BuildRequires:  python-devel
 BuildRequires:  python2-keystoneclient
 BuildRequires:  python2-mock
 BuildRequires:  python2-pbr
 BuildRequires:  python2-setuptools
-BuildRequires:  python2-testrepository
+BuildRequires:  python2-stestr
 BuildRequires:  python2-testscenarios
-BuildRequires:  python3-devel
 BuildRequires:  python3-keystoneclient
 BuildRequires:  python3-mock
 BuildRequires:  python3-pbr
 BuildRequires:  python3-setuptools
-BuildRequires:  python3-testrepository
+BuildRequires:  python3-stestr
 BuildRequires:  python3-testscenarios
 Requires:       python-requests >= 1.1.0
 Requires:       python-six >= 1.9.0
@@ -65,7 +63,6 @@
 BuildRequires:  python-Sphinx
 BuildRequires:  python-futures >= 3.0.0
 BuildRequires:  python-openstackdocstheme
-BuildRequires:  python-oslosphinx
 Requires:       %{name} = %{version}
 
 %description -n python-swiftclient-doc
@@ -75,7 +72,7 @@
 This package contains documentation files for %{name}.
 
 %prep
-%autosetup -p1 -n python-swiftclient-3.6.0
+%autosetup -p1 -n python-swiftclient-3.7.0
 %py_req_cleanup
 
 %build
@@ -95,9 +92,7 @@
 %python_uninstall_alternative swift
 
 %check
-%{python_expand rm -rf .testrepository
-$python setup.py testr
-}
+%python_exec -m stestr.cli run
 
 %files %{python_files}
 %license LICENSE

++++++ _service ++++++
--- /var/tmp/diff_new_pack.WGUReQ/_old  2019-05-03 22:43:22.559361397 +0200
+++ /var/tmp/diff_new_pack.WGUReQ/_new  2019-05-03 22:43:22.559361397 +0200
@@ -1,8 +1,8 @@
 <services>
   <service mode="disabled" name="renderspec">
-    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/rocky/openstack/python-swiftclient/python-swiftclient.spec.j2</param>
+    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/stein/openstack/python-swiftclient/python-swiftclient.spec.j2</param>
     <param name="output-name">python-swiftclient.spec</param>
-    <param 
name="requirements">https://raw.githubusercontent.com/openstack/python-swiftclient/stable/rocky/requirements.txt</param>
+    <param 
name="requirements">https://raw.githubusercontent.com/openstack/python-swiftclient/stable/stein/requirements.txt</param>
     <param name="changelog-email">[email protected]</param>
     <param name="changelog-provider">gh,openstack,python-swiftclient</param>
   </service>

++++++ python-swiftclient-3.6.0.tar.gz -> python-swiftclient-3.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/.functests 
new/python-swiftclient-3.7.0/.functests
--- old/python-swiftclient-3.6.0/.functests     2018-07-25 18:19:26.000000000 
+0200
+++ new/python-swiftclient-3.7.0/.functests     2019-03-05 14:10:18.000000000 
+0100
@@ -2,9 +2,13 @@
 set -e
 
 export OS_TEST_PATH='tests.functional'
-python setup.py testr --coverage --testr-args="--concurrency=1"
+export PYTHON='coverage run --source swiftclient --parallel-mode'
+stestr run --concurrency=1
 
 RET=$?
+coverage combine
+coverage html -d cover
+coverage xml -o cover/coverage.xml
 coverage report -m
 rm -f .coverage
 exit $RET
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/.mailmap 
new/python-swiftclient-3.7.0/.mailmap
--- old/python-swiftclient-3.6.0/.mailmap       2018-07-25 18:19:42.000000000 
+0200
+++ new/python-swiftclient-3.7.0/.mailmap       2019-03-05 14:10:18.000000000 
+0100
@@ -95,3 +95,5 @@
 Shashi Kant <[email protected]>
 Nandini Tata <[email protected]> <[email protected]>
 Flavio Percoco <[email protected]>
+Timur Alperovich <[email protected]> <[email protected]>
+Thiago da Silva <[email protected]> <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/.stestr.conf 
new/python-swiftclient-3.7.0/.stestr.conf
--- old/python-swiftclient-3.6.0/.stestr.conf   1970-01-01 01:00:00.000000000 
+0100
+++ new/python-swiftclient-3.7.0/.stestr.conf   2019-03-05 14:10:18.000000000 
+0100
@@ -0,0 +1,4 @@
+[DEFAULT]
+test_path=${OS_TEST_PATH:-./tests/unit}
+top_dir=./
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/.testr.conf 
new/python-swiftclient-3.7.0/.testr.conf
--- old/python-swiftclient-3.6.0/.testr.conf    2018-07-25 18:19:26.000000000 
+0200
+++ new/python-swiftclient-3.7.0/.testr.conf    1970-01-01 01:00:00.000000000 
+0100
@@ -1,4 +0,0 @@
-[DEFAULT]
-test_command=${PYTHON:-python} -m subunit.run discover -t ./ 
${OS_TEST_PATH:-./tests/unit} $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/.zuul.yaml 
new/python-swiftclient-3.7.0/.zuul.yaml
--- old/python-swiftclient-3.6.0/.zuul.yaml     2018-07-25 18:19:26.000000000 
+0200
+++ new/python-swiftclient-3.7.0/.zuul.yaml     2019-03-05 14:10:18.000000000 
+0100
@@ -1,7 +1,59 @@
+- job:
+    name: swiftclient-swift-functional
+    parent: swift-dsvm-functional
+    description: |
+      Run swift's functional tests with python-swiftclient
+      installed from source instead as package from PyPI.
+    # Ensure that we install python-swiftclient from git and
+    # do not install from pypi. This is needed since the parent
+    # job sets zuul_work_dir to the swift directory and uses tox
+    # for installation.
+    required-projects:
+      - git.openstack.org/openstack/python-swiftclient
+
+- job:
+    name: swiftclient-functional
+    parent: swift-dsvm-functional
+    description: |
+      Run functional tests of python-swiftclient with
+      python-swiftclient installed from source instead as package from
+      PyPI.
+    required-projects:
+      - git.openstack.org/openstack/python-swiftclient
+    vars:
+      # Override value from parent job to use swiftclient tests
+      zuul_work_dir: "{{ 
zuul.projects['git.openstack.org/openstack/python-swiftclient'].src_dir }}"
+
+- job:
+    name: swiftclient-functional-py2
+    parent: swiftclient-functional
+    description: |
+      Run functional tests of python-swiftclient under Python 2
+    vars:
+      tox_envlist: py2func
+
 - project:
+    templates:
+      - check-requirements
+      - lib-forward-testing
+      - openstack-lower-constraints-jobs
+      - openstack-pypy-jobs-nonvoting
+      - openstack-python-jobs
+      - openstack-python35-jobs
+      - openstack-python36-jobs
+      - openstack-python37-jobs
+      - publish-openstack-docs-pti
+      - release-notes-jobs-python3
     check:
       jobs:
-        - openstack-tox-lower-constraints
+        - swiftclient-swift-functional
+        - swiftclient-functional
+        - swiftclient-functional-py2
     gate:
       jobs:
-        - openstack-tox-lower-constraints
+        - swiftclient-swift-functional
+        - swiftclient-functional
+        - swiftclient-functional-py2
+    post:
+      jobs:
+        - openstack-tox-cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/AUTHORS 
new/python-swiftclient-3.7.0/AUTHORS
--- old/python-swiftclient-3.6.0/AUTHORS        2018-07-25 18:19:42.000000000 
+0200
+++ new/python-swiftclient-3.7.0/AUTHORS        2019-03-05 14:10:18.000000000 
+0100
@@ -92,6 +92,7 @@
 Nandini Tata ([email protected])
 Nelson Marcos ([email protected])
 Nguyen Hai ([email protected])
+Nguyen Hai Truong ([email protected])
 Nguyen Hung Phuong ([email protected])
 Nick Craig-Wood ([email protected])
 Ondrej Novy ([email protected])
@@ -103,6 +104,7 @@
 Petr Kovar ([email protected])
 Pradeep Kumar Singh ([email protected])
 Pratik Mallya ([email protected])
+qingszhao ([email protected])
 Qiu Yu ([email protected])
 Ray Chen ([email protected])
 ricolin ([email protected])
@@ -124,11 +126,12 @@
 Steve Martinelli ([email protected])
 Steven Hardy ([email protected])
 Stuart McLaren ([email protected])
+sunjia ([email protected])
 Sushil Kumar ([email protected])
 tanlin ([email protected])
 Taurus Cheung ([email protected])
 TheSriram ([email protected])
-Thiago da Silva ([email protected])
+Thiago da Silva ([email protected])
 Thomas Goirand ([email protected])
 Tihomir Trifonov ([email protected])
 Tim Burke ([email protected])
@@ -141,9 +144,11 @@
 venkatamahesh ([email protected])
 Victor Stinner ([email protected])
 Vitaly Gridnev ([email protected])
+Vu Cong Tuan ([email protected])
 wangqi ([email protected])
 wangxiyuan ([email protected])
 Wu Wenxiang ([email protected])
+wu.chunyang ([email protected])
 YangLei ([email protected])
 yangxurong ([email protected])
 You Yamagata ([email protected])
@@ -157,3 +162,5 @@
 zhangyanxian ([email protected])
 zheng yin ([email protected])
 Zhenguo Niu ([email protected])
+ZhijunWei ([email protected])
+zhubx007 ([email protected])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/ChangeLog 
new/python-swiftclient-3.7.0/ChangeLog
--- old/python-swiftclient-3.6.0/ChangeLog      2018-07-25 18:19:42.000000000 
+0200
+++ new/python-swiftclient-3.7.0/ChangeLog      2019-03-05 14:10:22.000000000 
+0100
@@ -1,3 +1,15 @@
+3.7.0
+-----
+
+* Added the delimiter keyword parameter to `get_account()` to match the
+  functionality of `get_container()`.
+
+* Fixed an issue in the client module where socket connections weren't
+  closed properly before being dereferenced.
+
+* Various other minor bug fixes and improvements.
+
+
 3.6.0
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/PKG-INFO 
new/python-swiftclient-3.7.0/PKG-INFO
--- old/python-swiftclient-3.6.0/PKG-INFO       2018-07-25 18:21:42.000000000 
+0200
+++ new/python-swiftclient-3.7.0/PKG-INFO       2019-03-05 14:11:12.000000000 
+0100
@@ -1,10 +1,10 @@
 Metadata-Version: 2.1
 Name: python-swiftclient
-Version: 3.6.0
+Version: 3.7.0
 Summary: OpenStack Object Storage API Client Library
 Home-page: https://docs.openstack.org/python-swiftclient/latest/
 Author: OpenStack
-Author-email: [email protected]
+Author-email: [email protected]
 License: UNKNOWN
 Description: ========================
         Team and repository tags
@@ -45,6 +45,7 @@
         * `Source`_
         * `Specs`_
         * `How to Contribute`_
+        * `Release Notes`_
         
         .. _PyPI: https://pypi.org/project/python-swiftclient
         .. _Online Documentation: 
https://docs.openstack.org/python-swiftclient/latest/
@@ -54,7 +55,7 @@
         .. _Source: https://git.openstack.org/cgit/openstack/python-swiftclient
         .. _How to Contribute: 
https://docs.openstack.org/infra/manual/developers.html
         .. _Specs: https://specs.openstack.org/openstack/swift-specs/
-        
+        .. _Release Notes: 
https://docs.openstack.org/releasenotes/python-swiftclient
         
         .. contents:: Contents:
            :local:
@@ -72,5 +73,7 @@
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.5
-Provides-Extra: keystone
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Provides-Extra: test
+Provides-Extra: keystone
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/README.rst 
new/python-swiftclient-3.7.0/README.rst
--- old/python-swiftclient-3.6.0/README.rst     2018-07-25 18:19:26.000000000 
+0200
+++ new/python-swiftclient-3.7.0/README.rst     2019-03-05 14:10:18.000000000 
+0100
@@ -37,6 +37,7 @@
 * `Source`_
 * `Specs`_
 * `How to Contribute`_
+* `Release Notes`_
 
 .. _PyPI: https://pypi.org/project/python-swiftclient
 .. _Online Documentation: https://docs.openstack.org/python-swiftclient/latest/
@@ -46,7 +47,7 @@
 .. _Source: https://git.openstack.org/cgit/openstack/python-swiftclient
 .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html
 .. _Specs: https://specs.openstack.org/openstack/swift-specs/
-
+.. _Release Notes: https://docs.openstack.org/releasenotes/python-swiftclient
 
 .. contents:: Contents:
    :local:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/RELEASENOTES.rst 
new/python-swiftclient-3.7.0/RELEASENOTES.rst
--- old/python-swiftclient-3.6.0/RELEASENOTES.rst       2018-07-25 
18:21:42.000000000 +0200
+++ new/python-swiftclient-3.7.0/RELEASENOTES.rst       1970-01-01 
01:00:00.000000000 +0100
@@ -1,94 +0,0 @@
-==================
-python-swiftclient
-==================
-
-.. _python-swiftclient_3.6.0:
-
-3.6.0
-=====
-
-.. _python-swiftclient_3.6.0_New Features:
-
-New Features
-------------
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Add the ``--prompt`` option for the CLI which will cause the user to be
-  prompted to enter a password. Any password otherwise specified by
-  ``--key`` , ``--os-password`` or an environment variable will be ignored.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Added bash completion support to the ``swift`` CLI. Enable this by sourcing
-  the included ``tools/swift.bash_completion`` file. Make it permanent by
-  including this file in the system's ``/etc/bash_completion.d`` directory.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Add ability to generate a temporary URL with an IP range restriction.
-  TempURLs with IP restrictions are supported are Swift 2.19.0 or later.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- The client.py SDK now supports a ``query_string`` option on the
-  ``head_object()`` method. This is useful for finding information on
-  SLO/DLO manifests without fetching the entire manifest.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- The client.py SDK now respects ``region_name`` when using sessions.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Added a ``.close()`` method to an object response, allowing clients to give
-  up on reading the rest of the response body, if they so choose.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Fixed a bug where using ``--debug`` in the CLI with unicode account names
-  would cause a client crash.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Make OS_AUTH_URL work in DevStack (for testing) by default.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Dropped Python 3.4 testing.
-
-.. releasenotes/notes/360_notes-1ec385df13a3a735.yaml @ 
172a09a4019dc637e525d14aef76f10e812385dd
-
-- Various other minor bug fixes and improvements.
-
-
-.. _python-swiftclient_3.5.0:
-
-3.5.0
-=====
-
-.. _python-swiftclient_3.5.0_New Features:
-
-New Features
-------------
-
-.. releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml @ 
b91651eba09ed43903c55f24e3a1a52aefeea75f
-
-- Allow for object uploads > 5GB from stdin.
-  
-  When uploading from standard input, swiftclient will turn the upload
-  into an SLO in the case of large objects. By default, input larger
-  than 10MB will be uploaded as an SLO with 10MB segment sizes. Users
-  can also supply the ``--segment-size`` option to alter that
-  threshold and the SLO segment size. One segment is buffered in
-  memory (which is why 10MB default was chosen).
-
-.. releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml @ 
b91651eba09ed43903c55f24e3a1a52aefeea75f
-
-- The ``--meta`` option can now be set on the upload command.
-
-.. releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml @ 
b91651eba09ed43903c55f24e3a1a52aefeea75f
-
-- Updated PyPy test dependency references to be more accurate
-  on different distros.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/lower-constraints.txt 
new/python-swiftclient-3.7.0/lower-constraints.txt
--- old/python-swiftclient-3.6.0/lower-constraints.txt  2018-07-25 
18:19:42.000000000 +0200
+++ new/python-swiftclient-3.7.0/lower-constraints.txt  2019-03-05 
14:10:18.000000000 +0100
@@ -39,7 +39,7 @@
 snowballstemmer==1.2.1
 sphinx==1.6.2
 sphinxcontrib-websupport==1.0.1
-testrepository==0.0.18
+stestr==2.0.0
 testtools==2.2.0
 traceback2==1.4.0
 unittest2==1.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/python_swiftclient.egg-info/PKG-INFO 
new/python-swiftclient-3.7.0/python_swiftclient.egg-info/PKG-INFO
--- old/python-swiftclient-3.6.0/python_swiftclient.egg-info/PKG-INFO   
2018-07-25 18:21:41.000000000 +0200
+++ new/python-swiftclient-3.7.0/python_swiftclient.egg-info/PKG-INFO   
2019-03-05 14:11:12.000000000 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 2.1
 Name: python-swiftclient
-Version: 3.6.0
+Version: 3.7.0
 Summary: OpenStack Object Storage API Client Library
 Home-page: https://docs.openstack.org/python-swiftclient/latest/
 Author: OpenStack
-Author-email: [email protected]
+Author-email: [email protected]
 License: UNKNOWN
 Description: ========================
         Team and repository tags
@@ -45,6 +45,7 @@
         * `Source`_
         * `Specs`_
         * `How to Contribute`_
+        * `Release Notes`_
         
         .. _PyPI: https://pypi.org/project/python-swiftclient
         .. _Online Documentation: 
https://docs.openstack.org/python-swiftclient/latest/
@@ -54,7 +55,7 @@
         .. _Source: https://git.openstack.org/cgit/openstack/python-swiftclient
         .. _How to Contribute: 
https://docs.openstack.org/infra/manual/developers.html
         .. _Specs: https://specs.openstack.org/openstack/swift-specs/
-        
+        .. _Release Notes: 
https://docs.openstack.org/releasenotes/python-swiftclient
         
         .. contents:: Contents:
            :local:
@@ -72,5 +73,7 @@
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.5
-Provides-Extra: keystone
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Provides-Extra: test
+Provides-Extra: keystone
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/python_swiftclient.egg-info/SOURCES.txt 
new/python-swiftclient-3.7.0/python_swiftclient.egg-info/SOURCES.txt
--- old/python-swiftclient-3.6.0/python_swiftclient.egg-info/SOURCES.txt        
2018-07-25 18:21:41.000000000 +0200
+++ new/python-swiftclient-3.7.0/python_swiftclient.egg-info/SOURCES.txt        
2019-03-05 14:11:12.000000000 +0100
@@ -2,7 +2,7 @@
 .functests
 .mailmap
 .manpages
-.testr.conf
+.stestr.conf
 .unittests
 .zuul.yaml
 AUTHORS
@@ -51,6 +51,7 @@
 releasenotes/notes/340_notes-1777780bbfdb4d96.yaml
 releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml
 releasenotes/notes/360_notes-1ec385df13a3a735.yaml
+releasenotes/notes/361_notes-59e020e68bcdd709.yaml
 releasenotes/source/conf.py
 releasenotes/source/current.rst
 releasenotes/source/index.rst
@@ -58,6 +59,7 @@
 releasenotes/source/ocata.rst
 releasenotes/source/pike.rst
 releasenotes/source/queens.rst
+releasenotes/source/rocky.rst
 swiftclient/__init__.py
 swiftclient/authv1.py
 swiftclient/client.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/python_swiftclient.egg-info/pbr.json 
new/python-swiftclient-3.7.0/python_swiftclient.egg-info/pbr.json
--- old/python-swiftclient-3.6.0/python_swiftclient.egg-info/pbr.json   
2018-07-25 18:21:41.000000000 +0200
+++ new/python-swiftclient-3.7.0/python_swiftclient.egg-info/pbr.json   
2019-03-05 14:11:12.000000000 +0100
@@ -1 +1 @@
-{"git_version": "1cf074f", "is_release": true}
\ No newline at end of file
+{"git_version": "991a6ce", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/python_swiftclient.egg-info/requires.txt 
new/python-swiftclient-3.7.0/python_swiftclient.egg-info/requires.txt
--- old/python-swiftclient-3.6.0/python_swiftclient.egg-info/requires.txt       
2018-07-25 18:21:41.000000000 +0200
+++ new/python-swiftclient-3.7.0/python_swiftclient.egg-info/requires.txt       
2019-03-05 14:11:12.000000000 +0100
@@ -1,17 +1,19 @@
-futures>=3.0.0
 requests>=1.1.0
 six>=1.9.0
 
+[:(python_version=='2.7' or python_version=='2.6')]
+futures>=3.0.0
+
 [keystone]
 python-keystoneclient>=0.7.0
 
 [test]
-hacking<0.11,>=0.10.0
+hacking<1.2.0,>=1.1.0
 coverage!=4.4,>=4.0
 keystoneauth1>=3.4.0
 mock>=1.2.0
 oslosphinx>=4.7.0
 sphinx!=1.6.6,!=1.6.7,>=1.6.2
-testrepository>=0.0.18
+stestr>=2.0.0
 reno>=2.5.0
 openstackdocstheme>=1.18.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/releasenotes/notes/361_notes-59e020e68bcdd709.yaml 
new/python-swiftclient-3.7.0/releasenotes/notes/361_notes-59e020e68bcdd709.yaml
--- 
old/python-swiftclient-3.6.0/releasenotes/notes/361_notes-59e020e68bcdd709.yaml 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python-swiftclient-3.7.0/releasenotes/notes/361_notes-59e020e68bcdd709.yaml 
    2019-03-05 14:10:18.000000000 +0100
@@ -0,0 +1,12 @@
+---
+fixes:
+  - |
+    Added the delimiter keyword parameter to ``get_account()`` to match the
+    functionality of ``get_container()``.
+
+  - |
+    Fixed an issue in the client module where socket connections weren't
+    closed properly before being dereferenced.
+
+  - |
+    Various other minor bug fixes and improvements.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/releasenotes/notes/reno.cache 
new/python-swiftclient-3.7.0/releasenotes/notes/reno.cache
--- old/python-swiftclient-3.6.0/releasenotes/notes/reno.cache  2018-07-25 
18:21:42.000000000 +0200
+++ new/python-swiftclient-3.7.0/releasenotes/notes/reno.cache  1970-01-01 
01:00:00.000000000 +0100
@@ -1,74 +0,0 @@
----
-file-contents:
-  releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml:
-    features: ['Allow for object uploads > 5GB from stdin.
-
-
-        When uploading from standard input, swiftclient will turn the upload
-
-        into an SLO in the case of large objects. By default, input larger
-
-        than 10MB will be uploaded as an SLO with 10MB segment sizes. Users
-
-        can also supply the ``--segment-size`` option to alter that
-
-        threshold and the SLO segment size. One segment is buffered in
-
-        memory (which is why 10MB default was chosen).
-
-        ', 'The ``--meta`` option can now be set on the upload command.
-
-        ', 'Updated PyPy test dependency references to be more accurate
-
-        on different distros.
-
-        ']
-  releasenotes/notes/360_notes-1ec385df13a3a735.yaml:
-    features: ['Add the ``--prompt`` option for the CLI which will cause the 
user
-        to be
-
-        prompted to enter a password. Any password otherwise specified by
-
-        ``--key`` , ``--os-password`` or an environment variable will be 
ignored.
-
-        ', 'Added bash completion support to the ``swift`` CLI. Enable this by 
sourcing
-
-        the included ``tools/swift.bash_completion`` file. Make it permanent by
-
-        including this file in the system''s ``/etc/bash_completion.d`` 
directory.
-
-        ', 'Add ability to generate a temporary URL with an IP range 
restriction.
-
-        TempURLs with IP restrictions are supported are Swift 2.19.0 or later.
-
-        ', 'The client.py SDK now supports a ``query_string`` option on the
-
-        ``head_object()`` method. This is useful for finding information on
-
-        SLO/DLO manifests without fetching the entire manifest.
-
-        ', 'The client.py SDK now respects ``region_name`` when using sessions.
-
-        ', 'Added a ``.close()`` method to an object response, allowing 
clients to
-        give
-
-        up on reading the rest of the response body, if they so choose.
-
-        ', 'Fixed a bug where using ``--debug`` in the CLI with unicode 
account names
-
-        would cause a client crash.
-
-        ', 'Make OS_AUTH_URL work in DevStack (for testing) by default.
-
-        ', 'Dropped Python 3.4 testing.
-
-        ', 'Various other minor bug fixes and improvements.
-
-        ']
-notes:
-- files:
-  - [releasenotes/notes/360_notes-1ec385df13a3a735.yaml, 
172a09a4019dc637e525d14aef76f10e812385dd]
-  version: 3.6.0
-- files:
-  - [releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml, 
b91651eba09ed43903c55f24e3a1a52aefeea75f]
-  version: 3.5.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/releasenotes/source/index.rst 
new/python-swiftclient-3.7.0/releasenotes/source/index.rst
--- old/python-swiftclient-3.6.0/releasenotes/source/index.rst  2018-07-25 
18:19:26.000000000 +0200
+++ new/python-swiftclient-3.7.0/releasenotes/source/index.rst  2019-03-05 
14:10:18.000000000 +0100
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    current
+   rocky
    queens
    pike
    ocata
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/releasenotes/source/rocky.rst 
new/python-swiftclient-3.7.0/releasenotes/source/rocky.rst
--- old/python-swiftclient-3.6.0/releasenotes/source/rocky.rst  1970-01-01 
01:00:00.000000000 +0100
+++ new/python-swiftclient-3.7.0/releasenotes/source/rocky.rst  2019-03-05 
14:10:18.000000000 +0100
@@ -0,0 +1,6 @@
+===================================
+ Rocky Series Release Notes
+===================================
+
+.. release-notes::
+   :branch: stable/rocky
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/setup.cfg 
new/python-swiftclient-3.7.0/setup.cfg
--- old/python-swiftclient-3.6.0/setup.cfg      2018-07-25 18:21:42.000000000 
+0200
+++ new/python-swiftclient-3.7.0/setup.cfg      2019-03-05 14:11:12.000000000 
+0100
@@ -4,7 +4,7 @@
 description-file = 
        README.rst
 author = OpenStack
-author-email = [email protected]
+author-email = [email protected]
 home-page = https://docs.openstack.org/python-swiftclient/latest/
 classifier = 
        Environment :: OpenStack
@@ -18,6 +18,8 @@
        Programming Language :: Python :: 2.7
        Programming Language :: Python :: 3
        Programming Language :: Python :: 3.5
+       Programming Language :: Python :: 3.6
+       Programming Language :: Python :: 3.7
 
 [global]
 setup-hooks = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/swiftclient/client.py 
new/python-swiftclient-3.7.0/swiftclient/client.py
--- old/python-swiftclient-3.6.0/swiftclient/client.py  2018-07-25 
18:19:42.000000000 +0200
+++ new/python-swiftclient-3.7.0/swiftclient/client.py  2019-03-05 
14:10:18.000000000 +0100
@@ -60,6 +60,19 @@
         def createLock(self):
             self.lock = None
 
+ksexceptions = ksclient_v2 = ksclient_v3 = None
+try:
+    from keystoneclient import exceptions as ksexceptions
+    # prevent keystoneclient warning us that it has no log handlers
+    logging.getLogger('keystoneclient').addHandler(NullHandler())
+    from keystoneclient.v2_0 import client as ksclient_v2
+except ImportError:
+    pass
+try:
+    from keystoneclient.v3 import client as ksclient_v3
+except ImportError:
+    pass
+
 # requests version 1.2.3 try to encode headers in ascii, preventing
 # utf-8 encoded header to be 'prepared'
 if StrictVersion(requests.__version__) < StrictVersion('2.0.0'):
@@ -235,8 +248,8 @@
         value = encode_utf8(value)
         header = header.lower()
 
-        if (isinstance(header, six.string_types)
-                and header.startswith(USER_METADATA_TYPE)):
+        if (isinstance(header, six.string_types) and
+                header.startswith(USER_METADATA_TYPE)):
             header = encode_utf8(header)
 
         ret[header] = value
@@ -389,6 +402,7 @@
         self.request_session = requests.Session()
         # Don't use requests's default headers
         self.request_session.headers = None
+        self.resp = None
         if self.parsed_url.scheme not in ('http', 'https'):
             raise ClientException('Unsupported scheme "%s" in url "%s"'
                                   % (self.parsed_url.scheme, url))
@@ -493,6 +507,11 @@
 
         return self.resp
 
+    def close(self):
+        if self.resp:
+            self.resp.close()
+        self.request_session.close()
+
 
 def http_connection(*arg, **kwarg):
     """:returns: tuple of (parsed url, connection object)"""
@@ -514,6 +533,8 @@
     conn.request(method, parsed.path, '', headers)
     resp = conn.getresponse()
     body = resp.read()
+    resp.close()
+    conn.close()
     http_log((url, method,), headers, resp, body)
     url = resp.getheader('x-storage-url')
 
@@ -540,25 +561,6 @@
     return get_auth_keystone(auth_url, user, key, os_options, **kwargs)
 
 
-def _import_keystone_client(auth_version):
-    # the attempted imports are encapsulated in this function to allow
-    # mocking for tests
-    try:
-        if auth_version in AUTH_VERSIONS_V3:
-            from keystoneclient.v3 import client as ksclient
-        else:
-            from keystoneclient.v2_0 import client as ksclient
-        from keystoneclient import exceptions
-        # prevent keystoneclient warning us that it has no log handlers
-        logging.getLogger('keystoneclient').addHandler(NullHandler())
-        return ksclient, exceptions
-    except ImportError:
-        raise ClientException('''
-Auth versions 2.0 and 3 require python-keystoneclient, install it or use Auth
-version 1.0 which requires ST_AUTH, ST_USER, and ST_KEY environment
-variables to be set or overridden with -A, -U, or -K.''')
-
-
 def get_auth_keystone(auth_url, user, key, os_options, **kwargs):
     """
     Authenticate against a keystone server.
@@ -587,7 +589,20 @@
     # Legacy default if not set
     if auth_version is None:
         auth_version = '2'
-    ksclient, exceptions = _import_keystone_client(auth_version)
+
+    ksclient = None
+    if auth_version in AUTH_VERSIONS_V3:
+        if ksclient_v3 is not None:
+            ksclient = ksclient_v3
+    else:
+        if ksclient_v2 is not None:
+            ksclient = ksclient_v2
+
+    if ksclient is None:
+        raise ClientException('''
+Auth versions 2.0 and 3 require python-keystoneclient, install it or use Auth
+version 1.0 which requires ST_AUTH, ST_USER, and ST_KEY environment
+variables to be set or overridden with -A, -U, or -K.''')
 
     try:
         _ksclient = ksclient.Client(
@@ -608,13 +623,13 @@
             cert=kwargs.get('cert'),
             key=kwargs.get('cert_key'),
             auth_url=auth_url, insecure=insecure, timeout=timeout)
-    except exceptions.Unauthorized:
+    except ksexceptions.Unauthorized:
         msg = 'Unauthorized. Check username, password and tenant name/id.'
         if auth_version in AUTH_VERSIONS_V3:
             msg = ('Unauthorized. Check username/id, password, '
                    'tenant name/id and user/tenant domain name/id.')
         raise ClientException(msg)
-    except exceptions.AuthorizationFailure as err:
+    except ksexceptions.AuthorizationFailure as err:
         raise ClientException('Authorization Failure. %s' % err)
     service_type = os_options.get('service_type') or 'object-store'
     endpoint_type = os_options.get('endpoint_type') or 'publicURL'
@@ -627,7 +642,7 @@
             service_type=service_type,
             endpoint_type=endpoint_type,
             **filter_kwargs)
-    except exceptions.EndpointNotFound:
+    except ksexceptions.EndpointNotFound:
         raise ClientException('Endpoint for %s not found - '
                               'have you specified a region?' % service_type)
     return endpoint, _ksclient.auth_token
@@ -691,9 +706,9 @@
         if kwargs.get('tenant_name'):
             os_options['tenant_name'] = kwargs['tenant_name']
 
-        if not (os_options.get('tenant_name') or os_options.get('tenant_id')
-                or os_options.get('project_name')
-                or os_options.get('project_id')):
+        if not (os_options.get('tenant_name') or os_options.get('tenant_id') or
+                os_options.get('project_name') or
+                os_options.get('project_id')):
             if auth_version in AUTH_VERSIONS_V2:
                 raise ClientException('No tenant specified')
             raise ClientException('No project name or project id specified.')
@@ -742,7 +757,7 @@
 
 def get_account(url, token, marker=None, limit=None, prefix=None,
                 end_marker=None, http_conn=None, full_listing=False,
-                service_token=None, headers=None):
+                service_token=None, headers=None, delimiter=None):
     """
     Get a listing of containers for the account.
 
@@ -758,6 +773,7 @@
                          of 10000 listings
     :param service_token: service auth token
     :param headers: additional headers to include in the request
+    :param delimiter: delimiter query
     :returns: a tuple of (response headers, a list of containers) The response
               headers will be a dict and all header names will be lowercase.
     :raises ClientException: HTTP GET request failed
@@ -771,14 +787,14 @@
     if not http_conn:
         http_conn = http_connection(url)
     if full_listing:
-        rv = get_account(url, token, marker, limit, prefix,
-                         end_marker, http_conn, headers=req_headers)
+        rv = get_account(url, token, marker, limit, prefix, end_marker,
+                         http_conn, headers=req_headers, delimiter=delimiter)
         listing = rv[1]
         while listing:
             marker = listing[-1]['name']
             listing = get_account(url, token, marker, limit, prefix,
-                                  end_marker, http_conn,
-                                  headers=req_headers)[1]
+                                  end_marker, http_conn, headers=req_headers,
+                                  delimiter=delimiter)[1]
             if listing:
                 rv[1].extend(listing)
         return rv
@@ -790,6 +806,8 @@
         qs += '&limit=%d' % limit
     if prefix:
         qs += '&prefix=%s' % quote(prefix)
+    if delimiter:
+        qs += '&delimiter=%s' % quote(delimiter)
     if end_marker:
         qs += '&end_marker=%s' % quote(end_marker)
     full_path = '%s?%s' % (parsed.path, qs)
@@ -1641,14 +1659,11 @@
         self.force_auth_retry = force_auth_retry
 
     def close(self):
-        if (self.http_conn and isinstance(self.http_conn, tuple)
-                and len(self.http_conn) > 1):
+        if (self.http_conn and isinstance(self.http_conn, tuple) and
+                len(self.http_conn) > 1):
             conn = self.http_conn[1]
-            if hasattr(conn, 'close') and callable(conn.close):
-                # XXX: Our HTTPConnection object has no close, should be
-                # trying to close the requests.Session here?
-                conn.close()
-                self.http_conn = None
+            conn.close()
+            self.http_conn = None
 
     def get_auth(self):
         self.url, self.token = get_auth(self.authurl, self.user, self.key,
@@ -1708,10 +1723,10 @@
             try:
                 if not self.url or not self.token:
                     self.url, self.token = self.get_auth()
-                    self.http_conn = None
+                    self.close()
                 if self.service_auth and not self.service_token:
                     self.url, self.service_token = self.get_service_auth()
-                    self.http_conn = None
+                    self.close()
                 self.auth_end_time = time()
                 if not self.http_conn:
                     self.http_conn = self.http_connection()
@@ -1767,14 +1782,16 @@
         return self._retry(None, head_account, headers=headers)
 
     def get_account(self, marker=None, limit=None, prefix=None,
-                    end_marker=None, full_listing=False, headers=None):
+                    end_marker=None, full_listing=False, headers=None,
+                    delimiter=None):
         """Wrapper for :func:`get_account`"""
         # TODO(unknown): With full_listing=True this will restart the entire
         # listing with each retry. Need to make a better version that just
         # retries where it left off.
         return self._retry(None, get_account, marker=marker, limit=limit,
                            prefix=prefix, end_marker=end_marker,
-                           full_listing=full_listing, headers=headers)
+                           full_listing=full_listing, headers=headers,
+                           delimiter=delimiter)
 
     def post_account(self, headers, response_dict=None,
                      query_string=None, data=None):
@@ -1901,8 +1918,7 @@
         url = url or self.url
         if not url:
             url, _ = self.get_auth()
-        scheme = urlparse(url).scheme
-        netloc = urlparse(url).netloc
-        url = scheme + '://' + netloc + '/info'
-        http_conn = self.http_connection(url)
-        return get_capabilities(http_conn)
+        parsed = urlparse(urljoin(url, '/info'))
+        if not self.http_conn:
+            self.http_conn = self.http_connection(url)
+        return get_capabilities((parsed, self.http_conn[1]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/swiftclient/service.py 
new/python-swiftclient-3.7.0/swiftclient/service.py
--- old/python-swiftclient-3.6.0/swiftclient/service.py 2018-07-25 
18:19:26.000000000 +0200
+++ new/python-swiftclient-3.7.0/swiftclient/service.py 2019-03-05 
14:10:18.000000000 +0100
@@ -424,8 +424,8 @@
                                  '{1} != {2}'.format(
                                      self._path, etag, self._expected_md5))
 
-        if (self._content_length is not None
-                and self._actual_read != self._content_length):
+        if (self._content_length is not None and
+                self._actual_read != self._content_length):
             raise SwiftError('Error downloading {0}: read_length != '
                              'content_length, {1:d} != {2:d}'.format(
                                  self._path, self._actual_read,
@@ -1244,8 +1244,8 @@
                 bytes_read = obj_body.bytes_read()
                 if fp is not None:
                     fp.close()
-                    if ('x-object-meta-mtime' in headers and not no_file
-                            and not options['ignore_mtime']):
+                    if ('x-object-meta-mtime' in headers and not no_file and
+                            not options['ignore_mtime']):
                         try:
                             mtime = float(headers['x-object-meta-mtime'])
                         except ValueError:
@@ -2036,8 +2036,8 @@
             new_slo_manifest_paths = set()
             segment_size = int(0 if options['segment_size'] is None
                                else options['segment_size'])
-            if (options['changed'] or options['skip_identical']
-                    or not options['leave_segments']):
+            if (options['changed'] or options['skip_identical'] or
+                    not options['leave_segments']):
                 try:
                     headers = conn.head_object(container, obj)
                     is_slo = config_true_value(
@@ -2058,9 +2058,9 @@
 
                     cl = int(headers.get('content-length'))
                     mt = headers.get('x-object-meta-mtime')
-                    if (path is not None and options['changed']
-                            and cl == getsize(path)
-                            and mt == put_headers['x-object-meta-mtime']):
+                    if (path is not None and options['changed'] and
+                            cl == getsize(path) and
+                            mt == put_headers['x-object-meta-mtime']):
                         res.update({
                             'success': True,
                             'status': 'skipped-changed'
@@ -2095,8 +2095,8 @@
             # a segment job if we're reading from a stream - we may fail if we
             # go over the single object limit, but this gives us a nice way
             # to create objects from memory
-            if (path is not None and segment_size
-                    and (getsize(path) > segment_size)):
+            if (path is not None and segment_size and
+                    (getsize(path) > segment_size)):
                 res['large_object'] = True
                 seg_container = container + '_segments'
                 if options['segment_container']:
@@ -2425,8 +2425,8 @@
 
                             # Cancel the remaining container deletes, but yield
                             # any pending results
-                            if (not cancelled and options['fail_fast']
-                                    and not res['success']):
+                            if (not cancelled and options['fail_fast'] and
+                                    not res['success']):
                                 cancelled = True
 
     def _bulk_delete_page_size(self, objects):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/swiftclient/shell.py 
new/python-swiftclient-3.7.0/swiftclient/shell.py
--- old/python-swiftclient-3.6.0/swiftclient/shell.py   2018-07-25 
18:19:42.000000000 +0200
+++ new/python-swiftclient-3.7.0/swiftclient/shell.py   2019-03-05 
14:10:18.000000000 +0100
@@ -1462,8 +1462,9 @@
             return
     else:
         fn_commands = [fn for fn in globals().keys()
-                       if fn.startswith('st_') and not fn.endswith('_options')
-                       and not fn.endswith('_help')]
+                       if fn.startswith('st_') and
+                       not fn.endswith('_options') and
+                       not fn.endswith('_help')]
 
     subparsers = parser.add_subparsers()
     subcommands = {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/test-requirements.txt 
new/python-swiftclient-3.7.0/test-requirements.txt
--- old/python-swiftclient-3.6.0/test-requirements.txt  2018-07-25 
18:19:26.000000000 +0200
+++ new/python-swiftclient-3.7.0/test-requirements.txt  2019-03-05 
14:10:18.000000000 +0100
@@ -1,10 +1,10 @@
-hacking<0.11,>=0.10.0
+hacking>=1.1.0,<1.2.0 # Apache-2.0
 
 coverage!=4.4,>=4.0 # Apache-2.0
 keystoneauth1>=3.4.0  # Apache-2.0
 mock>=1.2.0 # BSD
 oslosphinx>=4.7.0  # Apache-2.0
 sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
-testrepository>=0.0.18
+stestr>=2.0.0 # Apache-2.0
 reno>=2.5.0 # Apache-2.0
 openstackdocstheme>=1.18.1 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/tests/functional/test_swiftclient.py 
new/python-swiftclient-3.7.0/tests/functional/test_swiftclient.py
--- old/python-swiftclient-3.6.0/tests/functional/test_swiftclient.py   
2018-07-25 18:19:26.000000000 +0200
+++ new/python-swiftclient-3.7.0/tests/functional/test_swiftclient.py   
2019-03-05 14:10:18.000000000 +0100
@@ -108,6 +108,7 @@
                 self.conn.delete_container(container)
             except swiftclient.ClientException:
                 pass
+        self.conn.close()
 
     def _check_account_headers(self, headers):
         headers_to_check = [
@@ -153,6 +154,18 @@
         self.assertTrue(len(containers) >= 1)
         self.assertEqual(self.containername_2, containers[0].get('name'))
 
+        # Test prefix
+        _, containers = self.conn.get_account(prefix='dne')
+        self.assertEqual(0, len(containers))
+
+        # Test delimiter
+        _, containers = self.conn.get_account(
+            prefix=self.containername, delimiter='_')
+        self.assertEqual(2, len(containers))
+        self.assertEqual(self.containername, containers[0].get('name'))
+        self.assertTrue(
+            self.containername_2.startswith(containers[1].get('subdir')))
+
     def _check_container_headers(self, headers):
         self.assertTrue(headers.get('content-length'))
         self.assertTrue(headers.get('x-container-object-count'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/tests/unit/test_shell.py 
new/python-swiftclient-3.7.0/tests/unit/test_shell.py
--- old/python-swiftclient-3.6.0/tests/unit/test_shell.py       2018-07-25 
18:19:42.000000000 +0200
+++ new/python-swiftclient-3.7.0/tests/unit/test_shell.py       2019-03-05 
14:10:18.000000000 +0100
@@ -37,7 +37,7 @@
 
 from os.path import basename, dirname
 from .utils import (
-    CaptureOutput, fake_get_auth_keystone, _make_fake_import_keystone_client,
+    CaptureOutput, fake_get_auth_keystone,
     FakeKeystone, StubResponse, MockHttpTest)
 from swiftclient.utils import (
     EMPTY_ETAG, EXPIRES_ISO8601_FORMAT,
@@ -1996,8 +1996,8 @@
         self._environ_vars = {}
         keys = list(os.environ.keys())
         for k in keys:
-            if (k in ('ST_KEY', 'ST_USER', 'ST_AUTH')
-                    or k.startswith('OS_')):
+            if (k in ('ST_KEY', 'ST_USER', 'ST_AUTH') or
+                    k.startswith('OS_')):
                 self._environ_vars[k] = os.environ.pop(k)
 
     def _replace_swift_env_vars(self):
@@ -2534,7 +2534,17 @@
                               cmd_args=cmd_args)
         ks_endpoint = 'http://example.com:8080/v1/AUTH_acc'
         ks_token = 'fake_auth_token'
+        # check correct auth version gets used
+        key = 'auth-version'
         fake_ks = FakeKeystone(endpoint=ks_endpoint, token=ks_token)
+        if no_auth:
+            fake_ks2 = fake_ks3 = None
+        elif opts.get(key, self.defaults.get(key)) == '2.0':
+            fake_ks2 = fake_ks
+            fake_ks3 = None
+        else:
+            fake_ks2 = None
+            fake_ks3 = fake_ks
         # fake_conn will check that storage_url and auth_token are as expected
         endpoint = os_opts.get('storage-url', ks_endpoint)
         token = os_opts.get('auth-token', ks_token)
@@ -2542,8 +2552,8 @@
                                               storage_url=endpoint,
                                               auth_token=token)
 
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)), \
+        with mock.patch('swiftclient.client.ksclient_v2', fake_ks2), \
+                mock.patch('swiftclient.client.ksclient_v3', fake_ks3), \
                 mock.patch('swiftclient.client.http_connection', fake_conn), \
                 mock.patch.dict(os.environ, env, clear=True), \
                 patch_disable_warnings() as mock_disable_warnings:
@@ -2562,16 +2572,11 @@
                 self.assertEqual([], mock_disable_warnings.mock_calls)
 
         if no_auth:
-            # check that keystone client was not used and terminate tests
-            self.assertIsNone(getattr(fake_ks, 'auth_version'))
-            self.assertEqual(len(fake_ks.calls), 0)
+            # We patched out both keystoneclient versions to be None;
+            # they *can't* have been used and if we tried to, we would
+            # have raised ClientExceptions
             return
 
-        # check correct auth version was passed to _import_keystone_client
-        key = 'auth-version'
-        expected = opts.get(key, self.defaults.get(key))
-        self.assertEqual(expected, fake_ks.auth_version)
-
         # check args passed to keystone Client __init__
         self.assertEqual(len(fake_ks.calls), 1)
         actual_args = fake_ks.calls[0]
@@ -2942,9 +2947,9 @@
         self.account = 'AUTH_alice'
 
         # keystone returns endpoint for another account
-        fake_ks = FakeKeystone(endpoint='http://example.com:8080/v1/AUTH_bob',
-                               token='bob_token')
-        self.fake_ks_import = _make_fake_import_keystone_client(fake_ks)
+        self.fake_ks = FakeKeystone(
+            endpoint='http://example.com:8080/v1/AUTH_bob',
+            token='bob_token')
 
         self.cont = 'c1'
         self.cont_path = '/v1/%s/%s' % (self.account, self.cont)
@@ -2974,12 +2979,12 @@
             Modify response code to 200 if cross account permissions match.
             """
             status = 403
-            if (path.startswith('/v1/%s/%s' % (self.account, self.cont))
-                    and read_ok and method in ('GET', 'HEAD')):
+            if (path.startswith('/v1/%s/%s' % (self.account, self.cont)) and
+                    read_ok and method in ('GET', 'HEAD')):
                 status = 200
             elif (path.startswith('/v1/%s/%s%s'
-                                  % (self.account, self.cont, self.obj))
-                    and write_ok and method in ('PUT', 'POST', 'DELETE')):
+                                  % (self.account, self.cont, self.obj)) and
+                    write_ok and method in ('PUT', 'POST', 'DELETE')):
                 status = 200
             return status
         return on_request
@@ -3023,8 +3028,7 @@
 
         args, env = self._make_cmd('upload', cmd_args=[self.cont, self.obj,
                                                        '--leave-segments'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3046,8 +3050,7 @@
                                               on_request=req_handler)
         args, env = self._make_cmd('upload', cmd_args=[self.cont, self.obj,
                                                        '--leave-segments'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3073,8 +3076,7 @@
                                              '--segment-size=10',
                                              '--segment-container=%s'
                                              % self.cont])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3112,8 +3114,7 @@
                                    cmd_args=[self.cont, self.obj,
                                              '--leave-segments',
                                              '--segment-size=10'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3149,8 +3150,7 @@
 
         args, env = self._make_cmd('upload', cmd_args=[self.cont, self.obj,
                                                        '--leave-segments'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3207,8 +3207,7 @@
         args, env = self._make_cmd('download', cmd_args=[self.cont,
                                                          self.obj.lstrip('/'),
                                                          '--no-download'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3229,8 +3228,7 @@
         args, env = self._make_cmd('download', cmd_args=[self.cont,
                                                          self.obj.lstrip('/'),
                                                          '--no-download'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3248,8 +3246,7 @@
         args, env = self._make_cmd('download', cmd_args=[self.cont,
                                                          self.obj.lstrip('/'),
                                                          '--no-download'])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3273,8 +3270,7 @@
         fake_conn = self.fake_http_connection(resp, on_request=req_handler)
 
         args, env = self._make_cmd('download', cmd_args=[self.cont])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
@@ -3291,8 +3287,7 @@
         fake_conn = self.fake_http_connection(403)
 
         args, env = self._make_cmd('download', cmd_args=[self.cont])
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        self.fake_ks_import):
+        with mock.patch('swiftclient.client.ksclient_v3', self.fake_ks):
             with mock.patch('swiftclient.client.http_connection', fake_conn):
                 with mock.patch.dict(os.environ, env):
                     with CaptureOutput() as out:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-swiftclient-3.6.0/tests/unit/test_swiftclient.py 
new/python-swiftclient-3.7.0/tests/unit/test_swiftclient.py
--- old/python-swiftclient-3.6.0/tests/unit/test_swiftclient.py 2018-07-25 
18:19:26.000000000 +0200
+++ new/python-swiftclient-3.7.0/tests/unit/test_swiftclient.py 2019-03-05 
14:10:18.000000000 +0100
@@ -29,7 +29,7 @@
 from requests.exceptions import RequestException
 
 from .utils import (MockHttpTest, fake_get_auth_keystone, StubResponse,
-                    FakeKeystone, _make_fake_import_keystone_client)
+                    FakeKeystone)
 
 from swiftclient.utils import EMPTY_ETAG
 from swiftclient.exceptions import ClientException
@@ -322,8 +322,7 @@
         # TestConnection.test_timeout_passed_down but is required to check that
         # get_auth does the right thing when it is not passed a timeout arg
         fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v2', fake_ks):
             c.get_auth('http://www.test.com', 'asdf', 'asdf',
                        os_options=dict(tenant_name='tenant'),
                        auth_version="2.0", timeout=42.0)
@@ -580,8 +579,7 @@
     def test_get_auth_keystone_versionless(self):
         fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
 
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v3', fake_ks):
             c.get_auth_keystone('http://authurl', 'user', 'key', {})
         self.assertEqual(1, len(fake_ks.calls))
         self.assertEqual('http://authurl/v3', fake_ks.calls[0].get('auth_url'))
@@ -589,8 +587,7 @@
     def test_get_auth_keystone_versionless_auth_version_set(self):
         fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
 
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v2', fake_ks):
             c.get_auth_keystone('http://auth_url', 'user', 'key',
                                 {}, auth_version='2.0')
         self.assertEqual(1, len(fake_ks.calls))
@@ -600,8 +597,7 @@
     def test_get_auth_keystone_versionful(self):
         fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
 
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v3', fake_ks):
             c.get_auth_keystone('http://auth_url/v3', 'user', 'key',
                                 {}, auth_version='3')
         self.assertEqual(1, len(fake_ks.calls))
@@ -611,8 +607,7 @@
     def test_get_auth_keystone_devstack_versionful(self):
         fake_ks = FakeKeystone(
             endpoint='http://storage.example.com/v1/AUTH_user', token='secret')
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v3', fake_ks):
             c.get_auth_keystone('https://192.168.8.8/identity/v3',
                                 'user', 'key', {}, auth_version='3')
         self.assertEqual(1, len(fake_ks.calls))
@@ -622,8 +617,7 @@
     def test_get_auth_keystone_devstack_versionless(self):
         fake_ks = FakeKeystone(
             endpoint='http://storage.example.com/v1/AUTH_user', token='secret')
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v3', fake_ks):
             c.get_auth_keystone('https://192.168.8.8/identity',
                                 'user', 'key', {}, auth_version='3')
         self.assertEqual(1, len(fake_ks.calls))
@@ -634,8 +628,7 @@
         fake_ks = FakeKeystone(
             endpoint='http://storage.example.com/v1/AUTH_user',
             token='secret')
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v3', fake_ks):
             c.get_auth_keystone('http://blah.example.com/v2moo',
                                 'user', 'key', {}, auth_version='3')
         self.assertEqual(1, len(fake_ks.calls))
@@ -711,6 +704,18 @@
                 'x-auth-token': 'asdf'}),
         ])
 
+    def test_param_delimiter(self):
+        c.http_connection = self.fake_http_connection(
+            204,
+            query_string="format=json&delimiter=-")
+        c.get_account('http://www.test.com/v1/acct', 'asdf',
+                      delimiter='-')
+        self.assertRequests([
+            ('GET', '/v1/acct?format=json&delimiter=-', '', {
+                'accept-encoding': 'gzip',
+                'x-auth-token': 'asdf'}),
+        ])
+
 
 class TestHeadAccount(MockHttpTest):
 
@@ -2456,8 +2461,7 @@
             'http://auth.example.com', 'user', 'password', timeout=33.0,
             os_options=os_options, auth_version=2.0)
         fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
-        with mock.patch('swiftclient.client._import_keystone_client',
-                        _make_fake_import_keystone_client(fake_ks)):
+        with mock.patch('swiftclient.client.ksclient_v2', fake_ks):
             with mock.patch.multiple('swiftclient.client',
                                      http_connection=shim_connection,
                                      sleep=mock.DEFAULT):
@@ -2540,6 +2544,9 @@
             def read(self, *args, **kwargs):
                 return ''
 
+            def close(self):
+                pass
+
         def local_http_connection(url, proxy=None, cacert=None,
                                   insecure=False, cert=None, cert_key=None,
                                   ssl_compression=True, timeout=None):
@@ -2909,6 +2916,9 @@
         self.assertIsNone(conn.http_conn)
         conn.close()
         self.assertIsNone(conn.http_conn)
+        # Can re-close
+        conn.close()
+        self.assertIsNone(conn.http_conn)
 
     def test_close_ok(self):
         url = 'http://www.test.com'
@@ -2919,7 +2929,7 @@
         self.assertEqual(len(conn.http_conn), 2)
         http_conn_obj = conn.http_conn[1]
         self.assertIsInstance(http_conn_obj, c.HTTPConnection)
-        self.assertFalse(hasattr(http_conn_obj, 'close'))
+        self.assertTrue(hasattr(http_conn_obj, 'close'))
         conn.close()
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/tests/unit/utils.py 
new/python-swiftclient-3.7.0/tests/unit/utils.py
--- old/python-swiftclient-3.6.0/tests/unit/utils.py    2018-07-25 
18:19:26.000000000 +0200
+++ new/python-swiftclient-3.7.0/tests/unit/utils.py    2019-03-05 
14:10:18.000000000 +0100
@@ -78,6 +78,10 @@
         self.body = body
         self.headers = headers or {}
 
+    def __repr__(self):
+        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.status,
+                                   self.body, self.headers)
+
 
 def fake_http_connect(*code_iter, **kwargs):
     """
@@ -102,7 +106,6 @@
             self.etag = etag
             self.content = self.body = body
             self.timestamp = timestamp
-            self._is_closed = True
             self.headers = headers or {}
             self.request = None
 
@@ -162,6 +165,9 @@
         def getheader(self, name, default=None):
             return dict(self.getheaders()).get(name.lower(), default)
 
+        def close(self):
+            pass
+
     timestamps_iter = iter(kwargs.get('timestamps') or ['1'] * len(code_iter))
     etag_iter = iter(kwargs.get('etags') or [None] * len(code_iter))
     x = kwargs.get('missing_container', [False] * len(code_iter))
@@ -228,7 +234,8 @@
                 parsed, _conn = _orig_http_connection(url, proxy=proxy)
 
                 class RequestsWrapper(object):
-                    pass
+                    def close(self):
+                        pass
                 conn = RequestsWrapper()
 
                 def request(method, path, *args, **kwargs):
@@ -542,14 +549,6 @@
         pass
 
 
-def _make_fake_import_keystone_client(fake_import):
-    def _fake_import_keystone_client(auth_version):
-        fake_import.auth_version = auth_version
-        return fake_import, fake_import
-
-    return _fake_import_keystone_client
-
-
 class FakeStream(object):
     def __init__(self, size):
         self.bytes_read = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-swiftclient-3.6.0/tox.ini 
new/python-swiftclient-3.7.0/tox.ini
--- old/python-swiftclient-3.6.0/tox.ini        2018-07-25 18:19:26.000000000 
+0200
+++ new/python-swiftclient-3.7.0/tox.ini        2019-03-05 14:10:18.000000000 
+0100
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27,py35,pypy,pep8
+envlist = py37,py36,py35,py27,pypy,pep8
 minversion = 2.0
 skipsdist = True
 
@@ -8,7 +8,7 @@
 install_command = python -m pip install -U {opts} {packages}
 list_dependencies_command = python -m pip freeze
 setenv =
-  LANG=en_US.utf8
+  LANG=en_US.utf-8
   VIRTUAL_ENV={envdir}
 
 deps = -r{toxinidir}/requirements.txt
@@ -16,33 +16,55 @@
        .[keystone]
 commands = sh -c '(find . -not \( -type d -name .?\* -prune \) \
            \( -type d -name "__pycache__" -or -type f -name "*.py[co]" \) \
-           -print0; find . -name "*.dbm*" -print0) | xargs -0 rm -rf'
-           python setup.py testr --testr-args="{posargs}"
+           -print0) | xargs -0 rm -rf'
+           stestr run {posargs}
 whitelist_externals = sh
 passenv = SWIFT_* *_proxy
 
 [testenv:pep8]
+basepython = python3
 commands =
     python -m flake8 swiftclient tests
 
 [testenv:venv]
+basepython = python3
 commands = {posargs}
 
 [testenv:cover]
-commands = python setup.py testr --coverage
-           coverage report
+basepython = python3
+setenv =
+    PYTHON=coverage run --source swiftclient --parallel-mode
+commands =
+    stestr run
+    coverage combine
+    coverage html -d cover
+    coverage xml -o cover/coverage.xml
+    coverage report
 
 [testenv:func]
-setenv = OS_TEST_PATH=tests.functional
+basepython = python3
+setenv =
+    OS_TEST_PATH=tests.functional
+    PYTHON=coverage run --source swiftclient --parallel-mode
 whitelist_externals =
     coverage
     rm
 commands =
-    python setup.py testr --coverage --testr-args="--concurrency=1"
+    stestr run --concurrency=1
+    coverage combine
+    coverage html -d cover
+    coverage xml -o cover/coverage.xml
     coverage report -m
     rm -f .coverage
 
+[testenv:py2func]
+basepython=python2
+setenv = {[testenv:func]setenv}
+whitelist_externals = {[testenv:func]whitelist_externals}
+commands = {[testenv:func]commands}
+
 [testenv:docs]
+basepython = python3
 commands=
     python setup.py build_sphinx
 
@@ -55,11 +77,12 @@
 # H403: multi line docstrings should end on a new line
 # H404: multi line docstring should start without a leading new line
 # H405: multi line docstring summary not separated with an empty line
-ignore = H101,H301,H306,H401,H403,H404,H405
+ignore = E731,H101,H301,H306,H401,H403,H404,H405
 show-source = True
 exclude = .venv,.tox,dist,doc,*egg
 
 [testenv:bindep]
+basepython = python3
 # Do not install any requirements. We want this to be fast and work even if
 # system dependencies are missing, since it's used to tell you what system
 # dependencies are missing! This also means that bindep must be installed
@@ -69,6 +92,7 @@
 commands = bindep test
 
 [testenv:releasenotes]
+basepython = python3
 commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html 
releasenotes/source releasenotes/build/html
 
 [testenv:lower-constraints]


Reply via email to