jedi: fix completion of builtin types

Completions for `x.` where `x` is an instance of a builtin type was
broken because of filtering on the `builtins` modules. This extends
the filtering to allow attributes available on common builtin types
in Pybricks MicroPython.
This commit is contained in:
David Lechner
2022-12-28 15:33:33 -06:00
parent 236bda5f31
commit 8ee725722f
3 changed files with 291 additions and 84 deletions
+3
View File
@@ -4,6 +4,9 @@
## Unreleased
### Fixed
- Fixed code completion for builtin types.
## 1.6.0 - 2022-12-09
### Changed
+146 -84
View File
@@ -31,88 +31,147 @@ PYBRICKS_CODE_PACKAGES = {
# Subset of Python builtins included in Pybricks MicroPython.
PYBRICKS_BUILTINS = {
"abs",
"all",
"any",
"ArithmeticError",
"AssertionError",
"AttributeError",
"BaseException",
"bin",
"bool",
"bytearray",
"bytes",
"callable",
"chr",
"classmethod",
"complex",
"dict",
"dir",
"divmod",
"enumerate",
"EOFError",
"eval",
"Exception",
"exec",
"float",
"GeneratorExit",
"getattr",
"globals",
"hasattr",
"hash",
"help",
"hex",
"id",
"ImportError",
"IndentationError",
"IndexError",
"input",
"int",
"isinstance",
"issubclass",
"iter",
"KeyboardInterrupt",
"KeyError",
"len",
"list",
"locals",
"LookupError",
"map",
"max",
"MemoryError",
"min",
"NameError",
"next",
"NotImplementedError",
"object",
"oct",
"ord",
"OSError",
"OverflowError",
"pow",
"print",
"range",
"repr",
"reversed",
"round",
"RuntimeError",
"set",
"setattr",
"slice",
"sorted",
"staticmethod",
"StopIteration",
"str",
"sum",
"super",
"SyntaxError",
"SystemExit",
"tuple",
"type",
"TypeError",
"ValueError",
"ZeroDivisionError",
"zip",
"builtins.abs",
"builtins.all",
"builtins.any",
"builtins.ArithmeticError",
"builtins.AssertionError",
"builtins.AttributeError",
"builtins.BaseException",
"builtins.bin",
"builtins.bool",
"builtins.bytearray",
"builtins.bytes",
"builtins.callable",
"builtins.chr",
"builtins.classmethod",
"builtins.complex",
"builtins.dict",
"builtins.dir",
"builtins.divmod",
"builtins.enumerate",
"builtins.EOFError",
"builtins.eval",
"builtins.Exception",
"builtins.exec",
"builtins.float",
"builtins.GeneratorExit",
"builtins.getattr",
"builtins.globals",
"builtins.hasattr",
"builtins.hash",
"builtins.help",
"builtins.hex",
"builtins.id",
"builtins.ImportError",
"builtins.IndentationError",
"builtins.IndexError",
"builtins.input",
"builtins.int",
"builtins.isinstance",
"builtins.issubclass",
"builtins.iter",
"builtins.KeyboardInterrupt",
"builtins.KeyError",
"builtins.len",
"builtins.list",
"builtins.locals",
"builtins.LookupError",
"builtins.map",
"builtins.max",
"builtins.MemoryError",
"builtins.min",
"builtins.NameError",
"builtins.next",
"builtins.NotImplementedError",
"builtins.object",
"builtins.oct",
"builtins.ord",
"builtins.OSError",
"builtins.OverflowError",
"builtins.pow",
"builtins.print",
"builtins.range",
"builtins.repr",
"builtins.reversed",
"builtins.round",
"builtins.RuntimeError",
"builtins.set",
"builtins.setattr",
"builtins.slice",
"builtins.sorted",
"builtins.staticmethod",
"builtins.StopIteration",
"builtins.str",
"builtins.sum",
"builtins.super",
"builtins.SyntaxError",
"builtins.SystemExit",
"builtins.tuple",
"builtins.type",
"builtins.TypeError",
"builtins.ValueError",
"builtins.ZeroDivisionError",
"builtins.zip",
"builtins.bytearray.append",
"builtins.bytearray.extend",
"builtins.dict.clear",
"builtins.dict.copy",
"builtins.dict.fromkeys",
"builtins.dict.get",
"builtins.dict.items",
"builtins.dict.keys",
"builtins.dict.pop",
"builtins.dict.popitem",
"builtins.dict.setdefault",
"builtins.dict.update",
"builtins.dict.values",
"builtins.int.from_bytes",
"builtins.int.to_bytes",
"builtins.list.append",
"builtins.list.clear",
"builtins.list.copy",
"builtins.list.count",
"builtins.list.extend",
"builtins.list.index",
"builtins.list.insert",
"builtins.list.pop",
"builtins.list.remove",
"builtins.list.reverse",
"builtins.list.sort",
"builtins.str.count",
"builtins.str.endswith",
"builtins.str.find",
"builtins.str.format",
"builtins.str.index",
"builtins.str.isalpha",
"builtins.str.isdigit",
"builtins.str.islower",
"builtins.str.isspace",
"builtins.str.isupper",
"builtins.str.join",
"builtins.str.lower",
"builtins.str.lstrip",
"builtins.str.replace",
"builtins.str.rfind",
"builtins.str.rindex",
"builtins.str.rsplit",
"builtins.str.rstrip",
"builtins.str.split",
"builtins.str.startswith",
"builtins.str.strip",
"builtins.str.upper",
"builtins.tuple.count",
"builtins.tuple.index",
}
PYBRICKS_BUILTINS_NO_FULLNAME = {"items", "values"}
PYBRICKS_TYPING = {
"typing.MutableSequence.append",
"typing.MutableSequence.extend",
"typing.MutableMapping.pop",
"typing.Mapping.get",
}
# Types from monaco editor
@@ -256,7 +315,7 @@ def _is_pybricks(c: Completion) -> bool:
return False
# filter out typing types
if c.full_name.startswith("typing."):
if c.full_name.startswith("typing.") and c.full_name not in PYBRICKS_TYPING:
return False
# filter out packages/modules that are not included in Pybricks firmware
@@ -265,7 +324,10 @@ def _is_pybricks(c: Completion) -> bool:
# filter subset of builtins
if c.module_name == "builtins" and c.type != "keyword":
return c.name in PYBRICKS_BUILTINS
if c.full_name is None:
return c.name in PYBRICKS_BUILTINS_NO_FULLNAME
return c.full_name in PYBRICKS_BUILTINS
# this is a type alias, not a real type
if c.full_name == "pybricks.parameters.Number":
+142
View File
@@ -7,6 +7,9 @@ Tests for correct code completion of builtins.
import json
import pytest
from pybricks_jedi import CompletionItem, complete
@@ -124,3 +127,142 @@ def test_empty_code():
"ZeroDivisionError",
"zip",
]
FUNCTION_PARAMS = [
pytest.param(
"''.",
[
"count",
"endswith",
"find",
"format",
"index",
"isalpha",
"isdigit",
"islower",
"isspace",
"isupper",
"join",
"lower",
"lstrip",
"replace",
"rfind",
"rindex",
"rsplit",
"rstrip",
"split",
"startswith",
"strip",
"upper",
],
),
pytest.param(
"str().",
[
"count",
"endswith",
"find",
"format",
"index",
"isalpha",
"isdigit",
"islower",
"isspace",
"isupper",
"join",
"lower",
"lstrip",
"replace",
"rfind",
"rindex",
"rsplit",
"rstrip",
"split",
"startswith",
"strip",
"upper",
],
),
pytest.param("(0).", ["from_bytes", "to_bytes"]),
pytest.param("int().", ["from_bytes", "to_bytes"]),
pytest.param(
"{}.",
[
"clear",
"copy",
"fromkeys",
"get",
"items",
"keys",
"pop",
"popitem",
"setdefault",
"update",
"values",
],
),
pytest.param(
"dict().",
[
"clear",
"copy",
"fromkeys",
"get",
"items",
"keys",
"pop",
"popitem",
"setdefault",
"update",
"values",
],
),
pytest.param(
"[].",
[
"append",
"clear",
"copy",
"count",
"extend",
"index",
"insert",
"pop",
"remove",
"reverse",
"sort",
],
),
pytest.param(
"list().",
[
"append",
"clear",
"copy",
"count",
"extend",
"index",
"insert",
"pop",
"remove",
"reverse",
"sort",
],
),
pytest.param("().", ["count", "index"]),
pytest.param("tuple().", ["count", "index"]),
pytest.param("bytearray().", ["append", "extend"]),
pytest.param("bytes().", []),
pytest.param("b''.", []),
pytest.param("float().", []),
pytest.param("(0.0).", []),
pytest.param("complex().", []),
pytest.param("type().", []),
]
@pytest.mark.parametrize("code,attributes", FUNCTION_PARAMS)
def test_get_completion_for_builtins(code: str, attributes: list[str]):
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == attributes