FAQ: Context Managers - Handling Exceptions II

This community-built FAQ covers the “Handling Exceptions II” exercise from the lesson “Context Managers”.

Paths and Courses
This exercise can be found in the following Codecademy content:
Learn Intermediate Python3

FAQs on the exercise Handling Exceptions II

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in #get-help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to #get-help and #community:tips-and-resources. If you are wanting feedback or inspiration for a project, check out #project.

Looking for motivation to keep learning? Join our wider discussions in #community

Learn more about how to use this guide.

Found a bug? Report it online, or post in #community:Codecademy-Bug-Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Why is it preferable to use

if isinstance(exc_value, AttributeError):

instead of

if exc_type == AttributeError:

for exception type handeling in the __exit__() function of a context manager?

Since you already have the type here with exc_type you could consider https://docs.python.org/3/library/functions.html#issubclass instead for similar behaviour to isinstance.

If you want to match a type or any children of that type use isinstance instead of ==. The behaviour with isinstance/issubclass is similar to the behaviour of the except clause in a try statement where catching Exception catches any children of the Exception type too (which would be almost all runtime errors).

In many/most cases isinstance is used instead of type(obj) == because it allows types to replaced by a newer type that simply inherits from the old without breaking as much code (it handles inheritance which is normally considred good design). If you already have the type issubclass also handles inheritance.

As ever only catch the things you 100% want to catch so the most specific exception relevant to your problem and isinstance or issubclass would probably be the best way to go.

1 Like

That’s a great answer. Thanks. But as good answers often do, it leads me to a new question. Why, then include the exc_type at all? Couldn’t we get that information from type(exc_value)?

1 Like

Hmm, I think there’s a bit of a legacy issue with early versions of python when it comes to the three part value. In Python3 a single exception instance contains basically everything you need to know: type, value and traceback. The traceback for example is now bound to an exception too under .__traceback__. There are fewer tools that require all three parts but unfortunately they are still around, which I presume is because they can’t be removed without breaking too much legacy code.

You’d have to look into the history to find exactly why. I think trackbacks were a separate entity once upon a time (not bound in any way) and I think there was something funny about exception types being strings rather than real types which meant they were separate actions but that’s not something I know much about, if you’re really curious you might have to have a web search (it might go back to very early python versions).

Edit: Think I found the relevant details anyway:
The introduction of the .__traceback__ attribute: PEP 344 -- Exception Chaining and Embedded Tracebacks | Python.org
Note that some of the proposed future changes here (namely changing .__exit__ to a single parameter function never came about).

As for why types and values separated… read also the linked blog to Guido’s description of exceptions using strings prior to Python1.5 apparently (with legacy support for quite a long time afterwards apparently): python - Why does traceback.format_exception require a traceback parameter instead of using ex.__traceback__? - Stack Overflow

I’m confused on how exactly “return True” suppresses an error. What is True being returned to and how does it repress the error?

Thanks in advance.