From 1d096907cae1f729ff3abcff3b144df43df65af9 Mon Sep 17 00:00:00 2001 From: "Nick Howard (Twitter)" Date: Fri, 23 Sep 2016 10:59:05 -0600 Subject: [PATCH] [engine] Move subselectors to selector properties Select/Dependency/ProjectionNodes cause sub-selectors to be generated in order to select different products. This moves those selectors onto the selectors instead of having the nodes construct them directly. Working on the new validation / graph creation, I find myself needing those sub-selectors in a few other places, so I wanted to give them consistent names. Testing Done: Ran engine tests locally. CI away in PR. Bugs closed: 3867 Reviewed at https://rbcommons.com/s/twitter/r/4235/ closes #3867 --- src/python/pants/engine/nodes.py | 18 +++++++++++++----- src/python/pants/engine/selectors.py | 22 ++++++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/python/pants/engine/nodes.py b/src/python/pants/engine/nodes.py index 8b28fb34f2f..b5b777a3e5f 100644 --- a/src/python/pants/engine/nodes.py +++ b/src/python/pants/engine/nodes.py @@ -209,6 +209,8 @@ class SelectNode(datatype('SelectNode', ['subject', 'variants', 'selector']), No is_cacheable = False is_inlineable = True + _variant_selector = Select(Variants) + @property def variant_key(self): if isinstance(self.selector, SelectVariant): @@ -248,7 +250,7 @@ def step(self, step_context): # them to task nodes. variants = self.variants if type(self.subject) is Address and self.product is not Variants: - variants_node = step_context.select_node(Select(Variants), self.subject, self.variants) + variants_node = step_context.select_node(self._variant_selector, self.subject, self.variants) dep_state = step_context.get(variants_node) if type(dep_state) is Waiting: return dep_state @@ -342,11 +344,13 @@ def _dependency_nodes(self, step_context, dep_product): # If a subject has literal variants for particular dependencies, they win over all else. dependency, literal_variants = parse_variants(dependency) variants = Variants.merge(variants, literal_variants) - yield step_context.select_node(Select(self.product), subject=dependency, variants=variants) + yield step_context.select_node(self.selector.projected_product_selector, subject=dependency, variants=variants) def step(self, step_context): # Request the product we need in order to request dependencies. - dep_product_node = step_context.select_node(Select(self.dep_product), self.subject, self.variants) + dep_product_node = step_context.select_node(self.selector.dep_product_selector, + self.subject, + self.variants) dep_product_state = step_context.get(dep_product_node) if type(dep_product_state) in (Throw, Waiting): return dep_product_state @@ -406,7 +410,9 @@ def input_product(self): def step(self, step_context): # Request the product we need to compute the subject. - input_node = step_context.select_node(Select(self.input_product), self.subject, self.variants) + input_node = step_context.select_node(self.selector.input_product_selector, + self.subject, + self.variants) input_state = step_context.get(input_node) if type(input_state) in (Throw, Waiting): @@ -432,7 +438,9 @@ def step(self, step_context): self.projected_subject, e))) # When the output node is available, return its result. - output_node = step_context.select_node(Select(self.product), projected_subject, self.variants) + output_node = step_context.select_node(self.selector.projected_product_selector, + projected_subject, + self.variants) output_state = step_context.get(output_node) if type(output_state) in (Return, Throw, Waiting): return output_state diff --git a/src/python/pants/engine/selectors.py b/src/python/pants/engine/selectors.py index caabad4e63e..8be7edd6360 100644 --- a/src/python/pants/engine/selectors.py +++ b/src/python/pants/engine/selectors.py @@ -73,8 +73,7 @@ class SelectVariant(datatype('Variant', ['product', 'variant_key']), Selector): def __new__(cls, product, variant_key): if not isinstance(variant_key, six.string_types): raise ValueError('Expected variant_key to be a string, but was {!r}'.format(variant_key)) - obj = super(SelectVariant, cls).__new__(cls, product, variant_key) - return obj + return super(SelectVariant, cls).__new__(cls, product, variant_key) def __repr__(self): return '{}({}, {})'.format(type(self).__name__, @@ -98,8 +97,15 @@ class SelectDependencies(datatype('Dependencies', optional = False def __new__(cls, product, dep_product, field=None, field_types=tuple()): - obj = super(SelectDependencies, cls).__new__(cls, product, dep_product, field, field_types) - return obj + return super(SelectDependencies, cls).__new__(cls, product, dep_product, field, field_types) + + @property + def dep_product_selector(self): + return Select(self.dep_product) + + @property + def projected_product_selector(self): + return Select(self.product) def __repr__(self): if self.field_types: @@ -124,6 +130,14 @@ class SelectProjection(datatype('Projection', ['product', 'projected_subject', ' """ optional = False + @property + def input_product_selector(self): + return Select(self.input_product) + + @property + def projected_product_selector(self): + return Select(self.product) + def __repr__(self): return '{}({}, {}, {}, {})'.format(type(self).__name__, type_or_constraint_repr(self.product),