예제 #1
0
def generate_html_report(tree: MypyFile, path: str, type_map: Dict[Expression,
                                                                   Type],
                         output_dir: str) -> None:
    if is_special_module(path):
        return
    # There may be more than one right answer for "what should we do here?"
    # but this is a reasonable one.
    path = os.path.relpath(path)
    if path.startswith('..'):
        return
    visitor = StatisticsVisitor(inferred=True,
                                filename=tree.fullname(),
                                typemap=type_map,
                                all_nodes=True)
    tree.accept(visitor)
    assert not os.path.isabs(path) and not path.startswith('..')
    # This line is *wrong* if the preceding assert fails.
    target_path = os.path.join(output_dir, 'html', path)
    # replace .py or .pyi with .html
    target_path = os.path.splitext(target_path)[0] + '.html'
    assert target_path.endswith('.html')
    ensure_dir_exists(os.path.dirname(target_path))
    output = []  # type: List[str]
    append = output.append
    append('''\
<html>
<head>
  <style>
    .red { background-color: #faa; }
    .yellow { background-color: #ffa; }
    .white { }
    .lineno { color: #999; }
  </style>
</head>
<body>
<pre>''')
    num_imprecise_lines = 0
    num_lines = 0
    with open(path) as input_file:
        for i, line in enumerate(input_file):
            lineno = i + 1
            status = visitor.line_map.get(lineno, TYPE_PRECISE)
            style_map = {
                TYPE_PRECISE: 'white',
                TYPE_IMPRECISE: 'yellow',
                TYPE_ANY: 'red'
            }
            style = style_map[status]
            append('<span class="lineno">%4d</span>   ' % lineno +
                   '<span class="%s">%s</span>' % (style, cgi.escape(line)))
            if status != TYPE_PRECISE:
                num_imprecise_lines += 1
            if line.strip():
                num_lines += 1
    append('</pre>')
    append('</body></html>')
    with open(target_path, 'w') as output_file:
        output_file.writelines(output)
    target_path = target_path[len(output_dir) + 1:]
    html_files.append((path, target_path, num_lines, num_imprecise_lines))
예제 #2
0
파일: report.py 프로젝트: alexandrul/mypy
    def on_file(self, tree: MypyFile, type_map: Dict[Expression, Type]) -> None:
        self.last_xml = None
        path = os.path.relpath(tree.path)
        if stats.is_special_module(path):
            return
        if path.startswith('..'):
            return
        if 'stubs' in path.split('/'):
            return

        visitor = stats.StatisticsVisitor(inferred=True, typemap=type_map, all_nodes=True)
        tree.accept(visitor)

        root = etree.Element('mypy-report-file', name=path, module=tree._fullname)
        doc = etree.ElementTree(root)
        file_info = FileInfo(path, tree._fullname)

        with tokenize.open(path) as input_file:
            for lineno, line_text in enumerate(input_file, 1):
                status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
                file_info.counts[status] += 1
                etree.SubElement(root, 'line',
                                 number=str(lineno),
                                 precision=stats.precision_names[status],
                                 content=line_text[:-1])
        # Assumes a layout similar to what XmlReporter uses.
        xslt_path = os.path.relpath('mypy-html.xslt', path)
        transform_pi = etree.ProcessingInstruction('xml-stylesheet',
                'type="text/xsl" href="%s"' % cgi.escape(xslt_path, True))
        root.addprevious(transform_pi)
        self.schema.assertValid(doc)

        self.last_xml = doc
        self.files.append(file_info)
예제 #3
0
 def strip_file_top_level(self, file_node: MypyFile) -> None:
     """Strip a module top-level (don't recursive into functions)."""
     self.names = file_node.names
     self.file_node = file_node
     self.recurse_into_functions = False
     file_node.plugin_deps.clear()
     file_node.accept(self)
예제 #4
0
파일: deps.py 프로젝트: sixolet/mypy
def get_dependencies(target: MypyFile,
                     type_map: Dict[Expression, Type],
                     python_version: Tuple[int, int]) -> Dict[str, Set[str]]:
    """Get all dependencies of a node, recursively."""
    visitor = DependencyVisitor(type_map, python_version, target.alias_deps)
    target.accept(visitor)
    return visitor.map
예제 #5
0
파일: deps.py 프로젝트: lslaoang/mypy
def get_dependencies(target: MypyFile,
                     type_map: Dict[Expression, Type],
                     python_version: Tuple[int, int]) -> Dict[str, Set[str]]:
    """Get all dependencies of a node, recursively."""
    visitor = DependencyVisitor(type_map, python_version)
    target.accept(visitor)
    return visitor.map
