Automatically add many type hints, with ruff

If this library is to ship type hints, it is important that those type hints are valid.
A type checker (e.g. mypy or pyright) can check that those type hints are valid.

This PR is one small step towards that goal.

I ran:

```
ruff --extend-select=ANN201,ANN202,ANN204,ANN205,ANN206 --fi
x --unsafe-fixes docker
```

and I did not make any manual changes.

I chose not to also type other directories (such as `tests`) as that is a decision I'd first like to hear from core maintainers on.

Signed-off-by: Adam Dangoor <adamdangoor@gmail.com>
This commit is contained in:
Adam Dangoor 2024-01-26 19:26:32 +00:00
parent bd164f928a
commit 4716ee36cf
No known key found for this signature in database
41 changed files with 185 additions and 185 deletions

View File

@ -322,7 +322,7 @@ class BuildApiMixin:
params['all'] = all
return self._result(self._post(url, params=params), True)
def _set_auth_headers(self, headers):
def _set_auth_headers(self, headers) -> None:
log.debug('Looking for auth config')
# If we don't have any auth data so far, try reloading the config

View File

@ -106,7 +106,7 @@ class APIClient(
timeout=DEFAULT_TIMEOUT_SECONDS, tls=False,
user_agent=DEFAULT_USER_AGENT, num_pools=None,
credstore_env=None, use_ssh_client=False,
max_pool_size=DEFAULT_MAX_POOL_SIZE):
max_pool_size=DEFAULT_MAX_POOL_SIZE) -> None:
super().__init__()
if tls and not base_url:
@ -243,7 +243,7 @@ class APIClient(
def _delete(self, url, **kwargs):
return self.delete(url, **self._set_request_timeout(kwargs))
def _url(self, pathfmt, *args, **kwargs):
def _url(self, pathfmt, *args, **kwargs) -> str:
for arg in args:
if not isinstance(arg, str):
raise ValueError(
@ -259,7 +259,7 @@ class APIClient(
else:
return f'{self.base_url}{formatted_path}'
def _raise_for_status(self, response):
def _raise_for_status(self, response) -> None:
"""Raises stored :class:`APIError`, if one occurred."""
try:
response.raise_for_status()
@ -436,7 +436,7 @@ class APIClient(
finally:
response.close()
def _disable_socket_timeout(self, socket):
def _disable_socket_timeout(self, socket) -> None:
""" Depending on the combination of python version and whether we're
connecting over http or https, we might need to access _sock, which
may or may not exist; or we may need to just settimeout on socket
@ -488,7 +488,7 @@ class APIClient(
list(self._multiplexed_buffer_helper(res))
)
def _unmount(self, *args):
def _unmount(self, *args) -> None:
for proto in args:
self.adapters.pop(proto)
@ -505,7 +505,7 @@ class APIClient(
def api_version(self):
return self._version
def reload_config(self, dockercfg_path=None):
def reload_config(self, dockercfg_path=None) -> None:
"""
Force a reload of the auth configuration

View File

@ -56,7 +56,7 @@ class ConfigApiMixin:
@utils.minimum_version('1.30')
@utils.check_resource('id')
def remove_config(self, id):
def remove_config(self, id) -> bool:
"""
Remove a config

View File

@ -794,7 +794,7 @@ class ContainerApiMixin:
)
@utils.check_resource('container')
def kill(self, container, signal=None):
def kill(self, container, signal=None) -> None:
"""
Kill a container or send a signal to a container.
@ -900,7 +900,7 @@ class ContainerApiMixin:
return output
@utils.check_resource('container')
def pause(self, container):
def pause(self, container) -> None:
"""
Pauses all processes within a container.
@ -1013,7 +1013,7 @@ class ContainerApiMixin:
return self._result(self._post(url, params=params), True)
@utils.check_resource('container')
def remove_container(self, container, v=False, link=False, force=False):
def remove_container(self, container, v=False, link=False, force=False) -> None:
"""
Remove a container. Similar to the ``docker rm`` command.
@ -1036,7 +1036,7 @@ class ContainerApiMixin:
self._raise_for_status(res)
@utils.check_resource('container')
def rename(self, container, name):
def rename(self, container, name) -> None:
"""
Rename a container. Similar to the ``docker rename`` command.
@ -1054,7 +1054,7 @@ class ContainerApiMixin:
self._raise_for_status(res)
@utils.check_resource('container')
def resize(self, container, height, width):
def resize(self, container, height, width) -> None:
"""
Resize the tty session.
@ -1073,7 +1073,7 @@ class ContainerApiMixin:
self._raise_for_status(res)
@utils.check_resource('container')
def restart(self, container, timeout=10):
def restart(self, container, timeout=10) -> None:
"""
Restart a container. Similar to the ``docker restart`` command.
@ -1097,7 +1097,7 @@ class ContainerApiMixin:
self._raise_for_status(res)
@utils.check_resource('container')
def start(self, container, *args, **kwargs):
def start(self, container, *args, **kwargs) -> None:
"""
Start a container. Similar to the ``docker start`` command, but
doesn't support attach options.
@ -1183,7 +1183,7 @@ class ContainerApiMixin:
return self._result(self._get(url, params=params), json=True)
@utils.check_resource('container')
def stop(self, container, timeout=None):
def stop(self, container, timeout=None) -> None:
"""
Stops a container. Similar to the ``docker stop`` command.
@ -1233,7 +1233,7 @@ class ContainerApiMixin:
return self._result(self._get(u, params=params), True)
@utils.check_resource('container')
def unpause(self, container):
def unpause(self, container) -> None:
"""
Unpause all processes within a container.

View File

@ -97,7 +97,7 @@ class ExecApiMixin:
res = self._get(self._url("/exec/{0}/json", exec_id))
return self._result(res, True)
def exec_resize(self, exec_id, height=None, width=None):
def exec_resize(self, exec_id, height=None, width=None) -> None:
"""
Resize the tty session used by the specified exec command.

View File

@ -175,7 +175,7 @@ class NetworkApiMixin:
return self._result(self._post(url, params=params), True)
@check_resource('net_id')
def remove_network(self, net_id):
def remove_network(self, net_id) -> None:
"""
Remove a network. Similar to the ``docker network rm`` command.
@ -217,7 +217,7 @@ class NetworkApiMixin:
ipv4_address=None, ipv6_address=None,
aliases=None, links=None,
link_local_ips=None, driver_opt=None,
mac_address=None):
mac_address=None) -> None:
"""
Connect a container to a network.
@ -255,7 +255,7 @@ class NetworkApiMixin:
@check_resource('container')
def disconnect_container_from_network(self, container, net_id,
force=False):
force=False) -> None:
"""
Disconnect a container from a network.

View File

@ -4,7 +4,7 @@ from .. import auth, utils
class PluginApiMixin:
@utils.minimum_version('1.25')
@utils.check_resource('name')
def configure_plugin(self, name, options):
def configure_plugin(self, name, options) -> bool:
"""
Configure a plugin.
@ -25,7 +25,7 @@ class PluginApiMixin:
return True
@utils.minimum_version('1.25')
def create_plugin(self, name, plugin_data_dir, gzip=False):
def create_plugin(self, name, plugin_data_dir, gzip=False) -> bool:
"""
Create a new plugin.
@ -51,7 +51,7 @@ class PluginApiMixin:
return True
@utils.minimum_version('1.25')
def disable_plugin(self, name, force=False):
def disable_plugin(self, name, force=False) -> bool:
"""
Disable an installed plugin.
@ -69,7 +69,7 @@ class PluginApiMixin:
return True
@utils.minimum_version('1.25')
def enable_plugin(self, name, timeout=0):
def enable_plugin(self, name, timeout=0) -> bool:
"""
Enable an installed plugin.
@ -206,7 +206,7 @@ class PluginApiMixin:
@utils.minimum_version('1.25')
@utils.check_resource('name')
def remove_plugin(self, name, force=False):
def remove_plugin(self, name, force=False) -> bool:
"""
Remove an installed plugin.

View File

@ -63,7 +63,7 @@ class SecretApiMixin:
@utils.minimum_version('1.25')
@utils.check_resource('id')
def remove_secret(self, id):
def remove_secret(self, id) -> bool:
"""
Remove a secret

View File

@ -3,9 +3,9 @@ from ..types import ServiceMode
def _check_api_features(version, task_template, update_config, endpoint_spec,
rollback_config):
rollback_config) -> None:
def raise_version_error(param, min_version):
def raise_version_error(param, min_version) -> None:
raise errors.InvalidVersion(
f'{param} is not supported in API version < {min_version}'
)
@ -239,7 +239,7 @@ class ServiceApiMixin:
@utils.minimum_version('1.24')
@utils.check_resource('service')
def remove_service(self, service):
def remove_service(self, service) -> bool:
"""
Stop and remove a service.

View File

@ -216,7 +216,7 @@ class SwarmApiMixin:
@utils.minimum_version('1.24')
def join_swarm(self, remote_addrs, join_token, listen_addr='0.0.0.0:2377',
advertise_addr=None, data_path_addr=None):
advertise_addr=None, data_path_addr=None) -> bool:
"""
Make this Engine join a swarm that has already been created.
@ -266,7 +266,7 @@ class SwarmApiMixin:
return True
@utils.minimum_version('1.24')
def leave_swarm(self, force=False):
def leave_swarm(self, force=False) -> bool:
"""
Leave a swarm.
@ -319,7 +319,7 @@ class SwarmApiMixin:
@utils.check_resource('node_id')
@utils.minimum_version('1.24')
def remove_node(self, node_id, force=False):
def remove_node(self, node_id, force=False) -> bool:
"""
Remove a node from the swarm.
@ -345,7 +345,7 @@ class SwarmApiMixin:
return True
@utils.minimum_version('1.24')
def unlock_swarm(self, key):
def unlock_swarm(self, key) -> bool:
"""
Unlock a locked swarm.
@ -381,7 +381,7 @@ class SwarmApiMixin:
return True
@utils.minimum_version('1.24')
def update_node(self, node_id, version, node_spec=None):
def update_node(self, node_id, version, node_spec=None) -> bool:
"""
Update the node's configuration
@ -420,7 +420,7 @@ class SwarmApiMixin:
def update_swarm(self, version, swarm_spec=None,
rotate_worker_token=False,
rotate_manager_token=False,
rotate_manager_unlock_key=False):
rotate_manager_unlock_key=False) -> bool:
"""
Update the Swarm's configuration

View File

@ -138,7 +138,7 @@ class VolumeApiMixin:
url = self._url('/volumes/prune')
return self._result(self._post(url, params=params), True)
def remove_volume(self, name, force=False):
def remove_volume(self, name, force=False) -> None:
"""
Remove a volume. Similar to the ``docker volume rm`` command.

