Repository: pypa/pip

Issue:
Unhelpful error message when --find-links is a non-existent file path (without file:// scheme)
If `--find-links` is set to a file path (such as `/home/user/.cache/wheelhouse`), pip generates this warning when trying to install packages:

```
This repository located at None is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host None'.
```

This is not necessarily an issue if the path is not needed to install the package (for example, if the package is on PyPI, it will still successfully install, even with the warning). This is less of an issue now that pip caches wheels automatically (so removing manual caching of wheels is a viable solution for me), but caused me quite a bit of confusion.

After a bit of investigation, it seems like this is because the code [here](https://github.com/pypa/pip/blob/685c8b5ace6aaac7bf8c2c0269a9adb95e17a6ad/pip/index.py#L287-L288) sets `parsed` to `('', None, None)`. 

One potential solution is to use `location` instead of `parsed.hostname` in the [error message](https://github.com/pypa/pip/blob/685c8b5ace6aaac7bf8c2c0269a9adb95e17a6ad/pip/index.py#L338-L345) if the latter is `None`. 

But that raises the issue of whether file paths should be considered secure origins even if they don't use a `file:` scheme. I imagine they probably should, but haven't thought through all the implications. If so, then the logic elsewhere in the `_validate_secure_origin` function should probably be modified instead. Using a URL such as `file:///home/user/.cache/wheelhouse` does not cause this issue.

Another potential solution would be to require local file references to use the `file:` scheme. This could break existing use cases, however, since the [pip documentation](https://pip.readthedocs.org/en/latest/reference/pip_wheel.html#find-links) refers to "a local path or file:// url".



Discussion:
It looks like `/home/user/.cache/wheelhouse` did not exist and `_sort_locations` classified it as an url: https://github.com/pypa/pip/blob/685c8b5ace6aaac7bf8c2c0269a9adb95e17a6ad/pip/index.py#L222

I agree the warning could be improved maybe we could go the other way require a scheme for all url ? (and not for filepath).

Ahh, that helps explain why no one else is really seeing this bug. I started on a new machine around the same time pip started caching wheels, so I didn't bother to create the wheelhouse directory. I didn't realize that this warning only occurs for directories that don't exist (and therefore are assumed to be URLs).


Resolving patch:
diff --git a/pip/index.py b/pip/index.py
--- a/pip/index.py
+++ b/pip/index.py
@@ -25,7 +25,7 @@
     DistributionNotFound, BestVersionAlreadyInstalled, InvalidWheelFilename,
     UnsupportedWheel,
 )
-from pip.download import HAS_TLS, url_to_path, path_to_url
+from pip.download import HAS_TLS, is_url, path_to_url, url_to_path
 from pip.models import PyPI
 from pip.wheel import Wheel, wheel_ext
 from pip.pep425tags import supported_tags, supported_tags_noarch, get_platform
@@ -214,8 +214,17 @@ def sort_path(path):
                         urls.append(url)
                 elif os.path.isfile(path):
                     sort_path(path)
-            else:
+                else:
+                    logger.warning(
+                        "Url '%s' is ignored: it is neither a file "
+                        "nor a directory.", url)
+            elif is_url(url):
+                # Only add url with clear scheme
                 urls.append(url)
+            else:
+                logger.warning(
+                    "Url '%s' is ignored. It is either a non-existing "
+                    "path or lacks a specific scheme.", url)
 
         return files, urls
 


Test patch:
diff --git a/tests/unit/test_index.py b/tests/unit/test_index.py
--- a/tests/unit/test_index.py
+++ b/tests/unit/test_index.py
@@ -1,3 +1,4 @@
+import os.path
 import pytest
 
 from pip.download import PipSession
@@ -27,6 +28,16 @@ def test_sort_locations_file_not_find_link(data):
     assert urls and not files, "urls, but not files should have been found"
 
 
+def test_sort_locations_non_existing_path():
+    """
+    Test that a non-existing path is ignored.
+    """
+    finder = PackageFinder([], [], session=PipSession())
+    files, urls = finder._sort_locations(
+        [os.path.join('this', 'doesnt', 'exist')])
+    assert not urls and not files, "nothing should have been found"
+
+
 class TestLink(object):
 
     def test_splitext(self):