diff --git a/src/python/pants/base/specs.py b/src/python/pants/base/specs.py index c4247cc4b276..14445fcaf035 100644 --- a/src/python/pants/base/specs.py +++ b/src/python/pants/base/specs.py @@ -8,6 +8,7 @@ from abc import abstractmethod from pants.util.meta import AbstractClass +from pants.util.objects import DatatypeFieldDecl as F from pants.util.objects import datatype @@ -60,11 +61,11 @@ def to_spec_string(self): return '{}^'.format(self.directory) -class Specs(datatype(['dependencies', 'tags', ('exclude_patterns', tuple)])): +class Specs(datatype([ + 'dependencies', + F('tags', tuple, default_value=()), + F('exclude_patterns', tuple, default_value=())])): """A collection of Specs representing Spec subclasses, tags and regex filters.""" - def __new__(cls, dependencies, tags=tuple(), exclude_patterns=tuple()): - return super(Specs, cls).__new__(cls, dependencies, tags, exclude_patterns) - def exclude_patterns_memo(self): return [re.compile(pattern) for pattern in set(self.exclude_patterns or [])] diff --git a/src/python/pants/engine/selectors.py b/src/python/pants/engine/selectors.py index d46e4b88a1a5..9de04bea44c1 100644 --- a/src/python/pants/engine/selectors.py +++ b/src/python/pants/engine/selectors.py @@ -11,7 +11,8 @@ import six from pants.util.meta import AbstractClass -from pants.util.objects import Exactly, datatype +from pants.util.objects import DatatypeFieldDecl as F +from pants.util.objects import Exactly, SubclassesOf, datatype def type_or_constraint_repr(constraint): @@ -96,23 +97,25 @@ def product(self): """The product that this selector produces.""" -class Select(datatype(['product', 'optional']), Selector): +class Select(datatype([ + 'product', + F('optional', bool, default_value=False), +]), Selector): """Selects the given Product for the Subject provided to the constructor. If optional=True and no matching product can be produced, will return None. """ - def __new__(cls, product, optional=False): - obj = super(Select, cls).__new__(cls, product, optional) - return obj - def __repr__(self): return '{}({}{})'.format(type(self).__name__, type_or_constraint_repr(self.product), ', optional=True' if self.optional else '') -class SelectVariant(datatype(['product', 'variant_key']), Selector): +class SelectVariant(datatype([ + 'product', + ('variant_key', SubclassesOf(six.string_types)), +]), Selector): """Selects the matching Product and variant name for the Subject provided to the constructor. For example: a SelectVariant with a variant_key of "thrift" and a product of type ApacheThrift @@ -121,11 +124,6 @@ class SelectVariant(datatype(['product', 'variant_key']), Selector): """ optional = False - 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)) - return super(SelectVariant, cls).__new__(cls, product, variant_key) - def __repr__(self): return '{}({}, {})'.format(type(self).__name__, type_or_constraint_repr(self.product),