PCAP Exceptions and File I/O Practice Question
A junior developer is writing a helper that reads a small log file and returns its contents as a single string. The file is guaranteed to exist and be readable. The helper currently uses an explicit open, a try/finally block, and manual close call. A reviewer asks for the most idiomatic Python 3 replacement that guarantees closure. Which construct should be used?
⚠ Common exam trap
The trap here is treating a plain open followed by a close as equivalent to the with statement, forgetting that an exception between them bypasses the close call entirely.
Answer choices
Why each option matters
Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.
Correct answer & explanation
✓
with open('app.log') as f: return f.read()
The with statement uses the context manager protocol, invoking __exit__ on the file object so close runs even when an exception propagates out of the block. That makes it the idiomatic replacement for manual try/finally plus close. The alternatives either skip cleanup on exceptions, depend on garbage collection, or contain an empty finally that releases nothing.
Answer analysis
Option-by-option breakdown
For each option: why learners choose it and why it is or isn't the right answer here.
- ✗
f = open('app.log'); data = f.read(); f.close(); return data
Why it's wrong here
This works only when no exception occurs between open and close. If read raises, for example due to a decoding error, close is skipped and the descriptor leaks until garbage collection. The reviewer explicitly asked for a guarantee, so a bare sequential close does not meet the requirement even though it appears tidy.
- ✓
with open('app.log') as f: return f.read()
Why this is correct
The with statement is a context manager that calls close on the file object when the block exits, whether normally or through an exception. It replaces the manual try/finally and close calls with a single readable construct. This is the idiomatic Python 3 approach and directly satisfies the reviewer's request for guaranteed closure.
- ✗
data = open('app.log').read(); return data
Why it's wrong here
The file object created by open has no reference retained, so it relies on reference counting or the garbage collector to close it. In CPython this usually happens quickly, but it is not a language guarantee and other implementations may delay it. It also provides no protection if read raises before the object is collected.
- ✗
f = open('app.log'); try: return f.read(); finally: pass
Why it's wrong here
The finally block contains only pass, so it performs no cleanup at all. The file remains open after the function returns, leaking a descriptor on every call. Although the syntax resembles the correct pattern, the absence of an actual close call means the resource is never released deterministically.
Visual reference
Go deeper
Related to this question
About these practice questions
One of 421 original PCAP practice questions on Courseiva, each with a full explanation and wrong-answer analysis — not exam dumps or protected exam content. Learn why practice questions differ from exam dumps →
JA
Written and reviewed by Johnson Ajibi, MSc IT Security
Senior Network & Security Engineer · founder of Courseiva
Last reviewed September 2026 · checked against the official Python Institute exam blueprint
This PCAP practice question is part of Courseiva's free Python Institute certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PCAP exam.