]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed an internal "memoization" routine for method types such
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 8 Jun 2015 22:36:27 +0000 (18:36 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 8 Jun 2015 22:36:27 +0000 (18:36 -0400)
that a Python descriptor is no longer used; repairs inspectability
of these methods including support for Sphinx documentation.

doc/build/changelog/changelog_10.rst
lib/sqlalchemy/util/langhelpers.py
test/base/test_utils.py

index 522f48789ba9273bb119f6767f1308ff1415b72d..8521a6cd23e1b71a4efd7f3a006e8ede1bb03d4f 100644 (file)
 .. 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
index 3d7bfad0ae881302164ce1ab6331b9f1d145b8a1..499515142a1fd7a10afef823487bfbcdf437b95d 100644 (file)
@@ -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):
index df61d787473e2789af72cdb67cbcd773b704a425..256f52850c7a52fa6461f159d2b26c87a6d7f8a6 100644 (file)
@@ -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__