Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-32262: Fix codestyle; use f-strings formatting where necessary. #4775

Merged
merged 5 commits into from Dec 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Lib/asyncio/__init__.py
@@ -1,5 +1,7 @@
"""The asyncio package, tracking PEP 3156."""

# flake8: noqa

import sys

# This relies on each of the submodules having an __all__ variable.
Expand Down
122 changes: 60 additions & 62 deletions Lib/asyncio/base_events.py
Expand Up @@ -36,7 +36,7 @@
from .log import logger


__all__ = ['BaseEventLoop']
__all__ = 'BaseEventLoop',


# Minimum number of _scheduled timer handles before cleanup of
Expand Down Expand Up @@ -173,8 +173,7 @@ def _ensure_resolved(address, *, family=0, type=socket.SOCK_STREAM, proto=0,

def _run_until_complete_cb(fut):
exc = fut._exception
if (isinstance(exc, BaseException)
and not isinstance(exc, Exception)):
if isinstance(exc, BaseException) and not isinstance(exc, Exception):
# Issue #22429: run_forever() already finished, no need to
# stop it.
return
Expand All @@ -190,7 +189,7 @@ def __init__(self, loop, sockets):
self._waiters = []

def __repr__(self):
return '<%s sockets=%r>' % (self.__class__.__name__, self.sockets)
return f'<{self.__class__.__name__} sockets={self.sockets!r}>'

def _attach(self):
assert self.sockets is not None
Expand Down Expand Up @@ -262,9 +261,10 @@ def __init__(self):
self._asyncgens_shutdown_called = False

def __repr__(self):
return ('<%s running=%s closed=%s debug=%s>'
% (self.__class__.__name__, self.is_running(),
self.is_closed(), self.get_debug()))
return (
f'<{self.__class__.__name__} running={self.is_running()} '
f'closed={self.is_closed()} debug={self.get_debug()}>'
)

def create_future(self):
"""Create a Future object attached to the loop."""
Expand Down Expand Up @@ -362,8 +362,8 @@ def _asyncgen_finalizer_hook(self, agen):
def _asyncgen_firstiter_hook(self, agen):
if self._asyncgens_shutdown_called:
warnings.warn(
"asynchronous generator {!r} was scheduled after "
"loop.shutdown_asyncgens() call".format(agen),
f"asynchronous generator {agen!r} was scheduled after "
f"loop.shutdown_asyncgens() call",
ResourceWarning, source=self)

self._asyncgens.add(agen)
Expand All @@ -388,8 +388,8 @@ async def shutdown_asyncgens(self):
for result, agen in zip(results, closing_agens):
if isinstance(result, Exception):
self.call_exception_handler({
'message': 'an error occurred during closing of '
'asynchronous generator {!r}'.format(agen),
'message': f'an error occurred during closing of '
f'asynchronous generator {agen!r}',
'exception': result,
'asyncgen': agen
})
Expand Down Expand Up @@ -495,7 +495,7 @@ def is_closed(self):

def __del__(self):
if not self.is_closed():
warnings.warn("unclosed event loop %r" % self, ResourceWarning,
warnings.warn(f"unclosed event loop {self!r}", ResourceWarning,
source=self)
if not self.is_running():
self.close()
Expand Down Expand Up @@ -573,12 +573,11 @@ def _check_callback(self, callback, method):
if (coroutines.iscoroutine(callback) or
coroutines.iscoroutinefunction(callback)):
raise TypeError(
"coroutines cannot be used with {}()".format(method))
f"coroutines cannot be used with {method}()")
if not callable(callback):
raise TypeError(
'a callable object was expected by {}(), got {!r}'.format(
method, callback))

f'a callable object was expected by {method}(), '
f'got {callback!r}')

def _call_soon(self, callback, args):
handle = events.Handle(callback, args, self)
Expand Down Expand Up @@ -630,24 +629,23 @@ def set_default_executor(self, executor):
self._default_executor = executor

def _getaddrinfo_debug(self, host, port, family, type, proto, flags):
msg = ["%s:%r" % (host, port)]
msg = [f"{host}:{port!r}"]
if family:
msg.append('family=%r' % family)
msg.append(f'family={family!r}' % family)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a remaining % family after the f-string

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, created a PR to fix this: #4787

Thanks!