예제 #6
0
def dump_type_stats(tree: MypyFile,
                    path: str,
                    modules: Dict[str, MypyFile],
                    inferred: bool = False,
                    typemap: Optional[Dict[Expression, Type]] = None) -> None:
    if is_special_module(path):
        return
    print(path)
    visitor = StatisticsVisitor(inferred,
                                filename=tree.fullname(),
                                modules=modules,
                                typemap=typemap)
    tree.accept(visitor)
    for line in visitor.output:
        print(line)
    print('  ** precision **')
    print('  precise  ', visitor.num_precise_exprs)
    print('  imprecise', visitor.num_imprecise_exprs)
    print('  any      ', visitor.num_any_exprs)
    print('  ** kinds **')
    print('  simple   ', visitor.num_simple_types)
    print('  generic  ', visitor.num_generic_types)
    print('  function ', visitor.num_function_types)
    print('  tuple    ', visitor.num_tuple_types)
    print('  TypeVar  ', visitor.num_typevar_types)
    print('  complex  ', visitor.num_complex_types)
    print('  any      ', visitor.num_any_types)
예제 #7
0
파일: aststrip.py 프로젝트: alex2201/helpet
 def strip_file_top_level(self, file_node: MypyFile) -> None:
     """Strip a module top-level (don't recursive into functions)."""
     self.names = file_node.names
     self.file_node = file_node
     self.recurse_into_functions = False
     file_node.plugin_deps.clear()
     file_node.accept(self)
예제 #8
0
파일: report.py 프로젝트: chadrik/mypy
    def on_file(self,
                tree: MypyFile,
                type_map: Dict[Expression, Type],
                options: Options) -> None:
        path = os.path.relpath(tree.path)
        visitor = stats.StatisticsVisitor(inferred=True, filename=tree.fullname(),
                                          typemap=type_map, all_nodes=True)
        tree.accept(visitor)

        class_name = os.path.basename(path)
        file_info = FileInfo(path, tree._fullname)
        class_element = etree.Element('class',
                                      filename=path,
                                      complexity='1.0',
                                      name=class_name)
        etree.SubElement(class_element, 'methods')
        lines_element = etree.SubElement(class_element, 'lines')

        with tokenize.open(path) as input_file:
            class_lines_covered = 0
            class_total_lines = 0
            for lineno, _ in enumerate(input_file, 1):
                status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
                hits = 0
                branch = False
                if status == stats.TYPE_EMPTY:
                    continue
                class_total_lines += 1
                if status != stats.TYPE_ANY:
                    class_lines_covered += 1
                    hits = 1
                if status == stats.TYPE_IMPRECISE:
                    branch = True
                file_info.counts[status] += 1
                line_element = etree.SubElement(lines_element, 'line',
                                                number=str(lineno),
                                                precision=stats.precision_names[status],
                                                hits=str(hits),
                                                branch=str(branch).lower())
                if branch:
                    line_element.attrib['condition-coverage'] = '50% (1/2)'
            class_element.attrib['branch-rate'] = '0'
            class_element.attrib['line-rate'] = get_line_rate(class_lines_covered,
                                                              class_total_lines)
            # parent_module is set to whichever module contains this file.  For most files, we want
            # to simply strip the last element off of the module.  But for __init__.py files,
            # the module == the parent module.
            parent_module = file_info.module.rsplit('.', 1)[0]
            if file_info.name.endswith('__init__.py'):
                parent_module = file_info.module

            if parent_module not in self.root_package.packages:
                self.root_package.packages[parent_module] = CoberturaPackage(parent_module)
            current_package = self.root_package.packages[parent_module]
            packages_to_update = [self.root_package, current_package]
            for package in packages_to_update:
                package.total_lines += class_total_lines
                package.covered_lines += class_lines_covered
            current_package.classes[class_name] = class_element
예제 #9
0
    def on_file(self,
                tree: MypyFile,
                type_map: Dict[Expression, Type],
                options: Options) -> None:
        path = os.path.relpath(tree.path)
        visitor = stats.StatisticsVisitor(inferred=True, filename=tree.fullname(),
                                          typemap=type_map, all_nodes=True)
        tree.accept(visitor)

        class_name = os.path.basename(path)
        file_info = FileInfo(path, tree._fullname)
        class_element = etree.Element('class',
                                      filename=path,
                                      complexity='1.0',
                                      name=class_name)
        etree.SubElement(class_element, 'methods')
        lines_element = etree.SubElement(class_element, 'lines')

        with tokenize.open(path) as input_file:
            class_lines_covered = 0
            class_total_lines = 0
            for lineno, _ in enumerate(input_file, 1):
                status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
                hits = 0
                branch = False
                if status == stats.TYPE_EMPTY:
                    continue
                class_total_lines += 1
                if status != stats.TYPE_ANY:
                    class_lines_covered += 1
                    hits = 1
                if status == stats.TYPE_IMPRECISE:
                    branch = True
                file_info.counts[status] += 1
                line_element = etree.SubElement(lines_element, 'line',
                                                number=str(lineno),
                                                precision=stats.precision_names[status],
                                                hits=str(hits),
                                                branch=str(branch).lower())
                if branch:
                    line_element.attrib['condition-coverage'] = '50% (1/2)'
            class_element.attrib['branch-rate'] = '0'
            class_element.attrib['line-rate'] = get_line_rate(class_lines_covered,
                                                              class_total_lines)
            # parent_module is set to whichever module contains this file.  For most files, we want
            # to simply strip the last element off of the module.  But for __init__.py files,
            # the module == the parent module.
            parent_module = file_info.module.rsplit('.', 1)[0]
            if file_info.name.endswith('__init__.py'):
                parent_module = file_info.module

            if parent_module not in self.root_package.packages:
                self.root_package.packages[parent_module] = CoberturaPackage(parent_module)
            current_package = self.root_package.packages[parent_module]
            packages_to_update = [self.root_package, current_package]
            for package in packages_to_update:
                package.total_lines += class_total_lines
                package.covered_lines += class_lines_covered
            current_package.classes[class_name] = class_element
