diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ac544f4..e1a362d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -136,6 +136,9 @@ jobs: - name: Run tests run: pytest --tb=native test + + - name: Validate stubs + run: python -m mypy.stubtest --allowlist stubtest-allowlist.txt starlark - name: Run example run: | diff --git a/requirements-dev.txt b/requirements-dev.txt index 8166989..0ea4b66 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,6 @@ maturin pytest +mypy sphinx sphinx-copybutton diff --git a/starlark.pyi b/starlark.pyi new file mode 100644 index 0000000..8802cac --- /dev/null +++ b/starlark.pyi @@ -0,0 +1,108 @@ +from typing import Any, Callable, Optional, final + +@final +class ResolvedPos: + line: int + column: int + +@final +class ResolvedSpan: + begin: ResolvedPos + end: ResolvedPos + +@final +class ResolvedFileSpan: + file: str + span: ResolvedSpan + +class StarlarkError(Exception): ... + +@final +class EvalSeverity: + Error: EvalSeverity + Warning: EvalSeverity + Advice: EvalSeverity + Disabled: EvalSeverity + +@final +class Lint: + resolved_location: ResolvedFileSpan + short_name: str + severity: EvalSeverity + problem: str + original: str + +@final +class DialectTypes: + DISABLE: DialectTypes + PARSE_ONLY: DialectTypes + ENABLE: DialectTypes + +@final +class Dialect: + enable_def: bool + enable_lambda: bool + enable_load: bool + enable_keyword_only_arguments: bool + enable_types: DialectTypes + enable_load_reexport: bool + enable_top_level_stmt: bool + enable_f_strings: bool + + @staticmethod + def standard() -> "Dialect": ... + @staticmethod + def extended() -> "Dialect": ... + +@final +class AstModule: + def lint(self) -> list[Lint]: ... + +@final +class LibraryExtension: + StructType: LibraryExtension + RecordType: LibraryExtension + EnumType: LibraryExtension + Map: LibraryExtension + Filter: LibraryExtension + Partial: LibraryExtension + ExperimentalRegex: LibraryExtension + Debug: LibraryExtension + Print: LibraryExtension + Pprint: LibraryExtension + Breakpoint: LibraryExtension + Json: LibraryExtension + Typing: LibraryExtension + Internal: LibraryExtension + CallStack: LibraryExtension + +@final +class Globals: + @staticmethod + def standard() -> "Globals": ... + @staticmethod + def extended_by(extensions: list[LibraryExtension]) -> "Globals": ... + +@final +class FrozenModule: ... + +@final +class Module: + def __getitem__(self, key: str, /) -> Any: ... + def __setitem__(self, key: str, value: Any, /) -> None: ... + def add_callable(self, name: str, callable: Callable) -> None: ... + def freeze(self) -> FrozenModule: ... + +@final +class FileLoader: + def __init__(self, load_func: Callable[[str], FrozenModule]) -> None: ... + +def parse( + filename: str, content: str, dialect: Optional[Dialect] = None +) -> AstModule: ... +def eval( + module: Module, + ast: AstModule, + globals: Globals, + file_loader: Optional[FileLoader] = None, +) -> object: ... diff --git a/stubtest-allowlist.txt b/stubtest-allowlist.txt new file mode 100644 index 0000000..784aa2f --- /dev/null +++ b/stubtest-allowlist.txt @@ -0,0 +1 @@ +starlark.starlark \ No newline at end of file