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

In pypi, it is impossible to reupload a removed file. #74

Open
Natim opened this issue Sep 4, 2015 · 103 comments
Open

In pypi, it is impossible to reupload a removed file. #74

Natim opened this issue Sep 4, 2015 · 103 comments

Comments

@Natim
Copy link

Natim commented Sep 4, 2015

HTTPError: 400 Client Error: This filename has previously been used, you should use a different version.
@Natim
Copy link
Author

Natim commented Sep 4, 2015

Also the previous version has been removed and is impossible to find.

@daenney
Copy link

daenney commented Sep 4, 2015

It's probably still available in the Fastly caches, which is why you need to use a new filename. The old filename will have been marked as to cache indefinitely so even if you could upload a filename with the same name, if they had already fetched the old version they would never get the new one.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

In my case it isn't a problem because it is the exact same file.

@hickford
Copy link
Contributor

hickford commented Sep 4, 2015

See Donald's email at http://comments.gmane.org/gmane.comp.python.distutils.devel/22739

I've pushed changes to PyPI where it is no longer possible to reuse a filename and attempting to do it will give an 400 error "This filename has previously been used, you should use a different version."

@hickford
Copy link
Contributor

hickford commented Sep 4, 2015

Npm did the same in 2014. See http://blog.npmjs.org/post/77758351673/no-more-npm-publish-f

While it is annoying to have to bump the version number for typos documentation changes, I believe in the long run, the benefits of greater reliability and data integrity are well worth it.

I presume the justification is the same for PyPI. It's an FAQ, so should probably go in documentation somewhere.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

Then we shouldn't allow people to remove their files if they cannot put them back.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

I think we should allow to reupload the same removed file

@tylerdave
Copy link

There are very good reasons for the current behavior. Authors should be able to delete for any number of reasons (legal, security, etc.) Users of the package should be able to rely on getting the exact same thing every time they install a package of a specific version.

If you delete a package that someone relies on, they know the version is gone and they need to make a change to fix it. If you could delete a package and replace it with something different but with the same version, it can break their program is any number of subtle ways and it would be very hard to determine the cause of the problem.

Allowing this would break the entire version number contract. You may have what seems to be a good reason to replace a version but allowing it is not worth making versions unreliable.

@hickford
Copy link
Contributor

hickford commented Sep 4, 2015

Absolutely.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

If you delete a package that someone relies on

You broke their package and you cannot put it back.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

If you could delete a package and replace it with something different but with the same version, it can break their program

That's not what I am asking for.

I am asking for putting back the package I removed.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

Allowing this would break the entire version number contract.

Allowing to put back the version you removed doesn't break any contracts. + You already have the previous package hash so you can check the version didn't change and that you are really re-uploading the file that you removed.

@tylerdave
Copy link

There I agree. If it can be ensured via the hash that only the exact same package is uploaded to the same version then I don't see this being a problem in concept.

@hickford
Copy link
Contributor

hickford commented Sep 4, 2015

So long as the documentation and confirmation makes it clear that unpublishing is permanent, then I think it's reasonable and prudent.

It is generally considered bad behavior to remove versions of a library that others are depending on! Even if a package version is unpublished, that specific name and version combination can never be reused. In order to publish the package again, a new version number must be used.

https://docs.npmjs.com/cli/unpublish

@hickford
Copy link
Contributor

hickford commented Sep 4, 2015

To prevent malicious abuse, perhaps the policy should be strengthened to 'no uploads to old versions' #75

@dstufft
Copy link
Member

dstufft commented Sep 4, 2015

Unless you have the physical file laying around still, it's unlikely you're going to have something that matches the same hash. The setup.py sdist command does not have deterministic output, each time you run it even if the code hasn't changed. This also means you can't use setup.py to upload the file, since setup.py will only let you upload a file that it has created in the currently executing command, not an already created file. That doesn't make it impossible to upload a file with the same hash, but it makes it tricky which suggests it's a bad UX to expect authors to have to navigate.

