示例#1
0
def ensure_all_args_defined_in_sub(super_sig, sub_sig):
    sub_has_var_args = any(p.kind == Parameter.VAR_POSITIONAL
                           for p in sub_sig.parameters.values())
    sub_has_var_kwargs = any(p.kind == Parameter.VAR_KEYWORD
                             for p in sub_sig.parameters.values())
    for super_index, (name,
                      super_param) in enumerate(super_sig.parameters.items()):
        if not is_param_defined_in_sub(name, sub_has_var_args,
                                       sub_has_var_kwargs, sub_sig,
                                       super_param):
            raise TypeError(f"`{name}` is not present.")
        elif (name in sub_sig.parameters
              and super_param.kind != Parameter.VAR_POSITIONAL
              and super_param.kind != Parameter.VAR_KEYWORD):
            sub_index = list(sub_sig.parameters.keys()).index(name)
            sub_param = sub_sig.parameters[name]

            if (super_param.kind != sub_param.kind
                    and not (super_param.kind == Parameter.POSITIONAL_ONLY and
                             sub_param.kind == Parameter.POSITIONAL_OR_KEYWORD)
                    and
                    not (super_param.kind == Parameter.KEYWORD_ONLY and
                         sub_param.kind == Parameter.POSITIONAL_OR_KEYWORD)):
                raise TypeError(
                    f"`{name}` is not `{super_param.kind.description}`")
            elif super_index != sub_index and super_param.kind != Parameter.KEYWORD_ONLY:
                raise TypeError(f"`{name}` is not parameter `{super_index}`")
            elif (super_param.annotation != Parameter.empty
                  and sub_param.annotation != Parameter.empty and
                  not issubtype(super_param.annotation, sub_param.annotation)):
                raise TypeError(
                    f"`{name} must be a supertype of `{super_param.annotation}`"
                )
示例#2
0
文件: validation.py 项目: zoovu/rasa
def _validate_target(
    target_name: Text,
    target_type: Text,
    expected_type: Type,
    schema: GraphSchema,
) -> None:
    if target_name not in schema.nodes:
        raise GraphSchemaValidationException(
            f"Graph schema specifies invalid {target_type} target '{target_name}'. "
            f"Please make sure specify a valid node name as target.")

    if any(target_name in node.needs.values()
           for node in schema.nodes.values()):
        raise GraphSchemaValidationException(
            f"One graph node uses the {target_type} target '{target_name}' as input. "
            f"This is not allowed as NLU prediction and Core prediction are run "
            f"separately.")

    target_node = schema.nodes[target_name]
    _, target_return_type = _get_parameter_information(target_node.uses,
                                                       target_node.fn)

    if not typing_utils.issubtype(target_return_type, expected_type):
        raise GraphSchemaValidationException(
            f"Your {target_type} model's output component "
            f"'{target_node.uses.__name__}' returns an invalid return "
            f"type '{target_return_type}'. This is not allowed. The {target_type} "
            f"model's last component is expected to return the type '{expected_type}'. "
            f"See {DOCS_URL_GRAPH_COMPONENTS} for more information.")
示例#3
0
def ensure_return_type_compatibility(super_sig, sub_sig):
    if (super_sig.return_annotation != Signature.empty
            and sub_sig.return_annotation != Signature.empty and not issubtype(
                sub_sig.return_annotation, super_sig.return_annotation)):
        raise TypeError(
            f"`{sub_sig.return_annotation}` is not a `{super_sig.return_annotation}`."
        )
示例#4
0
def type_check_expr(sigma: dict, func_sigma: dict, expected, expr: Expr):
    actual = type_infer_expr(sigma, func_sigma, expr)
    if actual == TANY and isinstance(expr, Var):
        sigma[expr.name] = expected
        return expected
    if actual == expected or typing_utils.issubtype(actual, expected):
        return actual
    else:
        raise TypeError(
            f'{expr}: expected type {expected}, actual type {actual};\
                        issubtype({actual}, {expected})={typing_utils.issubtype(actual, expected)}'
        )
