def _validate_input(self, input_: Any, *, shorthand_form: bool) -> _Input: if isinstance(input_, type): if shorthand_form: raise TypeError( "Invalid Get. Because you are using the shorthand form " "Get(OutputType, InputType(constructor args)), the second argument should be " f"a constructor call, rather than a type, but given {input_}." ) else: raise TypeError( "Invalid Get. Because you are using the longhand form " "Get(OutputType, InputType, input), the third argument should be " f"an object, rather than a type, but given {input_}." ) # If the input_type is not annotated with `@union`, then we validate that the input is # exactly the same type as the input_type. (Why not check unions? We don't have access to # `UnionMembership` to know if it's a valid union member. The engine will check that.) if not is_union(self.input_type) and type(input_) != self.input_type: # We can assume we're using the longhand form because the shorthand form guarantees # that the `input_type` is the same as `input`. raise TypeError( f"Invalid Get. The third argument `{input_}` must have the exact same type as the " f"second argument, {self.input_type}, but had the type {type(input_)}." ) return cast(_Input, input_)
def register_task(rule: TaskRule) -> None: native_engine.tasks_task_begin( tasks, rule.func, rule.output_type, side_effecting=any( issubclass(t, SideEffecting) for t in rule.input_selectors), engine_aware_return_type=issubclass(rule.output_type, EngineAwareReturnType), cacheable=rule.cacheable, name=rule.canonical_name, desc=rule.desc or "", level=rule.level.level, ) for selector in rule.input_selectors: native_engine.tasks_add_select(tasks, selector) for the_get in rule.input_gets: if is_union(the_get.input_type): # Register a union. TODO: See #12934: this should involve an explicit interface # soon, rather than one being implicitly created with only the provided Param. for union_member in union_membership.get(the_get.input_type): native_engine.tasks_add_union(tasks, the_get.output_type, (union_member, )) else: # Otherwise, the Get subject is a "concrete" type, so add a single Get edge. native_engine.tasks_add_get(tasks, the_get.output_type, the_get.input_type) native_engine.tasks_task_end(tasks)
def create(cls, api_type: type, rules: Sequence[Rule | UnionRule], **kwargs) -> PluginAPITypeInfo: union_type: str | None = None for rule in filter(cls._member_type_for(api_type), rules): # All filtered rules out of `_member_type_for` will be `UnionRule`s. union_type = cast(UnionRule, rule).union_base.__name__ break task_rules = [rule for rule in rules if isinstance(rule, TaskRule)] return cls( name=api_type.__name__, module=api_type.__module__, documentation=maybe_cleandoc(api_type.__doc__), is_union=is_union(api_type), union_type=union_type, consumed_by_rules=cls._all_rules(cls._rule_consumes(api_type), task_rules), returned_by_rules=cls._all_rules(cls._rule_returns(api_type), task_rules), used_in_rules=cls._all_rules(cls._rule_uses(api_type), task_rules), **kwargs, )