From 0f54a63dfd33905d55de1148b2ef02cccb56b48c Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Fri, 11 Nov 2022 09:50:07 +0100 Subject: remove activate/deactivate support in favor of environments (#29317) Environments and environment views have taken over the role of `spack activate/deactivate`, and we should deprecate these commands for several reasons: - Global activation is a really poor idea: - Install prefixes should be immutable; since they can have multiple, unrelated dependents; see below - Added complexity elsewhere: verification of installations, tarballs for build caches, creation of environment views of packages with unrelated extensions "globally activated"... by removing the feature, it gets easier for people to contribute, and we'd end up with fewer bugs due to edge cases. - Environment accomplish the same thing for non-global "activation" i.e. `spack view`, but better. Also we write in the docs: ``` However, Spack global activations have two potential drawbacks: #. Activated packages that involve compiled C extensions may still need their dependencies to be loaded manually. For example, ``spack load openblas`` might be required to make ``py-numpy`` work. #. Global activations "break" a core feature of Spack, which is that multiple versions of a package can co-exist side-by-side. For example, suppose you wish to run a Python package in two different environments but the same basic Python --- one with ``py-numpy@1.7`` and one with ``py-numpy@1.8``. Spack extensions will not support this potential debugging use case. ``` Now that environments are established and views can take over the role of activation non-destructively, we can remove global activation/deactivation. --- var/spack/repos/builtin/packages/perl/package.py | 22 ----- var/spack/repos/builtin/packages/python/package.py | 108 +-------------------- 2 files changed, 1 insertion(+), 129 deletions(-) (limited to 'var') diff --git a/var/spack/repos/builtin/packages/perl/package.py b/var/spack/repos/builtin/packages/perl/package.py index b268c86f2b..76ee382ef4 100644 --- a/var/spack/repos/builtin/packages/perl/package.py +++ b/var/spack/repos/builtin/packages/perl/package.py @@ -482,28 +482,6 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package return match_predicate(ignore_arg, patterns) - def activate(self, ext_pkg, view, **args): - ignore = self.perl_ignore(ext_pkg, args) - args.update(ignore=ignore) - - super(Perl, self).activate(ext_pkg, view, **args) - - extensions_layout = view.extensions_layout - exts = extensions_layout.extension_map(self.spec) - exts[ext_pkg.name] = ext_pkg.spec - - def deactivate(self, ext_pkg, view, **args): - ignore = self.perl_ignore(ext_pkg, args) - args.update(ignore=ignore) - - super(Perl, self).deactivate(ext_pkg, view, **args) - - extensions_layout = view.extensions_layout - exts = extensions_layout.extension_map(self.spec) - # Make deactivate idempotent - if ext_pkg.name in exts: - del exts[ext_pkg.name] - @property def command(self): """Returns the Perl command, which may vary depending on the version diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py index 1681e2524e..91e635b38a 100644 --- a/var/spack/repos/builtin/packages/python/package.py +++ b/var/spack/repos/builtin/packages/python/package.py @@ -18,7 +18,7 @@ from llnl.util.filesystem import ( is_nonsymlink_exe_with_shebang, path_contains_subdirectory, ) -from llnl.util.lang import dedupe, match_predicate +from llnl.util.lang import dedupe from spack.build_environment import dso_suffix, stat_suffix from spack.package import * @@ -1401,10 +1401,6 @@ config.update(get_paths()) return path.replace(prefix, "") return os.path.join("include", "python{}".format(self.version.up_to(2))) - @property - def easy_install_file(self): - return join_path(self.purelib, "easy-install.pth") - def setup_run_environment(self, env): env.prepend_path("CPATH", os.pathsep.join(self.spec["python"].headers.directories)) @@ -1526,108 +1522,6 @@ config.update(get_paths()) mkdirp(module.python_platlib) mkdirp(module.python_purelib) - # ======================================================================== - # Handle specifics of activating and deactivating python modules. - # ======================================================================== - - def python_ignore(self, ext_pkg, args): - """Add some ignore files to activate/deactivate args.""" - ignore_arg = args.get("ignore", lambda f: False) - - # Always ignore easy-install.pth, as it needs to be merged. - patterns = [r"(site|dist)-packages/easy-install\.pth$"] - - # Ignore pieces of setuptools installed by other packages. - # Must include directory name or it will remove all site*.py files. - if ext_pkg.name != "py-setuptools": - patterns.extend( - [ - r"bin/easy_install[^/]*$", - r"(site|dist)-packages/setuptools[^/]*\.egg$", - r"(site|dist)-packages/setuptools\.pth$", - r"(site|dist)-packages/site[^/]*\.pyc?$", - r"(site|dist)-packages/__pycache__/site[^/]*\.pyc?$", - ] - ) - if ext_pkg.name != "py-pygments": - patterns.append(r"bin/pygmentize$") - if ext_pkg.name != "py-numpy": - patterns.append(r"bin/f2py[0-9.]*$") - - return match_predicate(ignore_arg, patterns) - - def write_easy_install_pth(self, exts, prefix=None): - if not prefix: - prefix = self.prefix - - paths = [] - unique_paths = set() - - for ext in sorted(exts.values()): - easy_pth = join_path(ext.prefix, self.easy_install_file) - - if not os.path.isfile(easy_pth): - continue - - with open(easy_pth) as f: - for line in f: - line = line.rstrip() - - # Skip lines matching these criteria - if not line: - continue - if re.search(r"^(import|#)", line): - continue - if ext.name != "py-setuptools" and re.search(r"setuptools.*egg$", line): - continue - - if line not in unique_paths: - unique_paths.add(line) - paths.append(line) - - main_pth = join_path(prefix, self.easy_install_file) - - if not paths: - if os.path.isfile(main_pth): - os.remove(main_pth) - - else: - with open(main_pth, "w") as f: - f.write("import sys; sys.__plen = len(sys.path)\n") - for path in paths: - f.write("{0}\n".format(path)) - f.write( - "import sys; new=sys.path[sys.__plen:]; " - "del sys.path[sys.__plen:]; " - "p=getattr(sys,'__egginsert',0); " - "sys.path[p:p]=new; " - "sys.__egginsert = p+len(new)\n" - ) - - def activate(self, ext_pkg, view, **args): - ignore = self.python_ignore(ext_pkg, args) - args.update(ignore=ignore) - - super(Python, self).activate(ext_pkg, view, **args) - - extensions_layout = view.extensions_layout - exts = extensions_layout.extension_map(self.spec) - exts[ext_pkg.name] = ext_pkg.spec - - self.write_easy_install_pth(exts, prefix=view.get_projection_for_spec(self.spec)) - - def deactivate(self, ext_pkg, view, **args): - args.update(ignore=self.python_ignore(ext_pkg, args)) - - super(Python, self).deactivate(ext_pkg, view, **args) - - extensions_layout = view.extensions_layout - exts = extensions_layout.extension_map(self.spec) - # Make deactivate idempotent - if ext_pkg.name in exts: - del exts[ext_pkg.name] - self.write_easy_install_pth(exts, prefix=view.get_projection_for_spec(self.spec)) - def add_files_to_view(self, view, merge_map, skip_if_exists=True): bin_dir = self.spec.prefix.bin if sys.platform != "win32" else self.spec.prefix for src, dst in merge_map.items(): -- cgit v1.2.3-70-g09d2