Exemplo n.º 1
0
    def register_semantic_type_to_format(self, semantic_type, artifact_format):
        if not issubclass(artifact_format, DirectoryFormat):
            raise TypeError("%r is not a directory format." % artifact_format)
        if not is_semantic_type(semantic_type):
            raise TypeError("%r is not a semantic type." % semantic_type)
        if not isinstance(semantic_type, grammar.TypeExpression):
            raise ValueError("%r is not a semantic type expression."
                             % semantic_type)
        if semantic_type.predicate is not None:
            raise ValueError("%r has a predicate, differentiating format on"
                             " predicate is not supported.")

        self.type_formats.append(TypeFormatRecord(
            type_expression=semantic_type,
            format=artifact_format, plugin=self))
Exemplo n.º 2
0
    def register_semantic_types(self, *semantic_types):
        for semantic_type in semantic_types:
            if not is_semantic_type(semantic_type):
                raise TypeError("%r is not a semantic type." % semantic_type)

            if not (isinstance(semantic_type, grammar.CompositeType) or
                    (semantic_type.is_concrete() and
                    not semantic_type.fields)):
                raise ValueError("%r is not a semantic type symbol."
                                 % semantic_type)

            if semantic_type.name in self.types:
                raise ValueError("Duplicate semantic type symbol %r."
                                 % semantic_type)

            self.types[semantic_type.name] = SemanticTypeRecord(
                semantic_type=semantic_type, plugin=self)
Exemplo n.º 3
0
def parse_type(string, expect=None):
    """Convert a string into a TypeExpression

    Parameters
    ----------
    string : str
        The string type expression to convert into a TypeExpression
    expect : {'semantic', 'primitive', 'visualization'}, optional
        Will raise a TypeError if the resulting TypeExpression is not a member
        of `expect`.

    Returns
    -------
    TypeExpression

    Raises
    ------
    ValueError
        Raised when `expect` has an invalid value
    TypeError
        Raised when the expression contains invalid characters
    TypeError
        Raised when the expression does not result in a member of `expect`
    UnknownTypeError
        Raised when unkown types are present in the expression.

    """
    if expect is not None and expect not in {'semantic', 'primitive',
                                             'visualization'}:
        raise ValueError("`expect` got %r, must be 'semantic', 'primitive',"
                         " 'visualization', or None." % (expect,))

    if '\n' in string or '\r' in string or ';' in string:
        raise TypeError("Found multiple statements in type expression %r. Will"
                        " not evaluate to avoid arbitrary code execution."
                        % string)

    pm = qiime2.sdk.PluginManager()
    locals_ = {n: getattr(qtype, n) for n in qtype.__all__ if '_' not in n}
    locals_.update({k: v.semantic_type for k, v in pm.semantic_types.items()})

    try:
        type_expr = eval(string, {'__builtins__': {}}, locals_)
        if expect is None:
            pass
        elif expect == 'semantic' and qtype.is_semantic_type(type_expr):
            pass
        # TODO optimize codepath for `expect=primitive` and
        # `expect=visualization` since `PluginManager` is slow and isn't
        # necessary for these types.
        elif expect == 'primitive' and qtype.is_primitive_type(type_expr):
            pass
        elif expect == 'visualization' and type_expr == qtype.Visualization:
            pass
        else:
            raise TypeError("Type expression %r is not a %s type."
                            % (type_expr, expect))
        return type_expr
    except NameError as e:
        # http://stackoverflow.com/a/2270822/579416
        name, = re.findall("name '(\w+)' is not defined", str(e))
        raise UnknownTypeError("Name %r is not a defined QIIME type, a plugin"
                               " may be needed to define it." % name)
Exemplo n.º 4
0
 def test_set_primitive_type(self):
     self.assertTrue(is_collection_type(Set[Int % Range(5)]))
     self.assertTrue(is_primitive_type(Set[Int % Range(5)]))
     self.assertFalse(is_semantic_type(Set[Int % Range(5)]))
Exemplo n.º 5
0
    def test_set_semantic_type(self):
        Foo = SemanticType('Foo')

        self.assertTrue(is_collection_type(Set[Foo]))
        self.assertTrue(is_semantic_type(Set[Foo]))
        self.assertFalse(is_primitive_type(Set[Foo]))
