summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-06-08 18:36:27 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-06-08 18:36:27 -0400
commit657be357de569ced699f44bdd96c6ba4e650b492 (patch)
tree53dbd0641c26d2e7a0a79a980a56ffd0c38fab05
parent0e1da3265445fc2afaa54c4025bcab442199dc2b (diff)
downloadsqlalchemy-657be357de569ced699f44bdd96c6ba4e650b492.tar.gz
- 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.
-rw-r--r--doc/build/changelog/changelog_10.rst8
-rw-r--r--lib/sqlalchemy/util/langhelpers.py30
-rw-r--r--test/base/test_utils.py3
3 files changed, 19 insertions, 22 deletions
diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst
index 522f48789..8521a6cd2 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 3d7bfad0a..499515142 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 df61d7874..256f52850 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__