示例#5
0
def _issubtype(left, right):
    if _contains_unbound_typevar(left):
        return True
    if right is None:
        return True
    if _contains_unbound_typevar(right):
        return True
    try:
        return issubtype(left, right)
    except TypeError:
        # Ignore all broken cases
        return True
示例#6
0
    def build_variable_value_tuple(
        self, variable_values: Tuple[hints.VariableValue,
                                     ...]) -> VariableValueTuple:
        """Prepares and validates a raw tuple of variable values to be passed into
        `compute_residual_vector` or `compute_residual_jacobians`.

        Slightly sketchy: checks the type hinting on `compute_residual_vector` and if
        the user expects a named tuple, we wrap the input accordingly. Otherwise, we
        just cast and return the input."""

        assert isinstance(variable_values, tuple)

        output: VariableValueTuple

        try:
            value_type: Type[VariableValueTuple] = get_type_hints(
                self.compute_residual_vector)["variable_values"]
        except KeyError as e:
            raise NotImplementedError(
                f"Missing type hints for {type(self).__name__}.compute_residual_vector"
            ) from e

        # Function should be hinted with a tuple of some kind, but not `tuple` itself
        assert issubtype(value_type, tuple), value_type is not tuple

        # Heuristic: evaluates to `True` for NamedTuple types but `False` for
        # `Tuple[...]` types. Note that standard superclass checking approaches don't
        # work for NamedTuple types.
        if type(value_type) is type:
            # Hint is `NamedTuple`
            tuple_content_types = tuple(get_type_hints(value_type).values())
            output = value_type(*variable_values)
        else:
            # Hint is `typing.Tuple` annotation
            tuple_content_types = get_args(value_type)
            output = cast(VariableValueTuple, variable_values)

        # Handle Ellipsis in type hints, eg `Tuple[SomeType, ...]`
        if len(tuple_content_types
               ) == 2 and tuple_content_types[1] is Ellipsis:
            tuple_content_types = tuple_content_types[0:1] * len(
                variable_values)

        # Validate expected and received types
        assert len(variable_values) == len(tuple_content_types)
        for i, (value, expected_type) in enumerate(
                zip(variable_values, tuple_content_types)):
            assert isinstance(value, expected_type), (
                f"Variable value type hint inconsistency: expected {expected_type} at, "
                f"position {i} but got {type(value)}.")

        return output
示例#7
0
文件: validation.py 项目: zoovu/rasa
def _validate_types_of_reserved_keywords(params: Dict[Text, ParameterInfo],
                                         node: SchemaNode,
                                         fn_name: Text) -> None:
    for param_name, param in params.items():
        if param_name in KEYWORDS_EXPECTED_TYPES:
            if not typing_utils.issubtype(param.type_annotation,
                                          KEYWORDS_EXPECTED_TYPES[param_name]):
                raise GraphSchemaValidationException(
                    f"Your model uses a component '{node.uses.__name__}' which has an "
                    f"incompatible type '{param.type_annotation}' for "
                    f"the '{param_name}' parameter in its '{fn_name}' method. "
                    f"The expected type is '{KEYWORDS_EXPECTED_TYPES[param_name]}'."
                    f"See {DOCS_URL_GRAPH_COMPONENTS} for more information.")
示例#8
0
def _validate_types_of_reserved_keywords(params: Dict[Text, ParameterInfo],
                                         node_name: Text, node: SchemaNode,
                                         fn_name: Text) -> None:
    for param_name, param in params.items():
        if param_name in KEYWORDS_EXPECTED_TYPES:
            if not typing_utils.issubtype(param.type_annotation,
                                          KEYWORDS_EXPECTED_TYPES[param_name]):
                raise GraphSchemaValidationException(
                    f"Node '{node_name}' uses a graph component "
                    f"'{node.uses.__name__}' which has an incompatible type "
                    f"'{param.type_annotation}' for the '{param_name}' parameter in "
                    f"its '{fn_name}' method. Expected type "
                    f"'{ KEYWORDS_EXPECTED_TYPES[param_name]}'.")