View File

@ -74,7 +74,7 @@ def get_credential_store(authconfig, registry):
class AuthConfig(dict):
def __init__(self, dct, credstore_env=None):
def __init__(self, dct, credstore_env=None) -> None:
if 'auths' not in dct:
dct['auths'] = {}
self.update(dct)
@ -202,7 +202,7 @@ class AuthConfig(dict):
return self.get('credHelpers', {})
@property
def is_empty(self):
def is_empty(self) -> bool:
return (
not self.auths and not self.creds_store and not self.cred_helpers
)
@ -303,7 +303,7 @@ class AuthConfig(dict):
return auth_data
def add_auth(self, reg, data):
def add_auth(self, reg, data) -> None:
self['auths'][reg] = data

View File

@ -41,7 +41,7 @@ class DockerClient:
max_pool_size (int): The maximum number of connections
to save in the pool.
"""
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
self.api = APIClient(*args, **kwargs)
@classmethod

View File

@ -130,7 +130,7 @@ class ContextAPI:
return cls.get_context()
@classmethod
def set_current_context(cls, name="default"):
def set_current_context(cls, name="default") -> None:
ctx = cls.get_context(name)
if not ctx:
raise errors.ContextNotFound(name)
@ -141,7 +141,7 @@ class ContextAPI:
f'Failed to set current context: {err}')
@classmethod
def remove_context(cls, name):
def remove_context(cls, name) -> None:
"""Remove a context. Similar to the ``docker context rm`` command.
Args:

