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)
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)
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
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))
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))