示例#9
0
def _validate_parent_return_type(
    node_name: Text,
    node: SchemaNode,
    parent_name: Text,
    parent: SchemaNode,
    required_type: TypeAnnotation,
) -> None:
    _, parent_return_type = _get_parameter_information(parent_name,
                                                       parent.uses, parent.fn)
    if not typing_utils.issubtype(parent_return_type, required_type):
        raise GraphSchemaValidationException(
            f"Parent of node '{node_name}' returns type "
            f"'{parent_return_type}' but type '{required_type}' "
            f"was expected by component '{node.uses.__name__}'.")
示例#10
0
    def inject_to(self, func: Callable[..., Awaitable]) -> Iterator[Any]:
        sig: Signature = signature(func)
        keywords: List[str] = [name for name in sig.parameters.keys()]

        combinations: Iterator[Tuple[Any, ...]] = product(
            *(self._dependencies.get(p.annotation, [])
              for p in sig.parameters.values()))

        async def _wrapper(**kwargs: Any) -> List[Any]:
            return [await func(**kwargs)]

        f: Callable[..., Awaitable] = _wrapper \
            if not issubtype(sig.return_annotation, List[Any]) else func  # type: ignore
        for values in combinations:
            yield f(**dict(zip(keywords, values)))
示例#11
0
文件: validation.py 项目: zoovu/rasa
def _validate_parent_return_type(
    node: SchemaNode,
    parent_node: Optional[SchemaNode],
    parent_return_type: TypeAnnotation,
    required_type: TypeAnnotation,
) -> None:

    if not typing_utils.issubtype(parent_return_type, required_type):
        parent_node_text = ""
        if parent_node:
            parent_node_text = f" by the component '{parent_node.uses.__name__}'"

        raise GraphSchemaValidationException(
            f"Your component '{node.uses.__name__}' expects an input of type "
            f"'{required_type}' but it receives an input of type '{parent_return_type}'"
            f"{parent_node_text}. "
            f"Please make sure that you registered "
            f"your component correctly and and that your model configuration is "
            f"valid."
            f"See {DOCS_URL_GRAPH_COMPONENTS} for more information.")
示例#12
0
文件: validation.py 项目: zoovu/rasa
def _validate_run_fn_return_type(node: SchemaNode, return_type: Type,
                                 is_training: bool) -> None:
    if return_type == inspect.Parameter.empty:
        raise GraphSchemaValidationException(
            f"Your model uses a component '{node.uses.__name__}' whose "
            f"method '{node.fn}' does not have a type annotation for "
            f"its return value. Type annotations are required for all "
            f"components to validate your model's structure."
            f"See {DOCS_URL_GRAPH_COMPONENTS} for more information.")

    # TODO: Handle forward references here
    if typing_utils.issubtype(return_type, list):
        return_type = typing_utils.get_args(return_type)[0]

    if is_training and not isinstance(return_type, Fingerprintable):
        raise GraphSchemaValidationException(
            f"Your model uses a component '{node.uses.__name__}' whose method "
            f"'{node.fn}' does not return a fingerprintable "
            f"output. This is required for proper caching between model trainings. "
            f"Please make sure you're using a return type which implements the "
            f"'{Fingerprintable.__name__}' protocol.")
