diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-04-30 20:20:02 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-04-30 20:20:02 -0400 |
commit | 4992aafecceb7a6301cfa4926bc709c873f37cc7 (patch) | |
tree | 3e8b944f4918aa2fbd26cedbe01db740d0a2a340 | |
parent | e0f9b279f43759886c61e6c82f97d95d0093fdf7 (diff) | |
download | sqlalchemy-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.py | 43 | ||||
-rw-r--r-- | test/engine/test_pool.py | 7 |
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) |