We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Interfaces with Protocols and ABCs step 12 of 26
Type **kwargs with a TypedDict and Unpack
open_connection(host, **kwargs) takes its options as keyword arguments,
and it has a bug. It reads kwargs.get("timeoutt", 5.0), with two t's, so
it ignores the timeout the caller passes and always uses 5.0. mypy says
nothing, because the starter annotates **kwargs: Any, and Any turns
checking off.
Describe the keywords with a TypedDict
The options already have a TypedDict. ConnOpts requires an integer
port, and its timeout and tls keys are NotRequired, so a caller may
leave them out. Wrap it in Unpack to tell mypy that each keyword argument
is one key of ConnOpts:
def open_connection(host: str, **kwargs: Unpack[ConnOpts]) -> Connection: ...
Now mypy checks every call against ConnOpts. Leaving out port, passing a
string for it, or writing timeoutt=2.5 is an error. Inside the function,
kwargs has the type ConnOpts, so mypy also catches the misspelled key in
the body. Change only the annotation, and mypy reports:
Argument "timeout" to "Connection" has incompatible type "object"; expected "float"
ConnOpts has no "timeoutt" key, so the best type mypy can give that
.get() call is object.
What to write
- Import
Unpackfromtyping, and annotate**kwargsasUnpack[ConnOpts]. - Fix the misspelled
"timeoutt"key. - Use
5.0when the caller leaves outtimeout, andFalsewhen they leave outtls. - Keep a timeout of
0.0when the caller passes one. A default applied withorwould replace it. - Keep
ConnOpts,Connectionandsolveas they are.
At runtime kwargs is still a plain dict. Unpack adds no defaults, so
the defaults stay in the function body.
What the driver returns
solve(host, port, timeout) returns three strings from
Connection.describe(), in this order:
- A connection with only
portpassed. - A connection with
portandtimeout. - A connection with
port,timeoutandtls=True.
Each string looks like tcp://db:5432?timeout=5.00, with tls in place of
tcp when TLS is on. For ("db", 5432, 2.5), the three timeouts are
5.00, 2.50 and 2.50.
Store the function with its keywords
Callable[...] cannot describe keyword arguments, but a callback protocol
can. With ConnOpts and Connection in scope, this type keeps every
keyword's name and type:
from typing import Protocol, Unpack
class ConnectionFactory(Protocol):
def __call__(self, host: str, **kwargs: Unpack[ConnOpts]) -> Connection: ...
factory: ConnectionFactory = open_connection
See Unpack for keyword arguments in the typing specification.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.