unpickler: make _safe_hasattr() even safer
Use object.__getattribute__() to implement our hasattr() workaround,
which is even more robust (and performant) than the previous solution.
The old version did work on Python2, but Python3 is unable to catch
recursion
errors so a better solution was needed.
Related-to:
@@ -44,13 +44,10 @@ def decode(string, backend=None, context=None, keys=False, reset=True,
def _safe_hasattr(obj, attr):
"""Workaround unreliable hasattr() availability on sqlalchemy objects"""
try:
- # In sqlalchemy >= 1.3 we can use hasattr().
- return hasattr(obj, attr)
- except RuntimeError:
- # In older versions we use a safe (but slow) method to avoid hasattr().
- # Older versions of sqlalchemy hit maximum recursion errors during
- # deserialization. The workaround is to avoid hasattr().
- return attr in dir(obj)
+ object.__getattribute__(obj, attr)
+ return True
+ except AttributeError:
+ return False
class _Proxy(object):
