15
0
Files
python-jsonpickle/sqlalchemy13.patch

85 lines
3.1 KiB
Diff

From 838c29e43267e3578d077698386e1adbcc0657c5 Mon Sep 17 00:00:00 2001
From: David Aguilar <davvid@gmail.com>
Date: Mon, 18 Mar 2019 22:32:54 -0700
Subject: [PATCH] unpickler: better support for sqlalchemy >= 1.3
The _safe_hasattr() workaround for older versions of SQLAlchemy
surprisingly breaks newer versions.
Be optimistic and catch the runtime error so that newer versions do not
incur the cost of the original workaround. The older versions are still
supported since they'll land in the old code path.
This is justifiable since it's a generic code path and will speed up
things for 99% of the other objects out there, including newer
sqlalchemy versions.
Closes #254
Signed-off-by: David Aguilar <davvid@gmail.com>
---
jsonpickle/unpickler.py | 11 +++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/jsonpickle/unpickler.py b/jsonpickle/unpickler.py
index f0a93d1..40af4e0 100644
--- a/jsonpickle/unpickler.py
+++ b/jsonpickle/unpickler.py
@@ -42,8 +42,15 @@ def decode(string, backend=None, context=None, keys=False, reset=True,
def _safe_hasattr(obj, attr):
- """A safe (but slow) hasattr() that avoids hasattr"""
- return attr in dir(obj)
+ """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)
class _Proxy(object):
From 670b678a109a7fab91e3e50fb35f65bf75aff1e9 Mon Sep 17 00:00:00 2001
From: David Aguilar <davvid@gmail.com>
Date: Tue, 19 Mar 2019 00:21:19 -0700
Subject: [PATCH] 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: #254
Signed-off-by: David Aguilar <davvid@gmail.com>
---
jsonpickle/unpickler.py | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/jsonpickle/unpickler.py b/jsonpickle/unpickler.py
index 40af4e0..e1f9e75 100644
--- a/jsonpickle/unpickler.py
+++ b/jsonpickle/unpickler.py
@@ -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):