Skip to content

Commit

Permalink
Move check_status_code to commands/upload; add corresponding test
Browse files Browse the repository at this point in the history
Signed-off-by: Aditya Saky <[email protected]>
  • Loading branch information
adityasaky committed Oct 7, 2019
1 parent a7780bf commit e7a3976
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 34 deletions.
20 changes: 20 additions & 0 deletions tests/test_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
NEW_SDIST_FIXTURE = 'tests/fixtures/twine-1.6.5.tar.gz'
NEW_WHEEL_FIXTURE = 'tests/fixtures/twine-1.6.5-py2.py3-none-any.whl'
NEW_RELEASE_URL = 'https://pypi.org/project/twine/1.6.5/'
DEFAULT_REPOSITORY = "https://upload.pypi.org/legacy/"
TEST_REPOSITORY = "https://test.pypi.org/legacy/"


def test_successful_upload(make_settings, capsys):
Expand Down Expand Up @@ -285,3 +287,21 @@ def none_upload(*args, **settings_kwargs):
assert "pypipassword" == upload_settings.password
assert "pypiuser" == upload_settings.username
assert "/foo/bar.crt" == upload_settings.cacert


def test_check_status_code(make_settings, capsys):
upload_settings = make_settings()

# override default upload_settings
upload_settings.repository_config['repository'] = \
"https://upload.pypi.org"


with pytest.raises(HTTPError):
result = upload.upload(upload_settings, [
WHEEL_FIXTURE, SDIST_FIXTURE, NEW_SDIST_FIXTURE, NEW_WHEEL_FIXTURE
])

captured = capsys.readouterr()
assert captured.out.count(DEFAULT_REPOSITORY) == 1
assert captured.out.count(TEST_REPOSITORY) == 1
42 changes: 40 additions & 2 deletions twine/commands/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
from twine.package import PackageFile
from twine import exceptions
from twine import settings
from twine import utils

from requests.exceptions import HTTPError


DEFAULT_REPOSITORY = "https://upload.pypi.org/legacy/"
TEST_REPOSITORY = "https://test.pypi.org/legacy/"


def skip_upload(response, skip_existing, package):
Expand Down Expand Up @@ -48,6 +53,39 @@ def skip_upload(response, skip_existing, package):
(response.status_code == 403 and msg_403 in response.text)))


def check_status_code(response, verbose):
"""
Additional safety net to catch response code 410 in case the
UploadToDeprecatedPyPIDetected exception breaks.
Also includes a check for response code 405 and prints helpful error
message guiding users to the right repository endpoints.
"""
if (response.status_code == 410 and
response.url.startswith(("https://pypi.python.org",
"https://testpypi.python.org"))):
print("It appears you're uploading to pypi.python.org (or "
"testpypi.python.org). You've received a 410 error response. "
"Uploading to those sites is deprecated. The new sites are "
"pypi.org and test.pypi.org. Try using "
"https://upload.pypi.org/legacy/ "
"(or https://test.pypi.org/legacy/) to upload your packages "
"instead. These are the default URLs for Twine now. More at "
"https://packaging.python.org/guides/migrating-to-pypi-org/ ")
elif response.status_code == 405 and "pypi.org" in response.url:
print(f"You probably want one of these two URLs: {DEFAULT_REPOSITORY} "
f"or {TEST_REPOSITORY}.")
try:
response.raise_for_status()
except HTTPError as err:
if response.text:
if verbose:
print('Content received from server:\n{}'.format(
response.text))
else:
print('NOTE: Try --verbose to see response content.')
raise err


def upload(upload_settings, dists):
dists = _find_dists(dists)

Expand Down Expand Up @@ -99,7 +137,7 @@ def upload(upload_settings, dists):
print(skip_message)
continue

utils.check_status_code(resp, upload_settings.verbose)
check_status_code(resp, upload_settings.verbose)

uploaded_packages.append(package)

Expand Down
32 changes: 0 additions & 32 deletions twine/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import configparser
from urllib.parse import urlparse, urlunparse

from requests.exceptions import HTTPError

try:
import keyring # noqa
Expand Down Expand Up @@ -129,37 +128,6 @@ def normalize_repository_url(url):
return urlunparse(parsed)


def check_status_code(response, verbose):
"""
Shouldn't happen, thanks to the UploadToDeprecatedPyPIDetected
exception, but this is in case that breaks and it does.
"""
if (response.status_code == 410 and
response.url.startswith(("https://pypi.python.org",
"https://testpypi.python.org"))):
print("It appears you're uploading to pypi.python.org (or "
"testpypi.python.org). You've received a 410 error response. "
"Uploading to those sites is deprecated. The new sites are "
"pypi.org and test.pypi.org. Try using "
"https://upload.pypi.org/legacy/ "
"(or https://test.pypi.org/legacy/) to upload your packages "
"instead. These are the default URLs for Twine now. More at "
"https://packaging.python.org/guides/migrating-to-pypi-org/ ")
elif response.status_code == 405 and "pypi.org" in response.url:
print(f"You probably want one of these two URLs: {DEFAULT_REPOSITORY} "
f"or {TEST_REPOSITORY}.")
try:
response.raise_for_status()
except HTTPError as err:
if response.text:
if verbose:
print('Content received from server:\n{}'.format(
response.text))
else:
print('NOTE: Try --verbose to see response content.')
raise err


def get_userpass_value(cli_value, config, key, prompt_strategy=None):
"""Gets the username / password from config.
Expand Down

0 comments on commit e7a3976

Please sign in to comment.