if type:
msg.append('type=%r' % type)
msg.append(f'type={type!r}')
if proto:
msg.append('proto=%r' % proto)
msg.append(f'proto={proto!r}')
if flags:
msg.append('flags=%r' % flags)
msg.append(f'flags={flags!r}')
msg = ', '.join(msg)
logger.debug('Get address info %s', msg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

F-string here too please 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's logging :(

logger.debug('Get address info %s', msg) -- means that msg will be interpolated only if the logging is ON and the logging level is DEBUG. Otherwise, msg.__str__() won't be called. This is a performance thing, as __repr__() and __str__() can be expensive for some objects.

logger.debug(f'Get address info {msg}') would mean that msg.__str__() is always called, even when logging is disabled.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this particular case we already computed the msg, so we can inline it. In 99.9% other cases we don't want to convert logging strings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is not only in performance.
Tools like sentry groups similar log messages basing on the message text. Calls with the same message template but different params are grouped together but pre-formatted templates are not.
As result the tool becames totally unusable: it displays tons of similar but unique messages.


t0 = self.time()
addrinfo = socket.getaddrinfo(host, port, family, type, proto, flags)
dt = self.time() - t0

msg = ('Getting address info %s took %.3f ms: %r'
% (msg, dt * 1e3, addrinfo))
msg = f'Getting address info {msg} took {dt * 1e3:.3f}ms: {addrinfo!r}'
if dt >= self.slow_callback_duration:
logger.info(msg)
else:
Expand Down Expand Up @@ -738,11 +736,12 @@ async def create_connection(self, protocol_factory, host=None, port=None,
sock.bind(laddr)
break
except OSError as exc:
exc = OSError(
exc.errno, 'error while '
'attempting to bind on address '
'{!r}: {}'.format(
laddr, exc.strerror.lower()))
msg = (
f'error while attempting to bind on '
f'address {laddr!r}: '
f'{exc.strerror.lower()}'
)
exc = OSError(exc.errno, msg)
exceptions.append(exc)
else:
sock.close()
Expand Down Expand Up @@ -786,7 +785,7 @@ async def create_connection(self, protocol_factory, host=None, port=None,
# Disallowing AF_UNIX in this method, breaks backwards
# compatibility.
raise ValueError(
'A Stream Socket was expected, got {!r}'.format(sock))
f'A Stream Socket was expected, got {sock!r}')

transport, protocol = await self._create_connection_transport(
sock, protocol_factory, ssl, server_hostname)
Expand Down Expand Up @@ -830,7 +829,7 @@ async def create_datagram_endpoint(self, protocol_factory,
if sock is not None:
if not _is_dgram_socket(sock):
raise ValueError(
'A UDP Socket was expected, got {!r}'.format(sock))
f'A UDP Socket was expected, got {sock!r}')
if (local_addr or remote_addr or
family or proto or flags or
reuse_address or reuse_port or allow_broadcast):
Expand All @@ -839,11 +838,10 @@ async def create_datagram_endpoint(self, protocol_factory,
family=family, proto=proto, flags=flags,
reuse_address=reuse_address, reuse_port=reuse_port,
allow_broadcast=allow_broadcast)
problems = ', '.join(
'{}={}'.format(k, v) for k, v in opts.items() if v)
problems = ', '.join(f'{k}={v}' for k, v in opts.items() if v)
raise ValueError(
'socket modifier keyword arguments can not be used '
'when sock is specified. ({})'.format(problems))
f'socket modifier keyword arguments can not be used '
f'when sock is specified. ({problems})')
sock.setblocking(False)
r_addr = None
else:
Expand Down Expand Up @@ -953,7 +951,7 @@ async def _create_server_getaddrinfo(self, host, port, family, flags):
type=socket.SOCK_STREAM,
flags=flags, loop=self)
if not infos:
raise OSError('getaddrinfo({!r}) returned empty list'.format(host))
raise OSError(f'getaddrinfo({host!r}) returned empty list')
return infos

