Repository: pypi/warehouse

Issue:
error 404 when searching for a package name with underscores
when I try to search for a package name which contains underscores I get a 404 error

example: https://pypi.io/search/?q=test_test

error 404 when searching for a package name with underscores
when I try to search for a package name which contains underscores I get a 404 error

example: https://pypi.io/search/?q=test_test



Discussion:

Resolving patch:
diff --git a/warehouse/utils/paginate.py b/warehouse/utils/paginate.py
--- a/warehouse/utils/paginate.py
+++ b/warehouse/utils/paginate.py
@@ -44,9 +44,10 @@ def __getitem__(self, range):
         self.results = self.query[range].execute()
 
         if hasattr(self.results, "suggest"):
-            suggestion = self.results.suggest.name_suggestion[0]
-            if suggestion.options:
-                self.best_guess = suggestion.options[0]
+            if self.results.suggest.name_suggestion:
+                suggestion = self.results.suggest.name_suggestion[0]
+                if suggestion.options:
+                    self.best_guess = suggestion.options[0]
 
         return list(self.results)
 
diff --git a/warehouse/views.py b/warehouse/views.py
--- a/warehouse/views.py
+++ b/warehouse/views.py
@@ -182,7 +182,7 @@ def search(request):
         url_maker=paginate_url_factory(request),
     )
 
-    if page_num > page.page_count:
+    if page.page_count and page_num > page.page_count:
         raise HTTPNotFound
 
     available_filters = collections.defaultdict(list)


Test patch:
diff --git a/tests/unit/utils/test_paginate.py b/tests/unit/utils/test_paginate.py
--- a/tests/unit/utils/test_paginate.py
+++ b/tests/unit/utils/test_paginate.py
@@ -47,14 +47,17 @@ def __iter__(self):
 
 class FakeSuggestResult(FakeResult):
 
-    def __init__(self, data, total, options):
+    def __init__(self, data, total, options=None, suggestion=None):
         super().__init__(data, total)
         self.options = options
+        self.suggestion = suggestion
 
     @property
     def suggest(self):
-        suggestion = FakeSuggestion(options=self.options)
-        return FakeSuggest(name_suggestion=[suggestion])
+        if self.suggestion is None:
+            suggestion = FakeSuggestion(options=self.options)
+            return FakeSuggest(name_suggestion=[suggestion])
+        return FakeSuggest(name_suggestion=self.suggestion)
 
 
 class FakeQuery:
@@ -77,14 +80,15 @@ def execute(self):
 
 class FakeSuggestQuery(FakeQuery):
 
-    def __init__(self, fake, options):
+    def __init__(self, fake, options=None, suggestion=None):
         super().__init__(fake)
         self.options = options
+        self.suggestion = suggestion
 
     def execute(self):
         data = self.fake[self.range]
         total = len(self.fake)
-        return FakeSuggestResult(data, total, self.options)
+        return FakeSuggestResult(data, total, self.options, self.suggestion)
 
 
 class TestElasticsearchWrapper:
@@ -127,6 +131,13 @@ def test_best_guess_suggestion(self):
 
         assert wrapper.best_guess == fake_option
 
+    def test_best_guess_suggestion_no_suggestions(self):
+        query = FakeSuggestQuery([1, 2, 3, 4, 5, 6], suggestion=[])
+        wrapper = paginate._ElasticsearchWrapper(query)
+        wrapper[1:3]
+
+        assert wrapper.best_guess is None
+
     def test_best_guess_suggestion_no_options(self):
         query = FakeSuggestQuery([1, 2, 3, 4, 5, 6], options=[])
         wrapper = paginate._ElasticsearchWrapper(query)