Skip to content

Commit 109bddc

Browse files
authored
Merge pull request #509 from adityasaky/enh-499-update-error-message
Add helpful error message for incorrect PyPI URL
2 parents f43ef0a + 360eb5a commit 109bddc

File tree

4 files changed

+66
-17
lines changed

4 files changed

+66
-17
lines changed

tests/test_upload.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,20 @@ def none_upload(*args, **settings_kwargs):
291291
assert "pypipassword" == upload_settings.password
292292
assert "pypiuser" == upload_settings.username
293293
assert "/foo/bar.crt" == upload_settings.cacert
294+
295+
296+
@pytest.mark.parametrize('repo_url', [
297+
"https://upload.pypi.org/",
298+
"https://test.pypi.org/",
299+
"https://pypi.org/"
300+
])
301+
def test_check_status_code_for_wrong_repo_url(repo_url, make_settings):
302+
upload_settings = make_settings()
303+
304+
# override defaults to use incorrect URL
305+
upload_settings.repository_config['repository'] = repo_url
306+
307+
with pytest.raises(twine.exceptions.InvalidPyPIUploadURL):
308+
upload.upload(upload_settings, [
309+
WHEEL_FIXTURE, SDIST_FIXTURE, NEW_SDIST_FIXTURE, NEW_WHEEL_FIXTURE
310+
])

tests/test_utils.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
import textwrap
1717

1818
import pytest
19+
import pretend
1920

20-
from twine import utils
21+
from twine import utils, exceptions
2122

2223
import helpers
2324

@@ -389,3 +390,18 @@ def t(foo=False):
389390
t(1)
390391

391392
assert t(foo=True)
393+
394+
395+
@pytest.mark.parametrize('repo_url', [
396+
"https://pypi.python.org",
397+
"https://testpypi.python.org"
398+
])
399+
def test_check_status_code_for_deprecated_pypi_url(repo_url):
400+
response = pretend.stub(
401+
status_code=410,
402+
url=repo_url
403+
)
404+
405+
# value of Verbose doesn't matter for this check
406+
with pytest.raises(exceptions.UploadToDeprecatedPyPIDetected):
407+
utils.check_status_code(response, False)

twine/exceptions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,12 @@ class InvalidDistribution(TwineException):
101101
"""Raised when a distribution is invalid."""
102102

103103
pass
104+
105+
106+
class InvalidPyPIUploadURL(TwineException):
107+
"""Repository configuration tries to use PyPI with an incorrect URL.
108+
109+
For example, https://pypi.org instead of https://upload.pypi.org/legacy.
110+
"""
111+
112+
pass

twine/utils.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import configparser
2323
from urllib.parse import urlparse, urlunparse
2424

25-
from requests.exceptions import HTTPError
25+
import requests
2626

2727
try:
2828
import keyring # noqa
@@ -130,24 +130,31 @@ def normalize_repository_url(url):
130130

131131

132132
def check_status_code(response, verbose):
133+
"""Generate a helpful message based on the response from the repository.
134+
135+
Raise a custom exception for recognized errors. Otherwise, print the
136+
response content (based on the verbose option) before re-raising the
137+
HTTPError.
133138
"""
134-
Shouldn't happen, thanks to the UploadToDeprecatedPyPIDetected
135-
exception, but this is in case that breaks and it does.
136-
"""
137-
if (response.status_code == 410 and
138-
response.url.startswith(("https://pypi.python.org",
139-
"https://testpypi.python.org"))):
140-
print("It appears you're uploading to pypi.python.org (or "
141-
"testpypi.python.org). You've received a 410 error response. "
142-
"Uploading to those sites is deprecated. The new sites are "
143-
"pypi.org and test.pypi.org. Try using "
144-
"https://upload.pypi.org/legacy/ "
145-
"(or https://test.pypi.org/legacy/) to upload your packages "
146-
"instead. These are the default URLs for Twine now. More at "
147-
"https://packaging.python.org/guides/migrating-to-pypi-org/ ")
139+
if response.status_code == 410 and "pypi.python.org" in response.url:
140+
raise exceptions.UploadToDeprecatedPyPIDetected(
141+
f"It appears you're uploading to pypi.python.org (or "
142+
f"testpypi.python.org). You've received a 410 error response. "
143+
f"Uploading to those sites is deprecated. The new sites are "
144+
f"pypi.org and test.pypi.org. Try using {DEFAULT_REPOSITORY} (or "
145+
f"{TEST_REPOSITORY}) to upload your packages instead. These are "
146+
f"the default URLs for Twine now. More at "
147+
f"https://packaging.python.org/guides/migrating-to-pypi-org/.")
148+
elif response.status_code == 405 and "pypi.org" in response.url:
149+
raise exceptions.InvalidPyPIUploadURL(
150+
f"It appears you're trying to upload to pypi.org but have an "
151+
f"invalid URL. You probably want one of these two URLs: "
152+
f"{DEFAULT_REPOSITORY} or {TEST_REPOSITORY}. Check your "
153+
f"--repository-url value.")
154+
148155
try:
149156
response.raise_for_status()
150-
except HTTPError as err:
157+
except requests.HTTPError as err:
151158
if response.text:
152159
if verbose:
153160
print('Content received from server:\n{}'.format(

0 commit comments

Comments
 (0)