internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pypi/warehouse

Issue:
Validate that Project URLs are actually URLs on Upload
As the title says, validate the project url metadata on upload, probably with [rfc3986](https://pypi.python.org/pypi/rfc3986).



Discussion:
Grabbing this. PR incoming.


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -88,6 +88,7 @@
         "pyramid_tm>=0.12",
         "readme>=0.5.1",
         "redis",
+        "rfc3986",
         "setproctitle",
         "setuptools",
         "sqlalchemy>=0.9",
diff --git a/warehouse/legacy/api/pypi.py b/warehouse/legacy/api/pypi.py
--- a/warehouse/legacy/api/pypi.py
+++ b/warehouse/legacy/api/pypi.py
@@ -20,6 +20,7 @@
 import pkg_resources
 import wtforms
 import wtforms.validators
+from rfc3986 import uri_reference
 
 from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPGone
 from pyramid.response import Response
@@ -194,7 +195,10 @@ def _validate_project_url(value):
     if not url:
         raise wtforms.validators.ValidationError("Must have an URL.")
 
-    # TODO: Actually validate that the URL is a valid URL.
+    url = uri_reference(url)
+    url = url.normalize()
+    if not (url.is_valid() and url.scheme in ('http', 'https')):
+        raise wtforms.validators.ValidationError("Invalid URL.")
 
 
 def _validate_project_url_list(form, field):


Test patch:
diff --git a/tests/unit/legacy/api/test_pypi.py b/tests/unit/legacy/api/test_pypi.py
--- a/tests/unit/legacy/api/test_pypi.py
+++ b/tests/unit/legacy/api/test_pypi.py
@@ -230,6 +230,8 @@ def test_validate_project_url_valid(self, project_url):
             ", https://pypi.python.org/",
             "Home, ",
             ("A" * 33) + ", https://example.com/",
+            "Home, I am a banana",
+            "Home, ssh://foobar",
         ],
     )
     def test_validate_project_url_invalid(self, project_url):
Repository: pypi/warehouse

Issue:
Link to GitHub from the homepage
It'd be nice to have a link to the GitHub repo in the header/footer. It makes it easier for users to file bugs, and avoids users getting confused between this repo and https://github.com/crateio/warehouse .



Discussion:

Resolving patch:
diff --git a/warehouse/__about__.py b/warehouse/__about__.py
--- a/warehouse/__about__.py
+++ b/warehouse/__about__.py
@@ -10,17 +10,32 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import os.path
+
 __all__ = [
-    "__title__", "__summary__", "__uri__", "__version__", "__author__",
-    "__email__", "__license__", "__copyright__",
+    "__title__", "__summary__", "__uri__", "__version__", "__commit__",
+    "__author__", "__email__", "__license__", "__copyright__",
 ]
 
+
+try:
+    base_dir = os.path.dirname(os.path.abspath(__file__))
+except NameError:
+    base_dir = None
+
+
 __title__ = "warehouse"
 __summary__ = "Next Generation Python Package Repository"
 __uri__ = "https://warehouse.python.org/"
 
 __version__ = "15.0.dev0"
 
+if base_dir is not None and os.path.exists(os.path.join(base_dir, ".commit")):
+    with open(os.path.join(base_dir, ".commit")) as fp:
+        __commit__ = fp.read().strip()
+else:
+    __commit__ = None
+
 __author__ = "The Python Packaging Authority"
 __email__ = "donald@stufft.io"
 
diff --git a/warehouse/__init__.py b/warehouse/__init__.py
--- a/warehouse/__init__.py
+++ b/warehouse/__init__.py
@@ -11,12 +11,12 @@
 # limitations under the License.
 
 from warehouse.__about__ import (
-    __author__, __copyright__, __email__, __license__, __summary__, __title__,
-    __uri__, __version__,
+    __author__, __commit__, __copyright__, __email__, __license__, __summary__,
+    __title__, __uri__, __version__,
 )
 
 
 __all__ = [
-    "__author__", "__copyright__", "__email__", "__license__", "__summary__",
-    "__title__", "__uri__", "__version__",
+    "__author__", "__commit__", "__copyright__", "__email__", "__license__",
+    "__summary__", "__title__", "__uri__", "__version__",
 ]
