I was reading this article and it was showing this interesting bit of code:
class Car(object):
def _factory_error_handler(self):
try:
yield
except FactoryColorError, err:
stacktrace = sys.exc_info()[2]
raise ValidationError(err.message), None, stacktrace
def _create_customizer_error_handler(self, vin):
try:
yield
except CustomizerError, err:
self._factory.remove_car(vin)
stacktrace = sys.exc_info()[2]
raise ValidationError(err.message), None, stacktrace
def _update_customizer_error_handler(self, vin):
try:
yield
except CustomizerError, err:
stacktrace = sys.exc_info()[2]
raise ValidationError(err.message), None, stacktrace
def create(self, color, stereo):
with self._factory_error_handler():
vin = self._factory.make_car(color)
with self._create_customizer_error_handler(vin):
self._customizer.update_car(vin, stereo)
return vin
def update(self, vin, color, stereo):
with self._factory_error_handler():
self._factory.update_car_color(vin, color)
with self._update_customizer_error_handler(vin):
self._customizer.update_car(vin, stereo)
return
Here, they are yielding with no argument in a try
block. And then using it within a with
block. Can someone please explain what is going on here?
The code in the post appears to be wrong. It would make sense if the various error handlers were decorated with contextmanager
. Note that, in the post, the code imports contextmanager
but doesn't use it. This makes me think the person just made a mistake in creating the post and left contextmanager
out of that example. (The later examples in the post do use contextmanager
.) I think the code as posted will cause an AttributeError
, because the various _error_handler
functions aren't context managers and don't have the right __enter__
and __exit__
methods.
With contextmanager
, the code makes sense based on the documentation:
At the point where the generator yields, the block nested in the with statement is executed. The generator is then resumed after the block is exited. If an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With