Context Manager Defines Both enter and exit
ID |
python.ctx_manager_enter_exit |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Python |
Tags |
reliability, suspicious-construct |
Description
Reports classes that define one half of the context-manager protocol but not the other. The runtime requires both enter and exit (or both aenter and aexit for async context managers); a class that only defines one half cannot be used in a with statement.
class Bad:
def __enter__(self): # FLAW — __exit__ is missing
return self
class AlsoBad:
def __exit__(self, *exc): # FLAW — __enter__ is missing
pass
class Good:
def __enter__(self):
return self
def __exit__(self, *exc):
pass
Rationale
A half-implemented context manager throws AttributeError the first time someone tries to use it in a with block — usually well after the class was added. Static detection turns the runtime crash into a code review.
Remediation
Implement the missing half (or remove the existing one if the class was never meant to be a context manager). For a no-op cleanup, exit(self, *exc): pass is sufficient.
For async context managers, use aenter / aexit. Mixing the two protocols (enter plus aexit) does not make a usable manager.