Ejemplo n.º 1
0
def start_server_and_analyze(config, workspace, python_executable=None):
    if settings is None:
        log.error('Settings is None')
        return

    log.info(f'mypy version: {mypy_version}')
    log.info(f'mypyls version: {mypyls_version}')

    options = Options()
    options.check_untyped_defs = True
    options.follow_imports = 'error'
    options.use_fine_grained_cache = True
    options.python_executable = python_executable

    stderr_stream = StringIO()
    config_file = settings.get('configFile')
    if config_file == '':
        # Use empty string rather than null in vscode settings, so that it's shown in settings editor GUI.
        config_file = None
    log.info(f'Trying to read mypy config file from {config_file or "default locations"}')
    with redirect_stderr(stderr_stream):
        if mypy_version >= '0.770':
            def set_strict_flags():
                # The code to set all strict options using the 'strict' flag is in mypy.main.process_options,
                # and we cannot access it from here, so we disable `strict = True` in the config file for now.
                stderr_stream.write(
                    "Setting 'strict' in the configuration file is not supported by mypy-vscode for now. "
                    "The option will be ignored. You may set individual strict flags instead "
                    "(see 'mypy -h' for the list of flags enabled in strict mode).")
            parse_config_file(options, set_strict_flags, config_file)
        else:
            parse_config_file(options, config_file)

    stderr = stderr_stream.getvalue()
    if stderr:
        log.error(f'Error reading mypy config file:\n{stderr}')
        workspace.show_message(f'Error reading mypy config file:\n{stderr}')
    if options.config_file:
        log.info(f'Read mypy config from: {options.config_file}')
    else:
        log.info(f'Mypy configuration not read, using defaults.')
        if config_file:
            workspace.show_message(f'Mypy config file not found:\n{config_file}')

    options.show_column_numbers = True
    if options.follow_imports not in ('error', 'skip'):
        workspace.show_message(f"Cannot use follow_imports='{options.follow_imports}', using 'error' instead.")
        options.follow_imports = 'error'

    if mypy_version > '0.720':
        options.color_output = False
        options.error_summary = False
        options.pretty = False

    log.info(f'python_executable after applying config: {options.python_executable}')
    workspace.mypy_server = Server(options, DEFAULT_STATUS_FILE)

    mypy_check(workspace, config)
Ejemplo n.º 2
0
def start_server_and_analyze(config, workspace, python_executable=None):
    if settings is None:
        log.error('Settings is None')
        return

    log.info(f'mypy version: {mypy_version}')
    log.info(f'mypyls version: {mypyls_version}')

    options = Options()
    options.check_untyped_defs = True
    options.follow_imports = 'error'
    options.use_fine_grained_cache = True
    options.python_executable = python_executable

    stderr_stream = StringIO()
    config_file = settings.get('configFile')
    if config_file == '':
        # Use empty string rather than null in vscode settings, so that it's shown in settings editor GUI.
        config_file = None
    log.info(
        f'Trying to read mypy config file from {config_file or "default locations"}'
    )
    with redirect_stderr(stderr_stream):
        parse_config_file(options, config_file)
    stderr = stderr_stream.getvalue()
    if stderr:
        log.error(f'Error reading mypy config file:\n{stderr}')
        workspace.show_message(f'Error reading mypy config file:\n{stderr}')
    if options.config_file:
        log.info(f'Read mypy config from: {options.config_file}')
    else:
        log.info(f'Mypy configuration not read, using defaults.')
        if config_file:
            workspace.show_message(
                f'Mypy config file not found:\n{config_file}')

    options.show_column_numbers = True
    if options.follow_imports not in ('error', 'skip'):
        workspace.show_message(
            f"Cannot use follow_imports='{options.follow_imports}', using 'error' instead."
        )
        options.follow_imports = 'error'

    if mypy_version > '0.720':
        options.color_output = False
        options.error_summary = False

    log.info(
        f'python_executable after applying config: {options.python_executable}'
    )
    workspace.mypy_server = Server(options, DEFAULT_STATUS_FILE)

    mypy_check(workspace, config)
Ejemplo n.º 3
0
    def get_options(self, source: str, testcase: DataDrivenTestCase,
                    build_cache: bool) -> Options:
        # This handles things like '# flags: --foo'.
        options = parse_options(source, testcase, incremental_step=1)
        options.incremental = True
        options.use_builtins_fixtures = True
        options.show_traceback = True
        options.fine_grained_incremental = not build_cache
        options.use_fine_grained_cache = self.use_cache and not build_cache
        options.cache_fine_grained = self.use_cache
        options.local_partial_types = True
        if options.follow_imports == 'normal':
            options.follow_imports = 'error'

        for name, _ in testcase.files:
            if 'mypy.ini' in name:
                parse_config_file(options, name)
                break

        return options
Ejemplo n.º 4
0
    def get_options(self,
                    source: str,
                    testcase: DataDrivenTestCase,
                    build_cache: bool) -> Options:
        # This handles things like '# flags: --foo'.
        options = parse_options(source, testcase, incremental_step=1)
        options.incremental = True
        options.use_builtins_fixtures = True
        options.show_traceback = True
        options.fine_grained_incremental = not build_cache
        options.use_fine_grained_cache = self.use_cache and not build_cache
        options.cache_fine_grained = self.use_cache
        options.local_partial_types = True
        if options.follow_imports == 'normal':
            options.follow_imports = 'error'

        for name, _ in testcase.files:
            if 'mypy.ini' in name:
                parse_config_file(options, name)
                break

        return options
