Skip to content

Commit

Permalink
Fix comments on safe_isinstance() (#602)
Browse files Browse the repository at this point in the history
isinstance() is even less safe than I thought.

Proof:

```
>>> class X:
...     @Property
...     def __class__(self): 1/0
... 
>>> isinstance(X(), int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __class__
ZeroDivisionError: division by zero
```
  • Loading branch information
JelleZijlstra authored Mar 18, 2023
1 parent 0e8482f commit 0cfe48a
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions pyanalyze/safe.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,14 @@ def safe_issubclass(cls: type, class_or_tuple: Union[type, Tuple[type, ...]]) ->
def safe_isinstance(obj: object, class_or_tuple: Union[type, Tuple[type, ...]]) -> bool:
"""Safe version of ``isinstance()``.
Apart from incorrect arguments, ``isinstance(a, b)`` can throw an error
only if `b` has a ``__instancecheck__`` method that throws an error.
Therefore, it is not necessary to use ``safe_isinstance()`` if the class
is known to not override ``__instancecheck__``.
``isinstance(a, b)`` can throw an error in the following circumstances:
- ``b`` is not a class
- ``b`` has an ``__instancecheck__`` method that throws an error
- ``a`` has a ``__class__`` property that throws an error
Therefore, ``safe_isinstance()`` must be used when doing ``isinstance`` checks
on arbitrary objects that come from user code.
Defaults to False if ``isinstance()`` throws.
Expand Down

0 comments on commit 0cfe48a

Please sign in to comment.