diff --git a/warehouse/config.py b/warehouse/config.py
--- a/warehouse/config.py
+++ b/warehouse/config.py
@@ -22,6 +22,7 @@
 from pyramid.httpexceptions import HTTPMovedPermanently
 from pyramid.response import Response
 
+from warehouse import __commit__
 from warehouse.utils.static import WarehouseCacheBuster
 
 
@@ -101,6 +102,9 @@ def configure(settings=None):
     if settings is None:
         settings = {}
 
+    # Add information about the current copy of the code.
+    settings.setdefault("warehouse.commit", __commit__)
+
     # Set the environment from an environment variable, if one hasn't already
     # been set.
     maybe_set(


Test patch:
diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py
--- a/tests/unit/test_config.py
+++ b/tests/unit/test_config.py
@@ -264,6 +264,7 @@ def __init__(self):
 
     expected_settings = {
         "warehouse.env": environment,
+        "warehouse.commit": None,
         "site.name": "Warehouse",
     }
Repository: pypi/warehouse

Issue:
Copyright end-date in footers needs updating
Harsh Gupta gupta.harsh96@gmail.com points out in email to webmaster@ that the page footer still shows "Copyright © 1990-2014, Python Software Foundation." The easy fix is a change to the templates, but it might be better to simply dynamically substitute the current year for the second date.

Is this the correct repo for the current PyPI?



Discussion:
I updated this on the live site, leaving this issue open we so get the date dynamically generated in Warehouse.


Resolving patch:
diff --git a/warehouse/config.py b/warehouse/config.py
--- a/warehouse/config.py
+++ b/warehouse/config.py
@@ -245,6 +245,7 @@ def configure(settings=None):
     jglobals = config.get_settings().setdefault("jinja2.globals", {})
     jglobals.setdefault("gravatar", "warehouse.utils.gravatar:gravatar")
     jglobals.setdefault("esi_include", "warehouse.cache.origin:esi_include")
+    jglobals.setdefault("now", "warehouse.utils:now")
 
     # We'll store all of our templates in one location, warehouse/templates
     # so we'll go ahead and add that to the Jinja2 search path.
diff --git a/warehouse/utils/__init__.py b/warehouse/utils/__init__.py
--- a/warehouse/utils/__init__.py
+++ b/warehouse/utils/__init__.py
@@ -9,3 +9,9 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+import datetime
+
+
+def now():
+    return datetime.datetime.utcnow()


Test patch:
Repository: pypi/warehouse

Issue:
Search results seem to need some relevancy tweaking
Searches seem to have some relevancy issues. For example:

![2016-03-17 at 11 13 am 1](https://cloud.githubusercontent.com/assets/21148/13856330/e99facd8-ec31-11e5-81a8-ff1033f1df67.png)

Or: https://warehouse.python.org/search/?q=django&page=1 - Django itself doesn't seem to appear in the first half-dozen or so pages (I gave up paging before I found it).

Jacob



Discussion:

Resolving patch:
diff --git a/warehouse/views.py b/warehouse/views.py
--- a/warehouse/views.py
+++ b/warehouse/views.py
@@ -159,7 +159,7 @@ def search(request):
             "multi_match",
             query=request.params["q"],
             fields=[
-                "name", "version", "author", "author_email", "maintainer",
+                "name^2", "version", "author", "author_email", "maintainer",
                 "maintainer_email", "home_page", "license", "summary",
                 "description", "keywords", "platform", "download_url",
             ],


Test patch:
diff --git a/tests/unit/test_views.py b/tests/unit/test_views.py
--- a/tests/unit/test_views.py
+++ b/tests/unit/test_views.py
@@ -133,9 +133,10 @@ def test_with_a_query(self, monkeypatch, page):
                 "multi_match",
                 query="foo bar",
                 fields=[
-                    "name", "version", "author", "author_email", "maintainer",
-                    "maintainer_email", "home_page", "license", "summary",
-                    "description", "keywords", "platform", "download_url",
+                    "name^2", "version", "author", "author_email",
+                    "maintainer", "maintainer_email", "home_page", "license",
+                    "summary", "description", "keywords", "platform",
+                    "download_url",
                 ],
             ),
         ]