예제 #10
0
파일: stubgen.py 프로젝트: alexandrul/mypy
def find_classes(node: MypyFile) -> Set[str]:
    results = set()  # type: Set[str]

    class ClassTraverser(mypy.traverser.TraverserVisitor):
        def visit_class_def(self, o: ClassDef) -> None:
            results.add(o.name)

    node.accept(ClassTraverser())
    return results
예제 #11
0
파일: stubgen.py 프로젝트: lamby/mypy
def find_classes(node: MypyFile) -> Set[str]:
    results = set()  # type: Set[str]

    class ClassTraverser(mypy.traverser.TraverserVisitor):
        def visit_class_def(self, o: ClassDef) -> None:
            results.add(o.name)

    node.accept(ClassTraverser())
    return results
예제 #12
0
 def strip_file_top_level(self, file_node: MypyFile) -> None:
     """Strip a module top-level (don't recursive into functions)."""
     self.recurse_into_functions = False
     file_node.plugin_deps.clear()
     file_node.accept(self)
     for name in file_node.names.copy():
         # TODO: this is a hot fix, we should delete all names,
         # see https://github.com/python/mypy/issues/6422.
         if '@' not in name:
             del file_node.names[name]
예제 #13
0
파일: report.py 프로젝트: vdt/mypy
 def on_file(self, tree: MypyFile, type_map: Dict[Expression, Type],
             options: Options) -> None:
     visitor = stats.StatisticsVisitor(inferred=True,
                                       filename=tree.fullname(),
                                       typemap=type_map,
                                       all_nodes=True)
     tree.accept(visitor)
     num_total = visitor.num_imprecise + visitor.num_precise + visitor.num_any
     if num_total > 0:
         self.counts[tree.fullname()] = (visitor.num_any, num_total)
예제 #14
0
파일: stats.py 프로젝트: alexandrul/mypy
def generate_html_report(tree: MypyFile, path: str, type_map: Dict[Expression, Type],
                         output_dir: str) -> None:
    if is_special_module(path):
        return
    # There may be more than one right answer for "what should we do here?"
    # but this is a reasonable one.
    path = os.path.relpath(path)
    if path.startswith('..'):
        return
    visitor = StatisticsVisitor(inferred=True, typemap=type_map, all_nodes=True)
    tree.accept(visitor)
    assert not os.path.isabs(path) and not path.startswith('..')
    # This line is *wrong* if the preceding assert fails.
    target_path = os.path.join(output_dir, 'html', path)
    # replace .py or .pyi with .html
    target_path = os.path.splitext(target_path)[0] + '.html'
    assert target_path.endswith('.html')
    ensure_dir_exists(os.path.dirname(target_path))
    output = []  # type: List[str]
    append = output.append
    append('''\
<html>
<head>
  <style>
    .red { background-color: #faa; }
    .yellow { background-color: #ffa; }
    .white { }
    .lineno { color: #999; }
  </style>
</head>
<body>
<pre>''')
    num_imprecise_lines = 0
    num_lines = 0
    with open(path) as input_file:
        for i, line in enumerate(input_file):
            lineno = i + 1
            status = visitor.line_map.get(lineno, TYPE_PRECISE)
            style_map = {TYPE_PRECISE: 'white',
                         TYPE_IMPRECISE: 'yellow',
                         TYPE_ANY: 'red'}
            style = style_map[status]
            append('<span class="lineno">%4d</span>   ' % lineno +
                   '<span class="%s">%s</span>' % (style,
                                                   cgi.escape(line)))
            if status != TYPE_PRECISE:
                num_imprecise_lines += 1
            if line.strip():
                num_lines += 1
    append('</pre>')
    append('</body></html>')
    with open(target_path, 'w') as output_file:
        output_file.writelines(output)
    target_path = target_path[len(output_dir) + 1:]
    html_files.append((path, target_path, num_lines, num_imprecise_lines))
예제 #15
0
파일: report.py 프로젝트: JdeH/Transcrypt
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        tree_source = open(tree.path).readlines()

        coverage_visitor = LineCoverageVisitor(tree_source)
        tree.accept(coverage_visitor)

        covered_lines = []
        for line_number, (_, typed) in enumerate(coverage_visitor.lines_covered):
            if typed:
                covered_lines.append(line_number + 1)

        self.lines_covered[os.path.abspath(tree.path)] = covered_lines