View File

@ -13,7 +13,7 @@ class Context:
"""A context."""
def __init__(self, name, orchestrator=None, host=None, endpoints=None,
tls=False):
tls=False) -> None:
if not name:
raise Exception("Name not provided")
self.name = name
@ -57,7 +57,7 @@ class Context:
def set_endpoint(
self, name="docker", host=None, tls_cfg=None,
skip_tls_verify=False, def_namespace=None):
skip_tls_verify=False, def_namespace=None) -> None:
self.endpoints[name] = {
"Host": get_context_host(host, not skip_tls_verify),
"SkipTLSVerify": skip_tls_verify
@ -113,7 +113,7 @@ class Context:
return metadata
def _load_certs(self):
def _load_certs(self) -> None:
certs = {}
tls_dir = get_tls_dir(self.name)
for endpoint in self.endpoints.keys():
@ -139,7 +139,7 @@ class Context:
self.tls_cfg = certs
self.tls_path = tls_dir
def save(self):
def save(self) -> None:
meta_dir = get_meta_dir(self.name)
if not os.path.isdir(meta_dir):
os.makedirs(meta_dir)
@ -166,16 +166,16 @@ class Context:
self.meta_path = get_meta_dir(self.name)
self.tls_path = get_tls_dir(self.name)
def remove(self):
def remove(self) -> None:
if os.path.isdir(self.meta_path):
rmtree(self.meta_path)
if os.path.isdir(self.tls_path):
rmtree(self.tls_path)
def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}: '{self.name}'>"
def __str__(self):
def __str__(self) -> str:
return json.dumps(self.__call__(), indent=2)
def __call__(self):

View File

@ -10,7 +10,7 @@ from .utils import create_environment_dict
class Store:
def __init__(self, program, environment=None):
def __init__(self, program, environment=None) -> None:
""" Create a store object that acts as an interface to
perform the basic operations for storing, retrieving
and erasing credentials using `program`.
@ -55,7 +55,7 @@ class Store:
}).encode('utf-8')
return self._execute('store', data_input)
def erase(self, server):
def erase(self, server) -> None:
""" Erase credentials for `server`. Raises a `StoreError` if an error
occurs.
"""

View File

@ -19,7 +19,7 @@ class DockerException(Exception):
"""
def create_api_error_from_http_exception(e):
def create_api_error_from_http_exception(e) -> None:
"""
Create a suitable APIError from requests.exceptions.HTTPError.
"""
@ -43,14 +43,14 @@ class APIError(requests.exceptions.HTTPError, DockerException):
"""
An HTTP error from the API.
"""
def __init__(self, message, response=None, explanation=None):
def __init__(self, message, response=None, explanation=None) -> None:
# requests 1.2 supports response as a keyword argument, but
# requests 1.1 doesn't
super().__init__(message)
self.response = response
self.explanation = explanation
def __str__(self):
def __str__(self) -> str:
message = super().__str__()
if self.is_client_error():
@ -118,10 +118,10 @@ class DeprecatedMethod(DockerException):
class TLSParameterError(DockerException):
def __init__(self, msg):
def __init__(self, msg) -> None:
self.msg = msg
def __str__(self):
def __str__(self) -> str:
return self.msg + (". TLS configurations should map the Docker CLI "
"client configurations. See "
"https://docs.docker.com/engine/articles/https/ "
@ -136,7 +136,7 @@ class ContainerError(DockerException):
"""
Represents a container that has exited with a non-zero exit code.
"""
def __init__(self, container, exit_status, command, image, stderr):
def __init__(self, container, exit_status, command, image, stderr) -> None:
self.container = container
self.exit_status = exit_status
self.command = command
@ -151,12 +151,12 @@ class ContainerError(DockerException):
class StreamParseError(RuntimeError):
def __init__(self, reason):
def __init__(self, reason) -> None:
self.msg = reason
class BuildError(DockerException):
def __init__(self, reason, build_log):
def __init__(self, reason, build_log) -> None:
super().__init__(reason)
self.msg = reason
self.build_log = build_log
@ -178,32 +178,32 @@ def create_unexpected_kwargs_error(name, kwargs):
class MissingContextParameter(DockerException):
def __init__(self, param):
def __init__(self, param) -> None:
self.param = param
def __str__(self):
def __str__(self) -> str:
return (f"missing parameter: {self.param}")
class ContextAlreadyExists(DockerException):
def __init__(self, name):
def __init__(self, name) -> None:
self.name = name
def __str__(self):
def __str__(self) -> str:
return (f"context {self.name} already exists")
class ContextException(DockerException):
def __init__(self, msg):
def __init__(self, msg) -> None:
self.msg = msg
def __str__(self):
def __str__(self) -> str:
return (self.msg)
class ContextNotFound(DockerException):
def __init__(self, name):
def __init__(self, name) -> None:
self.name = name
def __str__(self):
def __str__(self) -> str:
return (f"context '{self.name}' not found")

View File

@ -6,7 +6,7 @@ class Config(Model):
"""A config."""
id_attribute = 'ID'
def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}: '{self.name}'>"
@property

View File

@ -14,7 +14,7 @@ class Image(Model):
"""
An image on the server.
"""
def __repr__(self):
def __repr__(self) -> str:
tag_str = "', '".join(self.tags)
return f"<{self.__class__.__name__}: '{tag_str}'>"
@ -143,7 +143,7 @@ class RegistryData(Model):
"""
Image metadata stored on the registry, including available platforms.
"""
def __init__(self, image_name, *args, **kwargs):
def __init__(self, image_name, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.image_name = image_name
@ -208,7 +208,7 @@ class RegistryData(Model):
platform, self.client.version()
) in self.attrs['Platforms']
def reload(self):
def reload(self) -> None:
self.attrs = self.client.api.inspect_distribution(self.image_name)
reload.__doc__ = Model.reload.__doc__
@ -478,7 +478,7 @@ class ImageCollection(Collection):
return self.client.api.push(repository, tag=tag, **kwargs)
push.__doc__ = APIClient.push.__doc__
def remove(self, *args, **kwargs):
def remove(self, *args, **kwargs) -> None:
self.client.api.remove_image(*args, **kwargs)
remove.__doc__ = APIClient.remove_image.__doc__

