From be1d23e7e5472e8e27a9e24c6e92f1f2c53d5626 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 18 Dec 2025 11:31:43 +0100 Subject: [PATCH 1/2] Restore atheris stubs This reverts commit 106078c377c4d2be9d5c4fb07dd4d756aeb8122a. --- stubs/atheris/METADATA.toml | 11 ++++++ 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, 122 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 000000000000..a1ca99265ab2 --- /dev/null +++ b/stubs/atheris/METADATA.toml @@ -0,0 +1,11 @@ +version = "2.3.*" +upstream_repository = "https://github.com/google/atheris" +partial_stub = true +no_longer_updated = true + +[tool.stubtest] +ignore_missing_stub = true +# TODO (2025-03-05): unskip once `atheris` can be installed on `ubuntu-24.04`, +# see https://github.com/python/typeshed/pull/13582 and +# https://github.com/google/atheris/issues/82 +skip = true diff --git a/stubs/atheris/atheris/__init__.pyi b/stubs/atheris/atheris/__init__.pyi new file mode 100644 index 000000000000..2a3312448ab0 --- /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 000000000000..92ec044b7f0f --- /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 000000000000..450923a31de9 --- /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 000000000000..b6b935fd1c3b --- /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 000000000000..090c833ddb1a --- /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 000000000000..51c1d2060567 --- /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: ... From b98c5cf69d96ef181908b36247bc8f3a4f9fc0c7 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 18 Dec 2025 14:01:38 +0100 Subject: [PATCH 2/2] Remove no_longer_updated Co-authored-by: Alex Waygood --- stubs/atheris/METADATA.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/stubs/atheris/METADATA.toml b/stubs/atheris/METADATA.toml index a1ca99265ab2..2fe88957c58a 100644 --- a/stubs/atheris/METADATA.toml +++ b/stubs/atheris/METADATA.toml @@ -1,7 +1,6 @@ version = "2.3.*" upstream_repository = "https://github.com/google/atheris" partial_stub = true -no_longer_updated = true [tool.stubtest] ignore_missing_stub = true