Repository: pypa/pip

Issue:
Add pre-released package upgrade hints
Before this commit when querying for an installed package using pip if
the package that was returned contained a pre-released version of the
package it was not intuitive that the pre-released version of the
package could not be directly upgraded to without the `--pre` flag.

This commit shows additional information on how to upgrade to
pre-released versions of a package if one is found in the search.

Fixes #5169.

<!---
Thank you for your soon to be pull request. Before you submit this, please
double check to make sure that you've added a news file fragment. In pip we
generate our NEWS.rst from multiple news fragment files, and all pull requests
require either a news file fragment or a marker to indicate they don't require
one.

To read more about adding a news file fragment for your PR, please check out
our documentation at: https://pip.pypa.io/en/latest/development/#adding-a-news-entry
-->

Display pre-release version hint in package version output of "pip search" (and others)
* Pip version: pip 9.0.3 from c:\python36\lib\site-packages (python 3.6)
* Python version: Python 3.6.2
* Operating system: Windows 10

### Description:

In #5168 I learned that version numbers like "2018.04.04a" are interpreted as pre-release versions. Therefore I could not install them without adding the parameter `--pre`.

However, this is _implicit_ knowledge the user must have about interpretations of version numbers and related pip behavior in order to understand the behavior of pip. Otherwise, the user is irritated, just like I was until a couple of minutes ago.

Current situation where 2018.04.04a is not installable when `--pre` is not given:

```
C:\Users\karl.voit>pip search filetags
filetags (2018.04.04a)  - Management of simple tags within file names
  INSTALLED: 2018.3.19
  LATEST:    2018.04.04a

C:\Users\karl.voit>
```

Shouldn't there at least be a hint such as following suggestion?

```
C:\Users\karl.voit>pip search filetags
filetags (2018.04.04a)  - Management of simple tags within file names
  INSTALLED: 2018.3.19
  LATEST:    2018.04.04a (pre-release; install with "pip install --pre")

C:\Users\karl.voit>
```

Maybe this applies for multiple stdout messages.

### What I've run:

See #5168 to give you some background.


Discussion:
Hey @demophoon! Thanks for this PR! :)

Instead of a "trivial" NEWS fragment, this should have a "feature" NEWS fragment. 
I will add those tests when I get a free moment! Thanks for giving this a look over!
Pushing this down the road to the next release since I don't think this'd happen in time for 18.0.
@demophoon pip 18.1 is scheduled for next month; would you be able to take a look at this PR before then?

Otherwise, we can go ahead and defer this to a later release.
I scheduled some time this weekend to finish this up! Sorry it has taken so long!
I missed that you'd pushed changes to this PR.

The CI seems to be failing since the tests corresponding to this functionality are failing.

---

Deferring this to a later release since this isn't in a merge-able state right now.


Resolving patch:
diff --git a/src/pip/_internal/commands/search.py b/src/pip/_internal/commands/search.py
--- a/src/pip/_internal/commands/search.py
+++ b/src/pip/_internal/commands/search.py
@@ -126,7 +126,11 @@ def print_results(hits, name_column_width=None, terminal_width=None):
                         logger.info('INSTALLED: %s (latest)', dist.version)
                     else:
                         logger.info('INSTALLED: %s', dist.version)
-                        logger.info('LATEST:    %s', latest)
+                        if parse_version(latest).pre:
+                            logger.info('LATEST:    %s (pre-release; install'
+                                        ' with "pip install --pre")', latest)
+                        else:
+                            logger.info('LATEST:    %s', latest)
         except UnicodeEncodeError:
             pass
 


Test patch:
diff --git a/tests/functional/test_search.py b/tests/functional/test_search.py
--- a/tests/functional/test_search.py
+++ b/tests/functional/test_search.py
@@ -1,5 +1,6 @@
 import logging
 
+import pretend
 import pytest
 
 from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS
@@ -144,6 +145,33 @@ def test_search_exit_status_code_when_finds_no_package(script):
     assert result.returncode == NO_MATCHES_FOUND, result.returncode
 
 
+def test_latest_prerelease_install_message(caplog, monkeypatch):
+    """
+    Test documentation for installing pre-release packages is displayed
+    """
+    hits = [
+        {
+            'name': 'ni',
+            'summary': 'For knights who say Ni!',
+            'versions': ['1.0.0', '1.0.1a']
+        }
+    ]
+
+    installed_package = pretend.stub(project_name="ni")
+    monkeypatch.setattr("pip._vendor.pkg_resources.working_set",
+                        [installed_package])
+
+    dist = pretend.stub(version="1.0.0")
+    get_dist = pretend.call_recorder(lambda x: dist)
+    monkeypatch.setattr("pip._vendor.pkg_resources.get_distribution", get_dist)
+    with caplog.at_level(logging.INFO):
+        print_results(hits)
+
+    message = caplog.records[-1].getMessage()
+    assert 'pre-release; install with "pip install --pre"' in message
+    assert get_dist.calls == [pretend.call('ni')]
+
+
 def test_search_print_results_should_contain_latest_versions(caplog):
     """
     Test that printed search results contain the latest package versions