Repository: pypi/warehouse

Issue:
Uploads to pypi.io don't trigger auto-hide old releases functionality in pypi.python.org
It appears that [uploads to pypi.io are only syncing json metadata](https://github.com/pypa/setuptools/issues/589#issuecomment-223615124) and not updating the latest package [at the canonical location](https://pypi.python.org/pypi/setuptools).

I've tried [managing the project](https://pypi.python.org/pypi?%3Aaction=pkg_edit&name=setuptools) to see what releases might be present, but that URL returns 500 after 30 seconds (probably a timeout), so I'm unable to assess exactly why pypi.python.org isn't showing the latest release.



Discussion:
So the management interface did finally load, and as I suspected, the new releases are present in pypi.python.org; it's just that the older versions are not hidden:

![screen shot 2016-06-03 at 13 14 27](https://cloud.githubusercontent.com/assets/308610/15786937/32594e5a-298d-11e6-993c-9b7d0c11d40c.png)

Ah yes, Warehouse doesn't use the hidden flag, so it didn't occur to me to update that.


Resolving patch:
diff --git a/warehouse/forklift/legacy.py b/warehouse/forklift/legacy.py
--- a/warehouse/forklift/legacy.py
+++ b/warehouse/forklift/legacy.py
@@ -674,6 +674,7 @@ def file_upload(request):
                 c for c in all_classifiers
                 if c.classifier in form.classifiers.data
             ],
+            _pypi_hidden=False,
             dependencies=list(_construct_dependencies(
                 form,
                 {
@@ -727,6 +728,12 @@ def file_upload(request):
             releases, key=lambda x: packaging.version.parse(x.version))):
         r._pypi_ordering = i
 
+    # TODO: Again, we should figure out a better solution to doing this than
+    #       just inlining this inside this method.
+    if project.autohide:
+        for r in releases:
+            r._pypi_hidden = bool(not r == release)
+
     # Pull the filename out of our POST data.
     filename = request.POST["content"].filename
 


Test patch:
diff --git a/tests/unit/forklift/test_legacy.py b/tests/unit/forklift/test_legacy.py
--- a/tests/unit/forklift/test_legacy.py
+++ b/tests/unit/forklift/test_legacy.py
@@ -1710,6 +1710,160 @@ def test_fails_without_user(self, pyramid_config, pyramid_request):
             "403 Invalid or non-existent authentication information."
         )
 
+    def test_autohides_old_releases(self, pyramid_config, db_request):
+        pyramid_config.testing_securitypolicy(userid=1)
+
+        user = UserFactory.create()
+        project = ProjectFactory.create(autohide=True)
+        ReleaseFactory.create(
+            project=project,
+            version="0.5",
+            _pypi_hidden=False,
+        )
+        RoleFactory.create(user=user, project=project)
+
+        db_request.db.add(
+            Classifier(classifier="Environment :: Other Environment"),
+        )
+        db_request.db.add(
+            Classifier(classifier="Programming Language :: Python"),
+        )
+
+        filename = "{}-{}.tar.gz".format(project.name, "1.0")
+
+        db_request.user = user
+        db_request.client_addr = "10.10.10.20"
+        db_request.POST = MultiDict({
+            "metadata_version": "1.2",
+            "name": project.name,
+            "version": "1.0",
+            "summary": "This is my summary!",
+            "filetype": "sdist",
+            "md5_digest": "335c476dc930b959dda9ec82bd65ef19",
+            "content": pretend.stub(
+                filename=filename,
+                file=io.BytesIO(b"A fake file."),
+                type="application/tar",
+            ),
+        })
+        db_request.POST.extend([
+            ("classifiers", "Environment :: Other Environment"),
+            ("classifiers", "Programming Language :: Python"),
+            ("requires_dist", "foo"),
+            ("requires_dist", "bar (>1.0)"),
+            ("project_urls", "Test, https://example.com/"),
+            ("requires_external", "Cheese (>1.0)"),
+            ("provides", "testing"),
+        ])
+
+        storage_service = pretend.stub(store=lambda path, filepath, meta: None)
+        db_request.find_service = lambda svc: storage_service
+
+        resp = legacy.file_upload(db_request)
+
+        assert resp.status_code == 200
+
+        # Ensure that a Release object has been created and is not hidden.
+        release = (
+            db_request.db.query(Release)
+                         .filter((Release.project == project) &
+                                 (Release.version == "1.0"))
+                         .one()
+        )
+        assert not release._pypi_hidden
+
+        # Ensure that all the old release objects are hidden.
+        other_releases = (
+            db_request.db.query(Release)
+                      .filter((Release.project == project) &
+                              (Release.version != "1.0"))
+                      .all()
+        )
+        assert len(other_releases)
+        for r in other_releases:
+            assert r._pypi_hidden
+
+    def test_doesnt_autohides_old_releases(self, pyramid_config, db_request):
+        pyramid_config.testing_securitypolicy(userid=1)
+
+        user = UserFactory.create()
+        project = ProjectFactory.create(autohide=False)
+        previous_releases = {
+            "0.5": ReleaseFactory.create(
+                project=project,
+                version="0.5",
+                _pypi_hidden=False,
+            ),
+            "0.75": ReleaseFactory.create(
+                project=project,
+                version="0.75",
+                _pypi_hidden=False,
+            ),
+        }
+        RoleFactory.create(user=user, project=project)
+
+        db_request.db.add(
+            Classifier(classifier="Environment :: Other Environment"),
+        )
+        db_request.db.add(
+            Classifier(classifier="Programming Language :: Python"),
+        )
+
+        filename = "{}-{}.tar.gz".format(project.name, "1.0")
+
+        db_request.user = user
+        db_request.client_addr = "10.10.10.20"
+        db_request.POST = MultiDict({
+            "metadata_version": "1.2",
+            "name": project.name,
+            "version": "1.0",
+            "summary": "This is my summary!",
+            "filetype": "sdist",
+            "md5_digest": "335c476dc930b959dda9ec82bd65ef19",
+            "content": pretend.stub(
+                filename=filename,
+                file=io.BytesIO(b"A fake file."),
+                type="application/tar",
+            ),
+        })
+        db_request.POST.extend([
+            ("classifiers", "Environment :: Other Environment"),
+            ("classifiers", "Programming Language :: Python"),
+            ("requires_dist", "foo"),
+            ("requires_dist", "bar (>1.0)"),
+            ("project_urls", "Test, https://example.com/"),
+            ("requires_external", "Cheese (>1.0)"),
+            ("provides", "testing"),
+        ])
+
+        storage_service = pretend.stub(store=lambda path, filepath, meta: None)
+        db_request.find_service = lambda svc: storage_service
+
+        resp = legacy.file_upload(db_request)
+
+        assert resp.status_code == 200
+
+        # Ensure that a Release object has been created and is not hidden.
+        release = (
+            db_request.db.query(Release)
+                         .filter((Release.project == project) &
+                                 (Release.version == "1.0"))
+                         .one()
+        )
+        assert not release._pypi_hidden
+
+        # Ensure that all the old release objects still have the same hidden
+        # state.
+        other_releases = (
+            db_request.db.query(Release)
+                      .filter((Release.project == project) &
+                              (Release.version != "1.0"))
+                      .all()
+        )
+        assert len(other_releases)
+        for r in other_releases:
+            assert r._pypi_hidden == previous_releases[r.version]._pypi_hidden
+
 
 @pytest.mark.parametrize("status", [True, False])
 def test_legacy_purge(monkeypatch, status):