Most likely the eventual solution to this is that "delete" won't actually be a full out absolute deletion, it'll be more like a soft delete where it just acts as if it's deleted without actually deleting it (so it won't show up in the API, won't appear anywhere, etc) but there will be a list of these deleted things when the author logs in and a button that says "Restore" that allows them to restore a file they've previously deleted. Possibly this would have a periodic cleanup where if something was soft deleted for some period of time (a month? 6 months? a year?) we'll go through and clean it up and actually hard delete it then. Perhaps we'd also enable it for authors to trigger an immediate hard delete of something they've soft deleted, but there would be plenty of big warnings that if they press that button there is no recovery possible.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

That doesn't make it impossible to upload a file with the same hash, but it makes it tricky which suggests it's a bad UX to expect authors to have to navigate.

With twine it is as simple as:

twine upload cliquet-2.5.0-py2.py3-none.whl

@dstufft
Copy link
Member

dstufft commented Sep 4, 2015

Right, I wrote twine, but not everyone uses that so you have to explain to them that they have to use twine to be able to reupload not setup.py upload. In addition you have to explain to them they need the exact same file, not one created the same way. It's fiddly and people will get confused.

@Natim
Copy link
Author

Natim commented Sep 4, 2015

People are not dumb, if they need to do something complicated they will eventually succeed. The fact is even if they know all the things, they won't be able to do it.

But yeah #75 is a workaround for now, (using .zip instead of .tar.gz for instance)

@domibarton
Copy link

As I already wrote it in #75

I think that behaviour is quite OK for the live repo.

Though, to be honest, it's a huge PITA for the test repo. I support integrity and all that stuff on "production" systems. However, developers need to have their code / packages checked somewhere and it's a PITA if you can't upload them same version twice while testing a new release.

There's no other way than the test repo to test your package. With git (or any other SCM) you can easily create a new branch and test it until you're sure everything works. Or if you've a look at PHP Packagist (compose) there's a -dev version for each development branch. On Docker the same, you can test your feature/release branches before tagging and going "live".

With the new policy you basically say: You've ONE SINGLE TRY and that one SHOULD WORK. No chance for a 2nd try. IMHO this isn't the purpose of a testing system and breaks the whole "we've a testing repo" idea. To be honest, I think this only leads to annoyed developers and a lot of "crippled versions" because developers couldn't properly test their versions before going live.

tl;dr:
I suppose you do that on the live system but not on the test system.

@brianmay
Copy link

brianmay commented Mar 6, 2016

In my case, I forgot to sign the upload. It appears once you have uploaded the package it is impossible to fix any problems you made with the upload without making a new release. Even if you just want to upload the exact same version again.

@daenney
Copy link

daenney commented Mar 6, 2016

But how do you know it is "the exact same version"? Unless it checks the uploads are binary identical it would allow you to upload a totally different release with the same version which can cause any amount of problems.

@torarnv
Copy link

torarnv commented Mar 14, 2016

Just his what @domibarton is describing. What's the point of a test repo if you can't make mistakes?

@Natim
Copy link
Author

Natim commented Mar 14, 2016

Just his what @domibarton is describing. What's the point of a test repo if you can't make mistakes?

Why cannot you do package x.y.z.dev0 and then package x.y.z.dev1?

@torarnv
Copy link

torarnv commented Mar 14, 2016

I could, and then having to remember to wipe those temp changes from my working tree before pushing to the live pypi repo.

@snare
Copy link

snare commented Apr 24, 2016

I uploaded a new version of Voltron yesterday and the server threw a 500 error during the upload. This resulted in a partial file being hosted as the current wheel for this package. The file size was smaller than my local one, and the hash differed.

This operation needs to be atomic. If the upload fails, you have no opportunity to try again. The only option is to use a different version number, which is not an appropriate solution.

IMO it should be a requirement that the hash of the upload is verified by the author before it is marked as "published".

@Natim
Copy link
Author

Natim commented Apr 25, 2016

Yes I have the same problem with my last uploaded packages.

@niedakh
Copy link

