We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Modelling Data with Dataclasses step 4 of 28
Hide Secret Fields When You Print a Record
Your service logs its settings when it starts, and the log line shows the database password:
print(SAMPLES["endpoint"])
# Endpoint(host='db.internal', port=5432, password='hunter2')
Write redacted_repr, which returns the same text with '***' in place
of each field marked as secret.
solve("endpoint")
# "Endpoint(host='db.internal', port=5432, password='***')"
Three field options
The starter's classes use three options of dataclasses.field():
repr=Falseleaves the field out of the generated__repr__.compare=Falseleaves the field out of the generated==. The field still appears in the repr.metadatais a read-only mapping that you attach to a field for your own code to read. The dataclass ignores it. Here,metadata={"sensitive": True}marks a secret.
Metadata hides nothing by itself. print() on an Endpoint still shows
its password. Only code that calls redacted_repr hides it.
What to write
Fill in redacted_repr(obj). Go through dataclasses.fields(obj) in
declaration order, and apply these rules to each field, in this order:
- If
f.reprisFalse, leave the field out. - If
bool(f.metadata.get("sensitive", False))isTrue, write the value as'***'. Include the quotes, so the text is the same asrepr("***"). - If the value is a dataclass instance, call
redacted_repron it. Test for one withis_dataclass(value) and not isinstance(value, type), becauseis_dataclassis also true for a dataclass class. - Otherwise, write
repr(value).
Join the name=value parts with a comma and a space, and wrap them as
ClassName(...). Use type(obj).__name__, not __qualname__. A record
with no fields to show becomes ClassName().
Keep the classes and solve as they are. solve takes a name from
SAMPLES and calls your function.
Edge cases
- A secret field shows
'***'even when its value is empty. - A field that is both secret and
repr=Falsedoes not appear, because rule 1 comes first. - A secret field that holds a dataclass shows
'***'. Do not look inside it. - Recurse only into a field whose value is a dataclass. Lists, tuples and dicts keep their normal repr, even when they hold a secret.
For Credentials, user appears as normal, token becomes '***', and
api_key does not appear. endpoint recurses, so its password becomes
'***'. headers keeps its dict repr, and attempts appears even though
it has compare=False.
Your code must pass mypy --strict. DataclassInstance is a type that
exists only for the type checker and means "any dataclass instance". That
is why the starter imports it under if TYPE_CHECKING: and writes it in
quotes.
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.