diff --git a/pipenv/core.py b/pipenv/core.py index 25bd0b7e..d72d2e0f 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1257,6 +1257,26 @@ def do_init( ), err=True, ) + elif old_hash is None: + # Lockfile corrupted, remove it and replaced + click.echo( + crayons.red( + u"Pipfile.lock is corrupted, replaced with ({0})…".format( + new_hash[-6:] + ), + bold=True, + ), + err=True + ) + os.remove(project.lockfile_location) + do_lock( + system=system, + pre=pre, + keep_outdated=keep_outdated, + verbose=verbose, + write=True, + pypi_mirror=pypi_mirror, + ) else: click.echo( crayons.red( diff --git a/pipenv/project.py b/pipenv/project.py index b12f7c64..275a6b41 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -815,7 +815,11 @@ class Project(object): if not os.path.exists(self.lockfile_location): return - lockfile = self.load_lockfile(expand_env_vars=False) + try: + lockfile = self.load_lockfile(expand_env_vars=False) + except json.decoder.JSONDecodeError: + # Lockfile corrupted + return if "_meta" in lockfile and hasattr(lockfile, "keys"): return lockfile["_meta"].get("hash", {}).get("sha256") # Lockfile exists but has no hash at all diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py index 25195bfb..a0cdfe15 100644 --- a/tests/integration/test_lock.py +++ b/tests/integration/test_lock.py @@ -385,3 +385,25 @@ django = "*" django_version = '==2.0.6' if py_version.startswith('3') else '==1.11.13' assert py_version == '2.7.14' assert p.lockfile['default']['django']['version'] == django_version + + +@pytest.mark.lock +@pytest.mark.install +def test_lockfile_corrupted(PipenvInstance): + with PipenvInstance() as p: + with open(p.lockfile_path, 'w') as f: + f.write('{corrupt}') + c = p.pipenv('install') + assert c.return_code == 0 + assert p.lockfile['_meta'] + + +@pytest.mark.lock +@pytest.mark.install +def test_lockfile_with_empty_dict(PipenvInstance): + with PipenvInstance() as p: + with open(p.lockfile_path, 'w') as f: + f.write('{}') + c = p.pipenv('install') + assert c.return_code == 0 + assert p.lockfile['_meta'] \ No newline at end of file