예제 #16
0
파일: report.py 프로젝트: alunduil/mypy
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        physical_lines = len(open(tree.path).readlines())

        func_counter = FuncCounterVisitor()
        tree.accept(func_counter)
        unannotated_funcs, annotated_funcs = func_counter.counts
        total_funcs = annotated_funcs + unannotated_funcs

        imputed_annotated_lines = (physical_lines * annotated_funcs // total_funcs
                                   if total_funcs else physical_lines)

        self.counts[tree._fullname] = (imputed_annotated_lines, physical_lines,
                                       annotated_funcs, total_funcs)
예제 #17
0
    def anal_code(self, code: MypyFile) -> Dict[str, List[str]]:
        logger.debug(f"code.fullname = {code.fullname!r}, self.cache = {self.cache!r}")
        if code.fullname not in self.cache:
            try:
                visitor = RelationshipVisitor()
            except TypeError:  # pragma: no cover
                # Only supports versions that are bigger than 0.820
                return {}

            code.accept(visitor)
            self.cache[code.fullname] = visitor.relationships

        return self.cache[code.fullname]
예제 #18
0
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        physical_lines = len(open(tree.path).readlines())

        func_counter = FuncCounterVisitor()
        tree.accept(func_counter)
        unannotated_funcs, annotated_funcs = func_counter.counts
        total_funcs = annotated_funcs + unannotated_funcs

        imputed_annotated_lines = (physical_lines * annotated_funcs // total_funcs
                                   if total_funcs else physical_lines)

        self.counts[tree._fullname] = (imputed_annotated_lines, physical_lines,
                                       annotated_funcs, total_funcs)
예제 #19
0
파일: report.py 프로젝트: JdeH/Transcrypt
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        # Count physical lines.  This assumes the file's encoding is a
        # superset of ASCII (or at least uses \n in its line endings).
        physical_lines = len(open(tree.path, "rb").readlines())

        func_counter = FuncCounterVisitor()
        tree.accept(func_counter)
        unannotated_funcs, annotated_funcs = func_counter.counts
        total_funcs = annotated_funcs + unannotated_funcs

        imputed_annotated_lines = physical_lines * annotated_funcs // total_funcs if total_funcs else physical_lines

        self.counts[tree._fullname] = (imputed_annotated_lines, physical_lines, annotated_funcs, total_funcs)
예제 #20
0
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        tree_source = open(tree.path).readlines()

        coverage_visitor = LineCoverageVisitor(tree_source)
        tree.accept(coverage_visitor)

        covered_lines = []
        for line_number, (_,
                          typed) in enumerate(coverage_visitor.lines_covered):
            if typed:
                covered_lines.append(line_number + 1)

        self.lines_covered[os.path.abspath(tree.path)] = covered_lines
예제 #21
0
 def on_file(self, tree: MypyFile, type_map: Dict[Expression, Type],
             options: Options) -> None:
     visitor = stats.StatisticsVisitor(inferred=True,
                                       filename=tree.fullname(),
                                       typemap=type_map,
                                       all_nodes=True)
     tree.accept(visitor)
     num_unanalyzed_lines = list(visitor.line_map.values()).count(
         stats.TYPE_UNANALYZED)
     # count each line of dead code as one expression of type "Any"
     num_any = visitor.num_any + num_unanalyzed_lines
     num_total = visitor.num_imprecise + visitor.num_precise + num_any
     if num_total > 0:
         self.counts[tree.fullname()] = (num_any, num_total)
예제 #22
0
파일: report.py 프로젝트: chadrik/mypy
 def on_file(self,
             tree: MypyFile,
             type_map: Dict[Expression, Type],
             options: Options) -> None:
     visitor = stats.StatisticsVisitor(inferred=True, filename=tree.fullname(),
                                       typemap=type_map, all_nodes=True,
                                       visit_untyped_defs=False)
     tree.accept(visitor)
     self.any_types_counter[tree.fullname()] = visitor.type_of_any_counter
     num_unanalyzed_lines = list(visitor.line_map.values()).count(stats.TYPE_UNANALYZED)
     # count each line of dead code as one expression of type "Any"
     num_any = visitor.num_any_exprs + num_unanalyzed_lines
     num_total = visitor.num_imprecise_exprs + visitor.num_precise_exprs + num_any
     if num_total > 0:
         self.counts[tree.fullname()] = (num_any, num_total)
예제 #23
0
파일: report.py 프로젝트: zadaya/CourseTB
    def on_file(self, tree: MypyFile, type_map: Dict[Expression, Type],
                options: Options) -> None:
        with open(tree.path) as f:
            tree_source = f.readlines()

        coverage_visitor = LineCoverageVisitor(tree_source)
        tree.accept(coverage_visitor)

        covered_lines = []
        for line_number, (_,
                          typed) in enumerate(coverage_visitor.lines_covered):
            if typed:
                covered_lines.append(line_number + 1)

        self.lines_covered[os.path.abspath(tree.path)] = covered_lines