@@ -188,9 +189,10 @@ def test_with_an_ordering(self, monkeypatch, page):
                 "multi_match",
                 query="foo bar",
                 fields=[
-                    "name", "version", "author", "author_email", "maintainer",
-                    "maintainer_email", "home_page", "license", "summary",
-                    "description", "keywords", "platform", "download_url",
+                    "name^2", "version", "author", "author_email",
+                    "maintainer", "maintainer_email", "home_page", "license",
+                    "summary", "description", "keywords", "platform",
+                    "download_url",
                 ],
             ),
         ]
Repository: pypi/warehouse

Issue:
Permanent URL (Heroku "No such app" error)
I noticed that https://warehouse.python.org/ produces a `Heroku | No such app` error at the moment. Is this intentional? Are we permanently at https://pypi.io/ now?

If so, we should probably update the URL in a few places: https://github.com/pypa/warehouse/search?utf8=%E2%9C%93&q=%22warehouse.python.org%22



Discussion:
#1176 should make `warehouse.python.org` redirect to `https://pypi.io/` but we are permanently at `https://pypi.io/` (and `https://test.pypi.io/`) so we should still update those references.


Resolving patch:
diff --git a/warehouse/__about__.py b/warehouse/__about__.py
--- a/warehouse/__about__.py
+++ b/warehouse/__about__.py
@@ -26,7 +26,7 @@
 
 __title__ = "warehouse"
 __summary__ = "Next Generation Python Package Repository"
-__uri__ = "https://warehouse.python.org/"
+__uri__ = "https://pypi.io/"
 
 __version__ = "15.0.dev0"
 


Test patch:
Repository: pypi/warehouse

Issue:
Errors in celery don't get sent to Sentry



Discussion:

Resolving patch:
diff --git a/warehouse/celery.py b/warehouse/celery.py
--- a/warehouse/celery.py
+++ b/warehouse/celery.py
@@ -21,13 +21,16 @@
 from celery.signals import celeryd_init
 from pyramid import scripting
 from pyramid.threadlocal import get_current_request
+from raven.contrib.celery import register_signal, register_logger_signal
 
 from warehouse.config import Environment, configure
 
 
 @celeryd_init.connect
 def _configure_celery(*args, **kwargs):
-    configure()
+    config = configure()
+    register_logger_signal(config.registry["raven.client"])
+    register_signal(config.registry["raven.client"])
 
 
 class TLSRedisBackend(_RedisBackend):


Test patch:
diff --git a/tests/unit/test_celery.py b/tests/unit/test_celery.py
--- a/tests/unit/test_celery.py
+++ b/tests/unit/test_celery.py
@@ -21,12 +21,27 @@
 
 
 def test_configure_celery(monkeypatch):
-    configure = pretend.call_recorder(lambda: None)
+    client = pretend.stub()
+    getitem = pretend.call_recorder(lambda *a: client)
+    registry = pretend.stub(__getitem__=getitem)
+    configure = pretend.call_recorder(lambda: pretend.stub(registry=registry))
+    register_logger_signal = pretend.call_recorder(lambda x: None)
+    register_signal = pretend.call_recorder(lambda x: None)
     monkeypatch.setattr(celery, "configure", configure)