View File

@ -6,7 +6,7 @@ class Plugin(Model):
"""
A plugin on the server.
"""
def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}: '{self.name}'>"
@property
@ -30,7 +30,7 @@ class Plugin(Model):
"""
return self.attrs.get('Settings')
def configure(self, options):
def configure(self, options) -> None:
"""
Update the plugin's settings.
@ -44,7 +44,7 @@ class Plugin(Model):
self.client.api.configure_plugin(self.name, options)
self.reload()
def disable(self, force=False):
def disable(self, force=False) -> None:
"""
Disable the plugin.
@ -59,7 +59,7 @@ class Plugin(Model):
self.client.api.disable_plugin(self.name, force)
self.reload()
def enable(self, timeout=0):
def enable(self, timeout=0) -> None:
"""
Enable the plugin.

View File

@ -4,7 +4,7 @@ class Model:
"""
id_attribute = 'Id'
def __init__(self, attrs=None, client=None, collection=None):
def __init__(self, attrs=None, client=None, collection=None) -> None:
#: A client pointing at the server that this object is on.
self.client = client
@ -16,7 +16,7 @@ class Model:
if self.attrs is None:
self.attrs = {}
def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}: {self.short_id}>"
def __eq__(self, other):
@ -39,7 +39,7 @@ class Model:
"""
return self.id[:12]
def reload(self):
def reload(self) -> None:
"""
Load this object from the server again and update ``attrs`` with the
new data.
@ -57,7 +57,7 @@ class Collection:
#: The type of object this collection represents, set by subclasses
model = None
def __init__(self, client=None):
def __init__(self, client=None) -> None:
#: The client pointing at the server that this collection of objects
#: is on.
self.client = client
@ -69,13 +69,13 @@ class Collection:
"use docker.APIClient if so."
)
def list(self):
def list(self) -> None:
raise NotImplementedError
def get(self, key):
def get(self, key) -> None:
raise NotImplementedError
def create(self, attrs=None):
def create(self, attrs=None) -> None:
raise NotImplementedError
def prepare_model(self, attrs):

View File

@ -6,7 +6,7 @@ class Secret(Model):
"""A secret."""
id_attribute = 'ID'
def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}: '{self.name}'>"
@property

View File

@ -10,7 +10,7 @@ class Swarm(Model):
"""
id_attribute = 'ID'
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
if self.client:
try:
@ -140,7 +140,7 @@ class Swarm(Model):
return self.client.api.leave_swarm(*args, **kwargs)
leave.__doc__ = APIClient.leave_swarm.__doc__
def reload(self):
def reload(self) -> None:
"""
Inspect the swarm on the server and store the response in
:py:attr:`attrs`.

View File

@ -18,7 +18,7 @@ class TLSConfig:
ca_cert = None
verify = None
def __init__(self, client_cert=None, ca_cert=None, verify=None):
def __init__(self, client_cert=None, ca_cert=None, verify=None) -> None:
# Argument compatibility/mapping with
# https://docs.docker.com/engine/articles/https/
# This diverges from the Docker CLI in that users can specify 'tls'
@ -54,7 +54,7 @@ class TLSConfig:
'Invalid CA certificate provided for `ca_cert`.'
)
def configure_client(self, client):
def configure_client(self, client) -> None:
"""
Configure a client with these TLS options.
"""

View File

@ -2,7 +2,7 @@ import requests.adapters
class BaseHTTPAdapter(requests.adapters.HTTPAdapter):
def close(self):
def close(self) -> None:
super().close()
if hasattr(self, 'pools'):
self.pools.clear()

View File

@ -12,14 +12,14 @@ RecentlyUsedContainer = urllib3._collections.RecentlyUsedContainer
class NpipeHTTPConnection(urllib3.connection.HTTPConnection):
def __init__(self, npipe_path, timeout=60):
def __init__(self, npipe_path, timeout=60) -> None:
super().__init__(
'localhost', timeout=timeout
)
self.npipe_path = npipe_path
self.timeout = timeout
def connect(self):
def connect(self) -> None:
sock = NpipeSocket()
sock.settimeout(self.timeout)
sock.connect(self.npipe_path)
@ -27,7 +27,7 @@ class NpipeHTTPConnection(urllib3.connection.HTTPConnection):
class NpipeHTTPConnectionPool(urllib3.connectionpool.HTTPConnectionPool):
def __init__(self, npipe_path, timeout=60, maxsize=10):
def __init__(self, npipe_path, timeout=60, maxsize=10) -> None:
super().__init__(
'localhost', timeout=timeout, maxsize=maxsize
)
@ -70,7 +70,7 @@ class NpipeHTTPAdapter(BaseHTTPAdapter):
def __init__(self, base_url, timeout=60,
pool_connections=constants.DEFAULT_NUM_POOLS,
max_pool_size=constants.DEFAULT_MAX_POOL_SIZE):
max_pool_size=constants.DEFAULT_MAX_POOL_SIZE) -> None:
self.npipe_path = base_url.replace('npipe://', '')
self.timeout = timeout
self.max_pool_size = max_pool_size

View File

@ -33,18 +33,18 @@ class NpipeSocket:
implemented.
"""
def __init__(self, handle=None):
def __init__(self, handle=None) -> None:
self._timeout = win32pipe.NMPWAIT_USE_DEFAULT_WAIT
self._handle = handle
self._closed = False
def accept(self):
def accept(self) -> None:
raise NotImplementedError()
def bind(self, address):
def bind(self, address) -> None:
raise NotImplementedError()
def close(self):
def close(self) -> None:
self._handle.Close()
self._closed = True
@ -99,13 +99,13 @@ class NpipeSocket:
def getsockname(self):
return self._address
def getsockopt(self, level, optname, buflen=None):
def getsockopt(self, level, optname, buflen=None) -> None:
raise NotImplementedError()
def ioctl(self, control, option):
def ioctl(self, control, option) -> None:
raise NotImplementedError()
def listen(self, backlog):
def listen(self, backlog) -> None:
raise NotImplementedError()
def makefile(self, mode=None, bufsize=None):
@ -182,7 +182,7 @@ class NpipeSocket:
return self.settimeout(None)
return self.settimeout(0)
def settimeout(self, value):
def settimeout(self, value) -> None:
if value is None:
# Blocking mode
self._timeout = win32event.INFINITE
@ -195,7 +195,7 @@ class NpipeSocket:
def gettimeout(self):
return self._timeout
def setsockopt(self, level, optname, value):
def setsockopt(self, level, optname, value) -> None:
raise NotImplementedError()
@check_closed
@ -204,27 +204,27 @@ class NpipeSocket:
class NpipeFileIOBase(io.RawIOBase):
def __init__(self, npipe_socket):
def __init__(self, npipe_socket) -> None:
self.sock = npipe_socket
def close(self):
def close(self) -> None:
super().close()
self.sock = None
def fileno(self):
return self.sock.fileno()
def isatty(self):
def isatty(self) -> bool:
return False
def readable(self):
def readable(self) -> bool:
return True
def readinto(self, buf):
return self.sock.recv_into(buf)
def seekable(self):
def seekable(self) -> bool:
return False
def writable(self):
def writable(self) -> bool:
return False

