Exemplo n.º 1
0
    def substitute_and_reinfer(self):
        """
        Try substituting resolved parts of promotions and reinfer the types.
        """
        from numba import symtab

        if not self.variable.type.is_unresolved:
            return False

        # Find substitutions and save original variables
        old_vars = []
        for node in self.dependences:
            sub_type = self.substitution_candidate(node.variable)
            if sub_type:
                old_vars.append((node, node.variable))
                node.variable = symtab.Variable(sub_type, name='<substitute>')

        if old_vars:
            # We have some substitutions, retry type inference
            result = self._reinfer()
            # Reset our original variables!
            for node, old_var in old_vars:
                node.variable = old_var
            return result

        # We cannot substitute any promotion candidates, see if we can resolve
        # anyhow (this should be a cheap operation anyway if it fails)
        new_type = self.retry_infer()
        if not new_type.is_unresolved:
            self.variable.type = new_type
            return True

        return False
Exemplo n.º 2
0
def inherit_attributes(ext_type, class_dict):
    cls = ext_type.py_class
    if not is_numba_class(cls):
        # superclass is not a numba class
        return

    struct_type = cls.__numba_struct_type
    vtab_type = cls.__numba_vtab_type
    verify_base_class_compatibility(cls, struct_type, vtab_type)

    # Inherit attributes
    ext_type.attribute_struct = numba.struct(struct_type.fields)
    for field_name, field_type in ext_type.attribute_struct.fields:
        ext_type.symtab[field_name] = symtab.Variable(field_type,
                                                      promotable_type=False)

    # Inherit methods
    for method_name, method_type in vtab_type.fields:
        func_signature = method_type.base_type
        args = list(func_signature.args)
        if not (func_signature.is_class or func_signature.is_static):
            args[0] = ext_type
        func_signature = func_signature.return_type(*args)
        ext_type.add_method(method_name, func_signature)

    ext_type.parent_attr_struct = struct_type
    ext_type.parent_vtab_type = vtab_type
Exemplo n.º 3
0
def build_extension_symtab(ext_type):
    """
    Create symbol table for all attributes of the extension type. These
    are Variables which are used by the type inferencer and used to
    type check attribute assignments.

    New attribute assignments create new ExtensionAttributeVariable
    variables in the symtab. These variables update the attribute table
    during type inference:

        class Foo(object):

            value1 = double

            def __init__(self, value2):
                self.value2 = int_(value2)

    Before type inference of __init__ we have:

        symtab = { 'value1': Variable(double) }

    and after type inference of __init__ we have:

        symtab = {
            'value1': Variable(double),                   # type is fixed
            'value2': ExtensionAttributeVariable(int_),   # type is inferred
        }
    """
    table = ext_type.attribute_table
    for attr_name, attr_type in table.attributedict.iteritems():
        ext_type.symtab[attr_name] = symtab.Variable(attr_type,
                                                     promotable_type=False)
Exemplo n.º 4
0
def promote(typesystem, type1, type2, assignment=False):
    promote_ = partial(promote, typesystem)

    if type1.is_unresolved or type2.is_unresolved:
        if type1.is_unresolved:
            type1 = type1.resolve()
        if type2.is_unresolved:
            type2 = type2.resolve()

        if type1.is_unresolved or type2.is_unresolved:
            # The Variable is really only important for ast.Name, fabricate
            # one
            from numba import symtab
            var = symtab.Variable(None)
            return PromotionType(var, promote_, [type1, type2])
        else:
            return typesystem.promote(type1, type2)

    return typesystem.promote(type1, type2)
Exemplo n.º 5
0
    def promote_types(self, type1, type2, assignment=False):
        have = lambda p1, p2: have_properties(type1, type2, p1, p2)

        if (type1.is_array or type2.is_array) and not \
            (type1.is_array and type2.is_array):
            if type1.is_array:
                array_type = type1
                other_type = type2
            else:
                array_type = type2
                other_type = type1

            type = copy.copy(array_type)
            type.dtype = self.promote_types(array_type.dtype, other_type)

            if type.dtype.is_object and not array_type.dtype.is_object:
                # Make sure that (double[:], object_) -> object_
                type = object_
            return type
        elif type1.is_unresolved or type2.is_unresolved:
            if type1.is_unresolved:
                type1 = type1.resolve()
            if type2.is_unresolved:
                type2 = type2.resolve()

            if type1.is_unresolved or type2.is_unresolved:
                # The Variable is really only important for ast.Name, fabricate
                # one
                from numba import symtab
                var = symtab.Variable(None)
                return PromotionType(var, self.context, [type1, type2])
            else:
                return self.promote_types(type1, type2)
        elif have("is_pointer", "is_null"):
            return [type1, type2][type1.is_null]  # return the pointer type
        elif have("is_pointer", "is_int"):
            return [type1, type2][type1.is_int]  # return the pointer type

        return super(NumbaTypeMapper, self).promote_types(type1, type2)
Exemplo n.º 6
0
    def initialize_symtab(self, allow_rebind_args):
        """
        Populate the symbol table with variables and set their renaming status.

        Variables appearing in locals, or arguments typed through the 'jit'
        decorator are not renameable.
        """
        symbols = symtab.Symtab(self.symtab)
        for var_name in self.local_names:
            variable = symtab.Variable(None, name=var_name, is_local=True)

            # Set cellvar status. Free variables are not assignments, and
            # are caught in the type inferencer
            variable.is_cellvar = var_name in self.cellvars
            # variable.is_freevar = var_name in self.freevars

            variable.renameable = (
                var_name not in self.locals and not
                (variable.is_cellvar or variable.is_freevar) and
                (var_name not in self.argnames or allow_rebind_args))

            symbols[var_name] = variable

        return symbols