Hello community,

here is the log from the commit of package python-twine for openSUSE:Factory 
checked in at 2019-03-18 10:37:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-twine (Old)
 and      /work/SRC/openSUSE:Factory/.python-twine.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-twine"

Mon Mar 18 10:37:34 2019 rev:6 rq:680764 version:1.13.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-twine/python-twine.changes        
2019-02-13 10:00:16.965637102 +0100
+++ /work/SRC/openSUSE:Factory/.python-twine.new.28833/python-twine.changes     
2019-03-18 10:37:45.383499576 +0100
@@ -1,0 +2,29 @@
+Sat Mar  2 04:53:11 UTC 2019 - Arun Persaud <[email protected]>
+
+- specfile:
+  * be more specific in %files section
+  * remove patch fix-keyring-support.patch, included upstream
+
+- update to version 1.13.0:
+  * bug`452` Restore prompts while retaining support for suppressing
+    prompts.
+  * bug`447` Avoid requests-toolbelt to 0.9.0 to prevent attempting to
+    use openssl when it isn't available.
+  * :feature:`427` Add disable_progress_bar option to disable tqdm.
+  * :feature:`426` Allow defining an empty username and password in
+    .pypirc.
+  * bug`441` Only install pyblake2 if needed.
+  * bug`444` Use io.StringIO instead of StringIO.
+  * bug`436` Use modern Python language features.
+  * :support:`439` Refactor tox env and travis config.
+  * bug`435` Specify python_requires in setup.py
+  * bug`432` Use https URLs everywhere.
+  * bug`428` Fix --skip-existing for Nexus Repos.
+  * :feature:`419` Support keyring.get_credential.
+  * :feature:`418` Support keyring.get_username_and_password.
+  * bug`421` Remove unnecessary usage of readme_render.markdown.
+  * :feature:" Add Python 3.7 to classifiers.
+  * bug`412` Don't crash if there's no package description.
+  * bug`408` Fix keyring support.
+
+-------------------------------------------------------------------

Old:
----
  fix-keyring-support.patch
  twine-1.12.1.tar.gz

New:
----
  twine-1.13.0.tar.gz

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

Other differences:
------------------
++++++ python-twine.spec ++++++
--- /var/tmp/diff_new_pack.PJt0q6/_old  2019-03-18 10:37:51.455498259 +0100
+++ /var/tmp/diff_new_pack.PJt0q6/_new  2019-03-18 10:37:51.459498258 +0100
@@ -18,15 +18,13 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-twine
-Version:        1.12.1
+Version:        1.13.0
 Release:        0
 Summary:        Collection of utilities for interacting with PyPI
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://github.com/pypa/twine
 Source:         
https://files.pythonhosted.org/packages/source/t/twine/twine-%{version}.tar.gz
-# gh#pypa/twine#408
-Patch0:         fix-keyring-support.patch
 BuildRequires:  %{python_module pkginfo >= 1.4.2}
 BuildRequires:  %{python_module pretend}
 BuildRequires:  %{python_module pytest}
@@ -61,7 +59,6 @@
 
 %prep
 %setup -q -n twine-%{version}
-%autopatch -p1
 
 sed -i '1s/^#!.*//' twine/__main__.py
 
@@ -85,7 +82,10 @@
 %files %{python_files}
 %doc AUTHORS README.rst
 %license LICENSE
