Skip to content

Commit

Permalink
PEP 769: Better explanation on which exceptions are captured (#4272)
Browse files Browse the repository at this point in the history
* Better explanation on which exceptions are captured

* Better wording
  • Loading branch information
facundobatista authored Feb 15, 2025
1 parent 5fe54b0 commit 9a8c0f2
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions peps/pep-0769.rst
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ The implementation of ``attrgetter`` is quite direct: it implies using

try:
value = getattr(obj, "name")
except (TypeError, IndexError, KeyError):
except (IndexError, KeyError):
value = XYZ

Note we cannot rely on using ``getattr`` with a default value, as it would
Expand All @@ -200,35 +200,41 @@ attribute chain is specified (e.g.
The implementation for ``itemgetter`` and ``getitem`` is not that
easy. The more straightforward way is also simple to define and
understand: attempting ``__getitem__`` and catching a possible
exception (any of the three indicated in ``__getitem__`` `reference`_).
This way, ``itemgetter(123, default=XYZ)(obj)`` or
``getitem(obj, 123, default=XYZ)`` would be equivalent to::
exception (see below). This way, ``itemgetter(123, default=XYZ)(obj)``
or ``getitem(obj, 123, default=XYZ)`` would be equivalent to::

try:
value = obj[123]
except (TypeError, IndexError, KeyError):
except (IndexError, KeyError):
value = XYZ

However, for performance reasons the implementation may look more
like the following, which has the same exact behaviour::
like the following, which has the same exact behavior::

if type(obj) == dict:
value = obj.get(123, XYZ)
else:
try:
value = obj[123]
except (TypeError, IndexError, KeyError):
except (IndexError, KeyError):
value = XYZ

Note how the verification is about the exact type and not using
``isinstance``; this is to ensure the exact behaviour, which would be
``isinstance``; this is to ensure the exact behavior, which would be
impossible if the object is a user defined one that inherits ``dict``
but overwrites ``get`` (similar reason to not check if the object has
a ``get`` method).

This way, performance is better but it's just an implementation detail,
so we can keep the original explanation on how it behaves.

Regarding the exception to be captured, even if ``__getitem__``
can raise ``IndexError``, ``KeyError``, or ``TypeError`` (see its
`reference`_), only the first two can happen if the container does not
contain the indicated key or index, and the latter is likely to signal
a bug in the code, so we're not capturing it to trigger the default
behavior.


Corner Cases
------------
Expand Down

0 comments on commit 9a8c0f2

Please sign in to comment.