def from_func(func: Callable, schema: Any) -> "_FuncAsCreator": # pylint: disable=W0201 if schema is None: schema = parse_output_schema_from_comment(func) tr = _FuncAsCreator() tr._wrapper = FunctionWrapper(func, "^e?x*z?$", "^[dlspq]$") # type: ignore tr._need_engine = tr._wrapper.input_code.startswith("e") tr._need_output_schema = "s" == tr._wrapper.output_code tr._output_schema = Schema(schema) if len(tr._output_schema) == 0: assert_or_throw( not tr._need_output_schema, FugueInterfacelessError( f"schema must be provided for return type {tr._wrapper._rt}" ), ) else: assert_or_throw( tr._need_output_schema, FugueInterfacelessError( f"schema must not be provided for return type {tr._wrapper._rt}" ), ) return tr
def from_func(func: Callable, schema: Any, validation_rules: Dict[str, Any]) -> "_FuncAsProcessor": if schema is None: schema = parse_output_schema_from_comment(func) validation_rules.update(parse_validation_rules_from_comment(func)) tr = _FuncAsProcessor() tr._wrapper = FunctionWrapper(func, "^e?(c|[dlspq]+)x*z?$", "^[dlspq]$") # type: ignore tr._engine_param = (tr._wrapper._params.get_value_by_index(0) if tr._wrapper.input_code.startswith("e") else None) tr._use_dfs = "c" in tr._wrapper.input_code tr._need_output_schema = tr._wrapper.need_output_schema tr._validation_rules = validation_rules tr._output_schema = Schema(schema) if len(tr._output_schema) == 0: assert_or_throw( tr._need_output_schema is None or not tr._need_output_schema, FugueInterfacelessError( f"schema must be provided for return type {tr._wrapper._rt}" ), ) else: assert_or_throw( tr._need_output_schema is None or tr._need_output_schema, FugueInterfacelessError( f"schema must not be provided for return type {tr._wrapper._rt}" ), ) return tr
def _to_processor( obj: Any, schema: Any = None, global_vars: Optional[Dict[str, Any]] = None, local_vars: Optional[Dict[str, Any]] = None, validation_rules: Optional[Dict[str, Any]] = None, ) -> Processor: global_vars, local_vars = get_caller_global_local_vars( global_vars, local_vars) obj = _PROCESSOR_REGISTRY.get(obj) exp: Optional[Exception] = None if validation_rules is None: validation_rules = {} try: return copy.copy( to_instance(obj, Processor, global_vars=global_vars, local_vars=local_vars)) except Exception as e: exp = e try: f = to_function(obj, global_vars=global_vars, local_vars=local_vars) # this is for string expression of function with decorator if isinstance(f, Processor): return copy.copy(f) # this is for functions without decorator return _FuncAsProcessor.from_func(f, schema, validation_rules=validation_rules) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid processor", exp)
def _to_creator( obj: Any, schema: Any = None, global_vars: Optional[Dict[str, Any]] = None, local_vars: Optional[Dict[str, Any]] = None, ) -> Creator: global_vars, local_vars = get_caller_global_local_vars( global_vars, local_vars) exp: Optional[Exception] = None try: return copy.copy( to_instance(obj, Creator, global_vars=global_vars, local_vars=local_vars)) except Exception as e: exp = e try: f = to_function(obj, global_vars=global_vars, local_vars=local_vars) # this is for string expression of function with decorator if isinstance(f, Creator): return copy.copy(f) # this is for functions without decorator return _FuncAsCreator.from_func(f, schema) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid creator", exp)
def from_func(func: Callable, schema: Any, validation_rules: Dict[str, Any]) -> "_FuncAsCoTransformer": assert_or_throw( len(validation_rules) == 0, NotImplementedError( "CoTransformer does not support validation rules"), ) if schema is None: schema = parse_output_schema_from_comment(func) if isinstance(schema, Schema): # to be less strict on determinism schema = str(schema) if isinstance(schema, str): assert_or_throw( "*" not in schema, FugueInterfacelessError( "* can't be used on cotransformer output schema"), ) assert_arg_not_none(schema, "schema") tr = _FuncAsCoTransformer() tr._wrapper = FunctionWrapper( # type: ignore func, "^(c|[lspq]+)[fF]?x*z?$", "^[lspq]$") tr._dfs_input = tr._wrapper.input_code[0] == "c" # type: ignore tr._output_schema_arg = schema # type: ignore tr._validation_rules = {} # type: ignore tr._uses_callback = "f" in tr._wrapper.input_code.lower( ) # type: ignore tr._requires_callback = "F" in tr._wrapper.input_code # type: ignore return tr
def _validate_callback(ctx: Any) -> None: if ctx._requires_callback: assert_or_throw( ctx.has_callback, FugueInterfacelessError( f"Callback is required but not provided: {ctx}"), )
def _to_outputter( obj: Any, global_vars: Optional[Dict[str, Any]] = None, local_vars: Optional[Dict[str, Any]] = None, validation_rules: Optional[Dict[str, Any]] = None, ) -> Outputter: global_vars, local_vars = get_caller_global_local_vars(global_vars, local_vars) exp: Optional[Exception] = None if validation_rules is None: validation_rules = {} try: return copy.copy( to_instance(obj, Outputter, global_vars=global_vars, local_vars=local_vars) ) except Exception as e: exp = e try: f = to_function(obj, global_vars=global_vars, local_vars=local_vars) # this is for string expression of function with decorator if isinstance(f, Outputter): return copy.copy(f) # this is for functions without decorator return _FuncAsOutputter.from_func(f, validation_rules=validation_rules) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid outputter", exp)
def _to_transformer( # noqa: C901 obj: Any, schema: Any = None) -> Union[Transformer, CoTransformer]: exp: Optional[Exception] = None try: return copy.copy(to_instance(obj, Transformer)) except Exception as e: exp = e try: return copy.copy(to_instance(obj, CoTransformer)) except Exception as e: exp = e try: f = to_function(obj) # this is for string expression of function with decorator if isinstance(f, Transformer): return copy.copy(f) # this is for functions without decorator return _FuncAsTransformer.from_func(f, schema) except Exception as e: exp = e try: f = to_function(obj) # this is for string expression of function with decorator if isinstance(f, CoTransformer): return copy.copy(f) # this is for functions without decorator return _FuncAsCoTransformer.from_func(f, schema) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid transformer", exp)
def _get_callback(ctx: Any) -> List[Any]: uses_callback = ctx._uses_callback requires_callback = ctx._requires_callback if not uses_callback: return [] if requires_callback: assert_or_throw( ctx.has_callback, FugueInterfacelessError( f"Callback is required but not provided: {ctx}"), ) return [ctx.callback] return [ctx.callback if ctx.has_callback else None]
def _to_transformer( # noqa: C901 obj: Any, schema: Any = None, global_vars: Optional[Dict[str, Any]] = None, local_vars: Optional[Dict[str, Any]] = None, validation_rules: Optional[Dict[str, Any]] = None, func_transformer_type: Type = _FuncAsTransformer, func_cotransformer_type: Type = _FuncAsCoTransformer, ) -> Union[Transformer, CoTransformer]: global_vars, local_vars = get_caller_global_local_vars( global_vars, local_vars) exp: Optional[Exception] = None if validation_rules is None: validation_rules = {} try: return copy.copy( to_instance(obj, Transformer, global_vars=global_vars, local_vars=local_vars)) except Exception as e: exp = e try: return copy.copy( to_instance(obj, CoTransformer, global_vars=global_vars, local_vars=local_vars)) except Exception as e: exp = e try: f = to_function(obj, global_vars=global_vars, local_vars=local_vars) # this is for string expression of function with decorator if isinstance(f, Transformer): return copy.copy(f) # this is for functions without decorator return func_transformer_type.from_func( f, schema, validation_rules=validation_rules) except Exception as e: exp = e try: f = to_function(obj, global_vars=global_vars, local_vars=local_vars) # this is for string expression of function with decorator if isinstance(f, CoTransformer): return copy.copy(f) # this is for functions without decorator return func_cotransformer_type.from_func( f, schema, validation_rules=validation_rules) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid transformer", exp)
def _to_outputter(obj: Any) -> Outputter: exp: Optional[Exception] = None try: return copy.copy(to_instance(obj, Outputter)) except Exception as e: exp = e try: f = to_function(obj) # this is for string expression of function with decorator if isinstance(f, Outputter): return copy.copy(f) # this is for functions without decorator return _FuncAsOutputter.from_func(f) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid outputter", exp)
def _to_processor(obj: Any, schema: Any = None) -> Processor: exp: Optional[Exception] = None try: return copy.copy(to_instance(obj, Processor)) except Exception as e: exp = e try: f = to_function(obj) # this is for string expression of function with decorator if isinstance(f, Processor): return copy.copy(f) # this is for functions without decorator return _FuncAsProcessor.from_func(f, schema) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid processor", exp)
def _to_module( obj: Any, global_vars: Optional[Dict[str, Any]] = None, local_vars: Optional[Dict[str, Any]] = None, ) -> "_ModuleFunctionWrapper": if isinstance(obj, _ModuleFunctionWrapper): return obj global_vars, local_vars = get_caller_global_local_vars(global_vars, local_vars) try: f = to_function(obj, global_vars=global_vars, local_vars=local_vars) # this is for string expression of function with decorator if isinstance(f, _ModuleFunctionWrapper): return copy.copy(f) # this is for functions without decorator return _ModuleFunctionWrapper(f) except Exception as e: exp = e raise FugueInterfacelessError(f"{obj} is not a valid module", exp)