We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Everyday Standard Library Tools step 43 of 55
Close a Stream Only If You Opened It
Write two helpers that each make one decision. read_or_default
falls back to a default only when a file is missing. process closes a
stream only when it opened that stream itself.
read_or_default(lambda: "payload", "DEFAULT") # "payload"
read_or_default(load_missing_file, "DEFAULT") # "DEFAULT"
process(None, lambda: FakeStream("opened", log))
# "DATA FROM OPENED", and the new stream is closed
What to write
read_or_default(load, default):
- Call
load()once and return what it returns, even an empty string. - If it raises
FileNotFoundError, returndefault. - Let every other error through, including
PermissionErrorandIsADirectoryError.
Use suppress(FileNotFoundError). The starter suppresses Exception, which
hides the permission error too.
process(stream, factory) returns the stream's read() result in upper
case:
- If the caller passes a
stream, read it. Do not callfactory, and do not closestream, because the caller owns it. - If
streamisNone, callfactory()once, read the new stream, and close it when you finish, even ifread()raises. - If
factory()itself raises, let the error through.
Pick the context manager with nullcontext(stream) for a given stream and
closing(factory()) for a new one. Annotate it as
AbstractContextManager[FakeStream], and write the reading code once,
inside one with block. The starter repeats the reading code and closes a
stream it did not open.
FakeStream.read() returns "data from <name>". Its close() sets
closed to True and appends "close:<name>" to a shared log. It has no
__enter__, which is why it needs closing.
Write solve
solve(mode, provided) does these steps:
- Define a
loadfunction. It raisesFileNotFoundErrorwhenmodeis"missing", raisesPermissionErrorwhenmodeis"denied", and returns"payload"otherwise. - Call
read_or_default(load, "DEFAULT")and keep the result astext. If aPermissionErrorcomes out, settextto the string"PermissionError". Go on to step 3 in every case. - Create an empty
loglist. Ifprovidedis true, passFakeStream("given", log)toprocess. Otherwise passNone. The factory always createsFakeStream("opened", log). - Return a dict with the keys
text,result,logandgiven_closed.resultis whatprocessreturned.given_closedis the given stream'sclosedvalue, orNonewhen there is no given stream.
Expected results
- With
provided=True,resultis"DATA FROM GIVEN",logis[]andgiven_closedisFalse. - With
provided=False,resultis"DATA FROM OPENED",logis["close:opened"]andgiven_closedisNone. textis"DEFAULT"for"missing","PermissionError"for"denied", and"payload"for any other mode.
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.