Add option to copy only certain deptypes to Spec.copy()

- can now pass these to Spec.copy() and Spec._dup():
  - deps=True
  - deps=False
  - deps=(list of deptypes)

- Makes it easy to filter out only part of a spec.
This commit is contained in:
Todd Gamblin 2016-08-16 13:13:59 -07:00
parent 409e7a2e64
commit 235a045d08

View File

@ -1871,7 +1871,7 @@ def virtual_dependencies(self):
"""Return list of any virtual deps in this spec.""" """Return list of any virtual deps in this spec."""
return [spec for spec in self.traverse() if spec.virtual] return [spec for spec in self.traverse() if spec.virtual]
def _dup(self, other, **kwargs): def _dup(self, other, deps=True, cleardeps=True):
"""Copy the spec other into self. This is an overwriting """Copy the spec other into self. This is an overwriting
copy. It does not copy any dependents (parents), but by default copy. It does not copy any dependents (parents), but by default
copies dependencies. copies dependencies.
@ -1902,7 +1902,7 @@ def _dup(self, other, **kwargs):
self.versions = other.versions.copy() self.versions = other.versions.copy()
self.architecture = other.architecture self.architecture = other.architecture
self.compiler = other.compiler.copy() if other.compiler else None self.compiler = other.compiler.copy() if other.compiler else None
if kwargs.get('cleardeps', True): if cleardeps:
self._dependents = DependencyMap() self._dependents = DependencyMap()
self._dependencies = DependencyMap() self._dependencies = DependencyMap()
self.compiler_flags = other.compiler_flags.copy() self.compiler_flags = other.compiler_flags.copy()
@ -1912,19 +1912,15 @@ def _dup(self, other, **kwargs):
self.external_module = other.external_module self.external_module = other.external_module
self.namespace = other.namespace self.namespace = other.namespace
self._hash = other._hash self._hash = other._hash
self._cmp_key_cache = other._cmp_key_cache
# If we copy dependencies, preserve DAG structure in the new spec # If we copy dependencies, preserve DAG structure in the new spec
if kwargs.get('deps', True): if deps:
# This copies the deps from other using _dup(deps=False) # This copies the deps from other using _dup(deps=False)
# XXX(deptype): We can keep different instances of specs here iff deptypes = alldeps
# it is only a 'build' dependency (from its parent). if isinstance(deps, (tuple, list)):
# All other instances must be shared (due to symbol deptypes = deps
# and PATH contention). These should probably search new_nodes = other.flat_dependencies(deptypes=deptypes)
# for any existing installation which can satisfy the
# build and latch onto that because if 3 things need
# the same build dependency and it is *not*
# available, we only want to build it once.
new_nodes = other.flat_dependencies(deptype_query=alldeps)
new_nodes[self.name] = self new_nodes[self.name] = self
stack = [other] stack = [other]
@ -1933,6 +1929,9 @@ def _dup(self, other, **kwargs):
new_spec = new_nodes[cur_spec.name] new_spec = new_nodes[cur_spec.name]
for depspec in cur_spec._dependencies.values(): for depspec in cur_spec._dependencies.values():
if not any(d in deptypes for d in depspec.deptypes):
continue
stack.append(depspec.spec) stack.append(depspec.spec)
# XXX(deptype): add any new deptypes that may have appeared # XXX(deptype): add any new deptypes that may have appeared
@ -1948,13 +1947,22 @@ def _dup(self, other, **kwargs):
self.external_module = other.external_module self.external_module = other.external_module
return changed return changed
def copy(self, **kwargs): def copy(self, deps=True):
"""Return a copy of this spec. """Return a copy of this spec.
By default, returns a deep copy. Supply dependencies=False
to get a shallow copy. By default, returns a deep copy. To control how dependencies are
copied, supply:
deps=True: deep copy
deps=False: shallow copy (no dependencies)
deps=('link', 'build'):
only build and link dependencies. Similar for other deptypes.
""" """
clone = Spec.__new__(Spec) clone = Spec.__new__(Spec)
clone._dup(self, **kwargs) clone._dup(self, deps=deps)
return clone return clone
@property @property