Skip to content

Commit ea89dd0

Browse files
author
Naomi Seyfer
committed
Introduce Arg objects to make Callable more flexible.
This is the result of the discussion in python/typing#239 It allows you to specify Callable objects that have optional, keyword, keyword-only, and star (and double-star!) arguments. This particular commit is a first draft.
1 parent d309d32 commit ea89dd0

File tree

1 file changed

+51
-15
lines changed

1 file changed

+51
-15
lines changed

pep-0484.txt

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -240,36 +240,72 @@ This is equivalent to::
240240
Callable
241241
--------
242242

243-
Frameworks expecting callback functions of specific signatures might be
244-
type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``.
243+
Frameworks expecting callback functions of specific signatures are
244+
type hinted using ``Callable[ArgumentList, ReturnType]``.
245+
``ArgumentList`` is a list of types or ``Arg`` objects. A type in an
246+
argument list indicates a positional argument of that type with an
247+
unspecified name. ``Arg`` objects are used to specify arguments
248+
that must have a specific name or kind.
249+
250+
245251
Examples::
246252

247-
from typing import Callable
253+
from typing import Callable, StarArg, KwArg
248254

249255
def feeder(get_next_item: Callable[[], str]) -> None:
250-
# Body
256+
... # get_next_item has no arguments and returns a string
251257

252258
def async_query(on_success: Callable[[int], None],
253259
on_error: Callable[[int, Exception], None]) -> None:
254-
# Body
260+
...
261+
# on_success takes in a single int
262+
# on_error takes in an int and an Exception
263+
264+
def worker(logger: Callable[[str, OptArg("log_level", int)], None]) -> None:
265+
...
266+
# logger is a function that takes a string (the arg could be called
267+
# anything) and an optional int which must be called "log_level"
268+
269+
def print_report(
270+
self,
271+
formatter: Callable[[str, StarArg(str), KwArg(str)], str]) -> None:
272+
...
273+
# formatter is a function that takes in a str and also has a *args and a
274+
# **kwargs in its argument list (it takes in a str and any number of other
275+
# positional and keyword arguments)
255276

256-
It is possible to declare the return type of a callable without
257-
specifying the call signature by substituting a literal ellipsis
258-
(three dots) for the list of arguments::
277+
The available ``Arg`` objects are:
278+
279+
* ``Arg(name: Optional[str]=None, type: Type=Any, kw_only: bool=False)``
280+
Produces a required argument with the given name and type. If
281+
``kw_only`` is true, this argument is keyword-only, and no
282+
positional arguments may follow. Otherwise the argument is
283+
positional. In an argument list, ``Arg(type=int)`` is equivalent to
284+
writing plain ``int``.
285+
286+
* ``OptArg(name: Optional[str], type: Type=Any, kw_only: bool=False)``
287+
Produces an optional argument with the given name, type, and
288+
keyword-only nature.
289+
290+
* ``StarArg(type: Type=Any)`` Produces a star argument (aka variadic
291+
argument) to the function. The `type` is the type of all elements
292+
of the resulting tuple.
293+
294+
* ``KwArg(type: Type=Any)`` Produces a variadic keyword argument (aka
295+
double-star argument) to the function. The `type` is the type of all
296+
values of the resulting argument dictionary.
297+
298+
To declare the return type of a callable without specifying the call
299+
signature, substitute a literal ellipsis (three dots) for the list of
300+
arguments::
259301

260302
def partial(func: Callable[..., str], *args) -> Callable[..., str]:
261-
# Body
303+
... # func is any function that produces a string
262304

263305
Note that there are no square brackets around the ellipsis. The
264306
arguments of the callback are completely unconstrained in this case
265307
(and keyword arguments are acceptable).
266308

267-
Since using callbacks with keyword arguments is not perceived as a
268-
common use case, there is currently no support for specifying keyword
269-
arguments with ``Callable``. Similarly, there is no support for
270-
specifying callback signatures with a variable number of argument of a
271-
specific type.
272-
273309
Because ``typing.Callable`` does double-duty as a replacement for
274310
``collections.abc.Callable``, ``isinstance(x, typing.Callable)`` is
275311
implemented by deferring to ```isinstance(x, collections.abc.Callable)``.

0 commit comments

Comments
 (0)