예제 #24
0
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        # Count physical lines.  This assumes the file's encoding is a
        # superset of ASCII (or at least uses \n in its line endings).
        physical_lines = len(open(tree.path, 'rb').readlines())

        func_counter = FuncCounterVisitor()
        tree.accept(func_counter)
        unannotated_funcs, annotated_funcs = func_counter.counts
        total_funcs = annotated_funcs + unannotated_funcs

        imputed_annotated_lines = (physical_lines * annotated_funcs //
                                   total_funcs
                                   if total_funcs else physical_lines)

        self.counts[tree._fullname] = (imputed_annotated_lines, physical_lines,
                                       annotated_funcs, total_funcs)
예제 #25
0
파일: report.py 프로젝트: chadrik/mypy
    def on_file(self,
                tree: MypyFile,
                type_map: Dict[Expression, Type],
                options: Options) -> None:
        with open(tree.path) as f:
            tree_source = f.readlines()

        coverage_visitor = LineCoverageVisitor(tree_source)
        tree.accept(coverage_visitor)

        covered_lines = []
        for line_number, (_, typed) in enumerate(coverage_visitor.lines_covered):
            if typed:
                covered_lines.append(line_number + 1)

        self.lines_covered[os.path.abspath(tree.path)] = covered_lines
예제 #26
0
파일: report.py 프로젝트: rondan100/tkinter
 def on_file(self, tree: MypyFile, modules: Dict[str, MypyFile],
             type_map: Dict[Expression, Type], options: Options) -> None:
     visitor = stats.StatisticsVisitor(inferred=True,
                                       filename=tree.fullname,
                                       modules=modules,
                                       typemap=type_map,
                                       all_nodes=True,
                                       visit_untyped_defs=False)
     tree.accept(visitor)
     self.any_types_counter[tree.fullname] = visitor.type_of_any_counter
     num_unanalyzed_lines = list(visitor.line_map.values()).count(
         stats.TYPE_UNANALYZED)
     # count each line of dead code as one expression of type "Any"
     num_any = visitor.num_any_exprs + num_unanalyzed_lines
     num_total = visitor.num_imprecise_exprs + visitor.num_precise_exprs + num_any
     if num_total > 0:
         self.counts[tree.fullname] = (num_any, num_total)
예제 #27
0
파일: report.py 프로젝트: rondan100/tkinter
    def on_file(self, tree: MypyFile, modules: Dict[str, MypyFile],
                type_map: Dict[Expression, Type], options: Options) -> None:
        self.last_xml = None

        try:
            path = os.path.relpath(tree.path)
        except ValueError:
            return

        if should_skip_path(path):
            return

        visitor = stats.StatisticsVisitor(inferred=True,
                                          filename=tree.fullname,
                                          modules=modules,
                                          typemap=type_map,
                                          all_nodes=True)
        tree.accept(visitor)

        root = etree.Element('mypy-report-file',
                             name=path,
                             module=tree._fullname)
        doc = etree.ElementTree(root)
        file_info = FileInfo(path, tree._fullname)

        for lineno, line_text in iterate_python_lines(path):
            status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
            file_info.counts[status] += 1
            etree.SubElement(
                root,
                'line',
                any_info=self._get_any_info_for_line(visitor, lineno),
                content=line_text.rstrip('\n').translate(self.control_fixer),
                number=str(lineno),
                precision=stats.precision_names[status])
        # Assumes a layout similar to what XmlReporter uses.
        xslt_path = os.path.relpath('mypy-html.xslt', path)
        transform_pi = etree.ProcessingInstruction(
            'xml-stylesheet',
            'type="text/xsl" href="%s"' % pathname2url(xslt_path))
        root.addprevious(transform_pi)
        self.schema.assertValid(doc)

        self.last_xml = doc
        self.files.append(file_info)
예제 #28
0
파일: report.py 프로젝트: zadaya/CourseTB
    def on_file(self, tree: MypyFile, type_map: Dict[Expression, Type],
                options: Options) -> None:
        self.last_xml = None
        path = os.path.relpath(tree.path)
        if stats.is_special_module(path):
            return
        if path.startswith('..'):
            return
        if 'stubs' in path.split('/'):
            return

        visitor = stats.StatisticsVisitor(inferred=True,
                                          filename=tree.fullname(),
                                          typemap=type_map,
                                          all_nodes=True)
        tree.accept(visitor)

        root = etree.Element('mypy-report-file',
                             name=path,
                             module=tree._fullname)
        doc = etree.ElementTree(root)
        file_info = FileInfo(path, tree._fullname)

        with tokenize.open(path) as input_file:
            for lineno, line_text in enumerate(input_file, 1):
                status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
                file_info.counts[status] += 1
                etree.SubElement(root,
                                 'line',
                                 number=str(lineno),
                                 precision=stats.precision_names[status],
                                 content=line_text.rstrip('\n').translate(
                                     self.control_fixer),
                                 any_info=self._get_any_info_for_line(
                                     visitor, lineno))
        # Assumes a layout similar to what XmlReporter uses.
        xslt_path = os.path.relpath('mypy-html.xslt', path)
        transform_pi = etree.ProcessingInstruction(
            'xml-stylesheet',
            'type="text/xsl" href="%s"' % pathname2url(xslt_path))
        root.addprevious(transform_pi)
        self.schema.assertValid(doc)

        self.last_xml = doc
        self.files.append(file_info)