View File

@ -18,7 +18,7 @@ RecentlyUsedContainer = urllib3._collections.RecentlyUsedContainer
class SSHSocket(socket.socket):
def __init__(self, host):
def __init__(self, host) -> None:
super().__init__(
socket.AF_INET, socket.SOCK_STREAM)
self.host = host
@ -31,7 +31,7 @@ class SSHSocket(socket.socket):
self.proc = None
def connect(self, **kwargs):
def connect(self, **kwargs) -> None:
args = ['ssh']
if self.user:
args = args + ['-l', self.user]
@ -43,7 +43,7 @@ class SSHSocket(socket.socket):
preexec_func = None
if not constants.IS_WINDOWS_PLATFORM:
def f():
def f() -> None:
signal.signal(signal.SIGINT, signal.SIG_IGN)
preexec_func = f
@ -68,7 +68,7 @@ class SSHSocket(socket.socket):
self.proc.stdin.flush()
return written
def sendall(self, data):
def sendall(self, data) -> None:
self._write(data)
def send(self, data):
@ -87,7 +87,7 @@ class SSHSocket(socket.socket):
return self.proc.stdout
def close(self):
def close(self) -> None:
if not self.proc or self.proc.stdin.closed:
return
self.proc.stdin.write(b'\n\n')
@ -96,7 +96,7 @@ class SSHSocket(socket.socket):
class SSHConnection(urllib3.connection.HTTPConnection):
def __init__(self, ssh_transport=None, timeout=60, host=None):
def __init__(self, ssh_transport=None, timeout=60, host=None) -> None:
super().__init__(
'localhost', timeout=timeout
)
@ -104,7 +104,7 @@ class SSHConnection(urllib3.connection.HTTPConnection):
self.timeout = timeout
self.ssh_host = host
def connect(self):
def connect(self) -> None:
if self.ssh_transport:
sock = self.ssh_transport.open_session()
sock.settimeout(self.timeout)
@ -120,7 +120,7 @@ class SSHConnection(urllib3.connection.HTTPConnection):
class SSHConnectionPool(urllib3.connectionpool.HTTPConnectionPool):
scheme = 'ssh'
def __init__(self, ssh_client=None, timeout=60, maxsize=10, host=None):
def __init__(self, ssh_client=None, timeout=60, maxsize=10, host=None) -> None:
super().__init__(
'localhost', timeout=timeout, maxsize=maxsize
)
@ -165,7 +165,7 @@ class SSHHTTPAdapter(BaseHTTPAdapter):
def __init__(self, base_url, timeout=60,
pool_connections=constants.DEFAULT_NUM_POOLS,
max_pool_size=constants.DEFAULT_MAX_POOL_SIZE,
shell_out=False):
shell_out=False) -> None:
self.ssh_client = None
if not shell_out:
self._create_paramiko_client(base_url)
@ -182,7 +182,7 @@ class SSHHTTPAdapter(BaseHTTPAdapter):
)
super().__init__()
def _create_paramiko_client(self, base_url):
def _create_paramiko_client(self, base_url) -> None:
logging.getLogger("paramiko").setLevel(logging.WARNING)
self.ssh_client = paramiko.SSHClient()
base_url = urllib.parse.urlparse(base_url)
@ -213,7 +213,7 @@ class SSHHTTPAdapter(BaseHTTPAdapter):
self.ssh_client.load_system_host_keys()
self.ssh_client.set_missing_host_key_policy(paramiko.RejectPolicy())
def _connect(self):
def _connect(self) -> None:
if self.ssh_client:
self.ssh_client.connect(**self.ssh_params)
@ -244,7 +244,7 @@ class SSHHTTPAdapter(BaseHTTPAdapter):
return pool
def close(self):
def close(self) -> None:
super().close()
if self.ssh_client:
self.ssh_client.close()

View File

