Repository: pypa/pipenv

Issue:
Windows SHA Hash Mismatch
Pipenv version: 2018.10.13

### Issue description

I'm installing a whl file directly on Windows due to incompatibilities from pip.  The whl file comes from Gohlke.

I'm able to workaround the issue by manually modifying the SHA value on the lock file.  But anytime I run install or update again, I get the same error message.

### Expected result

The whl file is installed without errors.

### Actual result

Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (8ccf84)!
Installing dependencies from Pipfile.lock (8ccf84)…
An error occurred while installing ./python_ldap-3.1.0-cp37-cp37m-win_amd64.whl --hash=sha256:41975e79406502c092732c57ef0c2c2eb318d91e8e765f81f5d4ab6c1db727c5!
Will try again.
  ================================ 49/49 - 00:00:12
Installing initially failed dependencies…
Processing [........]\python_ldap-3.1.0-cp37-cp37m-win_amd64.whl

THESE PACKAGES DO NOT MATCH THE HASHES FROM Pipfile.lock!. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
    python-ldap==3.1.0 from [......]/python_ldap-3.1.0-cp37-cp37m-win_amd64.whl (from -r [..........]pipenv-[...]-requirement.txt (line 1)):
        Expected sha256 41975e79406502c092732c57ef0c2c2eb318d91e8e765f81f5d4ab6c1db727c5
             Got        a424ecb9f16ab7723d570c12713dd2f3ae84c605c93ee19d6cc1c47fec61815b


### Steps to replicate

pipenv install python_ldap-3.1.0-cp37-cp37m-win_amd64.whl
pipenv update




Discussion:
I've thought this should be fixed in #3147 

/cc @techalchemy 

Resolving patch:
diff --git a/pipenv/utils.py b/pipenv/utils.py
--- a/pipenv/utils.py
+++ b/pipenv/utils.py
@@ -361,36 +361,6 @@ def get_resolver(self, clear=False, pre=False):
             clear_caches=clear, prereleases=pre,
         )
 
-    def populate_file_hashes(self):
-        from pipenv.vendor.vistir.compat import Path, to_native_string
-        from pipenv.vendor.vistir.path import url_to_path
-
-        def _should_include(ireq):
-            # We can only hash artifacts.
-            try:
-                if not ireq.link.is_artifact:
-                    return False
-            except AttributeError:
-                return False
-
-            # But we don't want normal pypi artifcats since the normal resolver
-            # handles those
-            if is_pypi_url(ireq.link.url):
-                return False
-
-            # We also don't want to try to hash directories as this will fail
-            # as these are editable deps and are not hashable.
-            if (ireq.link.scheme == "file" and
-                    Path(to_native_string(url_to_path(ireq.link.url))).is_dir()):
-                return False
-            return True
-
-        self.hashes.update({
-            ireq: self.resolver._hash_cache.get_hash(ireq.link)
-            for ireq in self.parsed_constraints
-            if _should_include(ireq)
-        })
-
     @property
     def resolver(self):
         if self._resolver is None:
@@ -421,11 +391,39 @@ def resolve(self):
             return self.resolved_tree
 
     def resolve_hashes(self):
+        def _should_include_hash(ireq):
+            from pipenv.vendor.vistir.compat import Path, to_native_string
+            from pipenv.vendor.vistir.path import url_to_path
+
+            # We can only hash artifacts.
+            try:
+                if not ireq.link.is_artifact:
+                    return False
+            except AttributeError:
+                return False
+
+            # But we don't want normal pypi artifcats since the normal resolver
+            # handles those
+            if is_pypi_url(ireq.link.url):
+                return False
+
+            # We also don't want to try to hash directories as this will fail
+            # as these are editable deps and are not hashable.
+            if (ireq.link.scheme == "file" and
+                    Path(to_native_string(url_to_path(ireq.link.url))).is_dir()):
+                return False
+            return True
+
         if self.results is not None:
             resolved_hashes = self.resolver.resolve_hashes(self.results)
             for ireq, ireq_hashes in resolved_hashes.items():
                 if ireq not in self.hashes:
-                    self.hashes[ireq] = ireq_hashes
+                    if _should_include_hash(ireq):
+                        self.hashes[ireq] = [
+                            self.resolver.repository._hash_cache.get_hash(ireq.link)
+                        ]
+                    else:
+                        self.hashes[ireq] = ireq_hashes
             return self.hashes
 
 


Test patch: