Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Commit b100957

Browse files
iceboy2331st1
authored andcommitted
Python Issue #26654: Inspect keyword arguments of functools.partial.
1 parent f6117ee commit b100957

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

asyncio/coroutines.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ def _format_coroutine(coro):
271271
func = coro
272272

273273
if coro_name is None:
274-
coro_name = events._format_callback(func, ())
274+
coro_name = events._format_callback(func, (), {})
275275

276276
try:
277277
coro_code = coro.gi_code

asyncio/events.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,25 @@ def _get_function_source(func):
3535
return None
3636

3737

38-
def _format_args(args):
39-
"""Format function arguments.
38+
def _format_args_and_kwargs(args, kwargs):
39+
"""Format function arguments and keyword arguments.
4040
4141
Special case for a single parameter: ('hello',) is formatted as ('hello').
4242
"""
4343
# use reprlib to limit the length of the output
44-
args_repr = reprlib.repr(args)
45-
if len(args) == 1 and args_repr.endswith(',)'):
46-
args_repr = args_repr[:-2] + ')'
47-
return args_repr
44+
items = []
45+
if args:
46+
items.extend(reprlib.repr(arg) for arg in args)
47+
if kwargs:
48+
items.extend('{}={}'.format(k, reprlib.repr(v))
49+
for k, v in kwargs.items())
50+
return '(' + ', '.join(items) + ')'
4851

4952

50-
def _format_callback(func, args, suffix=''):
53+
def _format_callback(func, args, kwargs, suffix=''):
5154
if isinstance(func, functools.partial):
52-
if args is not None:
53-
suffix = _format_args(args) + suffix
54-
return _format_callback(func.func, func.args, suffix)
55+
suffix = _format_args_and_kwargs(args, kwargs) + suffix
56+
return _format_callback(func.func, func.args, func.keywords, suffix)
5557

5658
if hasattr(func, '__qualname__'):
5759
func_repr = getattr(func, '__qualname__')
@@ -60,14 +62,13 @@ def _format_callback(func, args, suffix=''):
6062
else:
6163
func_repr = repr(func)
6264

63-
if args is not None:
64-
func_repr += _format_args(args)
65+
func_repr += _format_args_and_kwargs(args, kwargs)
6566
if suffix:
6667
func_repr += suffix
6768
return func_repr
6869

6970
def _format_callback_source(func, args):
70-
func_repr = _format_callback(func, args)
71+
func_repr = _format_callback(func, args, None)
7172
source = _get_function_source(func)
7273
if source:
7374
func_repr += ' at %s:%s' % source

tests/test_events.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -2224,7 +2224,7 @@ def create_event_loop(self):
22242224
return asyncio.SelectorEventLoop(selectors.SelectSelector())
22252225

22262226

2227-
def noop(*args):
2227+
def noop(*args, **kwargs):
22282228
pass
22292229

22302230

@@ -2305,6 +2305,13 @@ def test_handle_repr(self):
23052305
% (re.escape(filename), lineno))
23062306
self.assertRegex(repr(h), regex)
23072307

2308+
# partial function with keyword args
2309+
cb = functools.partial(noop, x=1)
2310+
h = asyncio.Handle(cb, (2, 3), self.loop)
2311+
regex = (r'^<Handle noop\(x=1\)\(2, 3\) at %s:%s>$'
2312+
% (re.escape(filename), lineno))
2313+
self.assertRegex(repr(h), regex)
2314+
23082315
# partial method
23092316
if sys.version_info >= (3, 4):
23102317
method = HandleTests.test_handle_repr

0 commit comments

Comments
 (0)