We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Everyday Standard Library Tools step 53 of 55
Load a Server Config and Report the First Bad Setting
Load a TOML server config into a frozen dataclass. If a setting is wrong, report the first bad one with its name and the reason. Then the person who edits the file knows what to fix.
solve('[server]\nhost = "localhost"\nport = 8080\n')
# {"ok": True, "host": "localhost", "port": 8080, "workers": 4, "debug": False}
solve('[server]\nhost = "h"\nport = 70000\n')
# {"ok": False, "field": "server.port", "reason": "out of range"}
What to write
The starter already has ConfigError(field, reason), which keeps both
strings as attributes, and this dataclass:
@dataclass(frozen=True, slots=True)
class ServerConfig:
host: str
port: int
workers: int = 4
debug: bool = False
Fix load_config(stream: BinaryIO) -> ServerConfig:
- Read the stream with
tomllib.load. - Check the TOML syntax first, then the
servertable, thenhost,port,workersanddebug, in that order. Raise aConfigErrorfor the first problem you find, using the table below. - For each setting, check that it is there and has the right type before you check its range.
- Use
workers = 4anddebug = Falseonly when the key is missing. A value that is present must pass its check. - Keep
hostexactly as written, even if it is empty or only spaces. This exercise checks its type only. - Ignore other keys and other tables. Accept
serverwritten as an inline table too, such asserver = { host = "h", port = 80 }. - Check the types at runtime before you build
ServerConfig. The dataclass does not check them, and neither doestyping.cast.
| Problem | field |
reason |
|---|---|---|
TOMLDecodeError while parsing |
"<document>" |
"malformed TOML" |
server is missing or is not a table |
"server" |
"missing table" |
host is missing |
"server.host" |
"missing" |
host is not a string |
"server.host" |
"expected string" |
port is missing |
"server.port" |
"missing" |
port is not an integer, or is a boolean |
"server.port" |
"expected integer" |
port is outside 1 to 65535 |
"server.port" |
"out of range" |
workers is present but not an integer, or is a boolean |
"server.workers" |
"expected integer" |
workers is present but below 1 |
"server.workers" |
"out of range" |
debug is present but not a boolean |
"server.debug" |
"expected boolean" |
Turn only TOMLDecodeError into the "<document>" error. Let any other
error, such as a stream that fails to read, propagate.
Then fix solve(document). It already encodes the text as UTF-8, wraps it
in io.BytesIO and calls load_config. Catch ConfigError and return
{"ok": False, "field": exc.field, "reason": exc.reason}. On success, keep
the report the starter returns, with the keys ok, host, port,
workers and debug.
Edge cases
port = trueis an"expected integer"error, because a boolean is not a port number.workers = 0is an"out of range"error, not a reason to use the default.- The test documents use TOML 1.0 syntax.
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.