From the datamodel docs on context managers:
Note that
__exit__()
methods should not reraise the passed-in exception; this is the caller’s responsibility.
I have a temporary file, whose file descriptor I'd like to free with close
but without writing anything to disk. My intuitive solution was to pass on the exception, but that is discouraged in the docs - and surely for good reasons.
class Processor(object):
...
def write(self, *args, **kwargs):
if something_bad_happens:
raise RuntimeError('This format expects %s columns: %s, got %s.' % (
(len(self.cols), self.cols, len(args))))
self.writer.writerow(args)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
# the RuntimeError from write will be set as type, value and so on ..
# I'd like to close the stream here (release the file descriptor),
# but I do not leave a trace of the associated file -
# (one can always 'manually' delete with `os.remove` but maybe there's a
# better way ..?)
self.output_pipe.close()
Also I do not want in this particular case error handling in the caller for two reasons:
- to keep the code in the caller minimal (see below)
- the caller is happy with exceptions (fail fast is what we want here)
The context manager is used something like this:
class Worker(object):
...
def run(self):
# output setup so it will emit a three column CSV
with self.output().open('w') as output:
output.write('John', 'CA', 92101)
output.write('Jane', 'NY', 10304)
# should yield an error, since only three 'columns' are allowed
output.write('Hello', 'world')
update: My quesion was a bit ill-formulated as my problem really boiled down to this: In nested context managers, how can I pass an exception on to the outermost CM?