def test_noop_removal_full_single_subject_type(self): @rule(Exactly(A), [Select(C)]) def a_from_c(c): pass @rule(Exactly(A), []) def a(): pass rules = _suba_root_rules + [ a_from_c, a, ] fullgraph = self.create_full_graph(rules, validate=False) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for ()" [color=blue] "Select(A) for ()" -> {"(A, [], a) for ()"} // internal entries "(A, [], a) for ()" -> {} }""").strip(), fullgraph)
def test_noop_removal_transitive(self): # If a noop-able rule has rules that depend on it, # they should be removed from the graph. @rule(Exactly(B), [Select(C)]) def b_from_c(c): pass @rule(Exactly(A), [Select(B)]) def a_from_b(b): pass @rule(Exactly(A), []) def a(): pass rules = [ b_from_c, a_from_b, a, ] subgraph = self.create_subgraph(A, rules, SubA(), validate=False) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for ()" [color=blue] "Select(A) for ()" -> {"(A, [], a) for ()"} // internal entries "(A, [], a) for ()" -> {} }""").strip(), subgraph)
def test_noop_removal_in_subgraph(self): @rule(Exactly(A), [Select(C)]) def a_from_c(c): pass @rule(Exactly(A), []) def a(): pass rules = [ a_from_c, a, SingletonRule(B, B()), ] subgraph = self.create_subgraph(A, rules, SubA(), validate=False) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for ()" [color=blue] "Select(A) for ()" -> {"(A, [], a) for ()"} // internal entries "(A, [], a) for ()" -> {} }""").strip(), subgraph)
def test_str_and_repr(self): exactly_b = Exactly(self.B) self.assertEqual("Exactly(B)", str(exactly_b)) self.assertEqual("Exactly(B)", repr(exactly_b)) exactly_multiple = Exactly(self.A, self.B) self.assertEqual("Exactly(A or B)", str(exactly_multiple)) self.assertEqual("Exactly(A, B)", repr(exactly_multiple))
def test_str_and_repr(self): exactly_b_types = Exactly(self.B, description='B types') self.assertEquals("=(B types)", str(exactly_b_types)) self.assertEquals("Exactly(B types)", repr(exactly_b_types)) exactly_b = Exactly(self.B) self.assertEquals("=B", str(exactly_b)) self.assertEquals("Exactly(B)", repr(exactly_b)) exactly_multiple = Exactly(self.A, self.B) self.assertEquals("=(A, B)", str(exactly_multiple)) self.assertEquals("Exactly(A, B)", repr(exactly_multiple))
class PublishConfiguration(Struct): # An example of addressable and addressable_mapping field wrappers. def __init__(self, default_repo, repos, name=None, **kwargs): super().__init__(name=name, **kwargs) self.default_repo = default_repo self.repos = repos @addressable(Exactly(Struct)) def default_repo(self): """""" @addressable_dict(Exactly(Struct)) def repos(self): """"""
class ExecuteProcessRequest(datatype([ ('argv', tuple), ('input_files', DirectoryDigest), ('description', text_type), ('env', tuple), ('output_files', tuple), ('output_directories', tuple), # NB: timeout_seconds covers the whole remote operation including queuing and setup. ('timeout_seconds', Exactly(float, int)), ('jdk_home', Exactly(text_type, type(None))), ])): """Request for execution with args and snapshots to extract.""" def __new__( cls, argv, input_files, description, env=None, output_files=(), output_directories=(), timeout_seconds=_default_timeout_seconds, jdk_home=None, ): if env is None: env = () else: if not isinstance(env, dict): raise TypeCheckError( cls.__name__, "arg 'env' was invalid: value {} (with type {}) must be a dict".format( env, type(env) ) ) env = tuple(item for pair in env.items() for item in pair) return super(ExecuteProcessRequest, cls).__new__( cls, argv=argv, env=env, input_files=input_files, description=description, output_files=output_files, output_directories=output_directories, timeout_seconds=timeout_seconds, jdk_home=jdk_home, )
class MultiPlatformExecuteProcessRequest(datatype([ ('platform_constraints', hashable_string_list), ('execute_process_requests', TypedCollection(Exactly(ExecuteProcessRequest))), ])): # args collects a set of tuples representing platform constraints mapped to a req, just like a dict constructor can. def __new__(cls, request_dict): if len(request_dict) == 0: raise cls.make_type_error("At least one platform constrained ExecuteProcessRequest must be passed.") # validate the platform constraints using the platforms enum an flatten the keys. validated_constraints = tuple( constraint.value for pair in request_dict.keys() for constraint in pair if PlatformConstraint(constraint.value) ) if len({req.description for req in request_dict.values()}) != 1: raise ValueError(f"The `description` of all execute_process_requests in a {cls.__name__} must be identical.") return super().__new__( cls, validated_constraints, tuple(request_dict.values()) ) @property def product_description(self): # we can safely extract the first description because we guarantee that at # least one request exists and that all of their descriptions are the same # in __new__ return ProductDescription(self.execute_process_requests[0].description)
class ZefRequirement( datatype([ ('module_name', text_type), ('version_spec', Exactly(text_type, type(None))), ])): @classmethod def alias(cls): return 'zef_requirement' # TODO: this will reject many legal module names! _allowed_module_name_pattern = re.compile( r'\A([a-zA-Z]+)(::([a-zA-Z]+))*\Z') def __new__(cls, module_name, version_spec=None): if not cls._allowed_module_name_pattern.match(module_name): raise cls.make_type_error( "invalid Zef module name '{}': must match '{}'.".format( module_name, cls._allowed_module_name_pattern.pattern)) else: module_name = text_type(module_name) if version_spec is not None: version_spec = text_type(version_spec) return super(ZefRequirement, cls).__new__(cls, module_name, version_spec) @memoized_property def zef_identity_spec(self): if self.version_spec is not None: return '{}:ver<{}>'.format(self.module_name, self.version_spec) else: return module_name
def __new__(cls, output_type, input_selectors, func, input_gets, goal=None, dependency_optionables=None, cacheable=True): # Validate result type. if isinstance(output_type, Exactly): constraint = output_type elif isinstance(output_type, type): constraint = Exactly(output_type) else: raise TypeError( "Expected an output_type for rule `{}`, got: {}".format( func.__name__, output_type)) return super(TaskRule, cls).__new__( cls, constraint, input_selectors, input_gets, func, goal, dependency_optionables or tuple(), cacheable, )
def test_multiple(self): exactly_a_or_b = Exactly(self.A, self.B) self.assertEqual((self.A, self.B), exactly_a_or_b.types) self.assertTrue(exactly_a_or_b.satisfied_by(self.A())) self.assertTrue(exactly_a_or_b.satisfied_by(self.B())) self.assertFalse(exactly_a_or_b.satisfied_by(self.BPrime())) self.assertFalse(exactly_a_or_b.satisfied_by(self.C()))
def test_one_level_of_recursion(self): @rule(Exactly(A), [Select(B)]) def a_from_b(b): pass @rule(B, [Select(SubA)]) def b_from_suba(suba): pass rules = [ a_from_b, b_from_suba, ] subgraph = self.create_subgraph(A, rules, SubA()) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for SubA" [color=blue] "Select(A) for SubA" -> {"(A, [Select(B)], a_from_b) for SubA"} // internal entries "(A, [Select(B)], a_from_b) for SubA" -> {"(B, [Select(SubA)], b_from_suba) for SubA"} "(B, [Select(SubA)], b_from_suba) for SubA" -> {"Param(SubA)"} }""").strip(), subgraph)
def test_multiple_selects(self): @rule(Exactly(A), [Select(SubA), Select(B)]) def a_from_suba_and_b(suba, b): pass @rule(B, []) def b(): pass rules = [ a_from_suba_and_b, b, ] subgraph = self.create_subgraph(A, rules, SubA()) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for SubA" [color=blue] "Select(A) for SubA" -> {"(A, [Select(SubA), Select(B)], a_from_suba_and_b) for SubA"} // internal entries "(A, [Select(SubA), Select(B)], a_from_suba_and_b) for SubA" -> {"(B, [], b) for ()" "Param(SubA)"} "(B, [], b) for ()" -> {} }""").strip(), subgraph)
def test_select_dependencies_recurse_with_different_type(self): rules = [ TaskRule(Exactly(A), [SelectDependencies(B, SubA, field_types=( C, D, ))], noop), TaskRule(B, [Select(A)], noop), TaskRule(C, [Select(SubA)], noop), TaskRule(SubA, [], noop) ] subgraph = self.create_subgraph(A, rules, SubA()) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for SubA" [color=blue] "Select(A) for SubA" -> {"(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of SubA"} // internal entries "(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of C" -> {"(SubA, (,), noop) of C" "(B, (Select(A),), noop) of C" "(B, (Select(A),), noop) of D"} "(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of D" -> {"(SubA, (,), noop) of D" "(B, (Select(A),), noop) of C" "(B, (Select(A),), noop) of D"} "(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of SubA" -> {"SubjectIsProduct(SubA)" "(B, (Select(A),), noop) of C" "(B, (Select(A),), noop) of D"} "(B, (Select(A),), noop) of C" -> {"(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of C"} "(B, (Select(A),), noop) of D" -> {"(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of D"} "(SubA, (,), noop) of C" -> {} "(SubA, (,), noop) of D" -> {} }""").strip(), subgraph)
def test_select_dependencies_multiple_field_types_all_resolvable_with_deps( self): rules = [ TaskRule(Exactly(A), [SelectDependencies(B, SubA, field_types=( C, D, ))], noop), # for the C type, it'll just be a literal, but for D, it'll traverse one more edge TaskRule(B, [Select(C)], noop), TaskRule(C, [Select(D)], noop), ] subgraph = self.create_subgraph(A, rules, SubA()) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for SubA" [color=blue] "Select(A) for SubA" -> {"(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of SubA"} // internal entries "(A, (SelectDependencies(B, SubA, field_types=(C, D,)),), noop) of SubA" -> {"SubjectIsProduct(SubA)" "(B, (Select(C),), noop) of C" "(B, (Select(C),), noop) of D"} "(B, (Select(C),), noop) of C" -> {"SubjectIsProduct(C)"} "(B, (Select(C),), noop) of D" -> {"(C, (Select(D),), noop) of D"} "(C, (Select(D),), noop) of D" -> {"SubjectIsProduct(D)"} }""").strip(), subgraph)
def test_collection_single(self): collection_constraint = TypedCollection(Exactly(self.A)) self.assertTrue(collection_constraint.satisfied_by([self.A()])) self.assertFalse( collection_constraint.satisfied_by([self.A(), self.B()])) self.assertTrue( collection_constraint.satisfied_by([self.A(), self.A()]))
def test_get_simple(self): @rule(Exactly(A), []) def a(): _ = yield Get(B, D, D()) # noqa: F841 @rule(B, [Select(D)]) def b_from_d(d): pass rules = [ a, b_from_d, ] subgraph = self.create_subgraph(A, rules, SubA()) self.assert_equal_with_printing( dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for ()" [color=blue] "Select(A) for ()" -> {"(A, [], [Get(B, D)], a) for ()"} // internal entries "(A, [], [Get(B, D)], a) for ()" -> {"(B, [Select(D)], b_from_d) for D"} "(B, [Select(D)], b_from_d) for D" -> {"Param(D)"} }""").strip(), subgraph)
def test_single(self): exactly_b = Exactly(self.B) self.assertEqual((self.B,), exactly_b.types) self.assertFalse(exactly_b.satisfied_by(self.A())) self.assertTrue(exactly_b.satisfied_by(self.B())) self.assertFalse(exactly_b.satisfied_by(self.BPrime())) self.assertFalse(exactly_b.satisfied_by(self.C()))
def __new__(cls, output_type, input_selectors, func, input_gets=None): # Validate result type. if isinstance(output_type, Exactly): constraint = output_type elif isinstance(output_type, type): constraint = Exactly(output_type) else: raise TypeError( "Expected an output_type for rule `{}`, got: {}".format( func.__name__, output_type)) # Validate selectors. if not isinstance(input_selectors, list): raise TypeError( "Expected a list of Selectors for rule `{}`, got: {}".format( func.__name__, type(input_selectors))) # Validate gets. input_gets = [] if input_gets is None else input_gets if not isinstance(input_gets, list): raise TypeError( "Expected a list of Gets for rule `{}`, got: {}".format( func.__name__, type(input_gets))) # Create. return super(TaskRule, cls).__new__(cls, constraint, tuple(input_selectors), tuple(input_gets), func)
def test_no_complex_sub_constraint(self): sub_collection = TypedCollection(Exactly(self.A)) with self.assertRaisesWithMessage( TypeError, "constraint for collection must be a TypeOnlyConstraint! was: {}" .format(sub_collection)): TypedCollection(sub_collection)
class Series(SimpleSerializable): def __init__(self, values): super(AddressableListTest.Series, self).__init__() self.values = values @addressable_list(Exactly(int, float)) def values(self): """Return this series' values.
class Varz(SimpleSerializable): def __init__(self, varz): super(AddressableDictTest.Varz, self).__init__() self.varz = varz @addressable_dict(Exactly(int, float)) def varz(self): """Return a snapshot of the current /varz.
class NotSerializable: def __init__(self, count): super().__init__() self.count = count @addressable(Exactly(int)) def count(self): pass
class Person(SimpleSerializable): def __init__(self, age): super(AddressableTest.Person, self).__init__() self.age = age @addressable(Exactly(int)) def age(self): """Return the person's age in years.
def test_validate(self): exactly_a_or_b = Exactly(self.A, self.B) self.assertEqual(self.A(), exactly_a_or_b.validate_satisfied_by(self.A())) self.assertEqual(self.B(), exactly_a_or_b.validate_satisfied_by(self.B())) with self.assertRaisesWithMessage( TypeConstraintError, "value C() (with type 'C') must satisfy this type constraint: Exactly(A or B)."): exactly_a_or_b.validate_satisfied_by(self.C())
def packaged_dependent_constraint(cls): """Return a type constraint which is used to filter 3rdparty dependencies for a target. This is used to make packaged_native_deps() automatic and declarative. :return: :class:`pants.util.objects.TypeConstraint` """ return Exactly(PackagedNativeLibrary)
def test_ruleset_with_explicit_type_constraint(self): rules = _suba_root_rules + [ TaskRule(Exactly(A), [Select(B)], noop), TaskRule(B, [Select(A)], noop) ] validator = self.create_validator({}, rules) validator.assert_ruleset_valid()
def test_noop_removal_full_single_subject_type(self): rules = _suba_root_rules + [ TaskRule(Exactly(A), [Select(C)], noop), TaskRule(Exactly(A), [], noop), ] fullgraph = self.create_full_graph(rules, validate=False) self.assert_equal_with_printing(dedent(""" digraph { // root subject types: SubA // root entries "Select(A) for SubA" [color=blue] "Select(A) for SubA" -> {"(A, (,), noop) of SubA"} // internal entries "(A, (,), noop) of SubA" -> {} }""").strip(), fullgraph)
def constraint_for(type_or_constraint): """Given a type or an `Exactly` constraint, returns an `Exactly` constraint.""" if isinstance(type_or_constraint, Exactly): return type_or_constraint elif isinstance(type_or_constraint, type): return Exactly(type_or_constraint) else: raise TypeError("Expected a type or constraint: got: {}".format( type_or_constraint))
class PantsResult(datatype([ 'command', ('returncode', int), 'stdout_data', 'stderr_data', 'workdir', ('pid', Exactly(*IntegerForPid)), ])): pass