Commit 37d26ced authored by Stefano Rivera's avatar Stefano Rivera

Update upstream source from tag 'upstream/1.13.0'

Update to upstream version '1.13.0'
with Debian dir 513de3728b970ac8181c15266cf6b809d81c81ef
parents dc3a08e1 bbf3e8e1
......@@ -18,8 +18,9 @@ Andrew Watts <andrewwatts@gmail.com>
Anna Martelli Ravenscroft <annaraven@gmail.com>
Sumana Harihareswara <sh@changeset.nyc>
Dustin Ingram <di@di.codes> (https://di.codes)
Jesse Jarzynka <jesse@jessejoe.com> (http://jessejoe.com)
Jesse Jarzynka <jesse@jessejoe.com> (https://www.jessejoe.com/)
László Kiss Kollár <kiss.kollar.laszlo@gmail.com>
Frances Hocutt <frances.hocutt@gmail.com>
Tathagata Dasgupta <tathagatadg@gmail.com>
Wasim Thabraze <wasim@thabraze.me>
\ No newline at end of file
Wasim Thabraze <wasim@thabraze.me>
Varun Kamath <varunkamath18@gmail.com>
\ No newline at end of file
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
......
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: donald@stufft.io
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 @@ Description: twine
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 @@ Description: twine
[-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 @@ Description: twine
--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
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
.. 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 @@ The next time you run ``twine`` it will prompt you for a username and will grab
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 @@ Uploads one or more distributions to a repository.
[-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 @@ Uploads one or more distributions to a repository.
--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``
^^^^^^^^^^^^^^^
......
......@@ -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>`
......
......@@ -10,14 +10,6 @@ ignore =
[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 =
......
......@@ -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 @@ setup(
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 @@ setup(
"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 @@ setup(
],
},
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',
],
......
......@@ -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,
......
......@@ -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 @@ def test_check_passing_distribution(monkeypatch):
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_passing_distribution(monkeypatch):
]
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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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 import repository
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 @@ def test_package_is_uploaded_200s_with_no_releases():
)
assert repo.package_is_uploaded(package) is False
@pytest.mark.parametrize('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)
......@@ -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 @@ def test_settings_transforms_config(tmpdir):
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():
......
......@@ -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,
......@@ -137,6 +137,20 @@ def test_skip_existing_skips_files_already_on_PyPI(monkeypatch):
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
def test_skip_existing_skips_files_already_on_pypiserver(monkeypatch):
# pypiserver (https://pypi.org/project/pypiserver) responds with a
# 409 when the file already exists.
......
......@@ -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_get_config_missing(tmpdir):
}
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 @@ def test_get_password_keyring_defers_to_prompt(monkeypatch):
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):
"""
......@@ -237,11 +296,31 @@ def keyring_missing(monkeypatch):
monkeypatch.delitem(sys.modules, 'keyring', raising=False)
@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)
@pytest.fixture
def entered_username(monkeypatch):
monkeypatch.setattr(utils, 'input_func', lambda prompt: 'entered user')
@pytest.fixture
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 @@ def keyring_no_backends(monkeypatch):
monkeypatch.setitem(sys.modules, 'keyring', FailKeyring())
@pytest.fixture
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'
......
......@@ -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,
......
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: donald@stufft.io
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 @@ Description: twine
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 @@ Description: twine
[-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 @@ Description: twine
--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
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
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 @@ tqdm>=4.14
keyring
[with-blake2]
[with-blake2:python_version < "3.6" and platform_python_implementation == "CPython"]
pyblake2
......@@ -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 @@ __title__ = "twine"
__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__ = "donald@stufft.io"
......
......@@ -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 @@ def main():
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__":
......
......@@ -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 @@ from twine._installed import Installed
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 list_dependencies_and_versions():
def dep_versions():
return ', '.join(
'{0}: {1}'.format(*dependency)
'{}: {}'.format(*dependency)
for dependency in list_dependencies_and_versions()
)
......@@ -55,8 +55,10 @@ def dispatch(argv):
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",
......