hash_reqs: Include python version when generating hash.

Fixes #12868.
We now also include python version in the format
'major.minor.patchlevel', when generating hash for a
requirement file. This was necessary since packages tend to
break on different versions of python, so it is important to
track the version on which the venv was setup.

WARN: This commit will force all zulip venvs to be recreated.
This commit is contained in:
Aman Agrawal 2020-07-09 22:03:16 +05:30 committed by Tim Abbott
parent 2668829c93
commit 685ec2a098
3 changed files with 40 additions and 5 deletions

View File

@ -2,8 +2,9 @@
import argparse
import hashlib
import os
import subprocess
import sys
from typing import Iterable, List, MutableSet
from typing import Iterable, List
def expand_reqs_helper(fpath: str) -> List[str]:
@ -27,8 +28,14 @@ def expand_reqs(fpath: str) -> List[str]:
output = expand_reqs_helper(absfpath)
return sorted(set(output))
def python_version() -> str:
"""
Returns the Python version as string 'Python major.minor.patchlevel'
"""
return subprocess.check_output(["/usr/bin/python3", "-VV"], universal_newlines=True)
def hash_deps(deps: Iterable[str]) -> str:
deps_str = "\n".join(deps) + "\n"
deps_str = "\n".join(deps) + "\n" + python_version()
return hashlib.sha1(deps_str.encode('utf-8')).hexdigest()
def main() -> int:

View File

@ -262,16 +262,19 @@ def do_patch_activate_script(venv_path: str) -> None:
with open(script_path, 'w') as f:
f.write("".join(lines))
def generate_hash(requirements_file: str) -> str:
path = os.path.join(ZULIP_PATH, 'scripts', 'lib', 'hash_reqs.py')
output = subprocess.check_output([path, requirements_file], universal_newlines=True)
return output.split()[0]
def setup_virtualenv(
target_venv_path: Optional[str],
requirements_file: str,
patch_activate_script: bool = False,
) -> str:
sha1sum = generate_hash(requirements_file)
# Check if a cached version already exists
path = os.path.join(ZULIP_PATH, 'scripts', 'lib', 'hash_reqs.py')
output = subprocess.check_output([path, requirements_file], universal_newlines=True)
sha1sum = output.split()[0]
if target_venv_path is None:
cached_venv_path = os.path.join(VENV_CACHE_PATH, sha1sum, 'venv')
else:

View File

@ -0,0 +1,25 @@
import unittest
import mock
from scripts.lib.hash_reqs import expand_reqs, hash_deps
from tools.setup.setup_venvs import DEV_REQS_FILE
class TestHashCreation(unittest.TestCase):
def test_diff_hash_for_diff_python_version(self) -> None:
with mock.patch('scripts.lib.hash_reqs.python_version', return_value='Python 3.6.9'):
deps = expand_reqs(DEV_REQS_FILE)
hash1 = hash_deps(deps)
with mock.patch('scripts.lib.hash_reqs.python_version', return_value='Python 3.6.9'):
deps = expand_reqs(DEV_REQS_FILE)
hash2 = hash_deps(deps)
with mock.patch('scripts.lib.hash_reqs.python_version', return_value='Python 3.8.2'):
deps = expand_reqs(DEV_REQS_FILE)
hash3 = hash_deps(deps)
assert hash1 == hash2
assert hash1 != hash3