diff --git a/pylsp/plugins/symbols.py b/pylsp/plugins/symbols.py index 4e1890c1..3a7beb07 100644 --- a/pylsp/plugins/symbols.py +++ b/pylsp/plugins/symbols.py @@ -2,6 +2,7 @@ # Copyright 2021- Python Language Server Contributors. import logging +import re from pathlib import Path from pylsp import hookimpl @@ -19,6 +20,9 @@ def pylsp_document_symbols(config, document): symbols = [] exclude = set({}) redefinitions = {} + pattern_import = re.compile( + r"^\s*(?!#)\s*(from\s+[.\w]+(\.[\w]+)*\s+import\s+[\w\s,()*]+|import\s+[\w\s,.*]+)" + ) while definitions != []: d = definitions.pop(0) @@ -27,7 +31,8 @@ def pylsp_document_symbols(config, document): if not add_import_symbols: # Skip if there's an import in the code the symbol is defined. code = d.get_line_code() - if " import " in code or "import " in code: + + if pattern_import.match(code): continue # Skip imported symbols comparing module names. diff --git a/test/plugins/test_symbols.py b/test/plugins/test_symbols.py index c00ab935..242a38a1 100644 --- a/test/plugins/test_symbols.py +++ b/test/plugins/test_symbols.py @@ -30,6 +30,17 @@ def main(x): """ +DOC_IMPORTS = """from . import something +from ..module import something +from module import (a, b) + +def main(): + # import ignored + print("from module import x") # string with import + return something + +""" + def helper_check_symbols_all_scope(symbols): # All eight symbols (import sys, a, B, __init__, x, y, main, y) @@ -73,6 +84,24 @@ def sym(name): assert sym("main")["location"]["range"]["end"] == {"line": 12, "character": 0} +def test_symbols_complex_imports(config, workspace): + doc = Document(DOC_URI, workspace, DOC_IMPORTS) + config.update({"plugins": {"jedi_symbols": {"all_scopes": False}}}) + symbols = pylsp_document_symbols(config, doc) + + import_symbols = [s for s in symbols if s["kind"] == SymbolKind.Module] + + assert len(import_symbols) == 4 + + names = [s["name"] for s in import_symbols] + assert "something" in names + assert "a" in names or "b" in names + + assert any( + s["name"] == "main" and s["kind"] == SymbolKind.Function for s in symbols + ) + + def test_symbols_all_scopes(config, workspace) -> None: doc = Document(DOC_URI, workspace, DOC) symbols = pylsp_document_symbols(config, doc)