mirror of
https://github.com/ansible-collections/community.docker.git
synced 2026-07-29 03:46:55 +00:00
Python code modernization, 1/n (#1141)
* Remove unicode text prefixes. * Replace str.format() uses with f-strings. * Replace % with f-strings, and do some cleanup. * Fix wrong variable. * Avoid unnecessary string conversion.
This commit is contained in:
@@ -55,15 +55,15 @@ class APIClient(
|
||||
>>> import docker
|
||||
>>> client = docker.APIClient(base_url='unix://var/run/docker.sock')
|
||||
>>> client.version()
|
||||
{u'ApiVersion': u'1.33',
|
||||
u'Arch': u'amd64',
|
||||
u'BuildTime': u'2017-11-19T18:46:37.000000000+00:00',
|
||||
u'GitCommit': u'f4ffd2511c',
|
||||
u'GoVersion': u'go1.9.2',
|
||||
u'KernelVersion': u'4.14.3-1-ARCH',
|
||||
u'MinAPIVersion': u'1.12',
|
||||
u'Os': u'linux',
|
||||
u'Version': u'17.10.0-ce'}
|
||||
{'ApiVersion': '1.33',
|
||||
'Arch': 'amd64',
|
||||
'BuildTime': '2017-11-19T18:46:37.000000000+00:00',
|
||||
'GitCommit': 'f4ffd2511c',
|
||||
'GoVersion': 'go1.9.2',
|
||||
'KernelVersion': '4.14.3-1-ARCH',
|
||||
'MinAPIVersion': '1.12',
|
||||
'Os': 'linux',
|
||||
'Version': '17.10.0-ce'}
|
||||
|
||||
Args:
|
||||
base_url (str): URL to the Docker server. For example,
|
||||
@@ -187,14 +187,11 @@ class APIClient(
|
||||
self._version = version
|
||||
if not isinstance(self._version, str):
|
||||
raise DockerException(
|
||||
'Version parameter must be a string or None. Found {0}'.format(
|
||||
type(version).__name__
|
||||
)
|
||||
f'Version parameter must be a string or None. Found {type(version).__name__}'
|
||||
)
|
||||
if utils.version_lt(self._version, MINIMUM_DOCKER_API_VERSION):
|
||||
raise InvalidVersion(
|
||||
'API versions below {0} are no longer supported by this '
|
||||
'library.'.format(MINIMUM_DOCKER_API_VERSION)
|
||||
f'API versions below {MINIMUM_DOCKER_API_VERSION} are no longer supported by this library.'
|
||||
)
|
||||
|
||||
def _retrieve_server_version(self):
|
||||
@@ -202,7 +199,7 @@ class APIClient(
|
||||
version_result = self.version(api_version=False)
|
||||
except Exception as e:
|
||||
raise DockerException(
|
||||
'Error while fetching server API version: {0}'.format(e)
|
||||
f'Error while fetching server API version: {e}'
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -214,7 +211,7 @@ class APIClient(
|
||||
)
|
||||
except Exception as e:
|
||||
raise DockerException(
|
||||
'Error while fetching server API version: {0}. Response seems to be broken.'.format(e)
|
||||
f'Error while fetching server API version: {e}. Response seems to be broken.'
|
||||
)
|
||||
|
||||
def _set_request_timeout(self, kwargs):
|
||||
@@ -247,19 +244,16 @@ class APIClient(
|
||||
for arg in args:
|
||||
if not isinstance(arg, str):
|
||||
raise ValueError(
|
||||
'Expected a string but found {0} ({1}) '
|
||||
'instead'.format(arg, type(arg))
|
||||
f'Expected a string but found {arg} ({type(arg)}) instead'
|
||||
)
|
||||
|
||||
quote_f = partial(quote, safe="/:")
|
||||
args = map(quote_f, args)
|
||||
|
||||
if kwargs.get('versioned_api', True):
|
||||
return '{0}/v{1}{2}'.format(
|
||||
self.base_url, self._version, pathfmt.format(*args)
|
||||
)
|
||||
return f'{self.base_url}/v{self._version}{pathfmt.format(*args)}'
|
||||
else:
|
||||
return '{0}{1}'.format(self.base_url, pathfmt.format(*args))
|
||||
return f'{self.base_url}{pathfmt.format(*args)}'
|
||||
|
||||
def _raise_for_status(self, response):
|
||||
"""Raises stored :class:`APIError`, if one occurred."""
|
||||
|
||||
@@ -19,7 +19,7 @@ from .credentials.errors import StoreError, CredentialsNotFound
|
||||
from .utils import config
|
||||
|
||||
INDEX_NAME = 'docker.io'
|
||||
INDEX_URL = 'https://index.{0}/v1/'.format(INDEX_NAME)
|
||||
INDEX_URL = f'https://index.{INDEX_NAME}/v1/'
|
||||
TOKEN_USERNAME = '<token>'
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -28,14 +28,13 @@ log = logging.getLogger(__name__)
|
||||
def resolve_repository_name(repo_name):
|
||||
if '://' in repo_name:
|
||||
raise errors.InvalidRepository(
|
||||
'Repository name cannot contain a scheme ({0})'.format(repo_name)
|
||||
f'Repository name cannot contain a scheme ({repo_name})'
|
||||
)
|
||||
|
||||
index_name, remote_name = split_repo_name(repo_name)
|
||||
if index_name[0] == '-' or index_name[-1] == '-':
|
||||
raise errors.InvalidRepository(
|
||||
'Invalid index name ({0}). Cannot begin or end with a'
|
||||
' hyphen.'.format(index_name)
|
||||
f'Invalid index name ({index_name}). Cannot begin or end with a hyphen.'
|
||||
)
|
||||
return resolve_index_name(index_name), remote_name
|
||||
|
||||
@@ -117,9 +116,7 @@ class AuthConfig(dict):
|
||||
# keys is not formatted properly.
|
||||
if raise_on_error:
|
||||
raise errors.InvalidConfigFile(
|
||||
'Invalid configuration for registry {0}'.format(
|
||||
registry
|
||||
)
|
||||
f'Invalid configuration for registry {registry}'
|
||||
)
|
||||
return {}
|
||||
if 'identitytoken' in entry:
|
||||
@@ -272,7 +269,7 @@ class AuthConfig(dict):
|
||||
return None
|
||||
except StoreError as e:
|
||||
raise errors.DockerException(
|
||||
'Credentials store error: {0}'.format(repr(e))
|
||||
f'Credentials store error: {e}'
|
||||
)
|
||||
|
||||
def _get_store_instance(self, name):
|
||||
|
||||
@@ -146,14 +146,14 @@ class ContextAPI(object):
|
||||
names.append(name)
|
||||
except Exception as e:
|
||||
raise errors.ContextException(
|
||||
"Failed to load metafile {filepath}: {e}".format(filepath=filepath, e=e),
|
||||
f"Failed to load metafile {filepath}: {e}"
|
||||
) from e
|
||||
|
||||
contexts = [cls.get_default_context()]
|
||||
for name in names:
|
||||
context = Context.load_context(name)
|
||||
if not context:
|
||||
raise errors.ContextException("Context {context} cannot be found".format(context=name))
|
||||
raise errors.ContextException(f"Context {name} cannot be found")
|
||||
contexts.append(context)
|
||||
return contexts
|
||||
|
||||
@@ -174,7 +174,7 @@ class ContextAPI(object):
|
||||
err = write_context_name_to_docker_config(name)
|
||||
if err:
|
||||
raise errors.ContextException(
|
||||
'Failed to set current context: {err}'.format(err=err))
|
||||
f'Failed to set current context: {err}')
|
||||
|
||||
@classmethod
|
||||
def remove_context(cls, name):
|
||||
|
||||
@@ -29,7 +29,7 @@ def get_current_context_name_with_source():
|
||||
if docker_cfg_path:
|
||||
try:
|
||||
with open(docker_cfg_path) as f:
|
||||
return json.load(f).get("currentContext", "default"), "configuration file {file}".format(file=docker_cfg_path)
|
||||
return json.load(f).get("currentContext", "default"), f"configuration file {docker_cfg_path}"
|
||||
except Exception:
|
||||
pass
|
||||
return "default", "fallback value"
|
||||
|
||||
@@ -62,7 +62,7 @@ class Context(object):
|
||||
if not isinstance(v, dict):
|
||||
# unknown format
|
||||
raise ContextException(
|
||||
"Unknown endpoint format for context {name}: {v}".format(name=name, v=v),
|
||||
f"Unknown endpoint format for context {name}: {v}",
|
||||
)
|
||||
|
||||
self.endpoints[k] = v
|
||||
@@ -118,7 +118,7 @@ class Context(object):
|
||||
except (OSError, KeyError, ValueError) as e:
|
||||
# unknown format
|
||||
raise Exception(
|
||||
"Detected corrupted meta file for context {name} : {e}".format(name=name, e=e)
|
||||
f"Detected corrupted meta file for context {name} : {e}"
|
||||
) from e
|
||||
|
||||
# for docker endpoints, set defaults for
|
||||
@@ -193,7 +193,7 @@ class Context(object):
|
||||
rmtree(self.tls_path)
|
||||
|
||||
def __repr__(self):
|
||||
return "<{classname}: '{name}'>".format(classname=self.__class__.__name__, name=self.name)
|
||||
return f"<{self.__class__.__name__}: '{self.name}'>"
|
||||
|
||||
def __str__(self):
|
||||
return json.dumps(self.__call__(), indent=2)
|
||||
|
||||
@@ -26,12 +26,8 @@ def process_store_error(cpe, program):
|
||||
message = cpe.output.decode('utf-8')
|
||||
if 'credentials not found in native keychain' in message:
|
||||
return CredentialsNotFound(
|
||||
'No matching credentials in {0}'.format(
|
||||
program
|
||||
)
|
||||
f'No matching credentials in {program}'
|
||||
)
|
||||
return StoreError(
|
||||
'Credentials store {0} exited with "{1}".'.format(
|
||||
program, cpe.output.decode('utf-8').strip()
|
||||
)
|
||||
f'Credentials store {program} exited with "{cpe.output.decode("utf-8").strip()}".'
|
||||
)
|
||||
|
||||
@@ -30,9 +30,7 @@ class Store(object):
|
||||
self.environment = environment
|
||||
if self.exe is None:
|
||||
raise errors.InitializationError(
|
||||
'{0} not installed or not available in PATH'.format(
|
||||
self.program
|
||||
)
|
||||
f'{self.program} not installed or not available in PATH'
|
||||
)
|
||||
|
||||
def get(self, server):
|
||||
@@ -50,7 +48,7 @@ class Store(object):
|
||||
# raise CredentialsNotFound
|
||||
if result['Username'] == '' and result['Secret'] == '':
|
||||
raise errors.CredentialsNotFound(
|
||||
'No matching credentials in {0}'.format(self.program)
|
||||
f'No matching credentials in {self.program}'
|
||||
)
|
||||
|
||||
return result
|
||||
@@ -92,14 +90,10 @@ class Store(object):
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
raise errors.StoreError(
|
||||
'{0} not installed or not available in PATH'.format(
|
||||
self.program
|
||||
)
|
||||
f'{self.program} not installed or not available in PATH'
|
||||
)
|
||||
else:
|
||||
raise errors.StoreError(
|
||||
'Unexpected OS error "{0}", errno={1}'.format(
|
||||
e.strerror, e.errno
|
||||
)
|
||||
f'Unexpected OS error "{e.strerror}", errno={e.errno}'
|
||||
)
|
||||
return output
|
||||
|
||||
@@ -59,17 +59,13 @@ class APIError(_HTTPError, DockerException):
|
||||
message = super(APIError, self).__str__()
|
||||
|
||||
if self.is_client_error():
|
||||
message = '{0} Client Error for {1}: {2}'.format(
|
||||
self.response.status_code, self.response.url,
|
||||
self.response.reason)
|
||||
message = f'{self.response.status_code} Client Error for {self.response.url}: {self.response.reason}'
|
||||
|
||||
elif self.is_server_error():
|
||||
message = '{0} Server Error for {1}: {2}'.format(
|
||||
self.response.status_code, self.response.url,
|
||||
self.response.reason)
|
||||
message = f'{self.response.status_code} Server Error for {self.response.url}: {self.response.reason}'
|
||||
|
||||
if self.explanation:
|
||||
message = '{0} ("{1}")'.format(message, self.explanation)
|
||||
message = f'{message} ("{self.explanation}")'
|
||||
|
||||
return message
|
||||
|
||||
@@ -146,9 +142,8 @@ class ContainerError(DockerException):
|
||||
self.image = image
|
||||
self.stderr = stderr
|
||||
|
||||
err = ": {0}".format(stderr) if stderr is not None else ""
|
||||
msg = ("Command '{0}' in image '{1}' returned non-zero exit "
|
||||
"status {2}{3}").format(command, image, exit_status, err)
|
||||
err = f": {stderr}" if stderr is not None else ""
|
||||
msg = f"Command '{command}' in image '{image}' returned non-zero exit status {exit_status}{err}"
|
||||
|
||||
super(ContainerError, self).__init__(msg)
|
||||
|
||||
@@ -170,8 +165,8 @@ class ImageLoadError(DockerException):
|
||||
|
||||
|
||||
def create_unexpected_kwargs_error(name, kwargs):
|
||||
quoted_kwargs = ["'{0}'".format(k) for k in sorted(kwargs)]
|
||||
text = ["{0}() ".format(name)]
|
||||
quoted_kwargs = [f"'{k}'" for k in sorted(kwargs)]
|
||||
text = [f"{name}() "]
|
||||
if len(quoted_kwargs) == 1:
|
||||
text.append("got an unexpected keyword argument ")
|
||||
else:
|
||||
@@ -185,7 +180,7 @@ class MissingContextParameter(DockerException):
|
||||
self.param = param
|
||||
|
||||
def __str__(self):
|
||||
return ("missing parameter: {0}".format(self.param))
|
||||
return f"missing parameter: {self.param}"
|
||||
|
||||
|
||||
class ContextAlreadyExists(DockerException):
|
||||
@@ -193,7 +188,7 @@ class ContextAlreadyExists(DockerException):
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return ("context {0} already exists".format(self.name))
|
||||
return f"context {self.name} already exists"
|
||||
|
||||
|
||||
class ContextException(DockerException):
|
||||
@@ -209,7 +204,7 @@ class ContextNotFound(DockerException):
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return ("context '{0}' not found".format(self.name))
|
||||
return f"context '{self.name}' not found"
|
||||
|
||||
|
||||
class MissingRequirementException(DockerException):
|
||||
|
||||
@@ -107,7 +107,7 @@ def create_archive(root, files=None, fileobj=None, gzip=False,
|
||||
t.addfile(i, f)
|
||||
except IOError:
|
||||
raise IOError(
|
||||
'Can not read file in context: {0}'.format(full_path)
|
||||
f'Can not read file in context: {full_path}'
|
||||
)
|
||||
else:
|
||||
# Directories, FIFOs, symlinks... do not need to be read.
|
||||
@@ -271,18 +271,13 @@ def process_dockerfile(dockerfile, path):
|
||||
abs_dockerfile = os.path.join(path, dockerfile)
|
||||
if IS_WINDOWS_PLATFORM and path.startswith(
|
||||
WINDOWS_LONGPATH_PREFIX):
|
||||
abs_dockerfile = '{0}{1}'.format(
|
||||
WINDOWS_LONGPATH_PREFIX,
|
||||
os.path.normpath(
|
||||
abs_dockerfile[len(WINDOWS_LONGPATH_PREFIX):]
|
||||
)
|
||||
)
|
||||
abs_dockerfile = f'{WINDOWS_LONGPATH_PREFIX}{os.path.normpath(abs_dockerfile[len(WINDOWS_LONGPATH_PREFIX):])}'
|
||||
if (os.path.splitdrive(path)[0] != os.path.splitdrive(abs_dockerfile)[0] or
|
||||
os.path.relpath(abs_dockerfile, path).startswith('..')):
|
||||
# Dockerfile not in context - read data to insert into tar later
|
||||
with open(abs_dockerfile) as df:
|
||||
return (
|
||||
'.dockerfile.{random:x}'.format(random=random.getrandbits(160)),
|
||||
f'.dockerfile.{random.getrandbits(160):x}',
|
||||
df.read()
|
||||
)
|
||||
|
||||
|
||||
@@ -38,9 +38,7 @@ def minimum_version(version):
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if utils.version_lt(self._version, version):
|
||||
raise errors.InvalidVersion(
|
||||
'{0} is not available for version < {1}'.format(
|
||||
f.__name__, version
|
||||
)
|
||||
f'{f.__name__} is not available for version < {version}'
|
||||
)
|
||||
return f(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@@ -119,7 +119,7 @@ def translate(pat):
|
||||
stuff = '^' + stuff[1:]
|
||||
elif stuff[0] == '^':
|
||||
stuff = '\\' + stuff
|
||||
res = '%s[%s]' % (res, stuff)
|
||||
res = f'{res}[{stuff}]'
|
||||
else:
|
||||
res = res + re.escape(c)
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ def json_stream(stream):
|
||||
return split_buffer(stream, json_splitter, json_decoder.decode)
|
||||
|
||||
|
||||
def line_splitter(buffer, separator=u'\n'):
|
||||
def line_splitter(buffer, separator='\n'):
|
||||
index = buffer.find(str(separator))
|
||||
if index == -1:
|
||||
return None
|
||||
|
||||
@@ -49,19 +49,19 @@ def build_port_bindings(ports):
|
||||
|
||||
|
||||
def _raise_invalid_port(port):
|
||||
raise ValueError('Invalid port "%s", should be '
|
||||
raise ValueError(f'Invalid port "{port}", should be '
|
||||
'[[remote_ip:]remote_port[-remote_port]:]'
|
||||
'port[/protocol]' % port)
|
||||
'port[/protocol]')
|
||||
|
||||
|
||||
def port_range(start, end, proto, randomly_available_port=False):
|
||||
if not start:
|
||||
return start
|
||||
if not end:
|
||||
return [start + proto]
|
||||
return [f'{start}{proto}']
|
||||
if randomly_available_port:
|
||||
return ['{0}-{1}'.format(start, end) + proto]
|
||||
return [str(port) + proto for port in range(int(start), int(end) + 1)]
|
||||
return [f'{start}-{end}{proto}']
|
||||
return [f'{port}{proto}' for port in range(int(start), int(end) + 1)]
|
||||
|
||||
|
||||
def split_port(port):
|
||||
|
||||
@@ -80,5 +80,4 @@ class ProxyConfig(dict):
|
||||
return proxy_env + environment
|
||||
|
||||
def __str__(self):
|
||||
return 'ProxyConfig(http={0}, https={1}, ftp={2}, no_proxy={3})'.format(
|
||||
self.http, self.https, self.ftp, self.no_proxy)
|
||||
return f'ProxyConfig(http={self.http}, https={self.https}, ftp={self.ftp}, no_proxy={self.no_proxy})'
|
||||
|
||||
@@ -169,7 +169,7 @@ def consume_socket_output(frames, demux=False):
|
||||
# It is guaranteed that for each frame, one and only one stream
|
||||
# is not None.
|
||||
if frame == (None, None):
|
||||
raise AssertionError('frame must be (None, None), but got %s' % (frame, ))
|
||||
raise AssertionError(f'frame must be (None, None), but got {frame}')
|
||||
if frame[0] is not None:
|
||||
if out[0] is None:
|
||||
out[0] = frame[0]
|
||||
@@ -193,4 +193,4 @@ def demux_adaptor(stream_id, data):
|
||||
elif stream_id == STDERR:
|
||||
return (None, data)
|
||||
else:
|
||||
raise ValueError('{0} is not a valid stream'.format(stream_id))
|
||||
raise ValueError(f'{stream_id} is not a valid stream')
|
||||
|
||||
@@ -136,8 +136,7 @@ def convert_volume_binds(binds):
|
||||
if isinstance(v, dict):
|
||||
if 'ro' in v and 'mode' in v:
|
||||
raise ValueError(
|
||||
'Binding cannot contain both "ro" and "mode": {0}'
|
||||
.format(repr(v))
|
||||
f'Binding cannot contain both "ro" and "mode": {v!r}'
|
||||
)
|
||||
|
||||
bind = v['bind']
|
||||
@@ -167,11 +166,11 @@ def convert_volume_binds(binds):
|
||||
else:
|
||||
mode = v['propagation']
|
||||
|
||||
result.append('{0}:{1}:{2}'.format(k, bind, mode))
|
||||
result.append(f'{k}:{bind}:{mode}')
|
||||
else:
|
||||
if isinstance(v, bytes):
|
||||
v = v.decode('utf-8')
|
||||
result.append('{0}:{1}:rw'.format(k, v))
|
||||
result.append(f'{k}:{v}:rw')
|
||||
return result
|
||||
|
||||
|
||||
@@ -181,8 +180,7 @@ def convert_tmpfs_mounts(tmpfs):
|
||||
|
||||
if not isinstance(tmpfs, list):
|
||||
raise ValueError(
|
||||
'Expected tmpfs value to be either a list or a dict, found: {0}'
|
||||
.format(type(tmpfs).__name__)
|
||||
f'Expected tmpfs value to be either a list or a dict, found: {type(tmpfs).__name__}'
|
||||
)
|
||||
|
||||
result = {}
|
||||
@@ -196,8 +194,7 @@ def convert_tmpfs_mounts(tmpfs):
|
||||
|
||||
else:
|
||||
raise ValueError(
|
||||
"Expected item in tmpfs list to be a string, found: {0}"
|
||||
.format(type(mount).__name__)
|
||||
f"Expected item in tmpfs list to be a string, found: {type(mount).__name__}"
|
||||
)
|
||||
|
||||
result[name] = options
|
||||
@@ -257,14 +254,14 @@ def parse_host(addr, is_win32=False, tls=False):
|
||||
|
||||
if proto not in ('tcp', 'unix', 'npipe', 'ssh'):
|
||||
raise errors.DockerException(
|
||||
"Invalid bind address protocol: {0}".format(addr)
|
||||
f"Invalid bind address protocol: {addr}"
|
||||
)
|
||||
|
||||
if proto == 'tcp' and not parsed_url.netloc:
|
||||
# "tcp://" is exceptionally disallowed by convention;
|
||||
# omitting a hostname for other protocols is fine
|
||||
raise errors.DockerException(
|
||||
'Invalid bind address format: {0}'.format(addr)
|
||||
f'Invalid bind address format: {addr}'
|
||||
)
|
||||
|
||||
if any([
|
||||
@@ -272,13 +269,12 @@ def parse_host(addr, is_win32=False, tls=False):
|
||||
parsed_url.password
|
||||
]):
|
||||
raise errors.DockerException(
|
||||
'Invalid bind address format: {0}'.format(addr)
|
||||
f'Invalid bind address format: {addr}'
|
||||
)
|
||||
|
||||
if parsed_url.path and proto == 'ssh':
|
||||
raise errors.DockerException(
|
||||
'Invalid bind address format: no path allowed for this protocol:'
|
||||
' {0}'.format(addr)
|
||||
f'Invalid bind address format: no path allowed for this protocol: {addr}'
|
||||
)
|
||||
else:
|
||||
path = parsed_url.path
|
||||
@@ -292,19 +288,19 @@ def parse_host(addr, is_win32=False, tls=False):
|
||||
port = parsed_url.port or 0
|
||||
if port <= 0:
|
||||
port = 22 if proto == 'ssh' else (2375 if tls else 2376)
|
||||
netloc = '{0}:{1}'.format(parsed_url.netloc, port)
|
||||
netloc = f'{parsed_url.netloc}:{port}'
|
||||
|
||||
if not parsed_url.hostname:
|
||||
netloc = '{0}:{1}'.format(DEFAULT_HTTP_HOST, port)
|
||||
netloc = f'{DEFAULT_HTTP_HOST}:{port}'
|
||||
|
||||
# Rewrite schemes to fit library internals (requests adapters)
|
||||
if proto == 'tcp':
|
||||
proto = 'http{0}'.format('s' if tls else '')
|
||||
proto = f"http{'s' if tls else ''}"
|
||||
elif proto == 'unix':
|
||||
proto = 'http+unix'
|
||||
|
||||
if proto in ('http+unix', 'npipe'):
|
||||
return "{0}://{1}".format(proto, path).rstrip('/')
|
||||
return f"{proto}://{path}".rstrip('/')
|
||||
return urlunparse(URLComponents(
|
||||
scheme=proto,
|
||||
netloc=netloc,
|
||||
@@ -323,7 +319,7 @@ def parse_devices(devices):
|
||||
continue
|
||||
if not isinstance(device, str):
|
||||
raise errors.DockerException(
|
||||
'Invalid device type {0}'.format(type(device))
|
||||
f'Invalid device type {type(device)}'
|
||||
)
|
||||
device_mapping = device.split(':')
|
||||
if device_mapping:
|
||||
@@ -428,17 +424,14 @@ def parse_bytes(s):
|
||||
digits = float(digits_part)
|
||||
except ValueError:
|
||||
raise errors.DockerException(
|
||||
'Failed converting the string value for memory ({0}) to'
|
||||
' an integer.'.format(digits_part)
|
||||
f'Failed converting the string value for memory ({digits_part}) to an integer.'
|
||||
)
|
||||
|
||||
# Reconvert to long for the final result
|
||||
s = int(digits * units[suffix])
|
||||
else:
|
||||
raise errors.DockerException(
|
||||
'The specified value for memory ({0}) should specify the'
|
||||
' units. The postfix should be one of the `b` `k` `m` `g`'
|
||||
' characters'.format(s)
|
||||
f'The specified value for memory ({s}) should specify the units. The postfix should be one of the `b` `k` `m` `g` characters'
|
||||
)
|
||||
|
||||
return s
|
||||
@@ -448,7 +441,7 @@ def normalize_links(links):
|
||||
if isinstance(links, dict):
|
||||
links = links.items()
|
||||
|
||||
return ['{0}:{1}'.format(k, v) if v else k for k, v in sorted(links)]
|
||||
return [f'{k}:{v}' if v else k for k, v in sorted(links)]
|
||||
|
||||
|
||||
def parse_env_file(env_file):
|
||||
@@ -473,9 +466,7 @@ def parse_env_file(env_file):
|
||||
k, v = parse_line
|
||||
environment[k] = v
|
||||
else:
|
||||
raise errors.DockerException(
|
||||
'Invalid line in environment file {0}:\n{1}'.format(
|
||||
env_file, line))
|
||||
raise errors.DockerException(f'Invalid line in environment file {env_file}:\n{line}')
|
||||
|
||||
return environment
|
||||
|
||||
@@ -491,7 +482,7 @@ def format_environment(environment):
|
||||
if isinstance(value, bytes):
|
||||
value = value.decode('utf-8')
|
||||
|
||||
return u'{key}={value}'.format(key=key, value=value)
|
||||
return f'{key}={value}'
|
||||
return [format_env(*var) for var in environment.items()]
|
||||
|
||||
|
||||
@@ -499,11 +490,11 @@ def format_extra_hosts(extra_hosts, task=False):
|
||||
# Use format dictated by Swarm API if container is part of a task
|
||||
if task:
|
||||
return [
|
||||
'{0} {1}'.format(v, k) for k, v in sorted(extra_hosts.items())
|
||||
f'{v} {k}' for k, v in sorted(extra_hosts.items())
|
||||
]
|
||||
|
||||
return [
|
||||
'{0}:{1}'.format(k, v) for k, v in sorted(extra_hosts.items())
|
||||
f'{k}:{v}' for k, v in sorted(extra_hosts.items())
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user