mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-14 10:19:02 +00:00
Add referenced types to facades, making result types discoverable in the REPL
Facades declare the types their methods return or contain as ReferencedTypes (with an optional
whitelist of members for curation, e.g. for LanguageServerSymbol, and a flag for inclusion in the
facade description). Type documentation is generated from class docstrings, attribute annotations,
properties and method signatures/docstrings, and is available via s.info("<facade>.<Type>") or by
bare type name; method documentation points to the documentation of a referenced return type.
Annotations are rendered without module paths, such that the names in signatures are the names by
which types can be looked up. s.info accepts several items at once, reporting unknown items inline.
All APIs declare their result types; result classes declare their attributes at class level.
This commit is contained in:
1 parent
05603b2706
commit
6cb3d37e09
11 files changed
+299
-34
No files matched your search
@@ -52,6 +52,29 @@ class TestReplExecution:
|
||||
method_info = repl.execute('s.info("lsp.find_symbol")')
|
||||
assert "name_path_pattern" in method_info
|
||||
|
||||
def test_type_discovery(self, repl: SerenaRepl) -> None:
|
||||
# signatures render type names without module paths, and point to the documentation of referenced return types
|
||||
method_info = repl.execute('s.info("lsp.find_symbol")')
|
||||
assert "-> LspSymbolCollection" in method_info and "lsp_api." not in method_info
|
||||
assert 's.info("lsp.LspSymbolCollection")' in method_info
|
||||
|
||||
# the facade description includes types declared as important in full and lists the others by name
|
||||
facade_info = repl.execute('s.info("lsp")')
|
||||
assert "type LspSymbolCollection" in facade_info and "symbols: list[LanguageServerSymbol]" in facade_info
|
||||
assert "type LanguageServerSymbol" not in facade_info and "LanguageServerSymbol" in facade_info
|
||||
|
||||
# types can be requested via the facade or by bare name, and their curated members are documented
|
||||
type_info = repl.execute('s.info("lsp.LanguageServerSymbol")')
|
||||
assert type_info == repl.execute('s.info("LanguageServerSymbol")')
|
||||
assert "get_name_path() -> str" in type_info and "iter_children()" in type_info
|
||||
assert "to_dict" not in type_info # not among the curated members
|
||||
assert "represent" not in repl.execute('s.info("LspSymbolCollection")') # the representation mechanism is not exposed
|
||||
|
||||
def test_info_documents_several_items(self, repl: SerenaRepl) -> None:
|
||||
info = repl.execute('s.info("lsp.find_symbol", "nope", "lsp.LspSymbolCollection")')
|
||||
assert "lsp.find_symbol(" in info and "type LspSymbolCollection" in info
|
||||
assert "Unknown item 'nope'" in info # an unknown item does not prevent the documentation of the others
|
||||
|
||||
|
||||
class TestFacade:
|
||||
"""Tests the indirection between facades and their implementations."""
|
||||
@@ -131,7 +154,7 @@ class TestFacade:
|
||||
facade = Facade.from_api(self.DummyApi(MagicMock()), ApiScope())
|
||||
assert facade.add(1, 2) == 3
|
||||
assert "dummy.add(a: int, b: int) -> int" in facade.describe()
|
||||
assert "Adds two numbers." in facade.describe_method("add")
|
||||
assert "Adds two numbers." in facade.describe_member("add")
|
||||
|
||||
def test_disabled_methods_are_inaccessible_and_undocumented(self) -> None:
|
||||
facade = Facade.from_api(self.DummyApi(MagicMock()), self._scope(excluded_apis=["dummy.secret"]))
|
||||
@@ -139,7 +162,7 @@ class TestFacade:
|
||||
with pytest.raises(AttributeError):
|
||||
facade.secret()
|
||||
with pytest.raises(ValueError):
|
||||
facade.describe_method("secret")
|
||||
facade.describe_member("secret")
|
||||
assert "secret" not in facade.describe()
|
||||
assert "_internal" not in facade.describe()
|
||||
|
||||
|
||||
Reference in new issue
Block a user