summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPeter Scheibel <scheibel1@llnl.gov>2020-02-20 13:45:58 -0800
committerGitHub <noreply@github.com>2020-02-20 13:45:58 -0800
commit2e387ef5855d533f685478cc15e3d9bea799bf30 (patch)
tree25fc1e5cdfc3298de513144bd714345130e32398 /lib
parent01bda126924564a399c7d529eb1e94df71ba9e8e (diff)
downloadspack-2e387ef5855d533f685478cc15e3d9bea799bf30.tar.gz
spack-2e387ef5855d533f685478cc15e3d9bea799bf30.tar.bz2
spack-2e387ef5855d533f685478cc15e3d9bea799bf30.tar.xz
spack-2e387ef5855d533f685478cc15e3d9bea799bf30.zip
Package hashing: fix detection of directives (#14763)
The hashing logic looks for function calls that are Spack directives. It expects that when a Spack directive is used that it is referenced directly by name, and that the directive function is not itself retrieved by calling another function. When the hashing logic encountered a function call where the function was determined dynamically, it would fail (attempting to access a name attribute that does not happen to exist in this case). This updates the hashing logic to filter out function calls where the function is determined dynamically when looking for uses of Spack directives.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/test/packages.py4
-rw-r--r--lib/spack/spack/util/package_hash.py15
2 files changed, 19 insertions, 0 deletions
diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py
index c811f9040e..299c56481e 100644
--- a/lib/spack/spack/test/packages.py
+++ b/lib/spack/spack/test/packages.py
@@ -98,6 +98,10 @@ class TestPackage(object):
assert spec1.package.content_hash(content=content1) != \
spec2.package.content_hash(content=content2)
+ def test_parse_dynamic_function_call(self):
+ spec = Spec("hash-test4").concretized()
+ spec.package.content_hash()
+
# Below tests target direct imports of spack packages from the
# spack.pkg namespace
def test_import_package(self):
diff --git a/lib/spack/spack/util/package_hash.py b/lib/spack/spack/util/package_hash.py
index f689aa9710..adea1a498b 100644
--- a/lib/spack/spack/util/package_hash.py
+++ b/lib/spack/spack/util/package_hash.py
@@ -41,8 +41,23 @@ class RemoveDirectives(ast.NodeTransformer):
self.spec = spec
def is_directive(self, node):
+ """Check to determine if the node is a valid directive
+
+ Directives are assumed to be represented in the AST as a named function
+ call expression. This means that they will NOT be represented by a
+ named function call within a function call expression (e.g., as
+ callbacks are sometimes represented).
+
+ Args:
+ node (AST): the AST node being checked
+
+ Returns:
+ (bool): ``True`` if the node represents a known directive,
+ ``False`` otherwise
+ """
return (isinstance(node, ast.Expr) and
node.value and isinstance(node.value, ast.Call) and
+ isinstance(node.value.func, ast.Name) and
node.value.func.id in spack.directives.__all__)
def is_spack_attr(self, node):