예제 #29
0
파일: report.py 프로젝트: yang/mypy-hack
    def on_file(self, tree: MypyFile, type_map: Dict[Node, Type]) -> None:
        import lxml.etree as etree

        self.last_xml = None
        path = os.path.relpath(tree.path)
        if stats.is_special_module(path):
            return
        if path.startswith('..'):
            return
        if 'stubs' in path.split('/'):
            return

        visitor = stats.StatisticsVisitor(inferred=True,
                                          typemap=type_map,
                                          all_nodes=True)
        tree.accept(visitor)

        root = etree.Element('mypy-report-file',
                             name=path,
                             module=tree._fullname)
        doc = etree.ElementTree(root)
        file_info = FileInfo(path, tree._fullname)

        with open(path) as input_file:
            for lineno, line_text in enumerate(input_file, 1):
                status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
                file_info.counts[status] += 1
                etree.SubElement(root,
                                 'line',
                                 number=str(lineno),
                                 precision=stats.precision_names[status],
                                 content=line_text[:-1])
        # Assumes a layout similar to what XmlReporter uses.
        xslt_path = os.path.relpath('mypy-html.xslt', path)
        xml_pi = etree.ProcessingInstruction('xml',
                                             'version="1.0" encoding="utf-8"')
        transform_pi = etree.ProcessingInstruction(
            'xml-stylesheet',
            'type="text/xsl" href="%s"' % cgi.escape(xslt_path, True))
        root.addprevious(xml_pi)
        root.addprevious(transform_pi)
        self.schema.assertValid(doc)

        self.last_xml = doc
        self.files.append(file_info)
예제 #30
0
파일: report.py 프로젝트: yxliang01/mypy
    def on_file(self, tree: MypyFile, modules: Dict[str, MypyFile],
                type_map: Dict[Expression, Type], options: Options) -> None:
        path = os.path.relpath(tree.path)
        if should_skip_path(path):
            return

        visitor = stats.StatisticsVisitor(inferred=True,
                                          filename=tree.fullname(),
                                          modules=modules,
                                          typemap=type_map,
                                          all_nodes=True)
        tree.accept(visitor)

        file_info = FileInfo(path, tree._fullname)
        for lineno, _ in iterate_python_lines(path):
            status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
            file_info.counts[status] += 1

        self.files.append(file_info)
예제 #31
0
def dump_type_stats(tree: MypyFile, path: str, inferred: bool = False,
                    typemap: Dict[Node, Type] = None) -> None:
    if is_special_module(path):
        return
    print(path)
    visitor = StatisticsVisitor(inferred, typemap)
    tree.accept(visitor)
    for line in visitor.output:
        print(line)
    print('  ** precision **')
    print('  precise  ', visitor.num_precise)
    print('  imprecise', visitor.num_imprecise)
    print('  any      ', visitor.num_any)
    print('  ** kinds **')
    print('  simple   ', visitor.num_simple)
    print('  generic  ', visitor.num_generic)
    print('  function ', visitor.num_function)
    print('  tuple    ', visitor.num_tuple)
    print('  TypeVar  ', visitor.num_typevar)
    print('  complex  ', visitor.num_complex)
    print('  any      ', visitor.num_any)
예제 #32
0
파일: stats.py 프로젝트: python/mypy
def dump_type_stats(tree: MypyFile, path: str, inferred: bool = False,
                    typemap: Optional[Dict[Expression, Type]] = None) -> None:
    if is_special_module(path):
        return
    print(path)
    visitor = StatisticsVisitor(inferred, filename=tree.fullname(), typemap=typemap)
    tree.accept(visitor)
    for line in visitor.output:
        print(line)
    print('  ** precision **')
    print('  precise  ', visitor.num_precise_exprs)
    print('  imprecise', visitor.num_imprecise_exprs)
    print('  any      ', visitor.num_any_exprs)
    print('  ** kinds **')
    print('  simple   ', visitor.num_simple_types)
    print('  generic  ', visitor.num_generic_types)
    print('  function ', visitor.num_function_types)
    print('  tuple    ', visitor.num_tuple_types)
    print('  TypeVar  ', visitor.num_typevar_types)
    print('  complex  ', visitor.num_complex_types)
    print('  any      ', visitor.num_any_types)
