From: Mike Bayer Date: Mon, 8 Jun 2015 22:36:27 +0000 (-0400) Subject: - Fixed an internal "memoization" routine for method types such X-Git-Tag: rel_1_0_6~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=657be357de569ced699f44bdd96c6ba4e650b492;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed an internal "memoization" routine for method types such that a Python descriptor is no longer used; repairs inspectability of these methods including support for Sphinx documentation. --- diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 522f48789b..8521a6cd23 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -18,6 +18,14 @@ .. changelog:: :version: 1.0.6 + .. change:: + :tags: bug, documentation + :tickets: 2077 + + Fixed an internal "memoization" routine for method types such + that a Python descriptor is no longer used; repairs inspectability + of these methods including support for Sphinx documentation. + .. changelog:: :version: 1.0.5 :released: June 7, 2015 diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 3d7bfad0ae..499515142a 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -755,7 +755,7 @@ class memoized_property(object): obj.__dict__.pop(name, None) -class memoized_instancemethod(object): +def memoized_instancemethod(fn): """Decorate a method memoize its return value. Best applied to no-arg methods: memoization is not sensitive to @@ -764,26 +764,14 @@ class memoized_instancemethod(object): """ - def __init__(self, fget, doc=None): - self.fget = fget - self.__doc__ = doc or fget.__doc__ - self.__name__ = fget.__name__ - - def __get__(self, obj, cls): - if obj is None: - return self - - def oneshot(*args, **kw): - result = self.fget(obj, *args, **kw) - memo = lambda *a, **kw: result - memo.__name__ = self.__name__ - memo.__doc__ = self.__doc__ - obj.__dict__[self.__name__] = memo - return result - - oneshot.__name__ = self.__name__ - oneshot.__doc__ = self.__doc__ - return oneshot + def oneshot(self, *args, **kw): + result = fn(self, *args, **kw) + memo = lambda *a, **kw: result + memo.__name__ = fn.__name__ + memo.__doc__ = fn.__doc__ + self.__dict__[fn.__name__] = memo + return result + return update_wrapper(oneshot, fn) class group_expirable_memoized_property(object): diff --git a/test/base/test_utils.py b/test/base/test_utils.py index df61d78747..256f52850c 100644 --- a/test/base/test_utils.py +++ b/test/base/test_utils.py @@ -7,7 +7,7 @@ from sqlalchemy.testing.util import picklers, gc_collect from sqlalchemy.util import classproperty, WeakSequence, get_callable_argspec from sqlalchemy.sql import column from sqlalchemy.util import langhelpers - +import inspect class _KeyedTupleTest(object): @@ -276,6 +276,7 @@ class MemoizedAttrTest(fixtures.TestBase): val[0] += 1 return v + assert inspect.ismethod(Foo().bar) ne_(Foo.bar, None) f1 = Foo() assert 'bar' not in f1.__dict__