@ -13,7 +13,7 @@ RecentlyUsedContainer = urllib3._collections.RecentlyUsedContainer
class UnixHTTPConnection(urllib3.connection.HTTPConnection):
def __init__(self, base_url, unix_socket, timeout=60):
def __init__(self, base_url, unix_socket, timeout=60) -> None:
super().__init__(
'localhost', timeout=timeout
)
@ -21,7 +21,7 @@ class UnixHTTPConnection(urllib3.connection.HTTPConnection):
self.unix_socket = unix_socket
self.timeout = timeout
def connect(self):
def connect(self) -> None:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.settimeout(self.timeout)
sock.connect(self.unix_socket)
@ -29,7 +29,7 @@ class UnixHTTPConnection(urllib3.connection.HTTPConnection):
class UnixHTTPConnectionPool(urllib3.connectionpool.HTTPConnectionPool):
def __init__(self, base_url, socket_path, timeout=60, maxsize=10):
def __init__(self, base_url, socket_path, timeout=60, maxsize=10) -> None:
super().__init__(
'localhost', timeout=timeout, maxsize=maxsize
)
@ -52,7 +52,7 @@ class UnixHTTPAdapter(BaseHTTPAdapter):
def __init__(self, socket_url, timeout=60,
pool_connections=constants.DEFAULT_NUM_POOLS,
max_pool_size=constants.DEFAULT_MAX_POOL_SIZE):
max_pool_size=constants.DEFAULT_MAX_POOL_SIZE) -> None:
socket_path = socket_url.replace('http+unix://', '')
if not socket_path.startswith('/'):
socket_path = f"/{socket_path}"

View File

@ -1,4 +1,4 @@
class DictType(dict):
def __init__(self, init):
def __init__(self, init) -> None:
for k, v in init.items():
self[k] = v

View File

@ -55,7 +55,7 @@ class LogConfig(DictType):
"""
types = LogConfigTypesEnum
def __init__(self, **kwargs):
def __init__(self, **kwargs) -> None:
log_driver_type = kwargs.get('type', kwargs.get('Type'))
config = kwargs.get('config', kwargs.get('Config')) or {}
@ -72,20 +72,20 @@ class LogConfig(DictType):
return self['Type']
@type.setter
def type(self, value):
def type(self, value) -> None:
self['Type'] = value
@property
def config(self):
return self['Config']
def set_config_value(self, key, value):
def set_config_value(self, key, value) -> None:
""" Set a the value for ``key`` to ``value`` inside the ``config``
dict.
"""
self.config[key] = value
def unset_config(self, key):
def unset_config(self, key) -> None:
""" Remove the ``key`` property from the ``config`` dict. """
if key in self.config:
del self.config[key]
@ -114,7 +114,7 @@ class Ulimit(DictType):
[{'Name': 'nproc', 'Hard': 0, 'Soft': 1024}]
"""
def __init__(self, **kwargs):
def __init__(self, **kwargs) -> None:
name = kwargs.get('name', kwargs.get('Name'))
soft = kwargs.get('soft', kwargs.get('Soft'))
hard = kwargs.get('hard', kwargs.get('Hard'))
@ -135,7 +135,7 @@ class Ulimit(DictType):
return self['Name']
@name.setter
def name(self, value):
def name(self, value) -> None:
self['Name'] = value
@property
@ -143,7 +143,7 @@ class Ulimit(DictType):
return self.get('Soft')
@soft.setter
def soft(self, value):
def soft(self, value) -> None:
self['Soft'] = value
@property
@ -151,7 +151,7 @@ class Ulimit(DictType):
return self.get('Hard')
@hard.setter
def hard(self, value):
def hard(self, value) -> None:
self['Hard'] = value
@ -176,7 +176,7 @@ class DeviceRequest(DictType):
options (dict): Driver-specific options. Optional.
"""
def __init__(self, **kwargs):
def __init__(self, **kwargs) -> None:
driver = kwargs.get('driver', kwargs.get('Driver'))
count = kwargs.get('count', kwargs.get('Count'))
device_ids = kwargs.get('device_ids', kwargs.get('DeviceIDs'))
@ -217,7 +217,7 @@ class DeviceRequest(DictType):
return self['Driver']
@driver.setter
def driver(self, value):
def driver(self, value) -> None:
self['Driver'] = value
@property
@ -225,7 +225,7 @@ class DeviceRequest(DictType):
return self['Count']
@count.setter
def count(self, value):
def count(self, value) -> None:
self['Count'] = value
@property
@ -233,7 +233,7 @@ class DeviceRequest(DictType):
return self['DeviceIDs']
@device_ids.setter
def device_ids(self, value):
def device_ids(self, value) -> None:
self['DeviceIDs'] = value
@property
@ -241,7 +241,7 @@ class DeviceRequest(DictType):
return self['Capabilities']
@capabilities.setter
def capabilities(self, value):
def capabilities(self, value) -> None:
self['Capabilities'] = value
@property
@ -249,7 +249,7 @@ class DeviceRequest(DictType):
return self['Options']
@options.setter
def options(self, value):
def options(self, value) -> None:
self['Options'] = value
@ -276,7 +276,7 @@ class HostConfig(dict):
nano_cpus=None, cpuset_mems=None, runtime=None, mounts=None,
cpu_rt_period=None, cpu_rt_runtime=None,
device_cgroup_rules=None, device_requests=None,
cgroupns=None):
cgroupns=None) -> None:
if mem_limit is not None:
self['Memory'] = parse_bytes(mem_limit)
@ -685,7 +685,7 @@ class ContainerConfig(dict):
working_dir=None, domainname=None, host_config=None, mac_address=None,
labels=None, stop_signal=None, networking_config=None,
healthcheck=None, stop_timeout=None, runtime=None
):
) -> None:
if stop_timeout is not None and version_lt(version, '1.25'):
raise errors.InvalidVersion(

View File

@ -17,7 +17,7 @@ class CancellableStream:
>>> events.close()
"""
def __init__(self, stream, response):
def __init__(self, stream, response) -> None:
self._stream = stream
self._response = response
@ -34,7 +34,7 @@ class CancellableStream:
next = __next__
def close(self):
def close(self) -> None:
"""
Closes the event streaming.
"""

View File

