From abf70c24b1782f0c3ed1e2045db4df4c172b594d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 28 Mar 2022 15:58:40 -0600 Subject: [PATCH 1/3] Add get_pkg_name(). --- pyperformance/_pip.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pyperformance/_pip.py b/pyperformance/_pip.py index aa4f4983..7fc07874 100644 --- a/pyperformance/_pip.py +++ b/pyperformance/_pip.py @@ -14,6 +14,16 @@ OLD_SETUPTOOLS = '18.5' +def get_pkg_name(req): + """Return the name of the package in the given requirement text.""" + # strip env markers + req = req.partition(';')[0] + # strip version + req = req.partition('==')[0] + req = req.partition('>=')[0] + return req + + def get_best_pip_version(python): """Return the pip to install for the given Python executable.""" if not python or isinstance(python, str): From 378b8a56d9be3b52e17e10884dd81eb5f08f77e7 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 28 Mar 2022 15:59:04 -0600 Subject: [PATCH 2/3] Drop the optional part of Requirements. --- pyperformance/venv.py | 47 +++++++++---------------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/pyperformance/venv.py b/pyperformance/venv.py index b739bb38..453d724f 100644 --- a/pyperformance/venv.py +++ b/pyperformance/venv.py @@ -12,9 +12,9 @@ class Requirements(object): @classmethod - def from_file(cls, filename, optional=None): + def from_file(cls, filename): self = cls() - self._add_from_file(filename, optional) + self._add_from_file(filename) return self @classmethod @@ -32,44 +32,25 @@ def __init__(self): # requirements self.specs = [] - # optional requirements - self._optional = set() - def __len__(self): return len(self.specs) - def iter_non_optional(self): + def __iter__(self): for spec in self.specs: - if spec in self._optional: - continue yield spec - def iter_optional(self): - for spec in self.specs: - if spec not in self._optional: - continue - yield spec - - def _add_from_file(self, filename, optional=None): + def _add_from_file(self, filename): if not os.path.exists(filename): return for line in _utils.iter_clean_lines(filename): - self._add(line, optional) + self._add(line) - def _add(self, line, optional=None): + def _add(self, line): self.specs.append(line) - if optional: - # strip env markers - req = line.partition(';')[0] - # strip version - req = req.partition('==')[0] - req = req.partition('>=')[0] - if req in optional: - self._optional.add(line) def get(self, name): for req in self.specs: - if req.startswith(name): + if _pip.get_pkg_name(req) == name: return req return None @@ -186,7 +167,7 @@ def install_pyperformance(self): print("installing pyperformance in the venv at %s" % self.root) # Install pyperformance inside the virtual environment. if pyperformance.is_dev(): - basereqs = Requirements.from_file(REQUIREMENTS_FILE, ['psutil']) + basereqs = Requirements.from_file(REQUIREMENTS_FILE) self.ensure_reqs(basereqs) root_dir = os.path.dirname(pyperformance.PKG_ROOT) @@ -216,7 +197,7 @@ def ensure_reqs(self, requirements=None, *, exitonerror=False): # Every benchmark must depend on pyperf. if bench is not None and not requirements.get('pyperf'): - basereqs = Requirements.from_file(REQUIREMENTS_FILE, ['psutil']) + basereqs = Requirements.from_file(REQUIREMENTS_FILE) pyperf_req = basereqs.get('pyperf') if not pyperf_req: raise NotImplementedError @@ -229,7 +210,7 @@ def ensure_reqs(self, requirements=None, *, exitonerror=False): # install requirements try: super().ensure_reqs( - *requirements.iter_non_optional(), + *requirements, upgrade=False, ) except _venv.RequirementsInstallationFailedError: @@ -237,14 +218,6 @@ def ensure_reqs(self, requirements=None, *, exitonerror=False): sys.exit(1) raise # re-raise - # install optional requirements - for req in requirements.iter_optional(): - try: - super().ensure_reqs(req, upgrade=True) - except _venv.RequirementsInstallationFailedError: - print("WARNING: failed to install %s" % req) - print() - # Dump the package list and their versions: pip freeze _pip.run_pip('freeze', python=self.python, env=self._env) From ae59df9b18103fca6c7179c3601441cea038db4a Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 28 Mar 2022 15:59:43 -0600 Subject: [PATCH 3/3] Always try to install the optional pyperf depdencies. --- pyperformance/venv.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pyperformance/venv.py b/pyperformance/venv.py index 453d724f..d1cac9ac 100644 --- a/pyperformance/venv.py +++ b/pyperformance/venv.py @@ -7,6 +7,7 @@ REQUIREMENTS_FILE = os.path.join(pyperformance.DATA_DIR, 'requirements.txt') +PYPERF_OPTIONAL = ['psutil'] class Requirements(object): @@ -169,6 +170,8 @@ def install_pyperformance(self): if pyperformance.is_dev(): basereqs = Requirements.from_file(REQUIREMENTS_FILE) self.ensure_reqs(basereqs) + if basereqs.get('pyperf'): + self._install_pyperf_optional_dependencies() root_dir = os.path.dirname(pyperformance.PKG_ROOT) ec, _, _ = _pip.install_editable( @@ -183,9 +186,18 @@ def install_pyperformance(self): python=self.info, env=self._env, ) + self._install_pyperf_optional_dependencies() if ec != 0: sys.exit(ec) + def _install_pyperf_optional_dependencies(self): + for req in PYPERF_OPTIONAL: + try: + self.ensure_reqs([req]) + except _venv.RequirementsInstallationFailedError: + print("WARNING: failed to install %s" % req) + pass + def ensure_reqs(self, requirements=None, *, exitonerror=False): # parse requirements bench = None @@ -218,6 +230,9 @@ def ensure_reqs(self, requirements=None, *, exitonerror=False): sys.exit(1) raise # re-raise + if bench is not None: + self._install_pyperf_optional_dependencies() + # Dump the package list and their versions: pip freeze _pip.run_pip('freeze', python=self.python, env=self._env)