diff --git a/pylsp/__main__.py b/pylsp/__main__.py index 44aa3cfa..29f2d240 100644 --- a/pylsp/__main__.py +++ b/pylsp/__main__.py @@ -71,7 +71,9 @@ def main() -> None: parser = argparse.ArgumentParser() add_arguments(parser) args = parser.parse_args() - _configure_logger(args.verbose, args.log_config, args.log_file) + _configure_logger( + verbose=args.verbose, log_config=args.log_config, log_file=args.log_file + ) if args.tcp: start_tcp_lang_server( diff --git a/pylsp/_utils.py b/pylsp/_utils.py index 1be7e263..01b130b1 100644 --- a/pylsp/_utils.py +++ b/pylsp/_utils.py @@ -264,7 +264,9 @@ def position_to_jedi_linecolumn(document, position): code_position = { "line": position["line"] + 1, "column": clip_column( - position["character"], document.lines, position["line"] + column=position["character"], + lines=document.lines, + line_number=position["line"], ), } return code_position diff --git a/pylsp/plugins/autopep8_format.py b/pylsp/plugins/autopep8_format.py index 2b3491da..ee9f28a6 100644 --- a/pylsp/plugins/autopep8_format.py +++ b/pylsp/plugins/autopep8_format.py @@ -17,7 +17,7 @@ def pylsp_format_document(config, workspace, document, options): with workspace.report_progress("format: autopep8"): log.info("Formatting document %s with autopep8", document) - return _format(config, document) + return _format(config=config, document=document) @hookimpl(tryfirst=True) # Prefer autopep8 over YAPF @@ -31,11 +31,11 @@ def pylsp_format_range(config, workspace, document, range, options): # Add 1 for 1-indexing vs LSP's 0-indexing line_range = (range["start"]["line"] + 1, range["end"]["line"]) - return _format(config, document, line_range=line_range) + return _format(config=config, document=document, line_range=line_range) def _format(config, document, line_range=None): - options = _autopep8_config(config, document) + options = _autopep8_config(config=config, document=document) if line_range: options["line_range"] = list(line_range) diff --git a/pylsp/plugins/definition.py b/pylsp/plugins/definition.py index 67abfb71..950b8381 100644 --- a/pylsp/plugins/definition.py +++ b/pylsp/plugins/definition.py @@ -46,7 +46,9 @@ def pylsp_definitions( config: Config, document: Document, position: Dict[str, int] ) -> List[Dict[str, Any]]: settings = config.plugin_settings("jedi_definition") - code_position = _utils.position_to_jedi_linecolumn(document, position) + code_position = _utils.position_to_jedi_linecolumn( + document=document, position=position + ) script = document.jedi_script(use_document_path=True) auto_import_modules = jedi.settings.auto_import_modules @@ -57,14 +59,17 @@ def pylsp_definitions( follow_builtin_imports=settings.get("follow_builtin_imports", True), **code_position, ) - definitions = [_resolve_definition(d, script, settings) for d in definitions] + definitions = [ + _resolve_definition(maybe_defn=d, script=script, settings=settings) + for d in definitions + ] finally: jedi.settings.auto_import_modules = auto_import_modules follow_builtin_defns = settings.get("follow_builtin_definitions", True) return [ { - "uri": uris.uri_with(document.uri, path=str(d.module_path)), + "uri": uris.uri_with(uri=document.uri, path=str(d.module_path)), "range": { "start": {"line": d.line - 1, "character": d.column}, "end": {"line": d.line - 1, "character": d.column + len(d.name)}, diff --git a/pylsp/plugins/flake8_lint.py b/pylsp/plugins/flake8_lint.py index 74e2664c..df154c29 100644 --- a/pylsp/plugins/flake8_lint.py +++ b/pylsp/plugins/flake8_lint.py @@ -98,8 +98,13 @@ def pylsp_lint(workspace, document): # ensure the same source is used for flake8 execution and result parsing; # single source access improves performance as it is only one disk access source = document.source - output = run_flake8(flake8_executable, args, document, source) - return parse_stdout(source, output) + output = run_flake8( + flake8_executable=flake8_executable, + args=args, + document=document, + source=source, + ) + return parse_stdout(source=source, stdout=output) def run_flake8(flake8_executable, args, document, source): diff --git a/pylsp/plugins/folding.py b/pylsp/plugins/folding.py index 123ba4a8..361adf65 100644 --- a/pylsp/plugins/folding.py +++ b/pylsp/plugins/folding.py @@ -17,7 +17,7 @@ def pylsp_folding_range(document): program = document.source + "\n" lines = program.splitlines() tree = parso.parse(program) - ranges = __compute_folding_ranges(tree, lines) + ranges = __compute_folding_ranges(tree=tree, lines=lines) results = [] for start_line, end_line in ranges: @@ -88,18 +88,28 @@ def __compute_folding_ranges_identation(text): current_level = level elif level < current_level: identation_stack, folding_ranges = __match_identation_stack( - identation_stack, level, level_limits, folding_ranges, current_line + identation_stack=identation_stack, + level=level, + level_limits=level_limits, + folding_ranges=folding_ranges, + current_line=current_line, ) current_level = level else: folding_ranges = __empty_identation_stack( - identation_stack, level_limits, current_line, folding_ranges + identation_stack=identation_stack, + level_limits=level_limits, + current_line=current_line, + folding_ranges=folding_ranges, ) current_level = 0 if line.strip() != "": current_line = i folding_ranges = __empty_identation_stack( - identation_stack, level_limits, current_line, folding_ranges + identation_stack=identation_stack, + level_limits=level_limits, + current_line=current_line, + folding_ranges=folding_ranges, ) return dict(folding_ranges) @@ -136,17 +146,17 @@ def __handle_flow_nodes(node, end_line, stack): if isinstance(node, tree_nodes.Keyword): from_keyword = True if node.value in {"if", "elif", "with", "while"}: - node, end_line = __handle_skip(stack, 2) + node, end_line = __handle_skip(stack=stack, skip=2) elif node.value in {"except"}: first_node = stack[0] if isinstance(first_node, tree_nodes.Operator): - node, end_line = __handle_skip(stack, 1) + node, end_line = __handle_skip(stack=stack, skip=1) else: - node, end_line = __handle_skip(stack, 2) + node, end_line = __handle_skip(stack=stack, skip=2) elif node.value in {"for"}: - node, end_line = __handle_skip(stack, 4) + node, end_line = __handle_skip(stack=stack, skip=4) elif node.value in {"else"}: - node, end_line = __handle_skip(stack, 1) + node, end_line = __handle_skip(stack=stack, skip=1) return end_line, from_keyword, node, stack @@ -154,7 +164,9 @@ def __compute_start_end_lines(node, stack): start_line, _ = node.start_pos end_line, _ = node.end_pos modified = False - end_line, from_keyword, node, stack = __handle_flow_nodes(node, end_line, stack) + end_line, from_keyword, node, stack = __handle_flow_nodes( + node=node, end_line=end_line, stack=stack + ) last_leaf = node.get_last_leaf() last_newline = isinstance(last_leaf, tree_nodes.Newline) @@ -194,12 +206,16 @@ def __compute_folding_ranges(tree, lines): padding = [""] * start_line text = "\n".join(padding + lines[start_line:]) + "\n" identation_ranges = __compute_folding_ranges_identation(text) - folding_ranges = __merge_folding_ranges(folding_ranges, identation_ranges) + folding_ranges = __merge_folding_ranges( + left=folding_ranges, right=identation_ranges + ) break if not isinstance(node, SKIP_NODES): valid = __check_if_node_is_valid(node) if valid: - start_line, end_line, stack = __compute_start_end_lines(node, stack) + start_line, end_line, stack = __compute_start_end_lines( + node=node, stack=stack + ) if end_line > start_line: current_end = folding_ranges.get(start_line, -1) folding_ranges[start_line] = max(current_end, end_line) diff --git a/pylsp/plugins/highlight.py b/pylsp/plugins/highlight.py index c4c12406..b88ffaad 100644 --- a/pylsp/plugins/highlight.py +++ b/pylsp/plugins/highlight.py @@ -10,7 +10,9 @@ @hookimpl def pylsp_document_highlight(document, position): - code_position = _utils.position_to_jedi_linecolumn(document, position) + code_position = _utils.position_to_jedi_linecolumn( + document=document, position=position + ) usages = document.jedi_script().get_references(**code_position) def is_valid(definition): diff --git a/pylsp/plugins/hover.py b/pylsp/plugins/hover.py index ca69d1b3..192f712c 100644 --- a/pylsp/plugins/hover.py +++ b/pylsp/plugins/hover.py @@ -10,7 +10,9 @@ @hookimpl def pylsp_hover(config, document, position): - code_position = _utils.position_to_jedi_linecolumn(document, position) + code_position = _utils.position_to_jedi_linecolumn( + document=document, position=position + ) definitions = document.jedi_script(use_document_path=True).infer(**code_position) word = document.word_at_position(position) @@ -43,8 +45,8 @@ def pylsp_hover(config, document, position): return { "contents": _utils.format_docstring( # raw docstring returns only doc, without signature - definition.docstring(raw=True), - preferred_markup_kind, + contents=definition.docstring(raw=True), + markup_kind=preferred_markup_kind, signatures=[signature] if signature else None, ) } diff --git a/pylsp/plugins/jedi_completion.py b/pylsp/plugins/jedi_completion.py index 2796a093..e2f0d5af 100644 --- a/pylsp/plugins/jedi_completion.py +++ b/pylsp/plugins/jedi_completion.py @@ -40,7 +40,9 @@ def pylsp_completions(config, document, position): """Get formatted completions for current code position""" settings = config.plugin_settings("jedi_completion", document_path=document.path) resolve_eagerly = settings.get("eager", False) - code_position = _utils.position_to_jedi_linecolumn(document, position) + code_position = _utils.position_to_jedi_linecolumn( + document=document, position=position + ) code_position["fuzzy"] = settings.get("fuzzy", False) completions = document.jedi_script(use_document_path=True).complete(**code_position) @@ -67,22 +69,24 @@ def pylsp_completions(config, document, position): SNIPPET_RESOLVER.cached_modules = modules_to_cache_for include_params = ( - snippet_support and should_include_params and use_snippets(document, position) + snippet_support + and should_include_params + and use_snippets(document=document, position=position) ) include_class_objects = ( snippet_support and should_include_class_objects - and use_snippets(document, position) + and use_snippets(document=document, position=position) ) include_function_objects = ( snippet_support and should_include_function_objects - and use_snippets(document, position) + and use_snippets(document=document, position=position) ) ready_completions = [ _format_completion( - c, + d=c, markup_kind=preferred_markup_kind, include_params=include_params if c.type in ["class", "function"] else False, resolve=resolve_eagerly, @@ -97,7 +101,7 @@ def pylsp_completions(config, document, position): for i, c in enumerate(completions): if c.type == "class": completion_dict = _format_completion( - c, + d=c, markup_kind=preferred_markup_kind, include_params=False, resolve=resolve_eagerly, @@ -112,7 +116,7 @@ def pylsp_completions(config, document, position): for i, c in enumerate(completions): if c.type == "function": completion_dict = _format_completion( - c, + d=c, markup_kind=preferred_markup_kind, include_params=False, resolve=resolve_eagerly, @@ -152,7 +156,9 @@ def pylsp_completion_item_resolve(config, completion_item, document): if shared_data: completion, data = shared_data - return _resolve_completion(completion, data, markup_kind=preferred_markup_kind) + return _resolve_completion( + completion=completion, d=data, markup_kind=preferred_markup_kind + ) return completion_item @@ -211,7 +217,7 @@ def _resolve_completion(completion, d, markup_kind: str): completion["detail"] = _detail(d) try: docs = _utils.format_docstring( - d.docstring(raw=True), + contents=d.docstring(raw=True), signatures=[signature.to_string() for signature in d.get_signatures()], markup_kind=markup_kind, ) @@ -230,14 +236,16 @@ def _format_completion( snippet_support=False, ): completion = { - "label": _label(d, resolve_label_or_snippet), + "label": _label(definition=d, resolve=resolve_label_or_snippet), "kind": _TYPE_MAP.get(d.type), "sortText": _sort_text(d), "insertText": d.name, } if resolve: - completion = _resolve_completion(completion, d, markup_kind) + completion = _resolve_completion( + completion=completion, d=d, markup_kind=markup_kind + ) # Adjustments for file completions if d.type == "path": @@ -260,7 +268,7 @@ def _format_completion( completion["insertText"] = path if include_params and not is_exception_class(d.name): - snippet = _snippet(d, resolve_label_or_snippet) + snippet = _snippet(definition=d, resolve=resolve_label_or_snippet) completion.update(snippet) return completion diff --git a/pylsp/plugins/jedi_rename.py b/pylsp/plugins/jedi_rename.py index b35e321a..fb9a2a6d 100644 --- a/pylsp/plugins/jedi_rename.py +++ b/pylsp/plugins/jedi_rename.py @@ -13,7 +13,7 @@ def pylsp_rename(config, workspace, document, position, new_name): log.debug( "Executing rename of %s to %s", document.word_at_position(position), new_name ) - kwargs = _utils.position_to_jedi_linecolumn(document, position) + kwargs = _utils.position_to_jedi_linecolumn(document=document, position=position) kwargs["new_name"] = new_name try: refactoring = document.jedi_script().rename(**kwargs) diff --git a/pylsp/plugins/pydocstyle_lint.py b/pylsp/plugins/pydocstyle_lint.py index a310ac84..651a7784 100644 --- a/pylsp/plugins/pydocstyle_lint.py +++ b/pylsp/plugins/pydocstyle_lint.py @@ -86,7 +86,7 @@ def pylsp_lint(config, workspace, document): for error in errors: if error.code not in checked_codes: continue - diags.append(_parse_diagnostic(document, error)) + diags.append(_parse_diagnostic(document=document, error=error)) except pydocstyle.parser.ParseError: # In the case we cannot parse the Python file, just continue pass diff --git a/pylsp/plugins/pylint_lint.py b/pylsp/plugins/pylint_lint.py index beffe6f3..c6483618 100644 --- a/pylsp/plugins/pylint_lint.py +++ b/pylsp/plugins/pylint_lint.py @@ -223,7 +223,9 @@ def pylsp_lint(config, workspace, document, is_saved): if settings.get("executable") and sys.version_info[0] >= 3: flags = build_args_stdio(settings) pylint_executable = settings.get("executable", "pylint") - return pylint_lint_stdin(pylint_executable, document, flags) + return pylint_lint_stdin( + pylint_executable=pylint_executable, document=document, flags=flags + ) flags = _build_pylint_flags(settings) return PylintLinter.lint(document, is_saved, flags=flags) @@ -260,8 +262,10 @@ def pylint_lint_stdin(pylint_executable, document, flags): :return: linting diagnostics :rtype: list """ - pylint_result = _run_pylint_stdio(pylint_executable, document, flags) - return _parse_pylint_stdio_result(document, pylint_result) + pylint_result = _run_pylint_stdio( + pylint_executable=pylint_executable, document=document, flags=flags + ) + return _parse_pylint_stdio_result(document=document, stdout=pylint_result) def _run_pylint_stdio(pylint_executable, document, flags): diff --git a/pylsp/plugins/references.py b/pylsp/plugins/references.py index a4c61b52..1649ac15 100644 --- a/pylsp/plugins/references.py +++ b/pylsp/plugins/references.py @@ -10,7 +10,9 @@ @hookimpl def pylsp_references(document, position, exclude_declaration): - code_position = _utils.position_to_jedi_linecolumn(document, position) + code_position = _utils.position_to_jedi_linecolumn( + document=document, position=position + ) usages = document.jedi_script().get_references(**code_position) if exclude_declaration: @@ -20,7 +22,7 @@ def pylsp_references(document, position, exclude_declaration): # Filter out builtin modules return [ { - "uri": uris.uri_with(document.uri, path=str(d.module_path)) + "uri": uris.uri_with(uri=document.uri, path=str(d.module_path)) if d.module_path else document.uri, "range": { diff --git a/pylsp/plugins/rope_autoimport.py b/pylsp/plugins/rope_autoimport.py index 12f5d80b..cc0eafd0 100644 --- a/pylsp/plugins/rope_autoimport.py +++ b/pylsp/plugins/rope_autoimport.py @@ -120,8 +120,8 @@ def _should_insert(expr: tree.BaseNode, word_node: tree.Leaf) -> bool: if isinstance(first_child, (tree.PythonErrorNode, tree.PythonNode)): # The tree will often include error nodes like this to indicate errors # we want to ignore errors since the code is being written - return _should_insert(first_child, word_node) - return _handle_first_child(first_child, expr, word_node) + return _should_insert(expr=first_child, word_node=word_node) + return _handle_first_child(first_child=first_child, expr=expr, word_node=word_node) def _handle_first_child( @@ -136,9 +136,9 @@ def _handle_first_child( return False if isinstance(first_child, tree.Keyword): if first_child.value == "def": - return _should_import_function(word_node, expr) + return _should_import_function(word_node=word_node, expr=expr) if first_child.value == "class": - return _should_import_class(word_node, expr) + return _should_import_class(word_node=word_node, expr=expr) return True @@ -157,7 +157,7 @@ def _should_import_class(word_node: tree.Leaf, expr: tree.BaseNode) -> bool: def _should_import_function(word_node: tree.Leaf, expr: tree.BaseNode) -> bool: prev_node = None for node in expr.children: - if _handle_argument(node, word_node): + if _handle_argument(node=node, word_node=word_node): return True if isinstance(prev_node, tree.Operator): if prev_node.value == "->": @@ -174,7 +174,7 @@ def _handle_argument(node: NodeOrLeaf, word_node: tree.Leaf): return True if node.type == "parameters": for parameter in node.children: - if _handle_argument(parameter, word_node): + if _handle_argument(node=parameter, word_node=word_node): return True return False @@ -193,7 +193,10 @@ def _process_statements( edit_range = {"start": start, "end": start} edit = {"range": edit_range, "newText": suggestion.import_statement + "\n"} score = _get_score( - suggestion.source, suggestion.import_statement, suggestion.name, word + source=suggestion.source, + full_statement=suggestion.import_statement, + suggested_name=suggestion.name, + desired_name=word, ) if score > _score_max: continue @@ -246,7 +249,7 @@ def pylsp_completions( line = document.lines[position["line"]] expr = parso.parse(line) word_node = expr.get_leaf_for_position((1, position["character"])) - if not _should_insert(expr, word_node): + if not _should_insert(expr=expr, word_node=word_node): return [] word = word_node.value log.debug(f"autoimport: searching for word: {word}") @@ -258,7 +261,12 @@ def pylsp_completions( suggestions = list(autoimport.search_full(word, ignored_names=ignored_names)) results = sorted( _process_statements( - suggestions, document.uri, word, autoimport, document, "completions" + suggestions=suggestions, + doc_uri=document.uri, + word=word, + autoimport=autoimport, + document=document, + feature="completions", ), key=lambda statement: statement["sortText"], ) @@ -339,7 +347,7 @@ def pylsp_code_actions( if "undefined name" not in diagnostic.get("message", "").lower(): continue - word = get_name_or_module(document, diagnostic) + word = get_name_or_module(document=document, diagnostic=diagnostic) log.debug(f"autoimport: searching for word: {word}") rope_config = config.settings(document_path=document.path).get("rope", {}) autoimport = workspace._rope_autoimport(rope_config) @@ -347,12 +355,12 @@ def pylsp_code_actions( log.debug("autoimport: suggestions: %s", suggestions) results = sorted( _process_statements( - suggestions, - document.uri, - word, - autoimport, - document, - "code_actions", + suggestions=suggestions, + doc_uri=document.uri, + word=word, + autoimport=autoimport, + document=document, + feature="code_actions", ), key=lambda statement: statement["data"]["sortText"], ) diff --git a/pylsp/plugins/rope_completion.py b/pylsp/plugins/rope_completion.py index b3a1f066..8ea04040 100644 --- a/pylsp/plugins/rope_completion.py +++ b/pylsp/plugins/rope_completion.py @@ -18,7 +18,7 @@ def pylsp_settings(): def _resolve_completion(completion, data, markup_kind): try: - doc = _utils.format_docstring(data.get_doc(), markup_kind=markup_kind) + doc = _utils.format_docstring(contents=data.get_doc(), markup_kind=markup_kind) except Exception as e: log.debug("Failed to resolve Rope completion: %s", e) doc = "" @@ -74,7 +74,9 @@ def pylsp_completions(config, workspace, document, position): "data": {"doc_uri": document.uri}, } if resolve_eagerly: - item = _resolve_completion(item, d, preferred_markup_kind) + item = _resolve_completion( + completion=item, data=d, markup_kind=preferred_markup_kind + ) new_definitions.append(item) # most recently retrieved completion items, used for resolution @@ -105,7 +107,9 @@ def pylsp_completion_item_resolve(config, completion_item, document): if shared_data: completion, data = shared_data - return _resolve_completion(completion, data, preferred_markup_kind) + return _resolve_completion( + completion=completion, data=data, markup_kind=preferred_markup_kind + ) return completion_item diff --git a/pylsp/plugins/signature.py b/pylsp/plugins/signature.py index 7ad5b208..e192e159 100644 --- a/pylsp/plugins/signature.py +++ b/pylsp/plugins/signature.py @@ -17,7 +17,9 @@ @hookimpl def pylsp_signature_help(config, document, position): - code_position = _utils.position_to_jedi_linecolumn(document, position) + code_position = _utils.position_to_jedi_linecolumn( + document=document, position=position + ) signatures = document.jedi_script().get_signatures(**code_position) if not signatures: @@ -44,7 +46,7 @@ def pylsp_signature_help(config, document, position): sig = { "label": function_sig, "documentation": _utils.format_docstring( - s.docstring(raw=True), markup_kind=preferred_markup_kind + contents=s.docstring(raw=True), markup_kind=preferred_markup_kind ), } @@ -54,7 +56,8 @@ def pylsp_signature_help(config, document, position): { "label": p.name, "documentation": _utils.format_docstring( - _param_docs(docstring, p.name), markup_kind=preferred_markup_kind + contents=_param_docs(docstring=docstring, param_name=p.name), + markup_kind=preferred_markup_kind, ), } for p in s.params diff --git a/pylsp/plugins/yapf_format.py b/pylsp/plugins/yapf_format.py index 72aa7404..83aaed04 100644 --- a/pylsp/plugins/yapf_format.py +++ b/pylsp/plugins/yapf_format.py @@ -18,7 +18,7 @@ def pylsp_format_document(workspace, document, options): log.info("Formatting document %s with yapf", document) with workspace.report_progress("format: yapf"): - return _format(document, options=options) + return _format(document=document, options=options) @hookimpl @@ -37,7 +37,7 @@ def pylsp_format_range(document, range, options): # Add 1 for 1-indexing vs LSP's 0-indexing lines = [(range["start"]["line"] + 1, range["end"]["line"] + 1)] - return _format(document, lines=lines, options=options) + return _format(document=document, lines=lines, options=options) def get_style_config(document_path, options=None): diff --git a/pylsp/text_edit.py b/pylsp/text_edit.py index 07be2aa4..95e14026 100644 --- a/pylsp/text_edit.py +++ b/pylsp/text_edit.py @@ -45,7 +45,7 @@ def merge_sort_text_edits(text_edits): right_idx = 0 i = 0 while left_idx < len(left) and right_idx < len(right): - ret = compare_text_edits(left[left_idx], right[right_idx]) + ret = compare_text_edits(a=left[left_idx], b=right[right_idx]) if ret <= 0: # smaller_equal -> take left to preserve order text_edits[i] = left[left_idx] diff --git a/scripts/jsonschema2md.py b/scripts/jsonschema2md.py index c0a00759..f050afbc 100644 --- a/scripts/jsonschema2md.py +++ b/scripts/jsonschema2md.py @@ -79,7 +79,7 @@ def main(argv) -> None: parser.add_argument("markdown", type=FileType("w+"), default=sys.stdout) arguments = parser.parse_args(argv[1:]) schema = json.loads(arguments.schema.read()) - markdown = convert_schema(schema, source=arguments.schema.name) + markdown = convert_schema(schema=schema, source=arguments.schema.name) arguments.markdown.write(markdown) diff --git a/test/fixtures.py b/test/fixtures.py index dd10140c..e1be4ae6 100644 --- a/test/fixtures.py +++ b/test/fixtures.py @@ -67,7 +67,7 @@ def request(self, method, params=None): @pytest.fixture def pylsp(tmpdir): """Return an initialized python LS""" - ls = FakePythonLSPServer(StringIO, StringIO, endpoint_cls=FakeEndpoint) + ls = FakePythonLSPServer(rx=StringIO, tx=StringIO, endpoint_cls=FakeEndpoint) ls.m_initialize( processId=1, rootUri=uris.from_fs_path(str(tmpdir)), initializationOptions={} @@ -79,7 +79,7 @@ def pylsp(tmpdir): @pytest.fixture def pylsp_w_workspace_folders(tmpdir): """Return an initialized python LS""" - ls = FakePythonLSPServer(StringIO, StringIO, endpoint_cls=FakeEndpoint) + ls = FakePythonLSPServer(rx=StringIO, tx=StringIO, endpoint_cls=FakeEndpoint) folder1 = tmpdir.mkdir("folder1") folder2 = tmpdir.mkdir("folder2") @@ -114,8 +114,10 @@ class Dispatcher(FakeEditorMethodsMixin, MethodDispatcher): @pytest.fixture def workspace(tmpdir, endpoint) -> None: """Return a workspace.""" - ws = Workspace(uris.from_fs_path(str(tmpdir)), endpoint) - ws._config = Config(ws.root_uri, {}, 0, {}) + ws = Workspace(root_uri=uris.from_fs_path(str(tmpdir)), endpoint=endpoint) + ws._config = Config( + root_uri=ws.root_uri, init_opts={}, process_id=0, capabilities={} + ) yield ws ws.close() @@ -124,15 +126,19 @@ def workspace(tmpdir, endpoint) -> None: def workspace_other_root_path(tmpdir, endpoint): """Return a workspace with a root_path other than tmpdir.""" ws_path = str(tmpdir.mkdir("test123").mkdir("test456")) - ws = Workspace(uris.from_fs_path(ws_path), endpoint) - ws._config = Config(ws.root_uri, {}, 0, {}) + ws = Workspace(root_uri=uris.from_fs_path(ws_path), endpoint=endpoint) + ws._config = Config( + root_uri=ws.root_uri, init_opts={}, process_id=0, capabilities={} + ) return ws @pytest.fixture def config(workspace): """Return a config object.""" - cfg = Config(workspace.root_uri, {}, 0, {}) + cfg = Config( + root_uri=workspace.root_uri, init_opts={}, process_id=0, capabilities={} + ) cfg._plugin_settings = { "plugins": {"pylint": {"enabled": False, "args": [], "executable": None}} } @@ -141,7 +147,7 @@ def config(workspace): @pytest.fixture def doc(workspace): - return Document(DOC_URI, workspace, DOC) + return Document(uri=DOC_URI, workspace=workspace, source=DOC) @pytest.fixture diff --git a/test/plugins/test_autoimport.py b/test/plugins/test_autoimport.py index dbad8d02..cd1ead04 100644 --- a/test/plugins/test_autoimport.py +++ b/test/plugins/test_autoimport.py @@ -42,9 +42,12 @@ def contains_autoimport_quickfix(suggestion: Dict[str, Any], module: str) -> boo def autoimport_workspace(tmp_path_factory) -> Workspace: "Special autoimport workspace. Persists across sessions to make in-memory sqlite3 database fast." workspace = Workspace( - uris.from_fs_path(str(tmp_path_factory.mktemp("pylsp"))), Mock() + root_uri=uris.from_fs_path(str(tmp_path_factory.mktemp("pylsp"))), + endpoint=Mock(), + ) + workspace._config = Config( + root_uri=workspace.root_uri, init_opts={}, process_id=0, capabilities={} ) - workspace._config = Config(workspace.root_uri, {}, 0, {}) workspace._config.update( { "rope_autoimport": { @@ -67,7 +70,11 @@ def completions(config: Config, autoimport_workspace: Workspace, request) -> Non autoimport_workspace.put_document(DOC_URI, source=document) doc = autoimport_workspace.get_document(DOC_URI) yield pylsp_autoimport_completions( - config, autoimport_workspace, doc, com_position, None + config=config, + workspace=autoimport_workspace, + document=doc, + position=com_position, + ignored_names=None, ) autoimport_workspace.rm_document(DOC_URI) @@ -75,7 +82,7 @@ def completions(config: Config, autoimport_workspace: Workspace, request) -> Non def should_insert(phrase: str, position: int): expr = parso.parse(phrase) word_node = expr.get_leaf_for_position((1, position)) - return _should_insert(expr, word_node) + return _should_insert(expr=expr, word_node=word_node) def check_dict(query: Dict, results: List[Dict]) -> bool: @@ -89,7 +96,8 @@ def check_dict(query: Dict, results: List[Dict]) -> bool: def test_autoimport_completion(completions) -> None: assert completions assert check_dict( - {"label": "pathlib", "kind": lsp.CompletionItemKind.Module}, completions + query={"label": "pathlib", "kind": lsp.CompletionItemKind.Module}, + results=completions, ) @@ -146,7 +154,7 @@ def test_autoimport_class_incomplete(completions) -> None: @pytest.mark.parametrize("completions", [("""def func(s:Lis""", 12)], indirect=True) def test_autoimport_function_typing(completions) -> None: assert len(completions) > 0 - assert check_dict({"label": "List"}, completions) + assert check_dict(query={"label": "List"}, results=completions) @pytest.mark.parametrize( @@ -154,7 +162,7 @@ def test_autoimport_function_typing(completions) -> None: ) def test_autoimport_function_typing_complete(completions) -> None: assert len(completions) > 0 - assert check_dict({"label": "List"}, completions) + assert check_dict(query={"label": "List"}, results=completions) @pytest.mark.parametrize( @@ -162,7 +170,7 @@ def test_autoimport_function_typing_complete(completions) -> None: ) def test_autoimport_function_typing_return(completions) -> None: assert len(completions) > 0 - assert check_dict({"label": "Generator"}, completions) + assert check_dict(query={"label": "Generator"}, results=completions) def test_autoimport_defined_name(config, workspace) -> None: @@ -171,10 +179,14 @@ def test_autoimport_defined_name(config, workspace) -> None: workspace.put_document(DOC_URI, source=document) doc = workspace.get_document(DOC_URI) completions = pylsp_autoimport_completions( - config, workspace, doc, com_position, None + config=config, + workspace=workspace, + document=doc, + position=com_position, + ignored_names=None, ) workspace.rm_document(DOC_URI) - assert not check_dict({"label": "List"}, completions) + assert not check_dict(query={"label": "List"}, results=completions) class TestShouldInsert: @@ -196,24 +208,50 @@ def test_from(self) -> None: def test_sort_sources() -> None: - result1 = _get_score(1, "import pathlib", "pathlib", "pathli") - result2 = _get_score(2, "import pathlib", "pathlib", "pathli") + result1 = _get_score( + source=1, + full_statement="import pathlib", + suggested_name="pathlib", + desired_name="pathli", + ) + result2 = _get_score( + source=2, + full_statement="import pathlib", + suggested_name="pathlib", + desired_name="pathli", + ) assert result1 < result2 def test_sort_statements() -> None: result1 = _get_score( - 2, "from importlib_metadata import pathlib", "pathlib", "pathli" + source=2, + full_statement="from importlib_metadata import pathlib", + suggested_name="pathlib", + desired_name="pathli", + ) + result2 = _get_score( + source=2, + full_statement="import pathlib", + suggested_name="pathlib", + desired_name="pathli", ) - result2 = _get_score(2, "import pathlib", "pathlib", "pathli") assert result1 > result2 def test_sort_both() -> None: result1 = _get_score( - 3, "from importlib_metadata import pathlib", "pathlib", "pathli" + source=3, + full_statement="from importlib_metadata import pathlib", + suggested_name="pathlib", + desired_name="pathli", + ) + result2 = _get_score( + source=2, + full_statement="import pathlib", + suggested_name="pathlib", + desired_name="pathli", ) - result2 = _get_score(2, "import pathlib", "pathlib", "pathli") assert result1 > result2 @@ -250,7 +288,7 @@ def test_autoimport_code_actions_get_correct_module_name( }, "message": message, } - module_name = get_name_or_module(doc, diagnostic) + module_name = get_name_or_module(document=doc, diagnostic=diagnostic) autoimport_workspace.rm_document(DOC_URI) assert module_name == "os" @@ -279,8 +317,8 @@ def test_autoimport_code_actions_and_completions_for_notebook_document( ) -> None: client, server = client_server_pair send_initialize_request( - client, - { + client=client, + initialization_options={ "pylsp": { "plugins": { "rope_autoimport": { @@ -302,7 +340,9 @@ def test_autoimport_code_actions_and_completions_for_notebook_document( # already imported in the second cell. # 4. We receive an autoimport suggestion for "sys" because it's not already imported. # 5. If diagnostics doesn't contain "undefined name ...", we send empty quick fix suggestions. - send_notebook_did_open(client, ["os", "import os\nos", "os", "sys"]) + send_notebook_did_open( + client=client, cells=["os", "import os\nos", "os", "sys"] + ) wait_for_condition(lambda: mock_notify.call_count >= 4) # We received diagnostics messages for every cell assert all( @@ -318,29 +358,69 @@ def test_autoimport_code_actions_and_completions_for_notebook_document( wait_for_condition(lambda: not cache.is_blocked()) # 1. - quick_fixes = server.code_actions("cell_1_uri", {}, make_context("os", 0, 0, 2)) - assert any(s for s in quick_fixes if contains_autoimport_quickfix(s, "os")) + quick_fixes = server.code_actions( + "cell_1_uri", + {}, + make_context(module_name="os", line=0, character_start=0, character_end=2), + ) + assert any( + s + for s in quick_fixes + if contains_autoimport_quickfix(suggestion=s, module="os") + ) - completions = server.completions("cell_1_uri", position(0, 2)).get("items") - assert any(s for s in completions if contains_autoimport_completion(s, "os")) + completions = server.completions("cell_1_uri", position(line=0, character=2)).get( + "items" + ) + assert any( + s + for s in completions + if contains_autoimport_completion(suggestion=s, module="os") + ) # 2. # We don't test code actions here as in this case, there would be no code actions sent bc # there wouldn't be a diagnostics message. - completions = server.completions("cell_2_uri", position(1, 2)).get("items") - assert not any(s for s in completions if contains_autoimport_completion(s, "os")) + completions = server.completions("cell_2_uri", position(line=1, character=2)).get( + "items" + ) + assert not any( + s + for s in completions + if contains_autoimport_completion(suggestion=s, module="os") + ) # 3. # Same as in 2. - completions = server.completions("cell_3_uri", position(0, 2)).get("items") - assert not any(s for s in completions if contains_autoimport_completion(s, "os")) + completions = server.completions("cell_3_uri", position(line=0, character=2)).get( + "items" + ) + assert not any( + s + for s in completions + if contains_autoimport_completion(suggestion=s, module="os") + ) # 4. - quick_fixes = server.code_actions("cell_4_uri", {}, make_context("sys", 0, 0, 3)) - assert any(s for s in quick_fixes if contains_autoimport_quickfix(s, "sys")) + quick_fixes = server.code_actions( + "cell_4_uri", + {}, + make_context(module_name="sys", line=0, character_start=0, character_end=3), + ) + assert any( + s + for s in quick_fixes + if contains_autoimport_quickfix(suggestion=s, module="sys") + ) - completions = server.completions("cell_4_uri", position(0, 3)).get("items") - assert any(s for s in completions if contains_autoimport_completion(s, "sys")) + completions = server.completions("cell_4_uri", position(line=0, character=3)).get( + "items" + ) + assert any( + s + for s in completions + if contains_autoimport_completion(suggestion=s, module="sys") + ) # 5. context = {"diagnostics": [{"message": "A random message"}]} diff --git a/test/plugins/test_autopep8_format.py b/test/plugins/test_autopep8_format.py index 4966b89d..6c34ca81 100644 --- a/test/plugins/test_autopep8_format.py +++ b/test/plugins/test_autopep8_format.py @@ -40,21 +40,24 @@ def func(): def test_format(config, workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) - res = pylsp_format_document(config, workspace, doc, options=None) - + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + res = pylsp_format_document( + config=config, workspace=workspace, document=doc, options=None + ) assert len(res) == 1 assert res[0]["newText"] == "a = 123\n\n\ndef func():\n pass\n" def test_range_format(config, workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) def_range = { "start": {"line": 0, "character": 0}, "end": {"line": 2, "character": 0}, } - res = pylsp_format_range(config, workspace, doc, def_range, options=None) + res = pylsp_format_range( + config=config, workspace=workspace, document=doc, range=def_range, options=None + ) assert len(res) == 1 @@ -63,13 +66,18 @@ def test_range_format(config, workspace) -> None: def test_no_change(config, workspace) -> None: - doc = Document(DOC_URI, workspace, GOOD_DOC) - assert not pylsp_format_document(config, workspace, doc, options=None) + doc = Document(uri=DOC_URI, workspace=workspace, source=GOOD_DOC) + + assert not pylsp_format_document( + config=config, workspace=workspace, document=doc, options=None + ) def test_hanging_indentation(config, workspace) -> None: - doc = Document(DOC_URI, workspace, INDENTED_DOC) - res = pylsp_format_document(config, workspace, doc, options=None) + doc = Document(uri=DOC_URI, workspace=workspace, source=INDENTED_DOC) + res = pylsp_format_document( + config=config, workspace=workspace, document=doc, options=None + ) assert len(res) == 1 assert res[0]["newText"] == CORRECT_INDENTED_DOC @@ -77,8 +85,14 @@ def test_hanging_indentation(config, workspace) -> None: @pytest.mark.parametrize("newline", ["\r\n", "\r"]) def test_line_endings(config, workspace, newline) -> None: - doc = Document(DOC_URI, workspace, f"import os;import sys{2 * newline}dict(a=1)") - res = pylsp_format_document(config, workspace, doc, options=None) + doc = Document( + uri=DOC_URI, + workspace=workspace, + source=f"import os;import sys{2 * newline}dict(a=1)", + ) + res = pylsp_format_document( + config=config, workspace=workspace, document=doc, options=None + ) assert ( res[0]["newText"] diff --git a/test/plugins/test_completion.py b/test/plugins/test_completion.py index d1ca5ef8..5b8e78cb 100644 --- a/test/plugins/test_completion.py +++ b/test/plugins/test_completion.py @@ -53,8 +53,10 @@ def documented_hello(): def test_rope_import_completion(config, workspace) -> None: com_position = {"line": 0, "character": 7} - doc = Document(DOC_URI, workspace, DOC) - items = pylsp_rope_completions(config, workspace, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + items = pylsp_rope_completions( + config=config, workspace=workspace, document=doc, position=com_position + ) assert items is None @@ -125,8 +127,8 @@ def test_jedi_completion_type(case, config, workspace): ): return - doc = Document(DOC_URI, workspace, case.document) - items = pylsp_jedi_completions(config, doc, case.position) + doc = Document(uri=DOC_URI, workspace=workspace, source=case.document) + items = pylsp_jedi_completions(config=config, document=doc, position=case.position) items = {i["label"]: i for i in items} assert items[case.label]["kind"] == case.expected @@ -134,23 +136,27 @@ def test_jedi_completion_type(case, config, workspace): def test_jedi_completion(config, workspace) -> None: # Over 'i' in os.path.isabs(...) com_position = {"line": 1, "character": 15} - doc = Document(DOC_URI, workspace, DOC) - items = pylsp_jedi_completions(config, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) assert items labels = [i["label"] for i in items] assert "isfile(path)" in labels # Test we don't throw with big character - pylsp_jedi_completions(config, doc, {"line": 1, "character": 1000}) + pylsp_jedi_completions( + config=config, document=doc, position={"line": 1, "character": 1000} + ) def test_jedi_completion_item_resolve(config, workspace) -> None: # Over the blank line com_position = {"line": 8, "character": 0} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) config.update({"plugins": {"jedi_completion": {"resolve_at_most": math.inf}}}) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) items = {c["label"]: c for c in completions} @@ -160,7 +166,7 @@ def test_jedi_completion_item_resolve(config, workspace) -> None: assert "detail" not in documented_hello_item resolved_documented_hello = pylsp_jedi_completion_item_resolve( - doc._config, completion_item=documented_hello_item, document=doc + config=doc._config, completion_item=documented_hello_item, document=doc ) expected_doc = { "kind": "markdown", @@ -173,9 +179,9 @@ def test_jedi_completion_with_fuzzy_enabled(config, workspace) -> None: # Over 'i' in os.path.isabs(...) config.update({"plugins": {"jedi_completion": {"fuzzy": True}}}) com_position = {"line": 1, "character": 15} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) - items = pylsp_jedi_completions(config, doc, com_position) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) assert items @@ -185,23 +191,25 @@ def test_jedi_completion_with_fuzzy_enabled(config, workspace) -> None: assert items[0]["label"] == expected # Test we don't throw with big character - pylsp_jedi_completions(config, doc, {"line": 1, "character": 1000}) + pylsp_jedi_completions( + config=config, document=doc, position={"line": 1, "character": 1000} + ) def test_jedi_completion_resolve_at_most(config, workspace) -> None: # Over 'i' in os.path.isabs(...) com_position = {"line": 1, "character": 15} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) # Do not resolve any labels config.update({"plugins": {"jedi_completion": {"resolve_at_most": 0}}}) - items = pylsp_jedi_completions(config, doc, com_position) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) labels = {i["label"] for i in items} assert "isabs" in labels # Resolve all items config.update({"plugins": {"jedi_completion": {"resolve_at_most": math.inf}}}) - items = pylsp_jedi_completions(config, doc, com_position) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) labels = {i["label"] for i in items} assert "isfile(path)" in labels @@ -211,7 +219,9 @@ def test_rope_completion(config, workspace) -> None: com_position = {"line": 1, "character": 15} workspace.put_document(DOC_URI, source=DOC) doc = workspace.get_document(DOC_URI) - items = pylsp_rope_completions(config, workspace, doc, com_position) + items = pylsp_rope_completions( + config=config, workspace=workspace, document=doc, position=com_position + ) assert items assert items[0]["label"] == "isabs" @@ -220,9 +230,11 @@ def test_rope_completion(config, workspace) -> None: def test_jedi_completion_ordering(config, workspace) -> None: # Over the blank line com_position = {"line": 8, "character": 0} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) config.update({"plugins": {"jedi_completion": {"resolve_at_most": math.inf}}}) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) items = {c["label"]: c["sortText"] for c in completions} @@ -233,8 +245,10 @@ def test_jedi_completion_ordering(config, workspace) -> None: def test_jedi_property_completion(config, workspace) -> None: # Over the 'w' in 'print Hello().world' com_position = {"line": 18, "character": 15} - doc = Document(DOC_URI, workspace, DOC) - completions = pylsp_jedi_completions(config, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) items = {c["label"]: c["sortText"] for c in completions} @@ -245,14 +259,16 @@ def test_jedi_property_completion(config, workspace) -> None: def test_jedi_method_completion(config, workspace) -> None: # Over the 'y' in 'print Hello().every' com_position = {"line": 20, "character": 19} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } config.update({"plugins": {"jedi_completion": {"include_params": True}}}) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) everyone_method = [ completion for completion in completions @@ -266,7 +282,9 @@ def test_jedi_method_completion(config, workspace) -> None: # Disable param snippets config.update({"plugins": {"jedi_completion": {"include_params": False}}}) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) everyone_method = [ completion for completion in completions @@ -285,8 +303,10 @@ def test_pyqt_completion(config, workspace) -> None: # Over 'QA' in 'from PyQt5.QtWidgets import QApplication' doc_pyqt = "from PyQt5.QtWidgets import QA" com_position = {"line": 0, "character": len(doc_pyqt)} - doc = Document(DOC_URI, workspace, doc_pyqt) - completions = pylsp_jedi_completions(config, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_pyqt) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) assert completions is not None @@ -294,8 +314,8 @@ def test_pyqt_completion(config, workspace) -> None: def test_numpy_completions(config, workspace) -> None: doc_numpy = "import numpy as np; np." com_position = {"line": 0, "character": len(doc_numpy)} - doc = Document(DOC_URI, workspace, doc_numpy) - items = pylsp_jedi_completions(config, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_numpy) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) assert items assert any("array" in i["label"] for i in items) @@ -304,8 +324,8 @@ def test_numpy_completions(config, workspace) -> None: def test_pandas_completions(config, workspace) -> None: doc_pandas = "import pandas as pd; pd." com_position = {"line": 0, "character": len(doc_pandas)} - doc = Document(DOC_URI, workspace, doc_pandas) - items = pylsp_jedi_completions(config, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_pandas) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) assert items assert any("DataFrame" in i["label"] for i in items) @@ -314,8 +334,8 @@ def test_pandas_completions(config, workspace) -> None: def test_matplotlib_completions(config, workspace) -> None: doc_mpl = "import matplotlib.pyplot as plt; plt." com_position = {"line": 0, "character": len(doc_mpl)} - doc = Document(DOC_URI, workspace, doc_mpl) - items = pylsp_jedi_completions(config, doc, com_position) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_mpl) + items = pylsp_jedi_completions(config=config, document=doc, position=com_position) assert items assert any("plot" in i["label"] for i in items) @@ -324,23 +344,27 @@ def test_matplotlib_completions(config, workspace) -> None: def test_snippets_completion(config, workspace) -> None: doc_snippets = "from collections import defaultdict \na=defaultdict" com_position = {"line": 0, "character": 35} - doc = Document(DOC_URI, workspace, doc_snippets) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_snippets) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } config.update({"plugins": {"jedi_completion": {"include_params": True}}}) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) assert completions[0]["insertText"] == "defaultdict" com_position = {"line": 1, "character": len(doc_snippets)} - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) assert completions[0]["insertText"] == "defaultdict($0)" assert completions[0]["insertTextFormat"] == lsp.InsertTextFormat.Snippet def test_snippets_completion_at_most(config, workspace) -> None: doc_snippets = "from collections import defaultdict \na=defaultdict" - doc = Document(DOC_URI, workspace, doc_snippets) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_snippets) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } @@ -348,7 +372,9 @@ def test_snippets_completion_at_most(config, workspace) -> None: config.update({"plugins": {"jedi_completion": {"resolve_at_most": 0}}}) com_position = {"line": 1, "character": len(doc_snippets)} - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) assert completions[0]["insertText"] == "defaultdict" assert not completions[0].get("insertTextFormat", None) @@ -356,7 +382,7 @@ def test_snippets_completion_at_most(config, workspace) -> None: def test_completion_with_class_objects(config, workspace) -> None: doc_text = "class FOOBAR(Object): pass\nFOOB" com_position = {"line": 1, "character": 4} - doc = Document(DOC_URI, workspace, doc_text) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_text) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } @@ -370,7 +396,9 @@ def test_completion_with_class_objects(config, workspace) -> None: } } ) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) assert len(completions) == 2 assert completions[0]["label"] == "FOOBAR" @@ -383,7 +411,7 @@ def test_completion_with_class_objects(config, workspace) -> None: def test_completion_with_function_objects(config, workspace) -> None: doc_text = "def foobar(): pass\nfoob" com_position = {"line": 1, "character": 4} - doc = Document(DOC_URI, workspace, doc_text) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_text) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } @@ -397,7 +425,9 @@ def test_completion_with_function_objects(config, workspace) -> None: } } ) - completions = pylsp_jedi_completions(config, doc, com_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=com_position + ) assert len(completions) == 2 assert completions[0]["label"] == "foobar()" @@ -410,12 +440,14 @@ def test_completion_with_function_objects(config, workspace) -> None: def test_snippet_parsing(config, workspace) -> None: doc = "divmod" completion_position = {"line": 0, "character": 6} - doc = Document(DOC_URI, workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } config.update({"plugins": {"jedi_completion": {"include_params": True}}}) - completions = pylsp_jedi_completions(config, doc, completion_position) + completions = pylsp_jedi_completions( + config=config, document=doc, position=completion_position + ) out = "divmod(${1:x}, ${2:y})$0" if JEDI_VERSION == "0.18.0": @@ -425,35 +457,35 @@ def test_snippet_parsing(config, workspace) -> None: def test_multiline_import_snippets(config, workspace) -> None: document = "from datetime import(\n date,\n datetime)\na=date" - doc = Document(DOC_URI, workspace, document) + doc = Document(uri=DOC_URI, workspace=workspace, source=document) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } config.update({"plugins": {"jedi_completion": {"include_params": True}}}) position = {"line": 1, "character": 5} - completions = pylsp_jedi_completions(config, doc, position) + completions = pylsp_jedi_completions(config=config, document=doc, position=position) assert completions[0]["insertText"] == "date" position = {"line": 2, "character": 9} - completions = pylsp_jedi_completions(config, doc, position) + completions = pylsp_jedi_completions(config=config, document=doc, position=position) assert completions[0]["insertText"] == "datetime" def test_multiline_snippets(config, workspace) -> None: document = "from datetime import\\\n date,\\\n datetime \na=date" - doc = Document(DOC_URI, workspace, document) + doc = Document(uri=DOC_URI, workspace=workspace, source=document) config.capabilities["textDocument"] = { "completion": {"completionItem": {"snippetSupport": True}} } config.update({"plugins": {"jedi_completion": {"include_params": True}}}) position = {"line": 1, "character": 5} - completions = pylsp_jedi_completions(config, doc, position) + completions = pylsp_jedi_completions(config=config, document=doc, position=position) assert completions[0]["insertText"] == "date" position = {"line": 2, "character": 9} - completions = pylsp_jedi_completions(config, doc, position) + completions = pylsp_jedi_completions(config=config, document=doc, position=position) assert completions[0]["insertText"] == "datetime" @@ -464,15 +496,15 @@ def test_multistatement_snippet(config, workspace) -> None: config.update({"plugins": {"jedi_completion": {"include_params": True}}}) document = "a = 1; from datetime import date" - doc = Document(DOC_URI, workspace, document) + doc = Document(uri=DOC_URI, workspace=workspace, source=document) position = {"line": 0, "character": len(document)} - completions = pylsp_jedi_completions(config, doc, position) + completions = pylsp_jedi_completions(config=config, document=doc, position=position) assert completions[0]["insertText"] == "date" document = "from math import fmod; a = fmod" - doc = Document(DOC_URI, workspace, document) + doc = Document(uri=DOC_URI, workspace=workspace, source=document) position = {"line": 0, "character": len(document)} - completions = pylsp_jedi_completions(config, doc, position) + completions = pylsp_jedi_completions(config=config, document=doc, position=position) assert completions[0]["insertText"] == "fmod(${1:x}, ${2:y})$0" @@ -490,11 +522,13 @@ def spam(): # Content of doc to test completion doc_content = """import foo foo.s""" - doc = Document(DOC_URI, workspace, doc_content) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_content) # After 'foo.s' without extra paths com_position = {"line": 1, "character": 5} - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) assert completions is None # Update config extra paths @@ -503,7 +537,9 @@ def spam(): # After 'foo.s' with extra paths com_position = {"line": 1, "character": 5} - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) assert completions[0]["label"] == "spam()" @@ -514,7 +550,7 @@ def test_jedi_completion_environment(workspace) -> None: # Content of doc to test completion doc_content = """import logh """ - doc = Document(DOC_URI, workspace, doc_content) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_content) # After 'import logh' with default environment com_position = {"line": 0, "character": 11} @@ -523,7 +559,9 @@ def test_jedi_completion_environment(workspace) -> None: settings = {"pylsp": {"plugins": {"jedi": {"environment": None}}}} doc.update_config(settings) - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) assert completions is None # Update config extra environment @@ -532,10 +570,14 @@ def test_jedi_completion_environment(workspace) -> None: doc.update_config(settings) # After 'import logh' with new environment - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) assert completions[0]["label"] == "loghub" - resolved = pylsp_jedi_completion_item_resolve(doc._config, completions[0], doc) + resolved = pylsp_jedi_completion_item_resolve( + config=doc._config, completion_item=completions[0], document=doc + ) assert "changelog generator" in resolved["documentation"]["value"].lower() @@ -555,10 +597,12 @@ def foo(): mymodule.f""" doc_path = str(tmpdir) + os.path.sep + "myfile.py" doc_uri = uris.from_fs_path(doc_path) - doc = Document(doc_uri, workspace_other_root_path, doc_content) + doc = Document(uri=doc_uri, workspace=workspace_other_root_path, source=doc_content) com_position = {"line": 1, "character": 10} - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) assert completions[0]["label"] == "foo()" @@ -572,11 +616,13 @@ def test_file_completions(workspace, tmpdir) -> None: # Content of doc to test completion doc_content = '"' - doc = Document(DOC_URI, workspace, doc_content) + doc = Document(uri=DOC_URI, workspace=workspace, source=doc_content) # Request for completions com_position = {"line": 0, "character": 1} - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) # Check completions assert len(completions) == 2 @@ -591,7 +637,9 @@ def test_file_completions(workspace, tmpdir) -> None: "textDocument": {"completion": {"completionItem": {"snippetSupport": True}}} } doc._config.capabilities.update(support_snippet) - completions = pylsp_jedi_completions(doc._config, doc, com_position) + completions = pylsp_jedi_completions( + config=doc._config, document=doc, position=com_position + ) assert completions[0]["insertText"] == ( ("bar" + "\\\\") if os.name == "nt" else ("bar" + "\\/") ) diff --git a/test/plugins/test_definitions.py b/test/plugins/test_definitions.py index 7923524b..75962acb 100644 --- a/test/plugins/test_definitions.py +++ b/test/plugins/test_definitions.py @@ -51,9 +51,9 @@ def test_definitions(config, workspace) -> None: "end": {"line": 0, "character": 5}, } - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) assert [{"uri": DOC_URI, "range": def_range}] == pylsp_definitions( - config, doc, cursor_pos + config=config, document=doc, position=cursor_pos ) @@ -68,9 +68,9 @@ def test_indirect_definitions(config, workspace) -> None: "end": {"line": 14, "character": len("subscripted_before_reference")}, } - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) assert [{"uri": DOC_URI, "range": def_range}] == pylsp_definitions( - config, doc, cursor_pos + config=config, document=doc, position=cursor_pos ) @@ -85,9 +85,9 @@ def test_definition_with_multihop_inference_goto(config, workspace) -> None: "end": {"line": 24, "character": len("inception")}, } - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) assert [{"uri": DOC_URI, "range": def_range}] == pylsp_definitions( - config, doc, cursor_pos + config=config, document=doc, position=cursor_pos ) @@ -95,8 +95,8 @@ def test_numpy_definition(config, workspace) -> None: # Over numpy.ones cursor_pos = {"line": 29, "character": 8} - doc = Document(DOC_URI, workspace, DOC) - defns = pylsp_definitions(config, doc, cursor_pos) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + defns = pylsp_definitions(config=config, document=doc, position=cursor_pos) assert len(defns) > 0, defns @@ -104,21 +104,21 @@ def test_builtin_definition(config, workspace) -> None: # Over 'i' in dict cursor_pos = {"line": 8, "character": 24} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) orig_settings = config.settings() # Check definition for `dict` goes to `builtins.pyi::dict` follow_defns_setting = {"follow_builtin_definitions": True} settings = {"plugins": {"jedi_definition": follow_defns_setting}} config.update(settings) - defns = pylsp_definitions(config, doc, cursor_pos) + defns = pylsp_definitions(config=config, document=doc, position=cursor_pos) assert len(defns) == 1 assert defns[0]["uri"].endswith("builtins.pyi") # Check no definitions for `dict` follow_defns_setting["follow_builtin_definitions"] = False config.update(settings) - defns = pylsp_definitions(config, doc, cursor_pos) + defns = pylsp_definitions(config=config, document=doc, position=cursor_pos) assert not defns config.update(orig_settings) @@ -134,9 +134,9 @@ def test_assignment(config, workspace) -> None: "end": {"line": 8, "character": 20}, } - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) assert [{"uri": DOC_URI, "range": def_range}] == pylsp_definitions( - config, doc, cursor_pos + config=config, document=doc, position=cursor_pos ) @@ -155,7 +155,7 @@ def foo(): doc_content = """from mymodule import foo""" doc_path = str(tmpdir) + os.path.sep + "myfile.py" doc_uri = uris.from_fs_path(doc_path) - doc = Document(doc_uri, workspace_other_root_path, doc_content) + doc = Document(uri=doc_uri, workspace=workspace_other_root_path, source=doc_content) # The range where is defined in mymodule.py def_range = { @@ -171,5 +171,5 @@ def foo(): module_uri = uris.from_fs_path(module_path) assert [{"uri": module_uri, "range": def_range}] == pylsp_definitions( - config, doc, cursor_pos + config=config, document=doc, position=cursor_pos ) diff --git a/test/plugins/test_flake8_lint.py b/test/plugins/test_flake8_lint.py index e7b6b001..66cb180d 100644 --- a/test/plugins/test_flake8_lint.py +++ b/test/plugins/test_flake8_lint.py @@ -25,14 +25,15 @@ def temp_document(doc_text, workspace): with tempfile.NamedTemporaryFile(mode="w", delete=False) as temp_file: name = temp_file.name temp_file.write(doc_text) - doc = Document(uris.from_fs_path(name), workspace) + doc = Document(uri=uris.from_fs_path(name), workspace=workspace) return name, doc def test_flake8_unsaved(workspace) -> None: - doc = Document("", workspace, DOC) - diags = flake8_lint.pylsp_lint(workspace, doc) + doc = Document(uri="", workspace=workspace, source=DOC) + diags = flake8_lint.pylsp_lint(workspace=workspace, document=doc) + msg = "F841 local variable 'a' is assigned to but never used" unused_var = [d for d in diags if d["message"] == msg][0] @@ -45,9 +46,10 @@ def test_flake8_unsaved(workspace) -> None: def test_flake8_lint(workspace) -> None: - name, doc = temp_document(DOC, workspace) + name, doc = temp_document(doc_text=DOC, workspace=workspace) + try: - diags = flake8_lint.pylsp_lint(workspace, doc) + diags = flake8_lint.pylsp_lint(workspace=workspace, document=doc) msg = "F841 local variable 'a' is assigned to but never used" unused_var = [d for d in diags if d["message"] == msg][0] @@ -91,7 +93,9 @@ def test_flake8_respecting_configuration(workspace) -> None: workspace.put_document(made[rel]["uri"], contents) made[rel]["document"] = workspace._docs[made[rel]["uri"]] - diags = flake8_lint.pylsp_lint(workspace, made["src/a.py"]["document"]) + diags = flake8_lint.pylsp_lint( + workspace=workspace, document=made["src/a.py"]["document"] + ) assert diags == [ { "source": "flake8", @@ -106,7 +110,9 @@ def test_flake8_respecting_configuration(workspace) -> None: }, ] - diags = flake8_lint.pylsp_lint(workspace, made["src/b.py"]["document"]) + diags = flake8_lint.pylsp_lint( + workspace=workspace, document=made["src/b.py"]["document"] + ) assert diags == [ { "source": "flake8", @@ -128,8 +134,8 @@ def test_flake8_config_param(workspace) -> None: mock_instance.communicate.return_value = [bytes(), bytes()] flake8_conf = "/tmp/some.cfg" workspace._config.update({"plugins": {"flake8": {"config": flake8_conf}}}) - _name, doc = temp_document(DOC, workspace) - flake8_lint.pylsp_lint(workspace, doc) + _name, doc = temp_document(doc_text=DOC, workspace=workspace) + flake8_lint.pylsp_lint(workspace=workspace, document=doc) (call_args,) = popen_mock.call_args[0] assert "flake8" in call_args assert "--config={}".format(flake8_conf) in call_args @@ -145,8 +151,8 @@ def test_flake8_executable_param(workspace) -> None: {"plugins": {"flake8": {"executable": flake8_executable}}} ) - _name, doc = temp_document(DOC, workspace) - flake8_lint.pylsp_lint(workspace, doc) + _name, doc = temp_document(doc_text=DOC, workspace=workspace) + flake8_lint.pylsp_lint(workspace=workspace, document=doc) (call_args,) = popen_mock.call_args[0] assert flake8_executable in call_args @@ -180,7 +186,9 @@ def test_flake8_multiline(workspace) -> None: doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py")) workspace.put_document(doc_uri, doc_str) - flake8_settings = get_flake8_cfg_settings(workspace, config_str) + flake8_settings = get_flake8_cfg_settings( + workspace=workspace, config_str=config_str + ) assert "exclude" in flake8_settings assert len(flake8_settings["exclude"]) == 2 @@ -190,7 +198,7 @@ def test_flake8_multiline(workspace) -> None: mock_instance.communicate.return_value = [bytes(), bytes()] doc = workspace.get_document(doc_uri) - flake8_lint.pylsp_lint(workspace, doc) + flake8_lint.pylsp_lint(workspace=workspace, document=doc) call_args = popen_mock.call_args[0][0] @@ -222,7 +230,9 @@ def test_flake8_per_file_ignores(workspace) -> None: doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py")) workspace.put_document(doc_uri, doc_str) - flake8_settings = get_flake8_cfg_settings(workspace, config_str) + flake8_settings = get_flake8_cfg_settings( + workspace=workspace, config_str=config_str + ) assert "perFileIgnores" in flake8_settings assert len(flake8_settings["perFileIgnores"]) == 2 @@ -230,7 +240,7 @@ def test_flake8_per_file_ignores(workspace) -> None: assert len(flake8_settings["exclude"]) == 2 doc = workspace.get_document(doc_uri) - res = flake8_lint.pylsp_lint(workspace, doc) + res = flake8_lint.pylsp_lint(workspace=workspace, document=doc) assert not res os.unlink(os.path.join(workspace.root_path, "setup.cfg")) @@ -246,13 +256,15 @@ def test_per_file_ignores_alternative_syntax(workspace) -> None: doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py")) workspace.put_document(doc_uri, doc_str) - flake8_settings = get_flake8_cfg_settings(workspace, config_str) + flake8_settings = get_flake8_cfg_settings( + workspace=workspace, config_str=config_str + ) assert "perFileIgnores" in flake8_settings assert len(flake8_settings["perFileIgnores"]) == 2 doc = workspace.get_document(doc_uri) - res = flake8_lint.pylsp_lint(workspace, doc) + res = flake8_lint.pylsp_lint(workspace=workspace, document=doc) assert not res os.unlink(os.path.join(workspace.root_path, "setup.cfg")) diff --git a/test/plugins/test_folding.py b/test/plugins/test_folding.py index 1f0d34c8..540e62fb 100644 --- a/test/plugins/test_folding.py +++ b/test/plugins/test_folding.py @@ -117,7 +117,7 @@ class A(: def test_folding(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) ranges = pylsp_folding_range(doc) expected = [ {"startLine": 1, "endLine": 6}, @@ -161,7 +161,8 @@ def test_folding(workspace) -> None: def test_folding_syntax_error(workspace) -> None: - doc = Document(DOC_URI, workspace, SYNTAX_ERR) + doc = Document(uri=DOC_URI, workspace=workspace, source=SYNTAX_ERR) + ranges = pylsp_folding_range(doc) expected = [ {"startLine": 1, "endLine": 6}, diff --git a/test/plugins/test_highlight.py b/test/plugins/test_highlight.py index eb5485bb..61e72008 100644 --- a/test/plugins/test_highlight.py +++ b/test/plugins/test_highlight.py @@ -15,8 +15,8 @@ def test_highlight(workspace) -> None: # Over 'a' in a.startswith cursor_pos = {"line": 1, "character": 0} - doc = Document(DOC_URI, workspace, DOC) - assert pylsp_document_highlight(doc, cursor_pos) == [ + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + assert pylsp_document_highlight(document=doc, position=cursor_pos) == [ { "range": { "start": {"line": 0, "character": 0}, @@ -44,8 +44,8 @@ def test_highlight(workspace) -> None: def test_sys_highlight(workspace) -> None: cursor_pos = {"line": 0, "character": 8} - doc = Document(DOC_URI, workspace, SYS_DOC) - assert pylsp_document_highlight(doc, cursor_pos) == [ + doc = Document(uri=DOC_URI, workspace=workspace, source=SYS_DOC) + assert pylsp_document_highlight(document=doc, position=cursor_pos) == [ { "range": { "start": {"line": 0, "character": 7}, diff --git a/test/plugins/test_hover.py b/test/plugins/test_hover.py index 9674b872..2b41606a 100644 --- a/test/plugins/test_hover.py +++ b/test/plugins/test_hover.py @@ -35,27 +35,38 @@ def test_numpy_hover(workspace) -> None: # Over 'sin' in np.sin numpy_sin_hov_position = {"line": 3, "character": 4} - doc = Document(DOC_URI, workspace, NUMPY_DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=NUMPY_DOC) contents = "" - assert contents in pylsp_hover(doc._config, doc, no_hov_position)["contents"] + assert ( + contents + in pylsp_hover(config=doc._config, document=doc, position=no_hov_position)[ + "contents" + ] + ) contents = "NumPy\n=====\n\nProvides\n" assert ( contents - in pylsp_hover(doc._config, doc, numpy_hov_position_1)["contents"]["value"] + in pylsp_hover(config=doc._config, document=doc, position=numpy_hov_position_1)[ + "contents" + ]["value"] ) contents = "NumPy\n=====\n\nProvides\n" assert ( contents - in pylsp_hover(doc._config, doc, numpy_hov_position_2)["contents"]["value"] + in pylsp_hover(config=doc._config, document=doc, position=numpy_hov_position_2)[ + "contents" + ]["value"] ) contents = "NumPy\n=====\n\nProvides\n" assert ( contents - in pylsp_hover(doc._config, doc, numpy_hov_position_3)["contents"]["value"] + in pylsp_hover(config=doc._config, document=doc, position=numpy_hov_position_3)[ + "contents" + ]["value"] ) # https://github.com/davidhalter/jedi/issues/1746 @@ -65,9 +76,9 @@ def test_numpy_hover(workspace) -> None: contents = "Trigonometric sine, element-wise.\n\n" assert ( contents - in pylsp_hover(doc._config, doc, numpy_sin_hov_position)["contents"][ - "value" - ] + in pylsp_hover( + config=doc._config, document=doc, position=numpy_sin_hov_position + )["contents"]["value"] ) @@ -77,13 +88,17 @@ def test_hover(workspace) -> None: # Over the blank second line no_hov_position = {"line": 1, "character": 0} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) contents = {"kind": "markdown", "value": "```python\nmain()\n```\n\n\nhello world"} - assert {"contents": contents} == pylsp_hover(doc._config, doc, hov_position) + assert {"contents": contents} == pylsp_hover( + config=doc._config, document=doc, position=hov_position + ) - assert {"contents": ""} == pylsp_hover(doc._config, doc, no_hov_position) + assert {"contents": ""} == pylsp_hover( + config=doc._config, document=doc, position=no_hov_position + ) def test_document_path_hover(workspace_other_root_path, tmpdir) -> None: @@ -103,9 +118,11 @@ def foo(): foo""" doc_path = str(tmpdir) + os.path.sep + "myfile.py" doc_uri = uris.from_fs_path(doc_path) - doc = Document(doc_uri, workspace_other_root_path, doc_content) + doc = Document(uri=doc_uri, workspace=workspace_other_root_path, source=doc_content) cursor_pos = {"line": 1, "character": 3} - contents = pylsp_hover(doc._config, doc, cursor_pos)["contents"] + contents = pylsp_hover(config=doc._config, document=doc, position=cursor_pos)[ + "contents" + ] assert "A docstring for foo." in contents["value"] diff --git a/test/plugins/test_jedi_rename.py b/test/plugins/test_jedi_rename.py index 349274be..63d73626 100644 --- a/test/plugins/test_jedi_rename.py +++ b/test/plugins/test_jedi_rename.py @@ -37,9 +37,15 @@ def test_jedi_rename(tmp_workspace, config) -> None: # rename the `Test1` class position = {"line": 0, "character": 6} DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC_NAME)) - doc = Document(DOC_URI, tmp_workspace) - - result = pylsp_rename(config, tmp_workspace, doc, position, "ShouldBeRenamed") + doc = Document(uri=DOC_URI, workspace=tmp_workspace) + + result = pylsp_rename( + config=config, + workspace=tmp_workspace, + document=doc, + position=position, + new_name="ShouldBeRenamed", + ) assert len(result.keys()) == 1 changes = result.get("documentChanges") @@ -84,9 +90,15 @@ def test_jedi_rename(tmp_workspace, config) -> None: # rename foo position = {"line": 0, "character": 0} DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC_NAME_SIMPLE)) - doc = Document(DOC_URI, tmp_workspace) - - result = pylsp_rename(config, tmp_workspace, doc, position, "bar") + doc = Document(uri=DOC_URI, workspace=tmp_workspace) + + result = pylsp_rename( + config=config, + workspace=tmp_workspace, + document=doc, + position=position, + new_name="bar", + ) assert len(result.keys()) == 1 changes = result.get("documentChanges") diff --git a/test/plugins/test_mccabe_lint.py b/test/plugins/test_mccabe_lint.py index f4df0c2c..60704a49 100644 --- a/test/plugins/test_mccabe_lint.py +++ b/test/plugins/test_mccabe_lint.py @@ -18,8 +18,8 @@ def test_mccabe(config, workspace) -> None: old_settings = config.settings try: config.update({"plugins": {"mccabe": {"threshold": 1}}}) - doc = Document(DOC_URI, workspace, DOC) - diags = mccabe_lint.pylsp_lint(config, workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + diags = mccabe_lint.pylsp_lint(config=config, workspace=workspace, document=doc) assert all(d["source"] == "mccabe" for d in diags) @@ -35,5 +35,7 @@ def test_mccabe(config, workspace) -> None: def test_mccabe_syntax_error(config, workspace) -> None: - doc = Document(DOC_URI, workspace, DOC_SYNTAX_ERR) - assert mccabe_lint.pylsp_lint(config, workspace, doc) is None + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC_SYNTAX_ERR) + assert ( + mccabe_lint.pylsp_lint(config=config, workspace=workspace, document=doc) is None + ) diff --git a/test/plugins/test_pycodestyle_lint.py b/test/plugins/test_pycodestyle_lint.py index eea0b7de..5772d717 100644 --- a/test/plugins/test_pycodestyle_lint.py +++ b/test/plugins/test_pycodestyle_lint.py @@ -25,8 +25,8 @@ def hello( ): def test_pycodestyle(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) - diags = pycodestyle_lint.pylsp_lint(workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + diags = pycodestyle_lint.pylsp_lint(workspace=workspace, document=doc) assert all(d["source"] == "pycodestyle" for d in diags) @@ -84,7 +84,7 @@ def test_pycodestyle_config(workspace) -> None: doc = workspace.get_document(doc_uri) # Make sure we get a warning for 'indentation contains tabs' - diags = pycodestyle_lint.pylsp_lint(workspace, doc) + diags = pycodestyle_lint.pylsp_lint(workspace=workspace, document=doc) assert [d for d in diags if d["code"] == "W191"] content = { @@ -101,7 +101,7 @@ def test_pycodestyle_config(workspace) -> None: workspace._config.settings.cache_clear() # And make sure we don't get any warnings - diags = pycodestyle_lint.pylsp_lint(workspace, doc) + diags = pycodestyle_lint.pylsp_lint(workspace=workspace, document=doc) assert len([d for d in diags if d["code"] == "W191"]) == (0 if working else 1) assert len([d for d in diags if d["code"] == "E201"]) == (0 if working else 1) assert [d for d in diags if d["code"] == "W391"] @@ -111,7 +111,7 @@ def test_pycodestyle_config(workspace) -> None: # Make sure we can ignore via the PYLS config as well workspace._config.update({"plugins": {"pycodestyle": {"ignore": ["W191", "E201"]}}}) # And make sure we only get one warning - diags = pycodestyle_lint.pylsp_lint(workspace, doc) + diags = pycodestyle_lint.pylsp_lint(workspace=workspace, document=doc) assert not [d for d in diags if d["code"] == "W191"] assert not [d for d in diags if d["code"] == "E201"] assert [d for d in diags if d["code"] == "W391"] @@ -127,10 +127,10 @@ def test_line_endings(workspace, newline) -> None: source = f"try:{newline} 1/0{newline}except Exception:{newline} pass{newline}" # Create document - doc = Document(DOC_URI, workspace, source) + doc = Document(uri=DOC_URI, workspace=workspace, source=source) # Get diagnostics - diags = pycodestyle_lint.pylsp_lint(workspace, doc) + diags = pycodestyle_lint.pylsp_lint(workspace=workspace, document=doc) # Assert no diagnostics were given assert len(diags) == 0 diff --git a/test/plugins/test_pydocstyle_lint.py b/test/plugins/test_pydocstyle_lint.py index 383aaf1f..92561db9 100644 --- a/test/plugins/test_pydocstyle_lint.py +++ b/test/plugins/test_pydocstyle_lint.py @@ -20,8 +20,8 @@ def hello(): def test_pydocstyle(config, workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) - diags = pydocstyle_lint.pylsp_lint(config, workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + diags = pydocstyle_lint.pylsp_lint(config=config, workspace=workspace, document=doc) assert all(d["source"] == "pydocstyle" for d in diags) @@ -40,20 +40,22 @@ def test_pydocstyle(config, workspace) -> None: def test_pydocstyle_test_document(config, workspace) -> None: # The default --match argument excludes test_* documents. - doc = Document(TEST_DOC_URI, workspace, "") - diags = pydocstyle_lint.pylsp_lint(config, workspace, doc) + doc = Document(uri=TEST_DOC_URI, workspace=workspace, source="") + diags = pydocstyle_lint.pylsp_lint(config=config, workspace=workspace, document=doc) assert not diags def test_pydocstyle_empty_source(config, workspace) -> None: - doc = Document(DOC_URI, workspace, "") - diags = pydocstyle_lint.pylsp_lint(config, workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source="") + diags = pydocstyle_lint.pylsp_lint(config=config, workspace=workspace, document=doc) + assert diags[0]["message"] == "D100: Missing docstring in public module" assert len(diags) == 1 def test_pydocstyle_invalid_source(config, workspace) -> None: - doc = Document(DOC_URI, workspace, "bad syntax") - diags = pydocstyle_lint.pylsp_lint(config, workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source="bad syntax") + diags = pydocstyle_lint.pylsp_lint(config=config, workspace=workspace, document=doc) + # We're unable to parse the file, so can't get any pydocstyle diagnostics assert not diags diff --git a/test/plugins/test_pyflakes_lint.py b/test/plugins/test_pyflakes_lint.py index 8ab36320..57ef61e8 100644 --- a/test/plugins/test_pyflakes_lint.py +++ b/test/plugins/test_pyflakes_lint.py @@ -29,8 +29,8 @@ def hello(): def test_pyflakes(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) - diags = pyflakes_lint.pylsp_lint(workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + diags = pyflakes_lint.pylsp_lint(workspace=workspace, document=doc) # One we're expecting is: msg = "'sys' imported but unused" @@ -41,8 +41,8 @@ def test_pyflakes(workspace) -> None: def test_syntax_error_pyflakes(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC_SYNTAX_ERR) - diag = pyflakes_lint.pylsp_lint(workspace, doc)[0] + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC_SYNTAX_ERR) + diag = pyflakes_lint.pylsp_lint(workspace=workspace, document=doc)[0] if sys.version_info[:2] >= (3, 10): assert diag["message"] == "expected ':'" @@ -53,8 +53,8 @@ def test_syntax_error_pyflakes(workspace) -> None: def test_undefined_name_pyflakes(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC_UNDEFINED_NAME_ERR) - diag = pyflakes_lint.pylsp_lint(workspace, doc)[0] + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC_UNDEFINED_NAME_ERR) + diag = pyflakes_lint.pylsp_lint(workspace=workspace, document=doc)[0] assert diag["message"] == "undefined name 'b'" assert diag["range"]["start"] == {"line": 0, "character": 4} @@ -62,8 +62,8 @@ def test_undefined_name_pyflakes(workspace) -> None: def test_unicode_encoding(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC_ENCODING) - diags = pyflakes_lint.pylsp_lint(workspace, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC_ENCODING) + diags = pyflakes_lint.pylsp_lint(workspace=workspace, document=doc) assert len(diags) == 1 assert diags[0]["message"] == "'sys' imported but unused" diff --git a/test/plugins/test_pylint_lint.py b/test/plugins/test_pylint_lint.py index b4d511d0..64ff997c 100644 --- a/test/plugins/test_pylint_lint.py +++ b/test/plugins/test_pylint_lint.py @@ -31,7 +31,7 @@ def temp_document(doc_text, workspace) -> None: with tempfile.NamedTemporaryFile(mode="w", delete=False) as temp_file: name = temp_file.name temp_file.write(doc_text) - yield Document(uris.from_fs_path(name), workspace) + yield Document(uri=uris.from_fs_path(name), workspace=workspace) finally: os.remove(name) @@ -42,8 +42,10 @@ def write_temp_doc(document, contents) -> None: def test_pylint(config, workspace) -> None: - with temp_document(DOC, workspace) as doc: - diags = pylint_lint.pylsp_lint(config, workspace, doc, True) + with temp_document(doc_text=DOC, workspace=workspace) as doc: + diags = pylint_lint.pylsp_lint( + config=config, workspace=workspace, document=doc, is_saved=True + ) msg = "[unused-import] Unused import sys" unused_import = [d for d in diags if d["message"] == msg][0] @@ -54,7 +56,9 @@ def test_pylint(config, workspace) -> None: # test running pylint in stdin config.plugin_settings("pylint")["executable"] = "pylint" - diags = pylint_lint.pylsp_lint(config, workspace, doc, True) + diags = pylint_lint.pylsp_lint( + config=config, workspace=workspace, document=doc, is_saved=True + ) msg = "Unused import sys (unused-import)" unused_import = [d for d in diags if d["message"] == msg][0] @@ -67,8 +71,10 @@ def test_pylint(config, workspace) -> None: def test_syntax_error_pylint(config, workspace) -> None: - with temp_document(DOC_SYNTAX_ERR, workspace) as doc: - diag = pylint_lint.pylsp_lint(config, workspace, doc, True)[0] + with temp_document(doc_text=DOC_SYNTAX_ERR, workspace=workspace) as doc: + diag = pylint_lint.pylsp_lint( + config=config, workspace=workspace, document=doc, is_saved=True + )[0] assert diag["message"].startswith("[syntax-error]") assert diag["message"].count("expected ':'") or diag["message"].count( @@ -81,7 +87,9 @@ def test_syntax_error_pylint(config, workspace) -> None: # test running pylint in stdin config.plugin_settings("pylint")["executable"] = "pylint" - diag = pylint_lint.pylsp_lint(config, workspace, doc, True)[0] + diag = pylint_lint.pylsp_lint( + config=config, workspace=workspace, document=doc, is_saved=True + )[0] assert diag["message"].count("expected ':'") or diag["message"].count( "invalid syntax" @@ -95,9 +103,14 @@ def test_lint_free_pylint(config, workspace) -> None: # Can't use temp_document because it might give us a file that doesn't # match pylint's naming requirements. We should be keeping this file clean # though, so it works for a test of an empty lint. - ws = Workspace(str(Path(__file__).absolute().parents[2]), workspace._endpoint) + ws = Workspace( + root_uri=str(Path(__file__).absolute().parents[2]), endpoint=workspace._endpoint + ) assert not pylint_lint.pylsp_lint( - config, ws, Document(uris.from_fs_path(__file__), ws), True + config=config, + workspace=ws, + document=Document(uri=uris.from_fs_path(__file__), workspace=ws), + is_saved=True, ) @@ -112,14 +125,14 @@ def test_lint_caching(workspace) -> None: # file has capital letters in its name. flags = "--disable=invalid-name" - with temp_document(DOC, workspace) as doc: + with temp_document(doc_text=DOC, workspace=workspace) as doc: # Start with a file with errors. diags = pylint_lint.PylintLinter.lint(doc, True, flags) assert diags # Fix lint errors and write the changes to disk. Run the linter in the # in-memory mode to check the cached diagnostic behavior. - write_temp_doc(doc, "") + write_temp_doc(document=doc, contents="") assert pylint_lint.PylintLinter.lint(doc, False, flags) == diags # Now check the on-disk behavior. @@ -131,9 +144,14 @@ def test_lint_caching(workspace) -> None: def test_per_file_caching(config, workspace) -> None: # Ensure that diagnostics are cached per-file. - with temp_document(DOC, workspace) as doc: - assert pylint_lint.pylsp_lint(config, workspace, doc, True) + with temp_document(doc_text=DOC, workspace=workspace) as doc: + assert pylint_lint.pylsp_lint( + config=config, workspace=workspace, document=doc, is_saved=True + ) assert not pylint_lint.pylsp_lint( - config, workspace, Document(uris.from_fs_path(__file__), workspace), False + config=config, + workspace=workspace, + document=Document(uri=uris.from_fs_path(__file__), workspace=workspace), + is_saved=False, ) diff --git a/test/plugins/test_references.py b/test/plugins/test_references.py index f5121693..ac979be5 100644 --- a/test/plugins/test_references.py +++ b/test/plugins/test_references.py @@ -39,15 +39,17 @@ def test_references(tmp_workspace) -> None: # Over 'Test1' in class Test1(): position = {"line": 0, "character": 8} DOC1_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC1_NAME)) - doc1 = Document(DOC1_URI, tmp_workspace) + doc1 = Document(uri=DOC1_URI, workspace=tmp_workspace) - refs = pylsp_references(doc1, position, exclude_declaration=False) + refs = pylsp_references(document=doc1, position=position, exclude_declaration=False) # Definition, the import and the instantiation assert len(refs) == 3 # Briefly check excluding the definitions (also excludes imports, only counts uses) - no_def_refs = pylsp_references(doc1, position, exclude_declaration=True) + no_def_refs = pylsp_references( + document=doc1, position=position, exclude_declaration=True + ) assert len(no_def_refs) == 1 # Make sure our definition is correctly located @@ -69,9 +71,9 @@ def test_references_builtin(tmp_workspace) -> None: # Over 'UnicodeError': position = {"line": 4, "character": 7} doc2_uri = uris.from_fs_path(os.path.join(str(tmp_workspace.root_path), DOC2_NAME)) - doc2 = Document(doc2_uri, tmp_workspace) + doc2 = Document(uri=doc2_uri, workspace=tmp_workspace) - refs = pylsp_references(doc2, position, exclude_declaration=False) + refs = pylsp_references(document=doc2, position=position, exclude_declaration=False) assert len(refs) >= 1 expected = { diff --git a/test/plugins/test_signature.py b/test/plugins/test_signature.py index 4a0a84ef..f1915468 100644 --- a/test/plugins/test_signature.py +++ b/test/plugins/test_signature.py @@ -45,18 +45,22 @@ def main(param1=None, def test_no_signature(workspace) -> None: # Over blank line sig_position = {"line": 9, "character": 0} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) - sigs = signature.pylsp_signature_help(doc._config, doc, sig_position)["signatures"] + sigs = signature.pylsp_signature_help( + config=doc._config, document=doc, position=sig_position + )["signatures"] assert not sigs def test_signature(workspace) -> None: # Over '( ' in main( sig_position = {"line": 10, "character": 5} - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) - sig_info = signature.pylsp_signature_help(doc._config, doc, sig_position) + sig_info = signature.pylsp_signature_help( + config=doc._config, document=doc, position=sig_position + ) sigs = sig_info["signatures"] assert len(sigs) == 1 @@ -73,9 +77,11 @@ def test_signature(workspace) -> None: def test_multi_line_signature(workspace) -> None: # Over '( ' in main( sig_position = {"line": 17, "character": 5} - doc = Document(DOC_URI, workspace, MULTI_LINE_DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=MULTI_LINE_DOC) - sig_info = signature.pylsp_signature_help(doc._config, doc, sig_position) + sig_info = signature.pylsp_signature_help( + config=doc._config, document=doc, position=sig_position + ) sigs = sig_info["signatures"] assert len(sigs) == 1 diff --git a/test/plugins/test_symbols.py b/test/plugins/test_symbols.py index c00ab935..c93f8c26 100644 --- a/test/plugins/test_symbols.py +++ b/test/plugins/test_symbols.py @@ -49,9 +49,9 @@ def sym(name): def test_symbols(config, workspace): - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) config.update({"plugins": {"jedi_symbols": {"all_scopes": False}}}) - symbols = pylsp_document_symbols(config, doc) + symbols = pylsp_document_symbols(config=config, document=doc) # All four symbols (import sys, a, B, main) # y is not in the root scope, it shouldn't be returned @@ -74,8 +74,9 @@ def sym(name): def test_symbols_all_scopes(config, workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) - symbols = pylsp_document_symbols(config, doc) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + symbols = pylsp_document_symbols(config=config, document=doc) + helper_check_symbols_all_scope(symbols) @@ -84,8 +85,8 @@ def test_symbols_non_existing_file(config, workspace, tmpdir) -> None: # Check pre-condition: file must not exist assert not path.check(exists=1) - doc = Document(uris.from_fs_path(str(path)), workspace, DOC) - symbols = pylsp_document_symbols(config, doc) + doc = Document(uri=uris.from_fs_path(str(path)), workspace=workspace, source=DOC) + symbols = pylsp_document_symbols(config=config, document=doc) helper_check_symbols_all_scope(symbols) @@ -93,11 +94,11 @@ def test_symbols_non_existing_file(config, workspace, tmpdir) -> None: PY2 or not LINUX or not CI, reason="tested on linux and python 3 only" ) def test_symbols_all_scopes_with_jedi_environment(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) # Update config extra environment env_path = "/tmp/pyenv/bin/python" settings = {"pylsp": {"plugins": {"jedi": {"environment": env_path}}}} doc.update_config(settings) - symbols = pylsp_document_symbols(doc._config, doc) + symbols = pylsp_document_symbols(config=doc._config, document=doc) helper_check_symbols_all_scope(symbols) diff --git a/test/plugins/test_yapf_format.py b/test/plugins/test_yapf_format.py index f69541a4..00fcbfa0 100644 --- a/test/plugins/test_yapf_format.py +++ b/test/plugins/test_yapf_format.py @@ -28,28 +28,34 @@ def test_format(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) - res = pylsp_format_document(workspace, doc, None) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) + res = pylsp_format_document(workspace=workspace, document=doc, options=None) - assert apply_text_edits(doc, res) == "A = ['h', 'w', 'a']\n\nB = ['h', 'w']\n" + assert ( + apply_text_edits(doc=doc, text_edits=res) + == "A = ['h', 'w', 'a']\n\nB = ['h', 'w']\n" + ) def test_range_format(workspace) -> None: - doc = Document(DOC_URI, workspace, DOC) + doc = Document(uri=DOC_URI, workspace=workspace, source=DOC) def_range = { "start": {"line": 0, "character": 0}, "end": {"line": 4, "character": 10}, } - res = pylsp_format_range(doc, def_range, None) + res = pylsp_format_range(document=doc, range=def_range, options=None) # Make sure B is still badly formatted - assert apply_text_edits(doc, res) == "A = ['h', 'w', 'a']\n\nB = ['h',\n\n\n'w']\n" + assert ( + apply_text_edits(doc=doc, text_edits=res) + == "A = ['h', 'w', 'a']\n\nB = ['h',\n\n\n'w']\n" + ) def test_no_change(workspace) -> None: - doc = Document(DOC_URI, workspace, GOOD_DOC) - assert not pylsp_format_document(workspace, doc, options=None) + doc = Document(uri=DOC_URI, workspace=workspace, source=GOOD_DOC) + assert not pylsp_format_document(workspace=workspace, document=doc, options=None) def test_config_file(tmpdir, workspace) -> None: @@ -57,55 +63,71 @@ def test_config_file(tmpdir, workspace) -> None: conf = tmpdir.join(".style.yapf") conf.write("[style]\ncolumn_limit = 14") src = tmpdir.join("test.py") - doc = Document(uris.from_fs_path(src.strpath), workspace, DOC) + doc = Document(uri=uris.from_fs_path(src.strpath), workspace=workspace, source=DOC) - res = pylsp_format_document(workspace, doc, options=None) + res = pylsp_format_document(workspace=workspace, document=doc, options=None) # A was split on multiple lines because of column_limit from config file assert ( - apply_text_edits(doc, res) + apply_text_edits(doc=doc, text_edits=res) == "A = [\n 'h', 'w',\n 'a'\n]\n\nB = ['h', 'w']\n" ) @pytest.mark.parametrize("newline", ["\r\n"]) def test_line_endings(workspace, newline) -> None: - doc = Document(DOC_URI, workspace, f"import os;import sys{2 * newline}dict(a=1)") - res = pylsp_format_document(workspace, doc, options=None) + doc = Document( + uri=DOC_URI, + workspace=workspace, + source=f"import os;import sys{2 * newline}dict(a=1)", + ) + res = pylsp_format_document(workspace=workspace, document=doc, options=None) assert ( - apply_text_edits(doc, res) + apply_text_edits(doc=doc, text_edits=res) == f"import os{newline}import sys{2 * newline}dict(a=1){newline}" ) def test_format_with_tab_size_option(workspace) -> None: - doc = Document(DOC_URI, workspace, FOUR_SPACE_DOC) - res = pylsp_format_document(workspace, doc, {"tabSize": "8"}) + doc = Document(uri=DOC_URI, workspace=workspace, source=FOUR_SPACE_DOC) + res = pylsp_format_document( + workspace=workspace, document=doc, options={"tabSize": "8"} + ) - assert apply_text_edits(doc, res) == FOUR_SPACE_DOC.replace(" ", " ") + assert apply_text_edits(doc=doc, text_edits=res) == FOUR_SPACE_DOC.replace( + " ", " " + ) def test_format_with_insert_spaces_option(workspace) -> None: - doc = Document(DOC_URI, workspace, FOUR_SPACE_DOC) - res = pylsp_format_document(workspace, doc, {"insertSpaces": False}) + doc = Document(uri=DOC_URI, workspace=workspace, source=FOUR_SPACE_DOC) + res = pylsp_format_document( + workspace=workspace, document=doc, options={"insertSpaces": False} + ) - assert apply_text_edits(doc, res) == FOUR_SPACE_DOC.replace(" ", "\t") + assert apply_text_edits(doc=doc, text_edits=res) == FOUR_SPACE_DOC.replace( + " ", "\t" + ) def test_format_with_yapf_specific_option(workspace) -> None: - doc = Document(DOC_URI, workspace, FOUR_SPACE_DOC) - res = pylsp_format_document(workspace, doc, {"USE_TABS": True}) + doc = Document(uri=DOC_URI, workspace=workspace, source=FOUR_SPACE_DOC) + res = pylsp_format_document( + workspace=workspace, document=doc, options={"USE_TABS": True} + ) - assert apply_text_edits(doc, res) == FOUR_SPACE_DOC.replace(" ", "\t") + assert apply_text_edits(doc=doc, text_edits=res) == FOUR_SPACE_DOC.replace( + " ", "\t" + ) def test_format_returns_text_edit_per_line(workspace) -> None: single_space_indent = """def wow(): log("x") log("hi")""" - doc = Document(DOC_URI, workspace, single_space_indent) - res = pylsp_format_document(workspace, doc, options=None) + doc = Document(uri=DOC_URI, workspace=workspace, source=single_space_indent) + res = pylsp_format_document(workspace=workspace, document=doc, options=None) # two removes and two adds assert len(res) == 4 diff --git a/test/test_configuration.py b/test/test_configuration.py index e6b40121..e8450601 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -22,7 +22,9 @@ @pytest.mark.skipif(IS_WIN, reason="Flaky on Windows") def test_set_flake8_using_init_opts(client_server_pair) -> None: client, server = client_server_pair - send_initialize_request(client, INITIALIZATION_OPTIONS) + send_initialize_request( + client=client, initialization_options=INITIALIZATION_OPTIONS + ) for key, value in INITIALIZATION_OPTIONS["pylsp"]["plugins"].items(): assert server.workspace._config.settings().get("plugins").get(key).get( "enabled" @@ -34,7 +36,7 @@ def test_set_flake8_using_workspace_did_change_configuration( client_server_pair, ) -> None: client, server = client_server_pair - send_initialize_request(client, None) + send_initialize_request(client=client, initialization_options=None) assert ( server.workspace._config.settings().get("plugins").get("flake8").get("enabled") is False diff --git a/test/test_document.py b/test/test_document.py index f31d446e..d80bc727 100644 --- a/test/test_document.py +++ b/test/test_document.py @@ -16,8 +16,9 @@ def test_document_lines(doc) -> None: def test_document_source_unicode(workspace) -> None: - document_mem = Document(DOC_URI, workspace, "my source") - document_disk = Document(DOC_URI, workspace) + document_mem = Document(uri=DOC_URI, workspace=workspace, source="my source") + document_disk = Document(uri=DOC_URI, workspace=workspace) + assert isinstance(document_mem.source, type(document_disk.source)) @@ -44,7 +45,7 @@ def test_word_at_position(doc) -> None: def test_document_empty_edit(workspace) -> None: - doc = Document("file:///uri", workspace, "") + doc = Document(uri="file:///uri", workspace=workspace, source="") doc.apply_change( { "range": { @@ -58,7 +59,7 @@ def test_document_empty_edit(workspace) -> None: def test_document_line_edit(workspace) -> None: - doc = Document("file:///uri", workspace, "itshelloworld") + doc = Document(uri="file:///uri", workspace=workspace, source="itshelloworld") doc.apply_change( { "text": "goodbye", @@ -73,7 +74,7 @@ def test_document_line_edit(workspace) -> None: def test_document_multiline_edit(workspace) -> None: old = ["def hello(a, b):\n", " print a\n", " print b\n"] - doc = Document("file:///uri", workspace, "".join(old)) + doc = Document(uri="file:///uri", workspace=workspace, source="".join(old)) doc.apply_change( { "text": "print a, b", @@ -88,7 +89,7 @@ def test_document_multiline_edit(workspace) -> None: def test_document_end_of_file_edit(workspace) -> None: old = ["print 'a'\n", "print 'b'\n"] - doc = Document("file:///uri", workspace, "".join(old)) + doc = Document(uri="file:///uri", workspace=workspace, source="".join(old)) doc.apply_change( { "text": "o", diff --git a/test/test_language_server.py b/test/test_language_server.py index 9b362110..fb35c654 100644 --- a/test/test_language_server.py +++ b/test/test_language_server.py @@ -21,7 +21,9 @@ def client_exited_server() -> None: """A fixture that sets up a client/server pair that support checking parent process aliveness and assert the server has already exited """ - client_server_pair_obj = ClientServerPair(True, True) + client_server_pair_obj = ClientServerPair( + start_server_in_process=True, check_parent_process=True + ) yield client_server_pair_obj diff --git a/test/test_notebook_document.py b/test/test_notebook_document.py index ca0d477d..5459e511 100644 --- a/test/test_notebook_document.py +++ b/test/test_notebook_document.py @@ -90,7 +90,7 @@ def test_notebook_document__did_open( with patch.object(server._endpoint, "notify") as mock_notify: # Test as many edge cases as possible for the diagnostics messages send_notebook_did_open( - client, ["", "\n", "\nimport sys\n\nabc\n\n", "x", "y\n"] + client=client, cells=["", "\n", "\nimport sys\n\nabc\n\n", "x", "y\n"] ) wait_for_condition(lambda: mock_notify.call_count >= 5) expected_call_args = [ @@ -191,7 +191,7 @@ def test_notebook_document__did_change( # Open notebook with patch.object(server._endpoint, "notify") as mock_notify: - send_notebook_did_open(client, ["import sys", ""]) + send_notebook_did_open(client=client, cells=["import sys", ""]) wait_for_condition(lambda: mock_notify.call_count >= 2) assert len(server.workspace.documents) == 3 for uri in ["cell_1_uri", "cell_2_uri", "notebook_uri"]: @@ -426,7 +426,7 @@ def test_notebook__did_close( # Open notebook with patch.object(server._endpoint, "notify") as mock_notify: - send_notebook_did_open(client, ["import sys", ""]) + send_notebook_did_open(client=client, cells=["import sys", ""]) wait_for_condition(lambda: mock_notify.call_count >= 2) assert len(server.workspace.documents) == 3 for uri in ["cell_1_uri", "cell_2_uri", "notebook_uri"]: @@ -461,7 +461,7 @@ def test_notebook_definition(client_server_pair) -> None: # Open notebook with patch.object(server._endpoint, "notify") as mock_notify: - send_notebook_did_open(client, ["y=2\nx=1", "x"]) + send_notebook_did_open(client=client, cells=["y=2\nx=1", "x"]) # wait for expected diagnostics messages wait_for_condition(lambda: mock_notify.call_count >= 2) assert len(server.workspace.documents) == 3 @@ -500,7 +500,7 @@ def test_notebook_completion(client_server_pair) -> None: # Open notebook with patch.object(server._endpoint, "notify") as mock_notify: send_notebook_did_open( - client, ["answer_to_life_universe_everything = 42", "answer_"] + client=client, cells=["answer_to_life_universe_everything = 42", "answer_"] ) # wait for expected diagnostics messages wait_for_condition(lambda: mock_notify.call_count >= 2) diff --git a/test/test_text_edit.py b/test/test_text_edit.py index 1d9115bf..d7eeeb5a 100644 --- a/test/test_text_edit.py +++ b/test/test_text_edit.py @@ -13,8 +13,8 @@ def test_apply_text_edits_insert(pylsp) -> None: assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 0}, @@ -28,8 +28,8 @@ def test_apply_text_edits_insert(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 1}, @@ -43,8 +43,8 @@ def test_apply_text_edits_insert(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 1}, @@ -65,8 +65,8 @@ def test_apply_text_edits_insert(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 2}, @@ -114,8 +114,8 @@ def test_apply_text_edits_replace(pylsp) -> None: assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 3}, @@ -129,8 +129,8 @@ def test_apply_text_edits_replace(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 3}, @@ -151,8 +151,8 @@ def test_apply_text_edits_replace(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 3}, @@ -173,8 +173,8 @@ def test_apply_text_edits_replace(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 6}, @@ -195,8 +195,8 @@ def test_apply_text_edits_replace(pylsp) -> None: ) assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 3}, @@ -224,8 +224,8 @@ def test_apply_text_edits_overlap(pylsp) -> None: did_throw = False try: apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 3}, @@ -251,8 +251,8 @@ def test_apply_text_edits_overlap(pylsp) -> None: try: apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 0, "character": 3}, @@ -281,8 +281,8 @@ def test_apply_text_edits_multiline(pylsp) -> None: assert ( apply_text_edits( - test_doc, - [ + doc=test_doc, + text_edits=[ { "range": { "start": {"line": 2, "character": 0}, diff --git a/test/test_uris.py b/test/test_uris.py index 41c7f54d..cb371f0b 100644 --- a/test/test_uris.py +++ b/test/test_uris.py @@ -69,4 +69,4 @@ def test_win_from_fs_path(path, uri) -> None: ], ) def test_uri_with(uri, kwargs, new_uri) -> None: - assert uris.uri_with(uri, **kwargs) == new_uri + assert uris.uri_with(uri=uri, **kwargs) == new_uri diff --git a/test/test_utils.py b/test/test_utils.py index 07d04e34..913efb59 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -153,7 +153,7 @@ def test_debounce_keyed_by() -> None: interval = 0.1 obj = mock.Mock() - @_utils.debounce(0.1, keyed_by="key") + @_utils.debounce(interval_s=0.1, keyed_by="key") def call_m(key): obj(key) @@ -192,28 +192,28 @@ def test_find_parents(tmpdir) -> None: path = subsubdir.ensure("path.py") test_cfg = tmpdir.ensure("test.cfg") - assert _utils.find_parents(tmpdir.strpath, path.strpath, ["test.cfg"]) == [ - test_cfg.strpath - ] + assert _utils.find_parents( + root=tmpdir.strpath, path=path.strpath, names=["test.cfg"] + ) == [test_cfg.strpath] def test_merge_dicts() -> None: assert _utils.merge_dicts( - {"a": True, "b": {"x": 123, "y": {"hello": "world"}}}, - {"a": False, "b": {"y": [], "z": 987}}, + dict_a={"a": True, "b": {"x": 123, "y": {"hello": "world"}}}, + dict_b={"a": False, "b": {"y": [], "z": 987}}, ) == {"a": False, "b": {"x": 123, "y": [], "z": 987}} def test_clip_column() -> None: - assert _utils.clip_column(0, [], 0) == 0 - assert _utils.clip_column(2, ["123"], 0) == 2 - assert _utils.clip_column(3, ["123"], 0) == 3 - assert _utils.clip_column(5, ["123"], 0) == 3 - assert _utils.clip_column(0, ["\n", "123"], 0) == 0 - assert _utils.clip_column(1, ["\n", "123"], 0) == 0 - assert _utils.clip_column(2, ["123\n", "123"], 0) == 2 - assert _utils.clip_column(3, ["123\n", "123"], 0) == 3 - assert _utils.clip_column(4, ["123\n", "123"], 1) == 3 + assert _utils.clip_column(column=0, lines=[], line_number=0) == 0 + assert _utils.clip_column(column=2, lines=["123"], line_number=0) == 2 + assert _utils.clip_column(column=3, lines=["123"], line_number=0) == 3 + assert _utils.clip_column(column=5, lines=["123"], line_number=0) == 3 + assert _utils.clip_column(column=0, lines=["\n", "123"], line_number=0) == 0 + assert _utils.clip_column(column=1, lines=["\n", "123"], line_number=0) == 0 + assert _utils.clip_column(column=2, lines=["123\n", "123"], line_number=0) == 2 + assert _utils.clip_column(column=3, lines=["123\n", "123"], line_number=0) == 3 + assert _utils.clip_column(column=4, lines=["123\n", "123"], line_number=1) == 3 @mock.patch("docstring_to_markdown.convert") @@ -235,9 +235,9 @@ def test_format_docstring_valid_rst_signature(mock_convert) -> None: """ markdown = _utils.format_docstring( - docstring, - "markdown", - ["something(a: str) -> str"], + contents=docstring, + markup_kind="markdown", + signatures=["something(a: str) -> str"], )["value"] assert markdown.startswith( @@ -256,9 +256,9 @@ def test_format_docstring_invalid_rst_signature(_) -> None: """ markdown = _utils.format_docstring( - docstring, - "markdown", - ["something(a: str) -> str"], + contents=docstring, + markup_kind="markdown", + signatures=["something(a: str) -> str"], )["value"] assert markdown.startswith(