예제 #33
0
파일: report.py 프로젝트: zadaya/CourseTB
    def on_file(self, tree: MypyFile, type_map: Dict[Expression, Type],
                options: Options) -> None:
        # Count physical lines.  This assumes the file's encoding is a
        # superset of ASCII (or at least uses \n in its line endings).
        with open(tree.path, 'rb') as f:
            physical_lines = len(f.readlines())

        func_counter = FuncCounterVisitor()
        tree.accept(func_counter)
        unannotated_funcs, annotated_funcs = func_counter.counts
        total_funcs = annotated_funcs + unannotated_funcs

        # Don't count lines or functions as annotated if they have their errors ignored.
        if options.ignore_errors:
            annotated_funcs = 0

        imputed_annotated_lines = (physical_lines * annotated_funcs //
                                   total_funcs
                                   if total_funcs else physical_lines)

        self.counts[tree._fullname] = (imputed_annotated_lines, physical_lines,
                                       annotated_funcs, total_funcs)
예제 #34
0
파일: report.py 프로젝트: chadrik/mypy
    def on_file(self,
                tree: MypyFile,
                type_map: Dict[Expression, Type],
                options: Options) -> None:
        # Count physical lines.  This assumes the file's encoding is a
        # superset of ASCII (or at least uses \n in its line endings).
        with open(tree.path, 'rb') as f:
            physical_lines = len(f.readlines())

        func_counter = FuncCounterVisitor()
        tree.accept(func_counter)
        unannotated_funcs, annotated_funcs = func_counter.counts
        total_funcs = annotated_funcs + unannotated_funcs

        # Don't count lines or functions as annotated if they have their errors ignored.
        if options.ignore_errors:
            annotated_funcs = 0

        imputed_annotated_lines = (physical_lines * annotated_funcs // total_funcs
                                   if total_funcs else physical_lines)

        self.counts[tree._fullname] = (imputed_annotated_lines, physical_lines,
                                       annotated_funcs, total_funcs)
예제 #35
0
def build_ir(module: MypyFile, types: Dict[Expression, Type]) -> ModuleIR:
    mapper = Mapper()
    builder = IRBuilder(types, mapper)
    module.accept(builder)

    return ModuleIR(builder.imports, builder.functions, builder.classes)
예제 #36
0
    def visit_file(self, file: MypyFile, fnam: str, mod_id: str, options: Options) -> None:
        """Perform the first analysis pass.

        Populate module global table.  Resolve the full names of
        definitions not nested within functions and construct type
        info structures, but do not resolve inter-definition
        references such as base classes.

        Also add implicit definitions such as __name__.

        In this phase we don't resolve imports. For 'from ... import',
        we generate dummy symbol table nodes for the imported names,
        and these will get resolved in later phases of semantic
        analysis.
        """
        if options.allow_redefinition:
            # Perform renaming across the AST to allow variable redefinitions
            file.accept(VariableRenameVisitor())
        sem = self.sem
        self.sem.options = options  # Needed because we sometimes call into it
        self.pyversion = options.python_version
        self.platform = options.platform
        sem.cur_mod_id = mod_id
        sem.cur_mod_node = file
        sem.errors.set_file(fnam, mod_id, scope=sem.scope)
        sem.globals = SymbolTable()
        sem.global_decls = [set()]
        sem.nonlocal_decls = [set()]
        sem.block_depth = [0]

        sem.scope.enter_file(mod_id)

        defs = file.defs

        with state.strict_optional_set(options.strict_optional):
            # Add implicit definitions of module '__name__' etc.
            for name, t in implicit_module_attrs.items():
                # unicode docstrings should be accepted in Python 2
                if name == '__doc__':
                    if self.pyversion >= (3, 0):
                        typ = UnboundType('__builtins__.str')  # type: Type
                    else:
                        typ = UnionType([UnboundType('__builtins__.str'),
                                        UnboundType('__builtins__.unicode')])
                else:
                    assert t is not None, 'type should be specified for {}'.format(name)
                    typ = UnboundType(t)
                v = Var(name, typ)
                v._fullname = self.sem.qualified_name(name)
                self.sem.globals[name] = SymbolTableNode(GDEF, v)

            for i, d in enumerate(defs):
                d.accept(self)
                if isinstance(d, AssertStmt) and assert_will_always_fail(d, options):
                    # We've encountered an assert that's always false,
                    # e.g. assert sys.platform == 'lol'.  Truncate the
                    # list of statements.  This mutates file.defs too.
                    del defs[i + 1:]
                    break

            # Add implicit definition of literals/keywords to builtins, as we
            # cannot define a variable with them explicitly.
            if mod_id == 'builtins':
                literal_types = [
                    ('None', NoneTyp()),
                    # reveal_type is a mypy-only function that gives an error with
                    # the type of its arg.
                    ('reveal_type', AnyType(TypeOfAny.special_form)),
                    # reveal_locals is a mypy-only function that gives an error with the types of
                    # locals
                    ('reveal_locals', AnyType(TypeOfAny.special_form)),
                ]  # type: List[Tuple[str, Type]]

                # TODO(ddfisher): This guard is only needed because mypy defines
                # fake builtins for its tests which often don't define bool.  If
                # mypy is fast enough that we no longer need those, this
                # conditional check should be removed.
                if 'bool' in self.sem.globals:
                    bool_type = self.sem.named_type('bool')
                    literal_types.extend([
                        ('True', bool_type),
                        ('False', bool_type),
                        ('__debug__', bool_type),
                    ])
                else:
                    # We are running tests without 'bool' in builtins.
                    # TODO: Find a permanent solution to this problem.
                    # Maybe add 'bool' to all fixtures?
                    literal_types.append(('True', AnyType(TypeOfAny.special_form)))

                for name, typ in literal_types:
                    v = Var(name, typ)
                    v._fullname = self.sem.qualified_name(name)
                    self.sem.globals[name] = SymbolTableNode(GDEF, v)

            del self.sem.options

        sem.scope.leave()
