Skip to content

Commit

Permalink
Merge pull request #322 from pypa/deprecated-URL-exception
Browse files Browse the repository at this point in the history
 Raise exception if attempting upload to deprecated legacy PyPI URLs
  • Loading branch information
brainwane committed Mar 18, 2018
2 parents 5199edb + ecff890 commit 4a8c3d4
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 9 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Changelog
=========

* :bug:`322 major` Raise exception if attempting upload to deprecated legacy
PyPI URLs.
* :feature:`320` Remove PyPI as default ``register`` package index.
* :feature:`319` Support Metadata 2.1 (:pep:`566`), including Markdown
for ``description`` fields.
Expand Down
36 changes: 35 additions & 1 deletion tests/test_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import pytest

from twine.commands import upload
from twine import package, cli
from twine import package, cli, exceptions
import twine

import helpers
Expand Down Expand Up @@ -95,6 +95,40 @@ def test_get_config_old_format(tmpdir):
).format(pypirc)


def test_deprecated_repo(tmpdir):
with pytest.raises(exceptions.UploadToDeprecatedPyPIDetected) as err:
pypirc = os.path.join(str(tmpdir), ".pypirc")
dists = ["tests/fixtures/twine-1.5.0-py2.py3-none-any.whl"]

with open(pypirc, "w") as fp:
fp.write(textwrap.dedent("""
[pypi]
repository: https://pypi.python.org/pypi/
username:foo
password:bar
"""))

upload.upload(dists=dists, repository="pypi", sign=None, identity=None,
username=None, password=None, comment=None,
cert=None, client_cert=None,
sign_with=None, config_file=pypirc, skip_existing=False,
repository_url=None,
)

assert err.args[0] == (
"You're trying to upload to the legacy PyPI site "
"'https://pypi.python.org/pypi/'. "
"Uploading to those sites is deprecated. \n "
"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. \n "
"More at "
"https://packaging.python.org/guides/migrating-to-pypi-org/ ."
)


def test_skip_existing_skips_files_already_on_PyPI(monkeypatch):
response = pretend.stub(
status_code=400,
Expand Down
21 changes: 15 additions & 6 deletions twine/commands/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import twine.exceptions as exc
from twine.package import PackageFile
from twine.repository import Repository, LEGACY_PYPI
from twine.repository import Repository, LEGACY_PYPI, LEGACY_TEST_PYPI
from twine import utils


Expand Down Expand Up @@ -98,11 +98,20 @@ def upload(dists, repository, sign, identity, username, password, comment,

print("Uploading distributions to {0}".format(config["repository"]))

if config["repository"].startswith(LEGACY_PYPI):
print(
"Note: you are uploading to the old upload URL. It's recommended "
"to use the new URL \"{0}\" or to leave the URL unspecified and "
"allow twine to choose.".format(utils.DEFAULT_REPOSITORY))
if config["repository"].startswith((LEGACY_PYPI, LEGACY_TEST_PYPI)):
raise exc.UploadToDeprecatedPyPIDetected(
"You're trying to upload to the legacy PyPI site '{0}'. "
"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. "
"These are the default URLs for Twine now. \n More at "
"https://packaging.python.org/guides/migrating-to-pypi-org/ "
".".format(
config["repository"],
utils.DEFAULT_REPOSITORY,
utils.TEST_REPOSITORY
)
)

username = utils.get_username(username, config)
password = utils.get_password(
Expand Down
6 changes: 6 additions & 0 deletions twine/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ class PackageNotFound(Exception):
This is only used when attempting to register a package.
"""
pass


class UploadToDeprecatedPyPIDetected(Exception):
"""An upload attempt was detected to deprecated legacy PyPI
sites pypi.python.org or testpypi.python.org."""
pass
1 change: 1 addition & 0 deletions twine/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
KEYWORDS_TO_NOT_FLATTEN = set(["gpg_signature", "content"])

LEGACY_PYPI = 'https://pypi.python.org/'
LEGACY_TEST_PYPI = 'https://testpypi.python.org/'
WAREHOUSE = 'https://upload.pypi.org/'
OLD_WAREHOUSE = 'https://upload.pypi.io/'

Expand Down
8 changes: 6 additions & 2 deletions twine/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,15 @@ def normalize_repository_url(url):


def check_status_code(response):
if (response.status_code == 500 and
"""
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 500 error response. "
"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/ "
Expand Down

0 comments on commit 4a8c3d4

Please sign in to comment.