Exemplo n.º 6
0
def action_patch(self,
                 action: 'UsageAction',
                 inputs: 'UsageInputs',
                 outputs: 'UsageOutputNames',
                 ) -> 'UsageOutputs':
    """
    A monkeypatch for Usage.action that deals generously with archive versions
    that don't track output-name.

    If there are no output-names to search the signature with, it will attempt
    to search the signature.outputs for a parameter spec with the same
    QIIME type.

    Because our goal in the patched snippet is to assign a usage example type,
    a type-expression match should always return a correct usage example type.
    """
    if not isinstance(action, UsageAction):  # pragma: no cover
        raise ValueError('Invalid value for `action`: expected %r, '
                         'received %r.' % (UsageAction, type(action)))

    if not isinstance(inputs, UsageInputs):  # pragma: no cover
        raise ValueError('Invalid value for `inputs`: expected %r, '
                         'received %r.' % (UsageInputs, type(inputs)))

    if not isinstance(outputs, UsageOutputNames):  # pragma: no cover
        raise ValueError('Invalid value for `outputs`: expected %r, '
                         'received %r.' % (UsageOutputNames,
                                           type(outputs)))

    action_f = _get_action_if_plugin_present(action)

    @functools.lru_cache(maxsize=None)
    def memoized_action():  # pragma: no cover
        execed_inputs = inputs.map_variables(lambda v: v.execute())
        if self.asynchronous:
            return action_f.asynchronous(**execed_inputs).result()
        return action_f(**execed_inputs)

    usage_results = []
    # outputs will be ordered by the `UsageOutputNames` order, not the
    # signature order - this makes it so that the example writer doesn't
    # need to be explicitly aware of the signature order
    for param_name, var_name in outputs.items():
        # param name is not output-name in archive versions without output-name
        try:
            qiime_type = action_f.signature.outputs[param_name].qiime_type
        except KeyError:
            # param_name is often a snake-case qiime2 type, so we can check
            # if the same type still exists in the param spec. If so, use it.
            for (p_name, p_spec) in action_f.signature.outputs.items():
                searchable_type_name = camel_to_snake(str(p_spec.qiime_type))
                if param_name == searchable_type_name:
                    qiime_type = action_f.signature.outputs[p_name].qiime_type
                    break

        if is_visualization_type(qiime_type):
            var_type = 'visualization'
        elif is_semantic_type(qiime_type):
            var_type = 'artifact'
        else:  # pragma: no cover
            raise ValueError('unknown output type: %r' % (qiime_type,))

        def factory(name=param_name):  # pragma: no cover
            results = memoized_action()
            result = getattr(results, name)
            return result

        variable = self._usage_variable(var_name, factory, var_type)
        usage_results.append(variable)

    results = UsageOutputs(outputs.keys(), usage_results)
    cache_info = memoized_action.cache_info
    cache_clear = memoized_action.cache_clear
    # manually graft on cache operations
    object.__setattr__(results, '_cache_info', cache_info)
    object.__setattr__(results, '_cache_reset', cache_clear)
    return results
Exemplo n.º 7
0
 def test_set_primitive_type(self):
     self.assertTrue(is_collection_type(Set[Int % Range(5)]))
     self.assertTrue(is_primitive_type(Set[Int % Range(5)]))
     self.assertFalse(is_semantic_type(Set[Int % Range(5)]))
Exemplo n.º 8
0
    def test_set_semantic_type(self):
        Foo = SemanticType('Foo')

        self.assertTrue(is_collection_type(Set[Foo]))
        self.assertTrue(is_semantic_type(Set[Foo]))
        self.assertFalse(is_primitive_type(Set[Foo]))
Exemplo n.º 9
0
def parse_type(string, expect=None):
    """Convert a string into a TypeExpression

    Parameters
    ----------
    string : str
        The string type expression to convert into a TypeExpression
    expect : {'semantic', 'primitive', 'visualization'}, optional
        Will raise a TypeError if the resulting TypeExpression is not a member
        of `expect`.

    Returns
    -------
    TypeExpression

    Raises
    ------
    ValueError
        Raised when `expect` has an invalid value
    TypeError
        Raised when the expression contains invalid characters
    TypeError
        Raised when the expression does not result in a member of `expect`
    UnknownTypeError
        Raised when unkown types are present in the expression.

    """
    if expect is not None and expect not in {'semantic', 'primitive',
                                             'visualization'}:
        raise ValueError("`expect` got %r, must be 'semantic', 'primitive',"
                         " 'visualization', or None." % (expect,))

    if '\n' in string or '\r' in string or ';' in string:
        raise TypeError("Found multiple statements in type expression %r. Will"
                        " not evaluate to avoid arbitrary code execution."
                        % string)

    pm = qiime2.sdk.PluginManager()
    locals_ = {n: getattr(qtype, n) for n in qtype.__all__ if '_' not in n}
    locals_.update({k: v.semantic_type for k, v in pm.semantic_types.items()})

    try:
        type_expr = eval(string, {'__builtins__': {}}, locals_)
        if expect is None:
            pass
        elif expect == 'semantic' and qtype.is_semantic_type(type_expr):
            pass
        # TODO optimize codepath for `expect=primitive` and
        # `expect=visualization` since `PluginManager` is slow and isn't
        # necessary for these types.
        elif expect == 'primitive' and qtype.is_primitive_type(type_expr):
            pass
        elif expect == 'visualization' and type_expr == qtype.Visualization:
            pass
        else:
            raise TypeError("Type expression %r is not a %s type."
                            % (type_expr, expect))
        return type_expr
    except NameError as e:
        # http://stackoverflow.com/a/2270822/579416
        name, = re.findall(r"name '(\w+)' is not defined", str(e))
        raise UnknownTypeError("Name %r is not a defined QIIME type, a plugin"
                               " may be needed to define it." % name)