]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Check for __module__ not present in util.wrap_callable()
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 14 Oct 2016 17:26:35 +0000 (13:26 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 14 Oct 2016 17:26:35 +0000 (13:26 -0400)
The newly added wrap_callable() function assumes __module__
is present when this is not the case for objects such as
functools.partial.

Change-Id: Ia226260e9a65419e26d5c1f7187512f7fd4bb7c1
Fixes: #3823
doc/build/changelog/changelog_11.rst
lib/sqlalchemy/util/langhelpers.py
test/base/test_utils.py

index b879adc10bd65a385d95bc8b10baa68472e8b51e..b90b932b55402a7c1a8715d79a16625968bf4bbf 100644 (file)
 .. changelog::
     :version: 1.1.2
 
+    .. change::
+        :tags: bug, sql
+        :tickets: 3823
+
+        Fixed a regression caused by a newly added function that performs the
+        "wrap callable" function of sql :class:`.DefaultGenerator` objects,
+        an attribute error raised for ``__module__`` when the default callable
+        was a ``functools.partial`` or other object that doesn't have a
+        ``__module__`` attribute.
+
+
 .. changelog::
     :version: 1.1.1
     :released: October 7, 2016
index 4675f7cdb8039a619ce29672dedff72ca803275d..f2ca8066473b7aec63d5a090b45d41bf21e23441 100644 (file)
@@ -1398,7 +1398,8 @@ def wrap_callable(wrapper, fn):
     else:
         _f = wrapper
         _f.__name__ = fn.__class__.__name__
-        _f.__module__ = fn.__module__
+        if hasattr(fn, '__module__'):
+            _f.__module__ = fn.__module__
 
         if hasattr(fn.__call__, '__doc__') and fn.__call__.__doc__:
             _f.__doc__ = fn.__call__.__doc__
index 7e2473deed88d429907338b521a60970b1f73df3..5199d6155d87c573454354294bff0167b6bdb1da 100644 (file)
@@ -382,6 +382,19 @@ class WrapCallableTest(fixtures.TestBase):
         eq_(c.__name__, "MyFancyDefault")
         eq_(c.__doc__, None)
 
+    def test_wrapping_update_wrapper_functools_parial(self):
+        def my_default(x):
+            return x
+
+        import functools
+        my_functools_default = functools.partial(my_default, 5)
+
+        c = util.wrap_callable(
+            lambda: my_functools_default(), my_functools_default)
+        eq_(c.__name__, "partial")
+        eq_(c.__doc__, my_functools_default.__call__.__doc__)
+        eq_(c(), 5)
+
 
 class ToListTest(fixtures.TestBase):
     def test_from_string(self):