From 55b552121b38947a76e2f3cf70b5f69a410da98e Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Sat, 18 May 2024 13:26:17 +0100 Subject: [PATCH] Fix type of Docker BuildError.build_log (#11917) In working this out I also had a go at changing the json_stream functions used to create every BuildError in docker-py. There are two `BuildError`s raised in docker-py, both in https://github.com/docker/docker-py/blob/b6464dbed92b14b2c61d5ee49805fce041a3e083/docker/models/images.py#L304-L315 ```python result_stream, internal_stream = itertools.tee(json_stream(resp)) for chunk in internal_stream: if 'error' in chunk: raise BuildError(chunk['error'], result_stream) if 'stream' in chunk: match = re.search( r'(^Successfully built |sha256:)([0-9a-f]+)$', chunk['stream'] ) if match: image_id = match.group(2) last_event = chunk if image_id: return (self.get(image_id), result_stream) raise BuildError(last_event or 'Unknown', result_stream) ``` --- stubs/docker/docker/errors.pyi | 6 +++--- stubs/docker/docker/utils/json_stream.pyi | 24 +++++++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/stubs/docker/docker/errors.pyi b/stubs/docker/docker/errors.pyi index fa443f0ff..49e229002 100644 --- a/stubs/docker/docker/errors.pyi +++ b/stubs/docker/docker/errors.pyi @@ -1,5 +1,5 @@ from _typeshed import Incomplete -from collections.abc import Mapping +from collections.abc import Iterator, Mapping from typing import NoReturn from docker.models.containers import Container @@ -47,8 +47,8 @@ class StreamParseError(RuntimeError): class BuildError(DockerException): msg: str - build_log: str - def __init__(self, reason: str, build_log: str) -> None: ... + build_log: Iterator[dict[str, str]] + def __init__(self, reason: str, build_log: Iterator[dict[str, str]]) -> None: ... class ImageLoadError(DockerException): ... diff --git a/stubs/docker/docker/utils/json_stream.pyi b/stubs/docker/docker/utils/json_stream.pyi index a5c4ce401..39ddd9d18 100644 --- a/stubs/docker/docker/utils/json_stream.pyi +++ b/stubs/docker/docker/utils/json_stream.pyi @@ -1,10 +1,18 @@ -from _typeshed import Incomplete -from collections.abc import Generator +import json +from collections.abc import Callable, Generator, Iterator +from typing import Any +from typing_extensions import TypeAlias -json_decoder: Incomplete +json_decoder: json.JSONDecoder -def stream_as_text(stream) -> Generator[Incomplete, None, None]: ... -def json_splitter(buffer): ... -def json_stream(stream): ... -def line_splitter(buffer, separator: str = "\n"): ... -def split_buffer(stream, splitter: Incomplete | None = None, decoder=...) -> Generator[Incomplete, None, Incomplete]: ... +# Type alias for JSON, explained at: +# https://github.com/python/typing/issues/182#issuecomment-1320974824. +_JSON: TypeAlias = dict[str, _JSON] | list[_JSON] | str | int | float | bool | None + +def stream_as_text(stream: Iterator[str | bytes]) -> Generator[str, None, None]: ... +def json_splitter(buffer: str) -> tuple[_JSON, str] | None: ... +def json_stream(stream: Iterator[str]) -> Generator[_JSON, None, None]: ... +def line_splitter(buffer: str, separator: str = "\n") -> tuple[str, str] | None: ... +def split_buffer( + stream: Iterator[str | bytes], splitter: Callable[[str], tuple[str, str]] | None = None, decoder: Callable[[str], Any] = ... +) -> Generator[Any, None, None]: ...