niedakh commented Jun 3, 2016

My files were uploaded broken, due to a connection error, why can't I replace them?!

Yikun added a commit to Yikun/reposcore that referenced this issue Jan 8, 2021
The Repo Score v1 is forked from criticality_score and had much
not graceful modification on upstream code, after the discussion[1],
we decided to decouple the dependency of criticality_score.

So in this patch, we keep the v1 code and doc unchanged, only move
the criticality_score into requirements, set the setup version to
2.0.0 to avoid the pypi reupload problem[2].

[1] #1
[2] pypa/packaging-problems#74

Close: #1
@makseq
Copy link

makseq commented Jan 18, 2021

@arigo Unfortunately I have a problem with this approach:

pip install label-studio==0.9.0
DEPRECATION: Python 3.5 reached the end of its life on September 13th, 2020. Please upgrade your Python as Python 3.5 is no longer maintained. pip 21.0 will drop support for Python 3.5 in January 2021. pip 21.0 will remove support for this functionality.
Collecting label-studio==0.9.0
  Using cached label_studio-0.9.0-2-py3-none-any.whl (18.9 MB)
ERROR: Requested label-studio==0.9.0 from https://files.pythonhosted.org/packages/7f/32/da8e6b279134e96c8b835bba3c20b8638473fed4f514b10472582258ae8b/label_studio-0.9.0-2-py3-none-any.whl#sha256=1363a13887d6351b720c89c43be78d41d42fff1cee56cebdd4fbf60077668fb9 has different version in metadata: '0.9.0.post2'

@Tasty213
Copy link

Hi, I just removed a package version because my internet connection failed midway through and so it thought I had uploaded a file when I actually hadn't. I didn't realise this would mean I could never use that version number again because there's no warning. I think this is a bit absurd as now I'm going to have to make a new release (v0.1.4) without making any changes.

There should be a warning before you delete versions and files saying that you can never use those names again to ensure users understand what they're doing.

@henryiii
Copy link
Contributor

You can upload a post version, v0.1.3.post1 - this will be treated like the original, --upgrade will know they are the same, etc. You can also upload missing files without starting a new version if one or more wheels didn't upload (or the SDist).

@microprediction
Copy link

I just bumped the version number a few times, tried again and it worked fine, and got on with my day.

thaddeusdiamond added a commit to thaddeusdiamond/cardano-nft-vending-machine that referenced this issue Jun 1, 2022
terryjunyang pushed a commit to ibm-z-oss-oda/aniso8601 that referenced this issue Aug 11, 2022
3.0.1 upload failed, upload again as 3.0.2.

pypa/packaging-problems#74
@rzashakeri
Copy link

I also had the same problem and could not re-upload a package with the same version after deleting it from pypi, but the following solution worked for me.

https://stackoverflow.com/a/28874414/13175549

@octachrome
Copy link

octachrome commented Sep 29, 2023

I had a similar question but for binary packages. A fix for binary packages is to append a build tag to the version number, e.g. rename mypkg-1.2.3-cp310-cp310-win_amd64.whl to mypkg-1.2.3-1-cp310-cp310-win_amd64.whl. This behaviour is documented at https://peps.python.org/pep-0427/#file-name-convention:

build tag
Optional build number. Must start with a digit. Acts as a tie-breaker if two wheel file names are the same in all other respects (i.e. name, version, and other tags). Sort as an empty tuple if unspecified, else sort as a two-item tuple with the first item being the initial digits as an int, and the second item being the remainder of the tag as a str.

This is better than appending .post1 as mentioned in another comment, since that is considered a different version number by pip so users must change their requirements.txt etc., which was not acceptable for me. Appending -1, however, is considered by pip to be the same version.

This may not work with source distributions.

@pfmoore
Copy link
Member

pfmoore commented Sep 29, 2023

It should work with source distributions too, but I didn't test that.

Source distributions have no formal notion of a build tag, so if it works with sdists, that's likely to be by accident and shouldn't be relied on.

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

No branches or pull requests