From 4c94f8df88d103bea43693fd3bc689f0d7a2a422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Fern=C3=A1ndez=20Iglesias?= Date: Tue, 25 Nov 2025 16:37:06 +0100 Subject: [PATCH 1/3] [docker-py] Add some missing types - `Container` - `ContainerCollection` - `ExecApiMixin` --- stubs/docker/docker/api/exec_api.pyi | 81 ++++++++++++++++++++--- stubs/docker/docker/models/containers.pyi | 37 ++++++----- 2 files changed, 94 insertions(+), 24 deletions(-) diff --git a/stubs/docker/docker/api/exec_api.pyi b/stubs/docker/docker/api/exec_api.pyi index 60a3e4682c35..8289eab04419 100644 --- a/stubs/docker/docker/api/exec_api.pyi +++ b/stubs/docker/docker/api/exec_api.pyi @@ -1,3 +1,11 @@ +from _io import _BufferedReaderStream +from _typeshed import Incomplete +from socket import SocketIO +from typing import Literal, overload + +from docker.transport.sshconn import SSHSocket +from docker.types.daemon import CancellableStream + class ExecApiMixin: def exec_create( self, @@ -9,12 +17,69 @@ class ExecApiMixin: tty: bool = False, privileged: bool = False, user: str = "", - environment=None, - workdir=None, - detach_keys=None, - ): ... - def exec_inspect(self, exec_id): ... - def exec_resize(self, exec_id, height=None, width=None) -> None: ... + environment: dict[str, str] | list[str] | None = None, + workdir: str | None = None, + detach_keys: str | None = None, + ) -> dict[str, Incomplete]: ... + def exec_inspect(self, exec_id: str) -> dict[str, Incomplete]: ... + def exec_resize(self, exec_id: str, height: int | None = None, width: int | None = None) -> None: ... + @overload def exec_start( - self, exec_id, detach: bool = False, tty: bool = False, stream: bool = False, socket: bool = False, demux: bool = False - ): ... + self, + exec_id: str, + detach: Literal[True] = ..., + tty: bool = False, + stream: bool = False, + socket: bool = False, + demux: bool = False, + ) -> str: ... + @overload + def exec_start( + self, + exec_id: str, + detach: Literal[False] = False, + tty: bool = False, + stream: bool = False, + socket: Literal[True] = ..., + demux: bool = False, + ) -> SocketIO | _BufferedReaderStream | SSHSocket: ... + @overload + def exec_start( + self, + exec_id: str, + detach: Literal[False] = False, + tty: bool = False, + stream: Literal[True] = ..., + socket: Literal[False] = False, + demux: Literal[True] = ..., + ) -> CancellableStream[tuple[str | None, str | None]]: ... + @overload + def exec_start( + self, + exec_id: str, + detach: bool = False, + tty: bool = False, + stream: Literal[True] = ..., + socket: bool = False, + demux: bool = False, + ) -> CancellableStream[str]: ... + @overload + def exec_start( + self, + exec_id: str, + detach: bool = False, + tty: bool = False, + stream: bool = False, + socket: bool = False, + demux: Literal[True] = ..., + ) -> tuple[str | None, str | None]: ... + @overload + def exec_start( + self, + exec_id: str, + detach: bool = False, + tty: bool = False, + stream: bool = False, + socket: bool = False, + demux: bool = False, + ) -> str: ... diff --git a/stubs/docker/docker/models/containers.pyi b/stubs/docker/docker/models/containers.pyi index 7b12e2403bed..67097d2cc6bd 100644 --- a/stubs/docker/docker/models/containers.pyi +++ b/stubs/docker/docker/models/containers.pyi @@ -1,10 +1,13 @@ import datetime +from _io import _BufferedReaderStream from _typeshed import Incomplete -from collections.abc import Iterable, Mapping +from collections.abc import Iterable, Iterator, Mapping +from socket import SocketIO from typing import Literal, NamedTuple, TypedDict, overload, type_check_only from typing_extensions import NotRequired from docker._types import ContainerWeightDevice, WaitContainerResponse +from docker.transport.sshconn import SSHSocket from docker.types import EndpointConfig from docker.types.containers import DeviceRequest, LogConfig, Ulimit from docker.types.daemon import CancellableStream @@ -36,10 +39,12 @@ class Container(Model): def health(self) -> str: ... @property def ports(self) -> dict[Incomplete, Incomplete]: ... - def attach(self, **kwargs): ... - def attach_socket(self, **kwargs): ... - def commit(self, repository: str | None = None, tag: str | None = None, **kwargs): ... - def diff(self): ... + def attach( + self, **kwargs + ) -> str | tuple[str | None, str | None] | CancellableStream[str] | CancellableStream[tuple[str | None, str | None]]: ... + def attach_socket(self, **kwargs) -> SocketIO | _BufferedReaderStream | SSHSocket: ... + def commit(self, repository: str | None = None, tag: str | None = None, **kwargs) -> Image: ... + def diff(self) -> list[dict[str, Incomplete]]: ... def exec_run( self, cmd: str | list[str], @@ -52,15 +57,15 @@ class Container(Model): detach: bool = False, stream: bool = False, socket: bool = False, - environment=None, - workdir=None, + environment: dict[str, str] | list[str] | None = None, + workdir: str | None = None, demux: bool = False, ) -> ExecResult: ... def export(self, chunk_size: int | None = 2097152) -> str: ... def get_archive( self, path: str, chunk_size: int | None = 2097152, encode_stream: bool = False ) -> tuple[Incomplete, Incomplete]: ... - def kill(self, signal=None): ... + def kill(self, signal: str | int | None = None) -> None: ... @overload def logs( self, @@ -90,14 +95,14 @@ class Container(Model): def pause(self) -> None: ... def put_archive(self, path: str, data) -> bool: ... def remove(self, *, v: bool = False, link: bool = False, force: bool = False) -> None: ... - def rename(self, name: str): ... - def resize(self, height: int, width: int): ... - def restart(self, *, timeout: float | None = 10): ... + def rename(self, name: str) -> None: ... + def resize(self, height: int, width: int) -> None: ... + def restart(self, *, timeout: float | None = 10) -> None: ... def start(self) -> None: ... - def stats(self, **kwargs): ... + def stats(self, **kwargs) -> Iterator[dict[str, Incomplete]] | dict[str, Incomplete]: ... def stop(self, *, timeout: float | None = None) -> None: ... def top(self, *, ps_args: str | None = None) -> _TopResult: ... - def unpause(self): ... + def unpause(self) -> None: ... def update( self, *, @@ -405,13 +410,13 @@ class ContainerCollection(Collection[Container]): self, all: bool = False, before: str | None = None, - filters=None, + filters: dict[str, Incomplete] | None = None, limit: int = -1, since: str | None = None, sparse: bool = False, ignore_removed: bool = False, - ): ... - def prune(self, filters=None): ... + ) -> list[Container]: ... + def prune(self, filters: dict[str, Incomplete] | None = None) -> dict[str, Incomplete]: ... RUN_CREATE_KWARGS: list[str] RUN_HOST_CONFIG_KWARGS: list[str] From 14adf686f951db2ae4b6da06976e40a3b0656c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Fern=C3=A1ndez=20Iglesias?= Date: Wed, 26 Nov 2025 21:11:35 +0100 Subject: [PATCH 2/3] [docker-py] Fix `ExecApiMixin.exec_start` overloads --- stubs/docker/docker/api/exec_api.pyi | 64 +++++++++++++++++++++------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/stubs/docker/docker/api/exec_api.pyi b/stubs/docker/docker/api/exec_api.pyi index 8289eab04419..0fa2631cd5ed 100644 --- a/stubs/docker/docker/api/exec_api.pyi +++ b/stubs/docker/docker/api/exec_api.pyi @@ -27,59 +27,91 @@ class ExecApiMixin: def exec_start( self, exec_id: str, - detach: Literal[True] = ..., + detach: Literal[True], tty: bool = False, stream: bool = False, socket: bool = False, demux: bool = False, ) -> str: ... @overload + def exec_start( + self, exec_id: str, detach: Literal[False], tty: bool, stream: bool, socket: Literal[True], demux: bool = False + ) -> SocketIO | _BufferedReaderStream | SSHSocket: ... + @overload def exec_start( self, exec_id: str, detach: Literal[False] = False, tty: bool = False, stream: bool = False, - socket: Literal[True] = ..., demux: bool = False, + *, + socket: Literal[True], ) -> SocketIO | _BufferedReaderStream | SSHSocket: ... @overload + def exec_start( + self, exec_id: str, detach: Literal[False], tty: bool, stream: Literal[True], socket: Literal[False], demux: Literal[True] + ) -> CancellableStream[tuple[str | None, str | None]]: ... + @overload def exec_start( self, exec_id: str, detach: Literal[False] = False, tty: bool = False, - stream: Literal[True] = ..., socket: Literal[False] = False, - demux: Literal[True] = ..., + *, + stream: Literal[True], + demux: Literal[True], ) -> CancellableStream[tuple[str | None, str | None]]: ... @overload def exec_start( self, exec_id: str, - detach: bool = False, + detach: Literal[False], + tty: bool, + stream: Literal[True], + socket: Literal[False], + demux: Literal[False], + ) -> CancellableStream[str]: ... + @overload + def exec_start( + self, + exec_id: str, + detach: Literal[False] = False, tty: bool = False, - stream: Literal[True] = ..., - socket: bool = False, - demux: bool = False, + socket: Literal[False] = False, + demux: Literal[False] = False, + *, + stream: Literal[True], ) -> CancellableStream[str]: ... @overload def exec_start( self, exec_id: str, - detach: bool = False, + detach: Literal[False], + tty: bool, + stream: Literal[False], + socket: Literal[False], + demux: Literal[True], + ) -> tuple[str | None, str | None]: ... + @overload + def exec_start( + self, + exec_id: str, + detach: Literal[False] = False, tty: bool = False, - stream: bool = False, - socket: bool = False, - demux: Literal[True] = ..., + stream: Literal[False] = False, + socket: Literal[False] = False, + *, + demux: Literal[True], ) -> tuple[str | None, str | None]: ... @overload def exec_start( self, exec_id: str, - detach: bool = False, + detach: Literal[False] = False, tty: bool = False, - stream: bool = False, - socket: bool = False, - demux: bool = False, + stream: Literal[False] = False, + socket: Literal[False] = False, + demux: Literal[False] = False, ) -> str: ... From efc4b711dbd73df1f4686d451fd50edacb0a4066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Fern=C3=A1ndez=20Iglesias?= Date: Thu, 27 Nov 2025 07:44:39 +0100 Subject: [PATCH 3/3] [docker-py] Fix `ExecApiMixin.exec_start` overloads --- stubs/docker/docker/api/exec_api.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stubs/docker/docker/api/exec_api.pyi b/stubs/docker/docker/api/exec_api.pyi index 0fa2631cd5ed..0c50a6091cbe 100644 --- a/stubs/docker/docker/api/exec_api.pyi +++ b/stubs/docker/docker/api/exec_api.pyi @@ -44,9 +44,9 @@ class ExecApiMixin: detach: Literal[False] = False, tty: bool = False, stream: bool = False, - demux: bool = False, *, socket: Literal[True], + demux: bool = False, ) -> SocketIO | _BufferedReaderStream | SSHSocket: ... @overload def exec_start( @@ -79,10 +79,10 @@ class ExecApiMixin: exec_id: str, detach: Literal[False] = False, tty: bool = False, - socket: Literal[False] = False, - demux: Literal[False] = False, *, stream: Literal[True], + socket: Literal[False] = False, + demux: Literal[False] = False, ) -> CancellableStream[str]: ... @overload def exec_start(