async def create_server(self, protocol_factory, host=None, port=None,
Expand All @@ -967,8 +965,8 @@ async def create_server(self, protocol_factory, host=None, port=None,
reuse_port=None):
"""Create a TCP server.

The host parameter can be a string, in that case the TCP server is bound
to host and port.
The host parameter can be a string, in that case the TCP server is
bound to host and port.

The host parameter can also be a sequence of strings and in that case
the TCP server is bound to all hosts of the sequence. If a host
Expand Down Expand Up @@ -1046,8 +1044,7 @@ async def create_server(self, protocol_factory, host=None, port=None,
if sock is None:
raise ValueError('Neither host/port nor sock were specified')
if not _is_stream_socket(sock):
raise ValueError(
'A Stream Socket was expected, got {!r}'.format(sock))
raise ValueError(f'A Stream Socket was expected, got {sock!r}')
sockets = [sock]

server = Server(self, sockets)
Expand All @@ -1070,8 +1067,7 @@ async def connect_accepted_socket(self, protocol_factory, sock,
returns a (transport, protocol) pair.
"""
if not _is_stream_socket(sock):
raise ValueError(
'A Stream Socket was expected, got {!r}'.format(sock))
raise ValueError(f'A Stream Socket was expected, got {sock!r}')

transport, protocol = await self._create_connection_transport(
sock, protocol_factory, ssl, '', server_side=True)
Expand Down Expand Up @@ -1117,14 +1113,14 @@ async def connect_write_pipe(self, protocol_factory, pipe):
def _log_subprocess(self, msg, stdin, stdout, stderr):
info = [msg]
if stdin is not None:
info.append('stdin=%s' % _format_pipe(stdin))
info.append(f'stdin={_format_pipe(stdin)}')
if stdout is not None and stderr == subprocess.STDOUT:
info.append('stdout=stderr=%s' % _format_pipe(stdout))
info.append(f'stdout=stderr={_format_pipe(stdout)}')
else:
if stdout is not None:
info.append('stdout=%s' % _format_pipe(stdout))
info.append(f'stdout={_format_pipe(stdout)}')
if stderr is not None:
info.append('stderr=%s' % _format_pipe(stderr))
info.append(f'stderr={_format_pipe(stderr)}')
logger.debug(' '.join(info))

async def subprocess_shell(self, protocol_factory, cmd, *,
Expand Down Expand Up @@ -1167,14 +1163,14 @@ async def subprocess_exec(self, protocol_factory, program, *args,
popen_args = (program,) + args
for arg in popen_args:
if not isinstance(arg, (str, bytes)):
raise TypeError("program arguments must be "
"a bytes or text string, not %s"
% type(arg).__name__)
raise TypeError(
f"program arguments must be a bytes or text string, "
f"not {type(arg).__name__}")
protocol = protocol_factory()
if self._debug:
# don't log parameters: they may contain sensitive information
# (password) and may be too long
debug_log = 'execute program %r' % program
debug_log = f'execute program {program!r}'
self._log_subprocess(debug_log, stdin, stdout, stderr)
transport = await self._make_subprocess_transport(
protocol, popen_args, False, stdin, stdout, stderr,
Expand All @@ -1201,8 +1197,8 @@ def set_exception_handler(self, handler):
documentation for details about context).
"""
if handler is not None and not callable(handler):
raise TypeError('A callable object or None is expected, '
'got {!r}'.format(handler))
raise TypeError(f'A callable object or None is expected, '
f'got {handler!r}')
self._exception_handler = handler

def default_exception_handler(self, context):
Expand Down Expand Up @@ -1230,10 +1226,11 @@ def default_exception_handler(self, context):
else:
exc_info = False

if ('source_traceback' not in context
and self._current_handle is not None
and self._current_handle._source_traceback):
context['handle_traceback'] = self._current_handle._source_traceback
if ('source_traceback' not in context and
self._current_handle is not None and
self._current_handle._source_traceback):
context['handle_traceback'] = \
self._current_handle._source_traceback

log_lines = [message]
for key in sorted(context):
Expand All @@ -1250,7 +1247,7 @@ def default_exception_handler(self, context):
value += tb.rstrip()
else:
value = repr(value)
log_lines.append('{}: {}'.format(key, value))
log_lines.append(f'{key}: {value}')

logger.error('\n'.join(log_lines), exc_info=exc_info)

Expand Down Expand Up @@ -1438,18 +1435,19 @@ def _set_coroutine_wrapper(self, enabled):
if enabled:
if current_wrapper not in (None, wrapper):
warnings.warn(
"loop.set_debug(True): cannot set debug coroutine "
"wrapper; another wrapper is already set %r" %
current_wrapper, RuntimeWarning)
f"loop.set_debug(True): cannot set debug coroutine "
f"wrapper; another wrapper is already set "
f"{current_wrapper!r}",
RuntimeWarning)
else:
set_wrapper(wrapper)
self._coroutine_wrapper_set = True
else:
if current_wrapper not in (None, wrapper):
warnings.warn(
"loop.set_debug(False): cannot unset debug coroutine "
"wrapper; another wrapper was set %r" %
current_wrapper, RuntimeWarning)
f"loop.set_debug(False): cannot unset debug coroutine "
f"wrapper; another wrapper was set {current_wrapper!r}",
RuntimeWarning)
else:
set_wrapper(None)
self._coroutine_wrapper_set = False
Expand Down
10 changes: 5 additions & 5 deletions Lib/asyncio/base_futures.py
@@ -1,4 +1,4 @@
__all__ = []
__all__ = ()

import concurrent.futures._base
import reprlib
Expand Down Expand Up @@ -48,7 +48,7 @@ def format_cb(callback):
cb = '{}, <{} more>, {}'.format(format_cb(cb[0]),
size - 2,
format_cb(cb[-1]))
return 'cb=[%s]' % cb
return f'cb=[{cb}]'


def _future_repr_info(future):
Expand All @@ -57,15 +57,15 @@ def _future_repr_info(future):
info = [future._state.lower()]
if future._state == _FINISHED:
if future._exception is not None:
info.append('exception={!r}'.format(future._exception))
info.append(f'exception={future._exception!r}')
else:
# use reprlib to limit the length of the output, especially
# for very long strings
result = reprlib.repr(future._result)
info.append('result={}'.format(result))
info.append(f'result={result}')
if future._callbacks:
info.append(_format_callbacks(future._callbacks))
if future._source_traceback:
frame = future._source_traceback[-1]
info.append('created at %s:%s' % (frame[0], frame[1]))
info.append(f'created at {frame[0]}:{frame[1]}')
return info