Ejemplo n.º 5
0
    def run_case(self, testcase: DataDrivenTestCase) -> None:
        if self.should_skip(testcase):
            pytest.skip()
            return

        main_src = '\n'.join(testcase.input)
        main_path = os.path.join(test_temp_dir, 'main')
        with open(main_path, 'w') as f:
            f.write(main_src)

        options = self.get_options(main_src, testcase, build_cache=False)
        for name, _ in testcase.files:
            if 'mypy.ini' in name:
                config = name  # type: Optional[str]
                break
        else:
            config = None
        if config:
            parse_config_file(options, config)
        server = Server(options, alt_lib_path=test_temp_dir)

        step = 1
        sources = self.parse_sources(main_src, step, options)
        if self.use_cache:
            build_options = self.get_options(main_src,
                                             testcase,
                                             build_cache=True)
            if config:
                parse_config_file(build_options, config)
            messages = self.build(build_options, sources)
        else:
            messages = self.run_check(server, sources)

        a = []
        if messages:
            a.extend(normalize_messages(messages))

        if server.fine_grained_manager:
            if CHECK_CONSISTENCY:
                check_consistency(server.fine_grained_manager)

        steps = testcase.find_steps()
        all_triggered = []

        for operations in steps:
            step += 1
            for op in operations:
                if isinstance(op, UpdateFile):
                    # Modify/create file
                    copy_and_fudge_mtime(op.source_path, op.target_path)
                else:
                    # Delete file
                    os.remove(op.path)
            sources = self.parse_sources(main_src, step, options)
            new_messages = self.run_check(server, sources)

            updated = []  # type: List[str]
            changed = []  # type: List[str]
            if server.fine_grained_manager:
                if CHECK_CONSISTENCY:
                    check_consistency(server.fine_grained_manager)
                all_triggered.append(server.fine_grained_manager.triggered)

                updated = server.fine_grained_manager.updated_modules
                changed = [
                    mod for mod, file in
                    server.fine_grained_manager.changed_modules
                ]

            assert_module_equivalence(
                'stale' + str(step - 1),
                testcase.expected_stale_modules.get(step - 1), changed)
            assert_module_equivalence(
                'rechecked' + str(step - 1),
                testcase.expected_rechecked_modules.get(step - 1), updated)

            new_messages = normalize_messages(new_messages)

            a.append('==')
            a.extend(new_messages)

        # Normalize paths in test output (for Windows).
        a = [line.replace('\\', '/') for line in a]

        assert_string_arrays_equal(
            testcase.output, a,
            'Invalid output ({}, line {})'.format(testcase.file,
                                                  testcase.line))

        if testcase.triggered:
            assert_string_arrays_equal(
                testcase.triggered, self.format_triggered(all_triggered),
                'Invalid active triggers ({}, line {})'.format(
                    testcase.file, testcase.line))
Ejemplo n.º 6
0
    def run_case(self, testcase: DataDrivenTestCase) -> None:
        if self.should_skip(testcase):
            pytest.skip()
            return

        main_src = '\n'.join(testcase.input)
        main_path = os.path.join(test_temp_dir, 'main')
        with open(main_path, 'w') as f:
            f.write(main_src)

        options = self.get_options(main_src, testcase, build_cache=False)
        for name, _ in testcase.files:
            if 'mypy.ini' in name:
                config = name  # type: Optional[str]
                break
        else:
            config = None
        if config:
            parse_config_file(options, config)
        server = Server(options, alt_lib_path=test_temp_dir)

        step = 1
        sources = self.parse_sources(main_src, step, options)
        if self.use_cache:
            build_options = self.get_options(main_src, testcase, build_cache=True)
            if config:
                parse_config_file(build_options, config)
            messages = self.build(build_options, sources)
        else:
            messages = self.run_check(server, sources)

        a = []
        if messages:
            a.extend(normalize_messages(messages))

        if server.fine_grained_manager:
            if CHECK_CONSISTENCY:
                check_consistency(server.fine_grained_manager)

        steps = testcase.find_steps()
        all_triggered = []

        for operations in steps:
            step += 1
            for op in operations:
                if isinstance(op, UpdateFile):
                    # Modify/create file
                    copy_and_fudge_mtime(op.source_path, op.target_path)
                else:
                    # Delete file
                    os.remove(op.path)
            sources = self.parse_sources(main_src, step, options)
            new_messages = self.run_check(server, sources)

            updated = []  # type: List[str]
            changed = []  # type: List[str]
            if server.fine_grained_manager:
                if CHECK_CONSISTENCY:
                    check_consistency(server.fine_grained_manager)
                all_triggered.append(server.fine_grained_manager.triggered)

                updated = server.fine_grained_manager.updated_modules
                changed = [mod for mod, file in server.fine_grained_manager.changed_modules]

            assert_module_equivalence(
                'stale' + str(step - 1),
                testcase.expected_stale_modules.get(step - 1),
                changed)
            assert_module_equivalence(
                'rechecked' + str(step - 1),
                testcase.expected_rechecked_modules.get(step - 1),
                updated)

            new_messages = normalize_messages(new_messages)

            a.append('==')
            a.extend(new_messages)

        # Normalize paths in test output (for Windows).
        a = [line.replace('\\', '/') for line in a]

        assert_string_arrays_equal(
            testcase.output, a,
            'Invalid output ({}, line {})'.format(
                testcase.file, testcase.line))

        if testcase.triggered:
            assert_string_arrays_equal(
                testcase.triggered,
                self.format_triggered(all_triggered),
                'Invalid active triggers ({}, line {})'.format(testcase.file,
                                                               testcase.line))