예제 #37
0
 def mypyfile(self, node: MypyFile) -> MypyFile:
     new = node.accept(self)
     assert isinstance(new, MypyFile)
     new.set_line(node.line)
     return new
예제 #38
0
 def mypyfile(self, node: MypyFile) -> MypyFile:
     new = node.accept(self)
     assert isinstance(new, MypyFile)
     new.set_line(node.line)
     return new
예제 #39
0
    def visit_file(self, file: MypyFile, fnam: str, mod_id: str,
                   options: Options) -> None:
        """Perform the first analysis pass.

        Populate module global table.  Resolve the full names of
        definitions not nested within functions and construct type
        info structures, but do not resolve inter-definition
        references such as base classes.

        Also add implicit definitions such as __name__.

        In this phase we don't resolve imports. For 'from ... import',
        we generate dummy symbol table nodes for the imported names,
        and these will get resolved in later phases of semantic
        analysis.
        """
        if options.allow_redefinition:
            # Perform renaming across the AST to allow variable redefinitions
            file.accept(VariableRenameVisitor())
        sem = self.sem
        self.sem.options = options  # Needed because we sometimes call into it
        self.pyversion = options.python_version
        self.platform = options.platform
        sem.cur_mod_id = mod_id
        sem.cur_mod_node = file
        sem.errors.set_file(fnam, mod_id, scope=sem.scope)
        sem.globals = SymbolTable()
        sem.global_decls = [set()]
        sem.nonlocal_decls = [set()]
        sem.block_depth = [0]

        sem.scope.enter_file(mod_id)

        defs = file.defs

        with state.strict_optional_set(options.strict_optional):
            # Add implicit definitions of module '__name__' etc.
            for name, t in implicit_module_attrs.items():
                # unicode docstrings should be accepted in Python 2
                if name == '__doc__':
                    if self.pyversion >= (3, 0):
                        typ = UnboundType('__builtins__.str')  # type: Type
                    else:
                        typ = UnionType([
                            UnboundType('__builtins__.str'),
                            UnboundType('__builtins__.unicode')
                        ])
                else:
                    assert t is not None, 'type should be specified for {}'.format(
                        name)
                    typ = UnboundType(t)
                v = Var(name, typ)
                v._fullname = self.sem.qualified_name(name)
                self.sem.globals[name] = SymbolTableNode(GDEF, v)

            for i, d in enumerate(defs):
                d.accept(self)
                if isinstance(d, AssertStmt) and assert_will_always_fail(
                        d, options):
                    # We've encountered an assert that's always false,
                    # e.g. assert sys.platform == 'lol'.  Truncate the
                    # list of statements.  This mutates file.defs too.
                    del defs[i + 1:]
                    break

            # Add implicit definition of literals/keywords to builtins, as we
            # cannot define a variable with them explicitly.
            if mod_id == 'builtins':
                literal_types = [
                    ('None', NoneTyp()),
                    # reveal_type is a mypy-only function that gives an error with
                    # the type of its arg.
                    ('reveal_type', AnyType(TypeOfAny.special_form)),
                    # reveal_locals is a mypy-only function that gives an error with the types of
                    # locals
                    ('reveal_locals', AnyType(TypeOfAny.special_form)),
                ]  # type: List[Tuple[str, Type]]

                # TODO(ddfisher): This guard is only needed because mypy defines
                # fake builtins for its tests which often don't define bool.  If
                # mypy is fast enough that we no longer need those, this
                # conditional check should be removed.
                if 'bool' in self.sem.globals:
                    bool_type = self.sem.named_type('bool')
                    literal_types.extend([
                        ('True', bool_type),
                        ('False', bool_type),
                        ('__debug__', bool_type),
                    ])
                else:
                    # We are running tests without 'bool' in builtins.
                    # TODO: Find a permanent solution to this problem.
                    # Maybe add 'bool' to all fixtures?
                    literal_types.append(
                        ('True', AnyType(TypeOfAny.special_form)))

                for name, typ in literal_types:
                    v = Var(name, typ)
                    v._fullname = self.sem.qualified_name(name)
                    self.sem.globals[name] = SymbolTableNode(GDEF, v)

            del self.sem.options

        sem.scope.leave()