+    monkeypatch.setattr(
+        celery, "register_logger_signal", register_logger_signal
+    )
+    monkeypatch.setattr(celery, "register_signal", register_signal)
 
     celery._configure_celery()
 
     assert configure.calls == [pretend.call()]
+    assert getitem.calls == [
+        pretend.call('raven.client'),
+        pretend.call('raven.client'),
+    ]
+    assert register_logger_signal.calls == [pretend.call(client)]
+    assert register_signal.calls == [pretend.call(client)]
 
 
 def test_tls_redis_backend():
Repository: pypi/warehouse

Issue:
Integrate statuspage.io
We'll want to integrate statuspage.io so that people can get a link to the status.python.org incidents when one is occuring. They have a web API that we are currently using via javascript on pypi.python.org.

See: https://status-page-blog.herokuapp.com/embed-system-status-within-your-webapp



Discussion:
Design specification:

![screenshot from 2016-06-30 06-52-09](https://cloud.githubusercontent.com/assets/3323703/16478074/36753672-3e8f-11e6-8a1b-7beefb0ea379.png)


Resolving patch:
diff --git a/warehouse/config.py b/warehouse/config.py
--- a/warehouse/config.py
+++ b/warehouse/config.py
@@ -143,6 +143,7 @@ def configure(settings=None):
     maybe_set(settings, "camo.key", "CAMO_KEY")
     maybe_set(settings, "docs.url", "DOCS_URL")
     maybe_set(settings, "ga.tracking_id", "GA_TRACKING_ID")
+    maybe_set(settings, "statuspage.url", "STATUSPAGE_URL")
     maybe_set_compound(settings, "files", "backend", "FILES_BACKEND")
     maybe_set_compound(settings, "origin_cache", "backend", "ORIGIN_CACHE")
 
diff --git a/warehouse/csp.py b/warehouse/csp.py
--- a/warehouse/csp.py
+++ b/warehouse/csp.py
@@ -57,7 +57,7 @@ def includeme(config):
         "csp": {
             "base-uri": [SELF],
             "block-all-mixed-content": [],
-            "connect-src": [SELF],
+            "connect-src": [SELF, config.registry.settings["statuspage.url"]],
             "default-src": [NONE],
             "font-src": [SELF, "fonts.gstatic.com"],
             "form-action": [SELF],


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -140,6 +140,7 @@ def app_config(database):
             "files.url": "http://localhost:7000/",
             "sessions.secret": "123456",
             "sessions.url": "redis://localhost:0/",
+            "statuspage.url": "https://2p66nmmycsj3.statuspage.io",
         },
     )
 
diff --git a/tests/unit/test_csp.py b/tests/unit/test_csp.py
--- a/tests/unit/test_csp.py
+++ b/tests/unit/test_csp.py
@@ -175,7 +175,10 @@ def test_includeme():
             lambda fact, name: None),
         add_settings=pretend.call_recorder(lambda settings: None),
         add_tween=pretend.call_recorder(lambda tween: None),
-        registry=pretend.stub(settings={"camo.url": "camo.url.value"}),
+        registry=pretend.stub(settings={
+            "camo.url": "camo.url.value",
+            "statuspage.url": "https://2p66nmmycsj3.statuspage.io",
+        }),
     )
     csp.includeme(config)
 