示例#13
0
def test_is_subtype():
    # Any
    assert issubtype(typing.List, typing.Any)
    assert issubtype(typing.Any, typing.Any)

    # Self
    assert issubtype(list, list)
    assert issubtype(typing.List, typing.List)
    assert not issubtype(list, dict)
    assert not issubtype(typing.List, typing.Dict)

    # None
    assert issubtype(None, type(None))
    assert issubtype(type(None), None)
    assert issubtype(None, None)

    # alias
    assert issubtype(list, typing.List)
    assert issubtype(typing.List, list)
    assert issubtype(bytes, typing.ByteString)

    # Subclass
    assert issubtype(list, typing.Sequence)

    # FileLike
    with open("test", "wb") as file_ref:
        assert issubtype(type(file_ref), typing.BinaryIO)
    with open("test", "rb") as file_ref:
        assert issubtype(type(file_ref), typing.BinaryIO)
    with open("test", "w") as file_ref:
        assert issubtype(type(file_ref), typing.TextIO)
    with open("test", "r") as file_ref:
        assert issubtype(type(file_ref), typing.TextIO)

    assert issubtype(type(io.BytesIO(b"0")), typing.BinaryIO)
    assert issubtype(type(io.StringIO("0")), typing.TextIO)

    # subscribed generic
    assert issubtype(typing.List[int], list)
    assert issubtype(typing.List[typing.List], list)
    assert not issubtype(list, typing.List[int])

    # Union
    assert issubtype(list, typing.Union[typing.List, typing.Tuple])
    assert issubtype(typing.Union[list, tuple], typing.Union[list, tuple,
                                                             None])
    assert issubtype(typing.Union[list, tuple], typing.Sequence)

    assert not issubtype(list, typing.Union[typing.Tuple, typing.Set])
    assert not issubtype(typing.Tuple[typing.Union[int, None]],
                         typing.Tuple[None])

    # Nested containers
    assert issubtype(typing.List[int], typing.List[int])
    assert issubtype(typing.List[typing.List], typing.List[typing.Sequence])

    assert issubtype(typing.Dict[typing.List, int],
                     typing.Dict[typing.Sequence, int])
    assert issubtype(
        typing.Callable[[typing.List, int], int],
        typing.Callable[[typing.Sequence, int], int],
    )
    assert not issubtype(
        typing.Callable[[typing.Sequence, int], int],
        typing.Callable[[typing.List, int], int],
    )

    # Callable
    assert issubtype(
        typing.Callable[[typing.List, int], None],
        typing.Callable[[list, int], None],
    )
    assert issubtype(
        typing.Callable[[typing.List, int], None],
        typing.Callable[[typing.Sequence, int], None],
    )
    assert issubtype(
        typing.Callable[[typing.List[int], int], None],
        typing.Callable[[typing.Sequence[int], int], None],
    )
    assert not issubtype(
        typing.Callable[[typing.List[int], int], None],
        typing.Callable[[typing.List[str], int], None],
    )
    assert not issubtype(
        typing.Callable[[typing.List[int], int], None],
        typing.Callable[[typing.List[int], int], int],
    )
    assert not issubtype(
        typing.Callable[[typing.List[int], int, None], None],
        typing.Callable[[typing.List[int], int], None],
    )

    # ForwardRef
    assert issubtype(int, JSON, forward_refs={'JSON': JSON})
    assert issubtype(str, JSON, forward_refs={'JSON': JSON})
    assert issubtype(typing.Dict[str, str], JSON, forward_refs={'JSON': JSON})
    assert not issubtype(
        typing.Dict[str, bytes], JSON, forward_refs={'JSON': JSON})

    assert issubtype(typing.Dict[str, str],
                     typing.Union[JSON, bytes],
                     forward_refs={'JSON': JSON})
    assert not issubtype(typing.Dict[str, bytes],
                         typing.Union[JSON, bytes],
                         forward_refs={'JSON': JSON})

    # Ellipsis
    assert issubtype(typing.Tuple[list], typing.Tuple[list, ...])
    assert issubtype(typing.Tuple[typing.List], typing.Tuple[list, ...])
    assert issubtype(typing.Tuple[list, list], typing.Tuple[typing.Sequence,
                                                            ...])
    assert not issubtype(typing.Tuple[list, int], typing.Tuple[typing.Sequence,
                                                               ...])
    assert issubtype(typing.Tuple[list, ...], typing.Tuple[list, ...])
    assert issubtype(typing.Tuple[list, ...], typing.Tuple[typing.Sequence,
                                                           ...])
    assert not issubtype(typing.Tuple[list, ...], typing.Tuple[list])

    # TypeVar
    T1 = typing.TypeVar("T1")
    T2 = typing.TypeVar("T2")
    T3 = typing.TypeVar("T3", bound=str)
    T4 = typing.TypeVar("T4", bound="typing.Union[list, tuple]")
    assert issubtype(T1, T1)
    assert not issubtype(T1, T2) and issubtype(T1, T2) is unknown
    assert not issubtype(T3, T4) and issubtype(T3, T4) is not unknown
    assert issubtype(T3, str)
    assert issubtype(T4, typing.Sequence)