Exemple #1
0
 def visit_For(self, node):
     # Python doesn't create a scope for "for", but we will
     # treat it as if it did because it should
     union_type = Union(List(Unknown()), Set(Unknown()),
                        Dict(Unknown(), Unknown()), Str())
     self.check_type(node.iter, union_type)
     self.begin_scope()
     self.check_assign(node, node.target, node.iter, generator=True)
     self.generic_visit(node)
     self.end_scope()
Exemple #2
0
def import_module(name, current_filepath, imported, warn):
    try:
        source, filepath, is_package = import_source(name, current_filepath)
    except RuntimeError as error:
        warn('import-failed',
             name + ' ' + current_filepath + '\n' + str(error))
        return Unknown(), current_filepath, False

    cache_filename = sha256(filepath + '~' + source).hexdigest()
    cache_filepath = os.path.join(os.sep, os.environ['HOME'], '.pystarch',
                                  __version__, cache_filename)

    if False and os.path.exists(cache_filepath):
        with open(cache_filepath, 'rb') as cache_file:
            return pickle.load(cache_file), filepath, is_package
    elif filepath in imported:
        #i = imported.index(filepath)
        #paths = ' -> '.join(imported[i:] + [filepath])
        #print('CIRCULAR: ' + paths)
        return Instance('object', Scope()), filepath, is_package
    else:
        imported.append(filepath)
        scope, _, _ = analyze(source, filepath, imported=imported)
        module = Instance('object', scope)
        #try: os.makedirs(os.path.dirname(cache_filepath))
        #except: pass
        #with open(cache_filepath, 'wb') as cache_file:
        #    import ipdb; ipdb.set_trace()
        #    pickle.dump(module, cache_file, pickle.HIGHEST_PROTOCOL)
        return module, filepath, is_package
Exemple #3
0
 def check_type(self, node, expected_type=Unknown()):
     computed_type = visit_expression(node, expected_type, self.context(),
                                      self._warnings)
     if (not type_subset(computed_type, expected_type)
             and not isinstance(computed_type, Unknown)):
         details = '{0} vs {1}'.format(computed_type, expected_type)
         self.warn('type-error', node, details)
     return computed_type
Exemple #4
0
 def check_return(self, node, is_yield=False):
     if node.value is None:
         value_type = NoneType()
     else:
         value_type = self.check_type(node.value, Unknown())
     return_type = List(value_type) if is_yield else value_type
     static_value = self.evaluate(node.value)
     self._check_return(return_type, static_value)
Exemple #5
0
    def visit_FunctionDef(self, node):
        visitor = ScopeVisitor(self._filepath,
                               self.context(),
                               warnings=self._warnings)
        function_type = construct_function_type(node, visitor,
                                                self._class_instance)
        self._context.add(Symbol(node.name, function_type))

        # now check that all the types are consistent between
        # the default types, annotated types, and constrained types
        signature = function_type.signature
        types = zip(signature.names, signature.types,
                    signature.annotated_types, signature.default_types)
        for name, _, annotated_type, default_type in types:
            if (annotated_type != Unknown() and default_type != Unknown()
                    and default_type != annotated_type):
                self.warn('default-argument-type-error', node, name)
Exemple #6
0
    def visit_ImportFrom(self, node):
        filepath = get_path_for_level(self._filepath, node.level)
        parts = node.module.split('.') if node.module else [None]
        warn = lambda category, details: self._warnings.warn(
            node, category, details)
        for part in parts:
            import_type, filepath, is_package = import_module(
                part, filepath, self._imported, warn)

        for alias in node.names:
            symbol_name = alias.asname or alias.name
            if is_package:
                symbol_type, _, _ = import_module(alias.name, filepath,
                                                  self._imported, warn)
            else:
                if isinstance(import_type, Instance):
                    symbol_type = import_type.attributes.get_type(alias.name)
                    if symbol_type is None:
                        warn('name-not-found', alias.name)
                        continue
                else:
                    symbol_type = Unknown()
            self._context.add(Symbol(symbol_name, symbol_type))
Exemple #7
0
def import_chain(fully_qualified_name, asname, import_scope, current_filepath,
                 imported, warn):
    scope = import_scope
    filepath = current_filepath
    is_package = True
    names = fully_qualified_name.split('.') if fully_qualified_name else [None]
    for name in names:
        if scope is None:
            warn('import-error', fully_qualified_name)
            return Unknown()
        if is_package:
            import_type, filepath, is_package = import_module(
                name, filepath, imported, warn)
            if asname is None:
                scope.add(Symbol(name, import_type))
            scope = (import_type.attributes if isinstance(
                import_type, Instance) else None)
        else:
            import_type = scope.get_type(name)
            scope = None
    if asname is not None:
        import_scope.add(Symbol(asname, import_type))
    return import_type
Exemple #8
0
 def visit_Expr(self, node):
     self.check_type(node.value, Unknown())