@@ -192,7 +195,10 @@ def test_includeme():
             "csp": {
                 "base-uri": ["'self'"],
                 "block-all-mixed-content": [],
-                "connect-src": ["'self'"],
+                "connect-src": [
+                    "'self'",
+                    "https://2p66nmmycsj3.statuspage.io",
+                ],
                 "default-src": ["'none'"],
                 "font-src": ["'self'", "fonts.gstatic.com"],
                 "form-action": ["'self'"],
Repository: pypi/warehouse

Issue:
Reorder trove classifiers on search sidebar
It strikes me that the current ordering is probably not the most useful.

Maybe we reorder to be:
- By Topic
- By Intended Audience
- By Framework
- By Environment
- By License
- By Programming Language
- By Operating System
- By Natural Language
- By Development Status

Thoughts @dstufft ?



Discussion:
(They're currently just alphabetical)

I don't have any great insight here except that I think that License, Programming Language, and Framework are the 3 kinds of classifiers that are most likely to actually be filled out by a project.

ok, how about:

```
By License
By Programming Language
By Framework
By Topic
By Intended Audience
By Environment
By Operating System
By Natural Language
By Development Status
```

We should also make the first list closed by default...

That seems reasonable, though I'd maybe put `Programming Language` first.


Resolving patch:
diff --git a/warehouse/views.py b/warehouse/views.py
--- a/warehouse/views.py
+++ b/warehouse/views.py
@@ -44,6 +44,17 @@
     "keywords": 5,
     "summary": 5,
 }
+SEARCH_FILTER_ORDER = (
+    "Programming Language",
+    "License",
+    "Framework",
+    "Topic",
+    "Intended Audience",
+    "Environment",
+    "Operating System",
+    "Natural Language",
+    "Development Status",
+)
 
 
 @view_config(context=HTTPException)
@@ -211,11 +222,17 @@ def search(request):
         first, *_ = cls.classifier.split(' :: ')
         available_filters[first].append(cls.classifier)
 
+    def filter_key(item):
+        try:
+            return 0, SEARCH_FILTER_ORDER.index(item[0]), item[0]
+        except ValueError:
+            return 1, 0, item[0]
+
     return {
         "page": page,
         "term": q,
         "order": request.params.get("o", ''),
-        "available_filters": sorted(available_filters.items()),
+        "available_filters": sorted(available_filters.items(), key=filter_key),
         "applied_filters": request.params.getall("c"),
     }
 


Test patch:
Repository: pypi/warehouse

Issue:
Add support for opensearch
http://www.opensearch.org/

Lets you (at least from Chrome) type `pypi.io`, hit tab, and then let you type what you're searching for from the address bar instead of having to go to the site first to use the search box.



Discussion:

Resolving patch:
diff --git a/warehouse/routes.py b/warehouse/routes.py
--- a/warehouse/routes.py
+++ b/warehouse/routes.py
@@ -24,6 +24,7 @@ def includeme(config):
     # Basic global routes
     config.add_route("index", "/", domain=warehouse)
     config.add_route("robots.txt", "/robots.txt", domain=warehouse)
+    config.add_route("opensearch.xml", "/opensearch.xml", domain=warehouse)
     config.add_route("index.sitemap.xml", "/sitemap.xml", domain=warehouse)
     config.add_route(
         "bucket.sitemap.xml",
diff --git a/warehouse/views.py b/warehouse/views.py
--- a/warehouse/views.py
+++ b/warehouse/views.py
@@ -100,6 +100,23 @@ def robotstxt(request):
     return {}
 
 
+@view_config(
+    route_name="opensearch.xml",
+    renderer="opensearch.xml",
+    decorator=[
+        cache_control(1 * 24 * 60 * 60),         # 1 day
+        origin_cache(
+            1 * 24 * 60 * 60,                    # 1 day
+            stale_while_revalidate=6 * 60 * 60,  # 6 hours
+            stale_if_error=1 * 24 * 60 * 60,     # 1 day
+        )
+    ]
+)
+def opensearchxml(request):
+    request.response.content_type = "text/xml"
+    return {}
+
+
 @view_config(
     route_name="index",
     renderer="index.html",


Test patch:
diff --git a/tests/unit/test_routes.py b/tests/unit/test_routes.py
--- a/tests/unit/test_routes.py
+++ b/tests/unit/test_routes.py
@@ -70,6 +70,7 @@ def add_xmlrpc_endpoint(endpoint, pattern, header, domain=None):
         pretend.call("health", "/_health/"),
         pretend.call('index', '/', domain=warehouse),
         pretend.call("robots.txt", "/robots.txt", domain=warehouse),
+        pretend.call("opensearch.xml", "/opensearch.xml", domain=warehouse),
         pretend.call("index.sitemap.xml", "/sitemap.xml", domain=warehouse),
         pretend.call(
             "bucket.sitemap.xml",
diff --git a/tests/unit/test_views.py b/tests/unit/test_views.py
--- a/tests/unit/test_views.py
+++ b/tests/unit/test_views.py
@@ -24,7 +24,7 @@
 from warehouse import views
 from warehouse.views import (
     SEARCH_BOOSTS, SEARCH_FIELDS, current_user_indicator, forbidden, health,
-    httpexception_view, index, robotstxt, search
+    httpexception_view, index, robotstxt, opensearchxml, search
 )
 
 from ..common.db.accounts import UserFactory
@@ -69,6 +69,11 @@ def test_robotstxt(pyramid_request):
     assert pyramid_request.response.content_type == "text/plain"
 
 
+def test_opensearchxml(pyramid_request):
+    assert opensearchxml(pyramid_request) == {}
+    assert pyramid_request.response.content_type == "text/xml"
+
+
 class TestIndex:
 
     def test_index(self, db_request):
Repository: pypi/warehouse

Issue:
Expose 'requires-python' metadata in package detail sidebar
From #1061 

> Adding requires-python would be good, probably something that can wait until after launch though because while I think it's a generally useful feature, I don't think anyone currently uses it (because setuptools doesn't expose it).



Discussion:

Resolving patch:
diff --git a/warehouse/packaging/models.py b/warehouse/packaging/models.py
--- a/warehouse/packaging/models.py
+++ b/warehouse/packaging/models.py
@@ -348,7 +348,8 @@ def has_meta(self):
         return any([self.license,
                     self.keywords,
                     self.author, self.author_email,
-                    self.maintainer, self.maintainer_email])
+                    self.maintainer, self.maintainer_email,
+                    self.requires_python])
 
 
 class File(db.Model):


Test patch:
Repository: pypi/warehouse

Issue:
[WIP] Show Author and Maintainer in Project detail view
Refs #1060 

@dstufft I need some input regarding the implementation of email validation. How do you want to have this implemented? Should I use a self written primitive regex? Or a package like https://pypi.python.org/pypi/validate_email ? Something else?



Discussion:

Resolving patch:
diff --git a/warehouse/packaging/models.py b/warehouse/packaging/models.py
--- a/warehouse/packaging/models.py
+++ b/warehouse/packaging/models.py
@@ -342,7 +342,9 @@ def urls(self):
 
     @property
     def has_meta(self):
-        return any([self.keywords])
+        return any([self.keywords,
+                    self.author, self.author_email,
+                    self.maintainer, self.maintainer_email])
 
 
 class File(db.Model):


Test patch:
diff --git a/tests/unit/packaging/test_models.py b/tests/unit/packaging/test_models.py
--- a/tests/unit/packaging/test_models.py
+++ b/tests/unit/packaging/test_models.py
@@ -107,6 +107,20 @@ def test_has_meta_true_with_keywords(self, db_session):
         release = DBReleaseFactory.create(keywords="foo, bar")
         assert release.has_meta
 
+    def test_has_meta_true_with_author(self, db_session):
+        release = DBReleaseFactory.create(author="Batman")
+        assert release.has_meta
+
+        release = DBReleaseFactory.create(author_email="wayne@gotham.ny")
+        assert release.has_meta
+
+    def test_has_meta_true_with_maintainer(self, db_session):
+        release = DBReleaseFactory.create(maintainer="Spiderman")
+        assert release.has_meta
+
+        release = DBReleaseFactory.create(maintainer_email="peter@parker.mrvl")
+        assert release.has_meta
+
     def test_has_meta_false(self, db_session):
         release = DBReleaseFactory.create()
         assert not release.has_meta