@ -27,7 +27,7 @@ class Healthcheck(DictType):
initialize before starting health-retries countdown in
nanoseconds. It should be 0 or at least 1000000 (1 ms).
"""
def __init__(self, **kwargs):
def __init__(self, **kwargs) -> None:
test = kwargs.get('test', kwargs.get('Test'))
if isinstance(test, str):
test = ["CMD-SHELL", test]
@ -50,7 +50,7 @@ class Healthcheck(DictType):
return self['Test']
@test.setter
def test(self, value):
def test(self, value) -> None:
if isinstance(value, str):
value = ["CMD-SHELL", value]
self['Test'] = value
@ -60,7 +60,7 @@ class Healthcheck(DictType):
return self['Interval']
@interval.setter
def interval(self, value):
def interval(self, value) -> None:
self['Interval'] = value
@property
@ -68,7 +68,7 @@ class Healthcheck(DictType):
return self['Timeout']
@timeout.setter
def timeout(self, value):
def timeout(self, value) -> None:
self['Timeout'] = value
@property
@ -76,7 +76,7 @@ class Healthcheck(DictType):
return self['Retries']
@retries.setter
def retries(self, value):
def retries(self, value) -> None:
self['Retries'] = value
@property
@ -84,5 +84,5 @@ class Healthcheck(DictType):
return self['StartPeriod']
@start_period.setter
def start_period(self, value):
def start_period(self, value) -> None:
self['StartPeriod'] = value

View File

@ -5,7 +5,7 @@ from ..utils import normalize_links, version_lt
class EndpointConfig(dict):
def __init__(self, version, aliases=None, links=None, ipv4_address=None,
ipv6_address=None, link_local_ips=None, driver_opt=None,
mac_address=None):
mac_address=None) -> None:
if version_lt(version, '1.22'):
raise errors.InvalidVersion(
'Endpoint config is not supported for API version < 1.22'
@ -52,7 +52,7 @@ class EndpointConfig(dict):
class NetworkingConfig(dict):
def __init__(self, endpoints_config=None):
def __init__(self, endpoints_config=None) -> None:
if endpoints_config:
self["EndpointsConfig"] = endpoints_config
@ -76,7 +76,7 @@ class IPAMConfig(dict):
>>> network = client.create_network('network1', ipam=ipam_config)
"""
def __init__(self, driver='default', pool_configs=None, options=None):
def __init__(self, driver='default', pool_configs=None, options=None) -> None:
self.update({
'Driver': driver,
'Config': pool_configs or []
@ -119,7 +119,7 @@ class IPAMPool(dict):
pool_configs=[ipam_pool])
"""
def __init__(self, subnet=None, iprange=None, gateway=None,
aux_addresses=None):
aux_addresses=None) -> None:
self.update({
'Subnet': subnet,
'IPRange': iprange,

View File

@ -32,7 +32,7 @@ class TaskTemplate(dict):
def __init__(self, container_spec, resources=None, restart_policy=None,
placement=None, log_driver=None, networks=None,
force_update=None):
force_update=None) -> None:
self['ContainerSpec'] = container_spec
if resources:
self['Resources'] = resources
@ -125,7 +125,7 @@ class ContainerSpec(dict):
open_stdin=None, read_only=None, stop_signal=None,
healthcheck=None, hosts=None, dns_config=None, configs=None,
privileges=None, isolation=None, init=None, cap_add=None,
cap_drop=None, sysctls=None):
cap_drop=None, sysctls=None) -> None:
self['Image'] = image
if isinstance(command, str):
@ -245,7 +245,7 @@ class Mount(dict):
def __init__(self, target, source, type='volume', read_only=False,
consistency=None, propagation=None, no_copy=False,
labels=None, driver_config=None, tmpfs_size=None,
tmpfs_mode=None):
tmpfs_mode=None) -> None:
self['Target'] = target
self['Source'] = source
if type not in ('bind', 'volume', 'tmpfs', 'npipe'):
@ -344,7 +344,7 @@ class Resources(dict):
"""
def __init__(self, cpu_limit=None, mem_limit=None, cpu_reservation=None,
mem_reservation=None, generic_resources=None):
mem_reservation=None, generic_resources=None) -> None:
limits = {}
reservation = {}
if cpu_limit is not None:
@ -415,7 +415,7 @@ class UpdateConfig(dict):
"""
def __init__(self, parallelism=0, delay=None, failure_action='continue',
monitor=None, max_failure_ratio=None, order=None):
monitor=None, max_failure_ratio=None, order=None) -> None:
self['Parallelism'] = parallelism
if delay is not None:
self['Delay'] = delay
@ -500,7 +500,7 @@ class RestartPolicy(dict):
condition_types = RestartConditionTypesEnum
def __init__(self, condition=RestartConditionTypesEnum.NONE, delay=0,
max_attempts=0, window=0):
max_attempts=0, window=0) -> None:
if condition not in self.condition_types._values:
raise TypeError(
f'Invalid RestartPolicy condition {condition}'
@ -526,7 +526,7 @@ class DriverConfig(dict):
options (dict): Driver-specific options. Default: ``None``.
"""
def __init__(self, name, options=None):
def __init__(self, name, options=None) -> None:
self['Name'] = name
if options:
self['Options'] = options
@ -548,7 +548,7 @@ class EndpointSpec(dict):
Ports can only be provided if the ``vip`` resolution mode is used.
"""
def __init__(self, mode=None, ports=None):
def __init__(self, mode=None, ports=None) -> None:
if ports:
self['Ports'] = convert_service_ports(ports)
if mode:
@ -601,7 +601,7 @@ class ServiceMode(dict):
services only.
"""
def __init__(self, mode, replicas=None, concurrency=None):
def __init__(self, mode, replicas=None, concurrency=None) -> None:
replicated_modes = ('replicated', 'replicated-job')
supported_modes = replicated_modes + ('global', 'global-job')
@ -673,7 +673,7 @@ class SecretReference(dict):
"""
@check_resource('secret_id')
def __init__(self, secret_id, secret_name, filename=None, uid=None,
gid=None, mode=0o444):
gid=None, mode=0o444) -> None:
self['SecretName'] = secret_name
self['SecretID'] = secret_id
self['File'] = {
@ -701,7 +701,7 @@ class ConfigReference(dict):
"""
@check_resource('config_id')
def __init__(self, config_id, config_name, filename=None, uid=None,
gid=None, mode=0o444):
gid=None, mode=0o444) -> None:
self['ConfigName'] = config_name
self['ConfigID'] = config_id
self['File'] = {
@ -729,7 +729,7 @@ class Placement(dict):
"""
def __init__(self, constraints=None, preferences=None, platforms=None,
maxreplicas=None):
maxreplicas=None) -> None:
if constraints is not None:
self['Constraints'] = constraints
if preferences is not None:
@ -761,7 +761,7 @@ class PlacementPreference(dict):
nodes identified by this label.
"""
def __init__(self, strategy, descriptor):
def __init__(self, strategy, descriptor) -> None:
if strategy != 'spread':
raise errors.InvalidArgument(
f'PlacementPreference strategy value is invalid ({strategy}): '
@ -783,7 +783,7 @@ class DNSConfig(dict):
to be modified (e.g., ``debug``, ``ndots:3``, etc.).
"""
def __init__(self, nameservers=None, search=None, options=None):
def __init__(self, nameservers=None, search=None, options=None) -> None:
self['Nameservers'] = nameservers
self['Search'] = search
self['Options'] = options
@ -816,7 +816,7 @@ class Privileges(dict):
def __init__(self, credentialspec_file=None, credentialspec_registry=None,
selinux_disable=None, selinux_user=None, selinux_role=None,
selinux_type=None, selinux_level=None):
selinux_type=None, selinux_level=None) -> None:
credential_spec = {}
if credentialspec_registry is not None:
credential_spec['Registry'] = credentialspec_registry
@ -857,7 +857,7 @@ class NetworkAttachmentConfig(dict):
network target.
"""
def __init__(self, target, aliases=None, options=None):
def __init__(self, target, aliases=None, options=None) -> None:
self['Target'] = target
self['Aliases'] = aliases
self['DriverOpts'] = options

View File

@ -15,7 +15,7 @@ class SwarmSpec(dict):
node_cert_expiry=None, external_cas=None, name=None,
labels=None, signing_ca_cert=None, signing_ca_key=None,
ca_force_rotate=None, autolock_managers=None,
log_driver=None):
log_driver=None) -> None:
if task_history_retention_limit is not None:
self['Orchestration'] = {
'TaskHistoryRetentionLimit': task_history_retention_limit
@ -112,7 +112,7 @@ class SwarmExternalCA(dict):
"""
def __init__(self, url, protocol=None, options=None, ca_cert=None):
def __init__(self, url, protocol=None, options=None, ca_cert=None) -> None:
self['URL'] = url
self['Protocol'] = protocol
self['Options'] = options

View File

@ -158,7 +158,7 @@ def walk(root, patterns, default=True):
# Heavily based on
# https://github.com/moby/moby/blob/master/pkg/fileutils/fileutils.go
class PatternMatcher:
def __init__(self, patterns):
def __init__(self, patterns) -> None:
self.patterns = list(filter(
lambda p: p.dirs, [Pattern(p) for p in patterns]
))
@ -221,7 +221,7 @@ class PatternMatcher:
class Pattern:
def __init__(self, pattern_str):
def __init__(self, pattern_str) -> None:
self.exclusion = False
if pattern_str.startswith('!'):
self.exclusion = True

View File

@ -18,7 +18,7 @@ _cache = {}
_MAXCACHE = 100
def _purge():
def _purge() -> None:
"""Clear the pattern cache"""
_cache.clear()
@ -60,7 +60,7 @@ def fnmatchcase(name, pat):
return re_pat.match(name) is not None
def translate(pat):
def translate(pat) -> str:
"""Translate a shell PATTERN to a regular expression.
There is no way to quote meta-characters.

View File

@ -12,14 +12,14 @@ PORT_SPEC = re.compile(
)
def add_port_mapping(port_bindings, internal_port, external):
def add_port_mapping(port_bindings, internal_port, external) -> None:
if internal_port in port_bindings:
port_bindings[internal_port].append(external)
else:
port_bindings[internal_port] = [external]
def add_port(port_bindings, internal_port_range, external_range):
def add_port(port_bindings, internal_port_range, external_range) -> None:
if external_range is None:
for internal_port in internal_port_range:
add_port_mapping(port_bindings, internal_port, None)
@ -37,7 +37,7 @@ def build_port_bindings(ports):
return port_bindings
def _raise_invalid_port(port):
def _raise_invalid_port(port) -> None:
raise ValueError('Invalid port "%s", should be '
'[[remote_ip:]remote_port[-remote_port]:]'
'port[/protocol]' % port)

View File

@ -68,7 +68,7 @@ class ProxyConfig(dict):
# variables defined in "environment" to take precedence.
return proxy_env + environment
def __str__(self):
def __str__(self) -> str:
return (
'ProxyConfig('
f'http={self.http}, https={self.https}, '

View File

@ -24,14 +24,14 @@ URLComponents = collections.namedtuple(
)
def create_ipam_pool(*args, **kwargs):
def create_ipam_pool(*args, **kwargs) -> None:
raise errors.DeprecatedMethod(
'utils.create_ipam_pool has been removed. Please use a '
'docker.types.IPAMPool object instead.'
)
def create_ipam_config(*args, **kwargs):
def create_ipam_config(*args, **kwargs) -> None:
raise errors.DeprecatedMethod(
'utils.create_ipam_config has been removed. Please use a '
'docker.types.IPAMConfig object instead.'
@ -45,7 +45,7 @@ def decode_json_header(header):
@lru_cache(maxsize=None)
def compare_version(v1, v2):
def compare_version(v1, v2) -> int:
"""Compare docker versions
>>> v1 = '1.9'
@ -77,7 +77,7 @@ def version_lt(v1, v2):
return compare_version(v1, v2) > 0
def version_gte(v1, v2):
def version_gte(v1, v2) -> bool:
return not version_lt(v1, v2)
@ -509,7 +509,7 @@ def format_extra_hosts(extra_hosts, task=False):
]
def create_host_config(self, *args, **kwargs):
def create_host_config(self, *args, **kwargs) -> None:
raise errors.DeprecatedMethod(
'utils.create_host_config has been removed. Please use a '
'docker.types.HostConfig object instead.'