-%{python_sitelib}/*
+%dir %{python_sitelib}/twine
+%dir %{python_sitelib}/twine-%{version}-py*.egg-info
+%{python_sitelib}/twine/*
+%{python_sitelib}/twine-%{version}-py*.egg-info/*
 %python_alternative %{_bindir}/twine
 
 %changelog

++++++ twine-1.12.1.tar.gz -> twine-1.13.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/AUTHORS new/twine-1.13.0/AUTHORS
--- old/twine-1.12.1/AUTHORS    2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/AUTHORS    2019-02-13 21:35:39.000000000 +0100
@@ -18,8 +18,9 @@
 Anna Martelli Ravenscroft <[email protected]>
 Sumana Harihareswara <[email protected]>
 Dustin Ingram <[email protected]> (https://di.codes)
-Jesse Jarzynka <[email protected]> (http://jessejoe.com)
+Jesse Jarzynka <[email protected]> (https://www.jessejoe.com/)
 László Kiss Kollár <[email protected]>
 Frances Hocutt <[email protected]>
 Tathagata Dasgupta <[email protected]>
-Wasim Thabraze <[email protected]>
\ No newline at end of file
+Wasim Thabraze <[email protected]>
+Varun Kamath <[email protected]>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/LICENSE new/twine-1.13.0/LICENSE
--- old/twine-1.12.1/LICENSE    2017-01-19 15:23:11.000000000 +0100
+++ new/twine-1.13.0/LICENSE    2019-02-13 21:35:39.000000000 +0100
@@ -1,6 +1,6 @@
                               Apache License
                         Version 2.0, January 2004
-                     http://www.apache.org/licenses/
+                     https://www.apache.org/licenses/
 
 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/PKG-INFO new/twine-1.13.0/PKG-INFO
--- old/twine-1.12.1/PKG-INFO   2018-09-24 20:41:42.000000000 +0200
+++ new/twine-1.13.0/PKG-INFO   2019-02-13 22:38:54.000000000 +0100
@@ -1,15 +1,19 @@
 Metadata-Version: 2.1
 Name: twine
-Version: 1.12.1
+Version: 1.13.0
 Summary: Collection of utilities for publishing packages on PyPI
 Home-page: https://twine.readthedocs.io/
 Author: Donald Stufft and individual contributors
 Author-email: [email protected]
 License: Apache License, Version 2.0
-Project-URL: Twine source, https://github.com/pypa/twine/
 Project-URL: Packaging tutorial, 
https://packaging.python.org/tutorials/distributing-packages/
+Project-URL: Travis CI, https://travis-ci.org/pypa/twine
 Project-URL: Twine documentation, https://twine.readthedocs.io/en/latest/
-Description: twine
+Project-URL: Twine source, https://github.com/pypa/twine/
+Description: .. image:: 
https://img.shields.io/travis/pypa/twine/master.svg?label=travis-ci
+           :target: https://travis-ci.org/pypa/twine
+        
+        twine
         =====
         
         .. rtd-inclusion-marker-do-not-remove
@@ -148,7 +152,7 @@
         Disabling Keyring
         ^^^^^^^^^^^^^^^^^
         
-        In some cases, the presence of keyring may be problemmatic. To disable
+        In some cases, the presence of keyring may be problematic. To disable
         keyring and defer to a prompt for passwords, uninstall ``keyring``
         or if that's not an option, you can also configure keyring to be 
disabled.
         
@@ -171,6 +175,7 @@
                                 [-s] [--sign-with SIGN_WITH] [-i IDENTITY] [-u 
USERNAME]
                                 [-p PASSWORD] [-c COMMENT] [--config-file 
CONFIG_FILE]
                                 [--skip-existing] [--cert path] [--client-cert 
path]
+                                [--verbose] [--disable-progress-bar]
                                 dist [dist ...]
         
             positional arguments:
@@ -215,6 +220,9 @@
               --client-cert path    Path to SSL client certificate, a single 
file
                                     containing the private key and the 
certificate in PEM
                                     format.
+              --verbose             Show verbose output.
+              --disable-progress-bar
+                                    Disable the progress bar.
         
         ``twine check``
         ^^^^^^^^^^^^^^^
@@ -357,7 +365,9 @@
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
-Provides-Extra: keyring
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
 Provides-Extra: with-blake2
+Provides-Extra: keyring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/README.rst new/twine-1.13.0/README.rst
--- old/twine-1.12.1/README.rst 2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/README.rst 2019-02-13 21:35:39.000000000 +0100
@@ -1,3 +1,6 @@
+.. image:: https://img.shields.io/travis/pypa/twine/master.svg?label=travis-ci
+   :target: https://travis-ci.org/pypa/twine
+
 twine
 =====
 
@@ -137,7 +140,7 @@
 Disabling Keyring
 ^^^^^^^^^^^^^^^^^
 
-In some cases, the presence of keyring may be problemmatic. To disable
+In some cases, the presence of keyring may be problematic. To disable
 keyring and defer to a prompt for passwords, uninstall ``keyring``
 or if that's not an option, you can also configure keyring to be disabled.
 
@@ -160,6 +163,7 @@
                         [-s] [--sign-with SIGN_WITH] [-i IDENTITY] [-u 
USERNAME]
                         [-p PASSWORD] [-c COMMENT] [--config-file CONFIG_FILE]
                         [--skip-existing] [--cert path] [--client-cert path]
+                        [--verbose] [--disable-progress-bar]
                         dist [dist ...]
 
     positional arguments:
@@ -204,6 +208,9 @@
       --client-cert path    Path to SSL client certificate, a single file
                             containing the private key and the certificate in 
PEM
                             format.
+      --verbose             Show verbose output.
+      --disable-progress-bar
+                            Disable the progress bar.
 
 ``twine check``
 ^^^^^^^^^^^^^^^
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/docs/changelog.rst 
new/twine-1.13.0/docs/changelog.rst
--- old/twine-1.12.1/docs/changelog.rst 2018-09-24 20:40:31.000000000 +0200
+++ new/twine-1.13.0/docs/changelog.rst 2019-02-13 22:37:01.000000000 +0100
@@ -3,7 +3,25 @@
 =========
 Changelog
 =========
-
+* :release:`1.13.0 <2019-02-13>`
+* :bug:`452` Restore prompts while retaining support for suppressing prompts.
+* :bug:`447` Avoid requests-toolbelt to 0.9.0 to prevent attempting to use
+  openssl when it isn't available.
+* :feature:`427` Add disable_progress_bar option to disable tqdm.
+* :feature:`426` Allow defining an empty username and password in .pypirc.
+* :bug:`441` Only install pyblake2 if needed.
+* :bug:`444` Use io.StringIO instead of StringIO.
+* :bug:`436` Use modern Python language features.
+* :support:`439` Refactor tox env and travis config.
+* :bug:`435` Specify python_requires in setup.py
+* :bug:`432` Use https URLs everywhere.
+* :bug:`428` Fix --skip-existing for Nexus Repos.
+* :feature:`419` Support keyring.get_credential.
+* :feature:`418` Support keyring.get_username_and_password.
+* :bug:`421` Remove unnecessary usage of readme_render.markdown.
+* :feature:`` Add Python 3.7 to classifiers.
+* :bug:`412` Don't crash if there's no package description.
+* :bug:`408` Fix keyring support.
 * :release:`1.12.1 <2018-09-24>`
 * :bug:`404` Fix regression with upload exit code
 * :release:`1.12.0 <2018-09-24>`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/setup.cfg new/twine-1.13.0/setup.cfg
--- old/twine-1.12.1/setup.cfg  2018-09-24 20:41:42.000000000 +0200
+++ new/twine-1.13.0/setup.cfg  2019-02-13 22:38:54.000000000 +0100
@@ -10,14 +10,6 @@
 
 [metadata]
 license_file = LICENSE
-requires-dist = 
-       tqdm >= 4.14
-       requests >= 2.5.0, != 2.15, != 2.16
-       requests-toolbelt >= 0.8.0
-       pkginfo >= 1.4.2
-       setuptools >= 0.7.0
-       pyblake2; extra == 'with-blake2' and python_version < '3.6'
-       keyring; extra == 'keyring'
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/setup.py new/twine-1.13.0/setup.py
--- old/twine-1.12.1/setup.py   2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/setup.py   2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,19 +13,9 @@
 # limitations under the License.
 from setuptools import setup
 
-import sys
-
 import twine
 
 
-blake2_requires = []
-
-if sys.version_info[:2] < (3, 6):
-    blake2_requires += [
-        "pyblake2",
-    ]
-
-
 setup(
     name=twine.__title__,
     version=twine.__version__,
@@ -36,6 +26,7 @@
     url=twine.__uri__,
     project_urls={
         'Packaging tutorial': 
'https://packaging.python.org/tutorials/distributing-packages/',
+        'Travis CI': 'https://travis-ci.org/pypa/twine',
         'Twine documentation': 'https://twine.readthedocs.io/en/latest/',
         'Twine source': 'https://github.com/pypa/twine/',
     },
@@ -59,6 +50,7 @@
         "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
     ],
@@ -76,16 +68,19 @@
         ],
     },
 
+    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
     install_requires=[
         "pkginfo >= 1.4.2",
         "readme_renderer >= 21.0",
         "requests >= 2.5.0, != 2.15, != 2.16",
-        "requests-toolbelt >= 0.8.0",
+        "requests-toolbelt >= 0.8.0, != 0.9.0",
         "setuptools >= 0.7.0",
         "tqdm >= 4.14",
     ],
     extras_require={
-        'with-blake2': blake2_requires,
+        'with-blake2': [
+            'pyblake2; python_version<"3.6" and 
platform_python_implementation=="CPython"',
+        ],
         'keyring': [
             'keyring',
         ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/helpers.py 
new/twine-1.13.0/tests/helpers.py
--- old/twine-1.12.1/tests/helpers.py   2017-01-19 15:23:11.000000000 +0100
+++ new/twine-1.13.0/tests/helpers.py   2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_check.py 
new/twine-1.13.0/tests/test_check.py
--- old/twine-1.12.1/tests/test_check.py        2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/tests/test_check.py        2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -58,11 +58,13 @@
     renderer = pretend.stub(
         render=pretend.call_recorder(lambda *a, **kw: "valid")
     )
-    package = pretend.stub(metadata_dictionary=lambda: {"description": "blah"})
+    package = pretend.stub(metadata_dictionary=lambda: {
+        "description": "blah", 'description_content_type': 'text/markdown',
+    })
     output_stream = check.StringIO()
     warning_stream = ""
 
-    monkeypatch.setattr(check, "_RENDERERS", {"": renderer})
+    monkeypatch.setattr(check, "_RENDERERS", {None: renderer})
     monkeypatch.setattr(check, "_find_dists", lambda a: ["dist/dist.tar.gz"])
     monkeypatch.setattr(
         check,
@@ -81,15 +83,41 @@
     ]
 
 
+def test_check_no_description(monkeypatch, capsys):
+    package = pretend.stub(metadata_dictionary=lambda: {
+        'description': None, 'description_content_type': None,
+    })
+
+    monkeypatch.setattr(check, "_find_dists", lambda a: ["dist/dist.tar.gz"])
+    monkeypatch.setattr(
+        check,
+        "PackageFile",
+        pretend.stub(from_filename=lambda *a, **kw: package),
+    )
+
+    # used to crash with `AttributeError`
+    output_stream = check.StringIO()
+    check.check("dist/*", output_stream=output_stream)
+    assert output_stream.getvalue() == (
+        'Checking distribution dist/dist.tar.gz: '
+        'warning: `long_description_content_type` missing.  '
+        'defaulting to `text/x-rst`.\n'
+        'warning: `long_description` missing.\n'
+        'Passed\n'
+    )
+
+
 def test_check_failing_distribution(monkeypatch):
     renderer = pretend.stub(
         render=pretend.call_recorder(lambda *a, **kw: None)
     )
-    package = pretend.stub(metadata_dictionary=lambda: {"description": "blah"})
+    package = pretend.stub(metadata_dictionary=lambda: {
+        "description": "blah", "description_content_type": 'text/markdown',
+    })
     output_stream = check.StringIO()
     warning_stream = "WARNING"
 
-    monkeypatch.setattr(check, "_RENDERERS", {"": renderer})
+    monkeypatch.setattr(check, "_RENDERERS", {None: renderer})
     monkeypatch.setattr(check, "_find_dists", lambda a: ["dist/dist.tar.gz"])
     monkeypatch.setattr(
         check,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_cli.py 
new/twine-1.13.0/tests/test_cli.py
--- old/twine-1.12.1/tests/test_cli.py  2017-01-19 15:23:11.000000000 +0100
+++ new/twine-1.13.0/tests/test_cli.py  2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_main.py 
new/twine-1.13.0/tests/test_main.py
--- old/twine-1.12.1/tests/test_main.py 2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/tests/test_main.py 2019-02-13 21:35:39.000000000 +0100
@@ -2,7 +2,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_package.py 
new/twine-1.13.0/tests/test_package.py
--- old/twine-1.12.1/tests/test_package.py      2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/tests/test_package.py      2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_repository.py 
new/twine-1.13.0/tests/test_repository.py
--- old/twine-1.12.1/tests/test_repository.py   2018-04-28 13:17:37.000000000 
+0200
+++ new/twine-1.13.0/tests/test_repository.py   2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,6 +17,8 @@
 from twine.utils import DEFAULT_REPOSITORY
 
 import pretend
+import pytest
+from contextlib import contextmanager
 
 
 def test_gpg_signature_structure_is_preserved():
@@ -140,3 +142,49 @@
     )
 
     assert repo.package_is_uploaded(package) is False
+
+
[email protected]('disable_progress_bar', [
+    True,
+    False
+])
+def test_disable_progress_bar_is_forwarded_to_tqdm(monkeypatch, tmpdir,
+                                                   disable_progress_bar):
+    """Test whether the disable flag is passed to tqdm
+        when the disable_progress_bar option is passed to the
+        repository
+    """
+    @contextmanager
+    def progressbarstub(*args, **kwargs):
+        assert "disable" in kwargs
+        assert kwargs["disable"] == disable_progress_bar
+        yield
+
+    monkeypatch.setattr(repository, "ProgressBar", progressbarstub)
+    repo = repository.Repository(
+        repository_url=DEFAULT_REPOSITORY,
+        username='username',
+        password='password',
+        disable_progress_bar=disable_progress_bar
+    )
+
+    repo.session = pretend.stub(
+        post=lambda url, data, allow_redirects, headers: response_with(
+            status_code=200)
+    )
+
+    fakefile = tmpdir.join('fake.whl')
+    fakefile.write('.')
+
+    def dictfunc():
+        return {"name": "fake"}
+
+    package = pretend.stub(
+        safe_name='fake',
+        metadata=pretend.stub(version='2.12.0'),
+        basefilename="fake.whl",
+        filename=str(fakefile),
+        metadata_dictionary=dictfunc
+    )
+
+    repo.upload(package)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_settings.py 
new/twine-1.13.0/tests/test_settings.py
--- old/twine-1.12.1/tests/test_settings.py     2018-05-18 19:14:50.000000000 
+0200
+++ new/twine-1.13.0/tests/test_settings.py     2019-02-13 21:35:39.000000000 
+0100
@@ -5,7 +5,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -49,6 +49,7 @@
     assert s.password == 'password'
     assert s.cacert is None
     assert s.client_cert is None
+    assert s.disable_progress_bar is False
 
 
 def test_identity_requires_sign():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_upload.py 
new/twine-1.13.0/tests/test_upload.py
--- old/twine-1.12.1/tests/test_upload.py       2018-09-24 20:40:31.000000000 
+0200
+++ new/twine-1.13.0/tests/test_upload.py       2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -133,6 +133,20 @@
 
     pkg = package.PackageFile.from_filename(WHEEL_FIXTURE, None)
     assert upload.skip_upload(response=response,
+                              skip_existing=True,
+                              package=pkg) is True
+
+
+def test_skip_existing_skips_files_already_on_nexus(monkeypatch):
+    # Nexus Repository Manager (https://www.sonatype.com/nexus-repository-oss)
+    # responds with 400 when the file already exists
+    response = pretend.stub(
+        status_code=400,
+        reason="Repository does not allow updating assets: pypi for url: "
+               "http://www.foo.bar";)
+
+    pkg = package.PackageFile.from_filename(WHEEL_FIXTURE, None)
+    assert upload.skip_upload(response=response,
                               skip_existing=True,
                               package=pkg) is True
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_utils.py 
new/twine-1.13.0/tests/test_utils.py
--- old/twine-1.12.1/tests/test_utils.py        2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/tests/test_utils.py        2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -126,6 +126,26 @@
     }
 
 
+def test_empty_userpass(tmpdir):
+    """
+    Empty username and password may be supplied to suppress
+    prompts. See #426.
+    """
+    pypirc = os.path.join(str(tmpdir), ".pypirc")
+
+    with open(pypirc, "w") as fp:
+        fp.write(textwrap.dedent("""
+            [pypi]
+            username=
+            password=
+        """))
+
+    config = utils.get_config(pypirc)
+    pypi = config['pypi']
+
+    assert pypi['username'] == pypi['password'] == ''
+
+
 def test_get_repository_config_missing(tmpdir):
     pypirc = os.path.join(str(tmpdir), ".pypirc")
 
@@ -229,6 +249,45 @@
     assert pw == 'entered pw'
 
 
+def test_no_password_defers_to_prompt(monkeypatch):
+    monkeypatch.setattr(utils, 'password_prompt', lambda prompt: 'entered pw')
+    pw = utils.get_password('system', 'user', None, {'password': None})
+    assert pw == 'entered pw'
+
+
+def test_empty_password_bypasses_prompt(monkeypatch):
+    monkeypatch.setattr(utils, 'password_prompt', lambda prompt: 'entered pw')
+    pw = utils.get_password('system', 'user', None, {'password': ''})
+    assert pw == ''
+
+
+def test_get_username_and_password_keyring_overrides_prompt(monkeypatch):
+    import collections
+    Credential = collections.namedtuple('Credential', 'username password')
+
+    class MockKeyring:
+        @staticmethod
+        def get_credential(system, user):
+            return Credential(
+                'real_user',
+                'real_user@{system} sekure pa55word'.format(**locals())
+            )
+
+        @staticmethod
+        def get_password(system, user):
+            cred = MockKeyring.get_credential(system, user)
+            if user != cred.username:
+                raise RuntimeError("unexpected username")
+            return cred.password
+
+    monkeypatch.setitem(sys.modules, 'keyring', MockKeyring)
+
+    user = utils.get_username('system', None, {})
+    assert user == 'real_user'
+    pw = utils.get_password('system', user, None, {})
+    assert pw == 'real_user@system sekure pa55word'
+
+
 @pytest.fixture
 def keyring_missing(monkeypatch):
     """
@@ -238,10 +297,30 @@
 
 
 @pytest.fixture
+def keyring_missing_get_credentials(monkeypatch):
+    """
+    Simulate older versions of keyring that do not have the
+    'get_credentials' API.
+    """
+    monkeypatch.delattr('keyring.backends.KeyringBackend',
+                        'get_credential', raising=False)
+
+
[email protected]
+def entered_username(monkeypatch):
+    monkeypatch.setattr(utils, 'input_func', lambda prompt: 'entered user')
+
+
[email protected]
 def entered_password(monkeypatch):
     monkeypatch.setattr(utils, 'password_prompt', lambda prompt: 'entered pw')
 
 
+def test_get_username_keyring_missing_get_credentials_prompts(
+        entered_username, keyring_missing_get_credentials):
+    assert utils.get_username('system', None, {}) == 'entered user'
+
+
 def test_get_password_keyring_missing_prompts(
         entered_password, keyring_missing):
     assert utils.get_password('system', 'user', None, {}) == 'entered pw'
@@ -261,6 +340,28 @@
     monkeypatch.setitem(sys.modules, 'keyring', FailKeyring())
 
 
[email protected]
+def keyring_no_backends_get_credential(monkeypatch):
+    """
+    Simulate that keyring has no available backends. When keyring
+    has no backends for the system, the backend will be a
+    fail.Keyring, which raises RuntimeError on get_password.
+    """
+    class FailKeyring(object):
+        @staticmethod
+        def get_credential(system, username):
+            raise RuntimeError("fail!")
+    monkeypatch.setitem(sys.modules, 'keyring', FailKeyring())
+
+
+def test_get_username_runtime_error_suppressed(
+        entered_username, keyring_no_backends_get_credential, recwarn):
+    assert utils.get_username('system', None, {}) == 'entered user'
+    assert len(recwarn) == 1
+    warning = recwarn.pop(UserWarning)
+    assert 'fail!' in str(warning)
+
+
 def test_get_password_runtime_error_suppressed(
         entered_password, keyring_no_backends, recwarn):
     assert utils.get_password('system', 'user', None, {}) == 'entered pw'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/tests/test_wheel.py 
new/twine-1.13.0/tests/test_wheel.py
--- old/twine-1.12.1/tests/test_wheel.py        2017-05-17 13:50:28.000000000 
+0200
+++ new/twine-1.13.0/tests/test_wheel.py        2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/__init__.py 
new/twine-1.13.0/twine/__init__.py
--- old/twine-1.12.1/twine/__init__.py  2018-09-24 20:40:31.000000000 +0200
+++ new/twine-1.13.0/twine/__init__.py  2019-02-13 22:37:01.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,7 +22,7 @@
 __summary__ = "Collection of utilities for publishing packages on PyPI"
 __uri__ = "https://twine.readthedocs.io/";
 
-__version__ = "1.12.1"
+__version__ = "1.13.0"
 
 __author__ = "Donald Stufft and individual contributors"
 __email__ = "[email protected]"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/__main__.py 
new/twine-1.13.0/twine/__main__.py
--- old/twine-1.12.1/twine/__main__.py  2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/twine/__main__.py  2019-02-13 21:35:39.000000000 +0100
@@ -5,7 +5,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,10 +27,7 @@
     try:
         return dispatch(sys.argv[1:])
     except (exceptions.TwineException, requests.exceptions.HTTPError) as exc:
-        return '{0}: {1}'.format(
-            exc.__class__.__name__,
-            exc.args[0],
-        )
+        return '{}: {}'.format(exc.__class__.__name__, exc.args[0])
 
 
 if __name__ == "__main__":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/cli.py 
new/twine-1.13.0/twine/cli.py
--- old/twine-1.12.1/twine/cli.py       2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/twine/cli.py       2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -29,7 +29,7 @@
 
 def _registered_commands(group='twine.registered_commands'):
     registered_commands = pkg_resources.iter_entry_points(group=group)
-    return dict((c.name, c) for c in registered_commands)
+    return {c.name: c for c in registered_commands}
 
 
 def list_dependencies_and_versions():
@@ -44,7 +44,7 @@
 
 def dep_versions():
     return ', '.join(
-        '{0}: {1}'.format(*dependency)
+        '{}: {}'.format(*dependency)
         for dependency in list_dependencies_and_versions()
     )
 
@@ -55,8 +55,10 @@
     parser.add_argument(
         "--version",
         action="version",
-        version="%(prog)s version {0} ({1})".format(twine.__version__,
-                                                    dep_versions()),
+        version="%(prog)s version {} ({})".format(
+            twine.__version__,
+            dep_versions(),
+        ),
     )
     parser.add_argument(
         "command",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/commands/__init__.py 
new/twine-1.13.0/twine/commands/__init__.py
--- old/twine-1.12.1/twine/commands/__init__.py 2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/twine/commands/__init__.py 2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/commands/check.py 
new/twine-1.13.0/twine/commands/check.py
--- old/twine-1.12.1/twine/commands/check.py    2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/twine/commands/check.py    2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,25 +18,18 @@
 import cgi
 import re
 import sys
+from io import StringIO
 
-try:
-    from StringIO import StringIO
-except ImportError:
-    from _io import StringIO
-
-import readme_renderer.markdown
 import readme_renderer.rst
-import readme_renderer.txt
 
 from twine.commands import _find_dists
 from twine.package import PackageFile
 
 _RENDERERS = {
     None: readme_renderer.rst,  # Default if description_content_type is None
-    "": readme_renderer.rst,  # Default if description_content_type is None
-    "text/plain": readme_renderer.txt,
+    "text/plain": None,  # Rendering cannot fail
     "text/x-rst": readme_renderer.rst,
-    "text/markdown": readme_renderer.markdown,
+    "text/markdown": None,  # Rendering cannot fail
 }
 
 
@@ -85,28 +78,37 @@
         package = PackageFile.from_filename(filename, comment=None)
 
         metadata = package.metadata_dictionary()
-        content_type, parameters = cgi.parse_header(
-            metadata.get("description_content_type") or ""
-        )
-
-        # Get the appropriate renderer
-        renderer = _RENDERERS.get(content_type, readme_renderer.txt)
-
-        # Actually render the given value
-        rendered = renderer.render(
-            metadata.get("description"), stream=stream, **parameters
-        )
+        description = metadata["description"]
+        description_content_type = metadata["description_content_type"]
 
-        if rendered is None:
-            failure = True
-            output_stream.write("Failed\n")
+        if description_content_type is None:
             output_stream.write(
-                "The project's long_description has invalid markup which will "
-                "not be rendered on PyPI. The following syntax errors were "
-                "detected:\n%s" % stream
+                'warning: `long_description_content_type` missing.  '
+                'defaulting to `text/x-rst`.\n'
             )
-        else:
+            description_content_type = 'text/x-rst'
+
+        content_type, params = cgi.parse_header(description_content_type)
+        renderer = _RENDERERS.get(content_type, _RENDERERS[None])
+
+        if description in {None, 'UNKNOWN\n\n\n'}:
+            output_stream.write('warning: `long_description` missing.\n')
             output_stream.write("Passed\n")
+        else:
+            if (
+                renderer
+                and renderer.render(description, stream=stream, **params)
+                is None
+            ):
+                failure = True
+                output_stream.write("Failed\n")
+                output_stream.write(
+                    "The project's long_description has invalid markup which "
+                    "will not be rendered on PyPI. The following syntax "
+                    "errors were detected:\n%s" % stream
+                )
+            else:
+                output_stream.write("Passed\n")
 
     return failure
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/commands/register.py 
new/twine-1.13.0/twine/commands/register.py
--- old/twine-1.12.1/twine/commands/register.py 2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/twine/commands/register.py 2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,12 +24,12 @@
 def register(register_settings, package):
     repository_url = register_settings.repository_config['repository']
 
-    print("Registering package to {0}".format(repository_url))
+    print("Registering package to {}".format(repository_url))
     repository = register_settings.create_repository()
 
     if not os.path.exists(package):
         raise exceptions.PackageNotFound(
-            '"{0}" does not exist on the file system.'.format(package)
+            '"{}" does not exist on the file system.'.format(package)
         )
 
     resp = repository.register(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/commands/upload.py 
new/twine-1.13.0/twine/commands/upload.py
--- old/twine-1.12.1/twine/commands/upload.py   2018-09-24 20:40:31.000000000 
+0200
+++ new/twine-1.13.0/twine/commands/upload.py   2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -26,10 +26,14 @@
 
 def skip_upload(response, skip_existing, package):
     filename = package.basefilename
-    # NOTE(sigmavirus24): Old PyPI returns the first message while Warehouse
-    # returns the latter. This papers over the differences.
-    msg_400 = ('A file named "{0}" already exists for'.format(filename),
-               'File already exists')
+    msg_400 = (
+        # Old PyPI message:
+        'A file named "{}" already exists for'.format(filename),
+        # Warehouse message:
+        'File already exists',
+        # Nexus Repository OSS message:
+        'Repository does not allow updating assets',
+    )
     msg_403 = 'Not enough permissions to overwrite artifact'
     # NOTE(sigmavirus24): PyPI presently returns a 400 status code with the
     # error message in the reason attribute. Other implementations return a
@@ -38,7 +42,7 @@
     #    True) AND
     # 2. a) The response status code is 409 OR
     # 2. b) The response status code is 400 AND it has a reason that matches
-    #       what we expect PyPI to return to us. OR
+    #       what we expect PyPI or Nexus OSS to return to us. OR
     # 2. c) The response status code is 403 AND the text matches what we
     #       expect Artifactory to return to us.
     return (skip_existing and (response.status_code == 409 or
@@ -51,21 +55,19 @@
     dists = _find_dists(dists)
 
     # Determine if the user has passed in pre-signed distributions
-    signatures = dict(
-        (os.path.basename(d), d) for d in dists if d.endswith(".asc")
-    )
+    signatures = {os.path.basename(d): d for d in dists if d.endswith(".asc")}
     uploads = [i for i in dists if not i.endswith(".asc")]
     upload_settings.check_repository_url()
     repository_url = upload_settings.repository_config['repository']
 
-    print("Uploading distributions to {0}".format(repository_url))
+    print("Uploading distributions to {}".format(repository_url))
 
     repository = upload_settings.create_repository()
 
     for filename in uploads:
         package = PackageFile.from_filename(filename, upload_settings.comment)
         skip_message = (
-            "  Skipping {0} because it appears to already exist".format(
+            "  Skipping {} because it appears to already exist".format(
                 package.basefilename)
         )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/exceptions.py 
new/twine-1.13.0/twine/exceptions.py
--- old/twine-1.12.1/twine/exceptions.py        2018-09-22 15:31:35.000000000 
+0200
+++ new/twine-1.13.0/twine/exceptions.py        2019-02-13 21:35:39.000000000 
+0100
@@ -5,7 +5,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -50,10 +50,10 @@
     @classmethod
     def from_args(cls, target_url, default_url, test_url):
         """Return an UploadToDeprecatedPyPIDetected instance."""
-        return cls("You're trying to upload to the legacy PyPI site '{0}'. "
+        return cls("You're trying to upload to the legacy PyPI site '{}'. "
                    "Uploading to those sites is deprecated. \n "
                    "The new sites are pypi.org and test.pypi.org. Try using "
-                   "{1} (or {2}) to upload your packages instead. "
+                   "{} (or {}) to upload your packages instead. "
                    "These are the default URLs for Twine now. \n More at "
                    "https://packaging.python.org/guides/migrating-to-pypi-org/";
                    " .".format(target_url, default_url, test_url)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/package.py 
new/twine-1.13.0/twine/package.py
--- old/twine-1.12.1/twine/package.py   2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/twine/package.py   2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -160,7 +160,7 @@
             self.gpg_signature = (signature_filename, gpg.read())
 
     def sign(self, sign_with, identity):
-        print("Signing {0}".format(self.basefilename))
+        print("Signing {}".format(self.basefilename))
         gpg_args = (sign_with, "--detach-sign")
         if identity:
             gpg_args += ("--local-user", identity)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/repository.py 
new/twine-1.13.0/twine/repository.py
--- old/twine-1.12.1/twine/repository.py        2018-04-28 13:17:37.000000000 
+0200
+++ new/twine-1.13.0/twine/repository.py        2019-02-13 21:35:39.000000000 
+0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,7 +28,7 @@
 
 import twine
 
-KEYWORDS_TO_NOT_FLATTEN = set(["gpg_signature", "content"])
+KEYWORDS_TO_NOT_FLATTEN = {"gpg_signature", "content"}
 
 LEGACY_PYPI = 'https://pypi.python.org/'
 LEGACY_TEST_PYPI = 'https://testpypi.python.org/'
@@ -47,7 +47,8 @@
 
 
 class Repository(object):
-    def __init__(self, repository_url, username, password):
+    def __init__(self, repository_url, username, password,
+                 disable_progress_bar=False):
         self.url = repository_url
         self.session = requests.session()
         self.session.auth = (username, password)
@@ -55,6 +56,7 @@
         for scheme in ('http://', 'https://'):
             self.session.mount(scheme, self._make_adapter_with_retries())
         self._releases_json_data = {}
+        self.disable_progress_bar = disable_progress_bar
 
     @staticmethod
     def _make_adapter_with_retries():
@@ -106,7 +108,7 @@
             "protocol_version": "1",
         })
 
-        print("Registering {0}".format(package.basefilename))
+        print("Registering {}".format(package.basefilename))
 
         data_to_send = self._convert_data_to_list_of_tuples(data)
         encoder = MultipartEncoder(data_to_send)
@@ -130,7 +132,7 @@
 
         data_to_send = self._convert_data_to_list_of_tuples(data)
 
-        print("Uploading {0}".format(package.basefilename))
+        print("Uploading {}".format(package.basefilename))
 
         with open(package.filename, "rb") as fp:
             data_to_send.append((
@@ -140,7 +142,8 @@
             encoder = MultipartEncoder(data_to_send)
             with ProgressBar(total=encoder.len,
                              unit='B', unit_scale=True, unit_divisor=1024,
-                             miniters=1, file=sys.stdout) as bar:
+                             miniters=1, file=sys.stdout,
+                             disable=self.disable_progress_bar) as bar:
                 monitor = MultipartEncoderMonitor(
                     encoder, lambda monitor: bar.update_to(monitor.bytes_read)
                 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/settings.py 
new/twine-1.13.0/twine/settings.py
--- old/twine-1.12.1/twine/settings.py  2018-05-18 19:14:50.000000000 +0200
+++ new/twine-1.13.0/twine/settings.py  2019-02-13 21:35:39.000000000 +0100
@@ -5,7 +5,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -46,6 +46,7 @@
                  cacert=None, client_cert=None,
                  repository_name='pypi', repository_url=None,
                  verbose=False,
+                 disable_progress_bar=False,
                  **ignored_kwargs
                  ):
         """Initialize our settings instance.
@@ -95,10 +96,15 @@
             will override the settings inferred from ``repository_name``.
         :param bool verbose:
             Show verbose output.
+        :param bool disable_progress_bar:
+            Disable the progress bar.
+
+            This defaults to ``False``
         """
         self.config_file = config_file
         self.comment = comment
         self.verbose = verbose
+        self.disable_progress_bar = disable_progress_bar
         self.skip_existing = skip_existing
         self._handle_repository_options(
             repository_name=repository_name, repository_url=repository_url,
@@ -206,6 +212,13 @@
             action="store_true",
             help="Show verbose output."
         )
+        parser.add_argument(
+            "--disable-progress-bar",
+            default=False,
+            required=False,
+            action="store_true",
+            help="Disable the progress bar."
+        )
 
     @classmethod
     def from_argparse(cls, args):
@@ -235,7 +248,11 @@
         )
 
     def _handle_authentication(self, username, password):
-        self.username = utils.get_username(username, self.repository_config)
+        self.username = utils.get_username(
+            self.repository_config['repository'],
+            username,
+            self.repository_config
+        )
         self.password = utils.get_password(
             self.repository_config['repository'],
             self.username,
@@ -272,6 +289,7 @@
             self.repository_config['repository'],
             self.username,
             self.password,
+            self.disable_progress_bar
         )
         repo.set_certificate_authority(self.cacert)
         repo.set_client_certificate(self.client_cert)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/utils.py 
new/twine-1.13.0/twine/utils.py
--- old/twine-1.12.1/twine/utils.py     2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/twine/utils.py     2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -35,6 +35,11 @@
 except ImportError:
     from urllib.parse import urlparse, urlunparse
 
+try:
+    import keyring  # noqa
+except ImportError:
+    pass
+
 from twine import exceptions
 
 # Shim for raw_input in python3
@@ -110,7 +115,7 @@
         }
     if repository_url and "://" not in repository_url:
         raise exceptions.UnreachableRepositoryURLDetected(
-            "Repository URL {0} has no protocol. Please add "
+            "Repository URL {} has no protocol. Please add "
             "'https://'. \n".format(repository_url))
     try:
         return get_config(config_file)[repository]
@@ -128,8 +133,8 @@
         raise exceptions.InvalidConfiguration(msg)
 
 
-_HOSTNAMES = set(["pypi.python.org", "testpypi.python.org", "upload.pypi.org",
-                  "test.pypi.org"])
+_HOSTNAMES = {"pypi.python.org", "testpypi.python.org", "upload.pypi.org",
+              "test.pypi.org"}
 
 
 def normalize_repository_url(url):
@@ -190,7 +195,7 @@
     """
     if cli_value is not None:
         return cli_value
-    elif config.get(key):
+    elif config.get(key) is not None:
         return config[key]
     elif prompt_strategy:
         return prompt_strategy()
@@ -198,6 +203,23 @@
         return None
 
 
+def get_username_from_keyring(system):
+    if 'keyring' not in sys.modules:
+        return
+
+    try:
+        getter = sys.modules['keyring'].get_credential
+    except AttributeError:
+        return None
+
+    try:
+        creds = getter(system, None)
+        if creds:
+            return creds.username
+    except Exception as exc:
+        warnings.warn(str(exc))
+
+
 def password_prompt(prompt_text):  # Always expects unicode for our own sanity
     prompt = prompt_text
     # Workaround for https://github.com/pypa/twine/issues/116
@@ -211,12 +233,18 @@
         return
 
     try:
-        import keyring
-        return keyring.get_password(system, username)
+        return sys.modules['keyring'].get_password(system, username)
     except Exception as exc:
         warnings.warn(str(exc))
 
 
+def username_from_keyring_or_prompt(system):
+    return (
+        get_username_from_keyring(system)
+        or input_func('Enter your username: ')
+    )
+
+
 def password_from_keyring_or_prompt(system, username):
     return (
         get_password_from_keyring(system, username)
@@ -224,11 +252,18 @@
     )
 
 
-get_username = functools.partial(
-    get_userpass_value,
-    key='username',
-    prompt_strategy=functools.partial(input_func, 'Enter your username: '),
-)
+def get_username(system, cli_value, config):
+    return get_userpass_value(
+        cli_value,
+        config,
+        key='username',
+        prompt_strategy=functools.partial(
+            username_from_keyring_or_prompt,
+            system,
+        ),
+    )
+
+
 get_cacert = functools.partial(
     get_userpass_value,
     key='ca_cert',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine/wheel.py 
new/twine-1.13.0/twine/wheel.py
--- old/twine-1.12.1/twine/wheel.py     2018-09-22 15:31:35.000000000 +0200
+++ new/twine-1.13.0/twine/wheel.py     2019-02-13 21:35:39.000000000 +0100
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,11 +17,7 @@
 import os
 import re
 import zipfile
-
-try:
-    from StringIO import StringIO
-except ImportError:
-    from _io import StringIO
+from io import StringIO
 
 from pkginfo import distribution
 from pkginfo.distribution import Distribution
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine.egg-info/PKG-INFO 
new/twine-1.13.0/twine.egg-info/PKG-INFO
--- old/twine-1.12.1/twine.egg-info/PKG-INFO    2018-09-24 20:41:42.000000000 
+0200
+++ new/twine-1.13.0/twine.egg-info/PKG-INFO    2019-02-13 22:38:54.000000000 
+0100
@@ -1,15 +1,19 @@
 Metadata-Version: 2.1
 Name: twine
-Version: 1.12.1
+Version: 1.13.0
 Summary: Collection of utilities for publishing packages on PyPI
 Home-page: https://twine.readthedocs.io/
 Author: Donald Stufft and individual contributors
 Author-email: [email protected]
 License: Apache License, Version 2.0
-Project-URL: Twine source, https://github.com/pypa/twine/
 Project-URL: Packaging tutorial, 
https://packaging.python.org/tutorials/distributing-packages/
+Project-URL: Travis CI, https://travis-ci.org/pypa/twine
 Project-URL: Twine documentation, https://twine.readthedocs.io/en/latest/
-Description: twine
+Project-URL: Twine source, https://github.com/pypa/twine/
+Description: .. image:: 
https://img.shields.io/travis/pypa/twine/master.svg?label=travis-ci
+           :target: https://travis-ci.org/pypa/twine
+        
+        twine
         =====
         
         .. rtd-inclusion-marker-do-not-remove
@@ -148,7 +152,7 @@
         Disabling Keyring
         ^^^^^^^^^^^^^^^^^
         
-        In some cases, the presence of keyring may be problemmatic. To disable
+        In some cases, the presence of keyring may be problematic. To disable
         keyring and defer to a prompt for passwords, uninstall ``keyring``
         or if that's not an option, you can also configure keyring to be 
disabled.
         
@@ -171,6 +175,7 @@
                                 [-s] [--sign-with SIGN_WITH] [-i IDENTITY] [-u 
USERNAME]
                                 [-p PASSWORD] [-c COMMENT] [--config-file 
CONFIG_FILE]
                                 [--skip-existing] [--cert path] [--client-cert 
path]
+                                [--verbose] [--disable-progress-bar]
                                 dist [dist ...]
         
             positional arguments:
@@ -215,6 +220,9 @@
               --client-cert path    Path to SSL client certificate, a single 
file
                                     containing the private key and the 
certificate in PEM
                                     format.
+              --verbose             Show verbose output.
+              --disable-progress-bar
+                                    Disable the progress bar.
         
         ``twine check``
         ^^^^^^^^^^^^^^^
@@ -357,7 +365,9 @@
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
-Provides-Extra: keyring
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
 Provides-Extra: with-blake2
+Provides-Extra: keyring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/twine-1.12.1/twine.egg-info/requires.txt 
new/twine-1.13.0/twine.egg-info/requires.txt
--- old/twine-1.12.1/twine.egg-info/requires.txt        2018-09-24 
20:41:42.000000000 +0200
+++ new/twine-1.13.0/twine.egg-info/requires.txt        2019-02-13 
22:38:54.000000000 +0100
@@ -1,7 +1,7 @@
 pkginfo>=1.4.2
 readme_renderer>=21.0
 requests!=2.15,!=2.16,>=2.5.0
-requests-toolbelt>=0.8.0
+requests-toolbelt!=0.9.0,>=0.8.0
 setuptools>=0.7.0
 tqdm>=4.14
 
@@ -9,4 +9,6 @@
 keyring
 
 [with-blake2]
+
+[with-blake2:python_version < "3.6" and platform_python_implementation == 
"CPython"]
 pyblake2


Reply via email to