summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-04-30 20:20:02 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-04-30 20:20:02 -0400
commit4992aafecceb7a6301cfa4926bc709c873f37cc7 (patch)
tree3e8b944f4918aa2fbd26cedbe01db740d0a2a340
parente0f9b279f43759886c61e6c82f97d95d0093fdf7 (diff)
downloadsqlalchemy-4992aafecceb7a6301cfa4926bc709c873f37cc7.tar.gz
- revise the last commit with a more traditional approach
using descriptors; ensure that mock.patch() honors descriptor setters
-rw-r--r--lib/sqlalchemy/pool.py43
-rw-r--r--test/engine/test_pool.py7
2 files changed, 15 insertions, 35 deletions
diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py
index 8eb9d796d..0a4cdadc9 100644
--- a/lib/sqlalchemy/pool.py
+++ b/lib/sqlalchemy/pool.py
@@ -219,7 +219,6 @@ class Pool(log.Identified):
log.instance_logger(self, echoflag=echo)
self._threadconns = threading.local()
self._creator = creator
- self._set_should_wrap_creator()
self._recycle = recycle
self._invalidate_time = 0
self._use_threadlocal = use_threadlocal
@@ -250,7 +249,16 @@ class Pool(log.Identified):
for l in listeners:
self.add_listener(l)
- def _set_should_wrap_creator(self):
+ @property
+ def _creator(self):
+ return self.__dict__['_creator']
+
+ @_creator.setter
+ def _creator(self, creator):
+ self.__dict__['_creator'] = creator
+ self._invoke_creator = self._should_wrap_creator(creator)
+
+ def _should_wrap_creator(self, creator):
"""Detect if creator accepts a single argument, or is sent
as a legacy style no-arg function.
@@ -259,8 +267,7 @@ class Pool(log.Identified):
try:
argspec = util.get_callable_argspec(self._creator, no_self=True)
except TypeError:
- self._should_wrap_creator = (True, self._creator)
- return
+ return lambda crec: creator()
defaulted = argspec[3] is not None and len(argspec[3]) or 0
positionals = len(argspec[0]) - defaulted
@@ -268,36 +275,14 @@ class Pool(log.Identified):
# look for the exact arg signature that DefaultStrategy
# sends us
if (argspec[0], argspec[3]) == (['connection_record'], (None,)):
- self._should_wrap_creator = (False, self._creator)
+ return creator
# or just a single positional
elif positionals == 1:
- self._should_wrap_creator = (False, self._creator)
+ return creator
# all other cases, just wrap and assume legacy "creator" callable
# thing
else:
- self._should_wrap_creator = (True, self._creator)
-
- def _invoke_creator(self, connection_record):
- """adjust for old or new style "creator" callable.
-
- This function is spending extra effort in order to accommodate
- any degree of manipulation of the _creator callable by end-user
- applications, including ad-hoc patching in test suites.
-
- """
-
- should_wrap, against_creator = self._should_wrap_creator
- creator = self._creator
-
- if creator is not against_creator:
- # check if the _creator function has been patched since
- # we last looked at it
- self._set_should_wrap_creator()
- return self._invoke_creator(connection_record)
- elif should_wrap:
- return self._creator()
- else:
- return self._creator(connection_record)
+ return lambda crec: creator()
def _close_connection(self, connection):
self.logger.debug("Closing connection %r", connection)
diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py
index 912c6c3fe..3684fc3e6 100644
--- a/test/engine/test_pool.py
+++ b/test/engine/test_pool.py
@@ -1844,21 +1844,16 @@ class CreatorCompatibilityTest(PoolTestBase):
conn.invalidate()
conn.close()
- # test that the 'should_wrap_creator' memoized attribute
+ # test that the 'should_wrap_creator' status
# will dynamically switch if the _creator is monkeypatched.
- is_(e.pool.__dict__.get("_should_wrap_creator")[0], False)
-
# patch it with a zero-arg form
with patch.object(e.pool, "_creator", mock_create):
conn = e.connect()
conn.invalidate()
conn.close()
- is_(e.pool.__dict__.get("_should_wrap_creator")[0], True)
-
conn = e.connect()
conn.close()
- is_(e.pool.__dict__.get("_should_wrap_creator")[0], False)