From 4109c06d07ce3e79d8c5146665c34fdb8cc8c734 Mon Sep 17 00:00:00 2001 From: Andrew Murray <3112309+radarhere@users.noreply.github.com> Date: Fri, 30 Aug 2024 22:36:34 +1000 Subject: [PATCH] Added types for atheris (#12462) --- stubs/atheris/METADATA.toml | 6 ++++ stubs/atheris/atheris/__init__.pyi | 9 +++++ stubs/atheris/atheris/function_hooks.pyi | 14 ++++++++ stubs/atheris/atheris/import_hook.pyi | 36 +++++++++++++++++++ stubs/atheris/atheris/instrument_bytecode.pyi | 7 ++++ stubs/atheris/atheris/utils.pyi | 18 ++++++++++ stubs/atheris/atheris/version_dependent.pyi | 27 ++++++++++++++ 7 files changed, 117 insertions(+) create mode 100644 stubs/atheris/METADATA.toml create mode 100644 stubs/atheris/atheris/__init__.pyi create mode 100644 stubs/atheris/atheris/function_hooks.pyi create mode 100644 stubs/atheris/atheris/import_hook.pyi create mode 100644 stubs/atheris/atheris/instrument_bytecode.pyi create mode 100644 stubs/atheris/atheris/utils.pyi create mode 100644 stubs/atheris/atheris/version_dependent.pyi diff --git a/stubs/atheris/METADATA.toml b/stubs/atheris/METADATA.toml new file mode 100644 index 000000000..5a014d0c8 --- /dev/null +++ b/stubs/atheris/METADATA.toml @@ -0,0 +1,6 @@ +version = "2.3.*" +upstream_repository = "https://github.com/google/atheris" +partial_stub = true + +[tool.stubtest] +ignore_missing_stub = true diff --git a/stubs/atheris/atheris/__init__.pyi b/stubs/atheris/atheris/__init__.pyi new file mode 100644 index 000000000..2a3312448 --- /dev/null +++ b/stubs/atheris/atheris/__init__.pyi @@ -0,0 +1,9 @@ +from collections.abc import Callable + +def Setup( + args: list[str], + test_one_input: Callable[[bytes], None], + **kwargs: bool | Callable[[bytes, int, int], str | bytes] | Callable[[bytes, bytes, int, int], str | bytes] | None, +) -> list[str]: ... +def Fuzz() -> None: ... +def Mutate(data: bytes, max_size: int) -> bytes: ... diff --git a/stubs/atheris/atheris/function_hooks.pyi b/stubs/atheris/atheris/function_hooks.pyi new file mode 100644 index 000000000..92ec044b7 --- /dev/null +++ b/stubs/atheris/atheris/function_hooks.pyi @@ -0,0 +1,14 @@ +from typing import Any + +def hook_re_module() -> None: ... + +class EnabledHooks: + def __init__(self) -> None: ... + def add(self, hook: str) -> None: ... + def __contains__(self, hook: str) -> bool: ... + +enabled_hooks: EnabledHooks + +# args[1] is an arbitrary string method that is called +# with the subsequent arguments, so they will vary +def _hook_str(*args: Any, **kwargs: Any) -> bool: ... diff --git a/stubs/atheris/atheris/import_hook.pyi b/stubs/atheris/atheris/import_hook.pyi new file mode 100644 index 000000000..450923a31 --- /dev/null +++ b/stubs/atheris/atheris/import_hook.pyi @@ -0,0 +1,36 @@ +import types +from collections.abc import Sequence +from importlib import abc, machinery +from typing_extensions import Self + +def _should_skip(loader: abc.Loader) -> bool: ... + +class AtherisMetaPathFinder(abc.MetaPathFinder): + def __init__( + self, include_packages: set[str], exclude_modules: set[str], enable_loader_override: bool, trace_dataflow: bool + ) -> None: ... + def find_spec( + self, fullname: str, path: Sequence[str] | None, target: types.ModuleType | None = None + ) -> machinery.ModuleSpec | None: ... + def invalidate_caches(self) -> None: ... + +class AtherisSourceFileLoader: + def __init__(self, name: str, path: str, trace_dataflow: bool) -> None: ... + def get_code(self, fullname: str) -> types.CodeType | None: ... + +class AtherisSourcelessFileLoader: + def __init__(self, name: str, path: str, trace_dataflow: bool) -> None: ... + def get_code(self, fullname: str) -> types.CodeType | None: ... + +def make_dynamic_atheris_loader(loader: abc.Loader | type[abc.Loader], trace_dataflow: bool) -> abc.Loader: ... + +class HookManager: + def __init__( + self, include_packages: set[str], exclude_modules: set[str], enable_loader_override: bool, trace_dataflow: bool + ) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *args: object) -> None: ... + +def instrument_imports( + include: Sequence[str] | None = None, exclude: Sequence[str] | None = None, enable_loader_override: bool = True +) -> HookManager: ... diff --git a/stubs/atheris/atheris/instrument_bytecode.pyi b/stubs/atheris/atheris/instrument_bytecode.pyi new file mode 100644 index 000000000..b6b935fd1 --- /dev/null +++ b/stubs/atheris/atheris/instrument_bytecode.pyi @@ -0,0 +1,7 @@ +from collections.abc import Callable +from typing import TypeVar + +_T = TypeVar("_T") + +def instrument_func(func: Callable[..., _T]) -> Callable[..., _T]: ... +def instrument_all() -> None: ... diff --git a/stubs/atheris/atheris/utils.pyi b/stubs/atheris/atheris/utils.pyi new file mode 100644 index 000000000..090c833dd --- /dev/null +++ b/stubs/atheris/atheris/utils.pyi @@ -0,0 +1,18 @@ +from typing import Protocol, type_check_only + +def path() -> str: ... +@type_check_only +class _Writer(Protocol): + def isatty(self) -> bool: ... + def write(self, content: str, /) -> object: ... + def flush(self) -> object: ... + +class ProgressRenderer: + def __init__(self, stream: _Writer, total_count: int) -> None: ... + def render(self) -> None: ... + def erase(self) -> None: ... + def drop(self) -> None: ... + @property + def count(self) -> int: ... + @count.setter + def count(self, new_count: int) -> None: ... diff --git a/stubs/atheris/atheris/version_dependent.pyi b/stubs/atheris/atheris/version_dependent.pyi new file mode 100644 index 000000000..51c1d2060 --- /dev/null +++ b/stubs/atheris/atheris/version_dependent.pyi @@ -0,0 +1,27 @@ +import types +from typing import Final + +PYTHON_VERSION: Final[tuple[int, int]] +CONDITIONAL_JUMPS: Final[list[str]] +UNCONDITIONAL_JUMPS: Final[list[str]] +ENDS_FUNCTION: Final[list[str]] +HAVE_REL_REFERENCE: Final[list[str]] +HAVE_ABS_REFERENCE: Final[list[str]] +REL_REFERENCE_IS_INVERTED: Final[list[str]] + +def rel_reference_scale(opname: str) -> int: ... + +REVERSE_CMP_OP: Final[list[int]] + +def jump_arg_bytes(arg: int) -> int: ... +def add_bytes_to_jump_arg(arg: int, size: int) -> int: ... + +class ExceptionTableEntry: + def __init__(self, start_offset: int, end_offset: int, target: int, depth: int, lasti: bool) -> None: ... + def __eq__(self, other: object) -> bool: ... + +class ExceptionTable: + def __init__(self, entries: list[ExceptionTableEntry]) -> None: ... + def __eq__(self, other: object) -> bool: ... + +def generate_exceptiontable(original_code: types.CodeType, exception_table_entries: list[ExceptionTableEntry]) -> bytes: ...