Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Having a new check to avoid redirects from PyPI #809

Closed
wants to merge 7 commits into from

Conversation

dukecat0
Copy link
Member

@dukecat0 dukecat0 commented Sep 12, 2021

Fixes #310

We should also update the redirect test as it is using https://test.pypi.org/legacy for the test, which is replaced by the exception InvalidPyPIUploadURLinstead of RedirectDetected currently. Any suggestions? (I think we need a new URL to test.)

twine/tests/test_upload.py

Lines 251 to 278 in f543114

def test_exception_for_redirect(make_settings):
# Not using fixtures because this setup is significantly different
upload_settings = make_settings(
"""
[pypi]
repository: https://test.pypi.org/legacy
username:foo
password:bar
"""
)
stub_response = pretend.stub(
is_redirect=True,
status_code=301,
headers={"location": "https://test.pypi.org/legacy/"},
)
stub_repository = pretend.stub(
upload=lambda package: stub_response, close=lambda: None
)
upload_settings.create_repository = lambda: stub_repository
with pytest.raises(exceptions.RedirectDetected) as err:
upload.upload(upload_settings, [helpers.WHEEL_FIXTURE])
assert "https://test.pypi.org/legacy/" in err.value.args[0]

Old:

$ twine upload -r pypitest dist/*
[...]
RedirectDetected: https://test.pypi.org/legacy attempted to redirect to https://test.pypi.org/legacy/.
If you trust these URLs, set https://test.pypi.org/legacy/ as your repository URL.
Aborting.

New:

$ twine upload -r pypitest dist/*
InvalidPyPIUploadURL: The configured repository https://test.pypi.org/legacy is not a known PyPI repository.
Did you mean https://upload.pypi.org/legacy/ or https://test.pypi.org/legacy/ ?
Check your --repository-url value or modify the url in ~/.pypirc (if you are using -r or --repository),
so twine can upload your distributions properly.
See https://packaging.python.org/specifications/pypirc/ for more details.

f"or {utils.TEST_REPOSITORY} ?\n"
f"Check your --repository-url value or "
f"modify the url in {self.config_file} "
f"(if you are using -r or --repository),\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the parenthetical is necessary or helpful as written

Copy link
Member Author

@dukecat0 dukecat0 Sep 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using --repository-url https://test.pypi.org/legacy will also raise InvalidPyPIUploadURL. Probably folks who use --repository-url won't know what is ~/.pypirc and makes confusion to them?

@bhrutledge bhrutledge self-requested a review September 12, 2021 13:29
Copy link
Contributor

@bhrutledge bhrutledge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at the failing test yet, but that should be fixed, and probably a new one added for this behavior.

Comment on lines 343 to 356
if "pypi.org" in repository_url and repository_url not in [
utils.DEFAULT_REPOSITORY,
utils.TEST_REPOSITORY,
]:
raise exceptions.InvalidPyPIUploadURL(
f"The configured repository {repository_url} is not a known "
f"PyPI repository.\n"
f"You probably want {utils.DEFAULT_REPOSITORY} "
f"or {utils.TEST_REPOSITORY}.\n"
f"Check your --repository-url value "
f"or the repository configuration in {self.config_file}.\n"
f"See https://packaging.python.org/specifications/pypirc/ "
f"for more details."
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up on #809 (comment), I generalized the logic to catch more cases, and tweaked the message. Here's what it looks like:

% twine upload --repository-url https://upload.pypi.org/legacy dist/*
InvalidPyPIUploadURL: The configured repository https://upload.pypi.org/legacy is not a known PyPI repository.
You probably want https://upload.pypi.org/legacy/ or https://test.pypi.org/legacy/.
Check your --repository-url value or the repository configuration in ~/.pypirc.
See https://packaging.python.org/specifications/pypirc/ for more details.

In the process, I noted that the logic and messages is very similar to twine.utils.check_status_code. I'd really like to refactor that, maybe by moving the messages into the exception definitions. But I'm guessing that should be a follow-up PR, related to #586.

@dukecat0
Copy link
Member Author

dukecat0 commented Sep 12, 2021

I haven't looked at the failing test yet, but that should be fixed, and probably a new one added for this behavior.

Yes, and the failing test is about the redirecting test. Probably we need a new link to pass the test.

#809 (comment)

f"See https://packaging.python.org/specifications/pypirc/ "
f"for more details."
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the failing test and adding coverage for the new behavior in 414625b, but looking at the drop in coverage via Codecov emphasized my point in #809 (comment), i.e. that this is similar to utils.check_status_code.

Taking a closer look at that, plus the comments in #310, plus my initial attempt in #460 to offer a better error message, I'm now wondering if it's needlessly redundant, with the primary difference being that this executes before an upload, while check_status_code executes afterwards. Instead, maybe we could improve the post-upload RedirectDetected message by tweaking the language, possibly with a special message for a trailing slash, regardless of whether or not it's a pypi.org hostname.

In other words, this feels like a case of "Look Before You Leap" vs "It's Easter to Ask Forgiveness than Permission", and with this PR, I think we're doing both. I'm going to mull this over a bit, and maybe put up another PR that improves the EAFP approach.

@meowmeowmeowcat Apologies for the confusion here; I should have taken a closer look at the existing behavior.

Copy link
Member Author

@dukecat0 dukecat0 Sep 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bhrutledge I think the improved message in #812 would be also helpful:

RedirectDetected: https://upload.pypi.org/legacy attempted to redirect to https://upload.pypi.org/legacy/.
Your repository URL is missing a trailing slash. Please add it and try again.

But I also think that having this check will save folks' time. They will know there is an error in the config or --repository-url before twine tries to upload their distributions, although this check is similar to utils.check_status_code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true that it will save a little bit of time, but I'm not sure it's worth the added complexity and technical debt of duplicated logic. It's also not as robust as the repository-independent implementation in #812. Furthermore, if PyPI ever supports a different URL, then this implementation will block people from uploading to it at all.

Copy link
Member Author

@dukecat0 dukecat0 Sep 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Probably this PR can be closed? The improved message in #812 is enough.

Copy link
Contributor

@bhrutledge bhrutledge Sep 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to get @sigmavirus24's feedback on #812 first.

@bhrutledge
Copy link
Contributor

Closing in favor of #812 (which I'll merge once I've added a changelog entry). Thanks again for the effort, @meowmeowmeowcat.

@bhrutledge bhrutledge closed this Sep 16, 2021
@dukecat0 dukecat0 deleted the new-check branch September 16, 2021 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

leaving out a trailing slash in the pypi URL causes twine to fail with a 410
3 participants