]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- The ``__module__`` attribute is now set for all those SQL and
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 14 Oct 2014 15:59:48 +0000 (11:59 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 14 Oct 2014 15:59:48 +0000 (11:59 -0400)
ORM functions that are derived as "public factory" symbols, which
should assist with documentation tools being able to report on the
target module.
fixes #3218

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

index 3d471f1929e2923a8203340ee35a9d08814068bb..8578c788395cb2e98ebdf863c48f43484ce650eb 100644 (file)
     series as well.  For changes that are specific to 1.0 with an emphasis
     on compatibility concerns, see :doc:`/changelog/migration_10`.
 
+    .. change::
+        :tags: bug, general
+        :tickets: 3218
+
+        The ``__module__`` attribute is now set for all those SQL and
+        ORM functions that are derived as "public factory" symbols, which
+        should assist with documentation tools being able to report on the
+        target module.
+
     .. change::
         :tags: feature, sql
 
index f6da9a87d1224399c19761cefc2b62e01379a2a7..5c17bea886d842f5f660d73900e254c17669fa80 100644 (file)
@@ -134,7 +134,8 @@ def public_factory(target, location):
         fn = target.__init__
         callable_ = target
         doc = "Construct a new :class:`.%s` object. \n\n"\
-            "This constructor is mirrored as a public API function; see :func:`~%s` "\
+            "This constructor is mirrored as a public API function; "\
+            "see :func:`~%s` "\
             "for a full usage and argument description." % (
                 target.__name__, location, )
     else:
@@ -155,6 +156,7 @@ def %(name)s(%(args)s):
     exec(code, env)
     decorated = env[location_name]
     decorated.__doc__ = fn.__doc__
+    decorated.__module__ = "sqlalchemy" + location.rsplit(".", 1)[0]
     if compat.py2k or hasattr(fn, '__func__'):
         fn.__func__.__doc__ = doc
     else:
index a378b0160c790144f2525b9a436390998caca72c..f75c5cbe9cfdec52b72d61c97425d352982aa511 100644 (file)
@@ -6,7 +6,7 @@ from sqlalchemy.testing import eq_, is_, ne_, fails_if
 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
 
 class _KeyedTupleTest(object):
 
@@ -1274,6 +1274,43 @@ class DuckTypeCollectionTest(fixtures.TestBase):
             is_(util.duck_type_collection(instance), None)
 
 
+class PublicFactoryTest(fixtures.TestBase):
+
+    def _fixture(self):
+        class Thingy(object):
+            def __init__(self, value):
+                "make a thingy"
+                self.value = value
+
+            @classmethod
+            def foobar(cls, x, y):
+                "do the foobar"
+                return Thingy(x + y)
+
+        return Thingy
+
+    def test_classmethod(self):
+        Thingy = self._fixture()
+        foob = langhelpers.public_factory(
+            Thingy.foobar, ".sql.elements.foob")
+        eq_(foob(3, 4).value, 7)
+        eq_(foob(x=3, y=4).value, 7)
+        eq_(foob.__doc__, "do the foobar")
+        eq_(foob.__module__, "sqlalchemy.sql.elements")
+        assert Thingy.foobar.__doc__.startswith("This function is mirrored;")
+
+    def test_constructor(self):
+        Thingy = self._fixture()
+        foob = langhelpers.public_factory(
+            Thingy, ".sql.elements.foob")
+        eq_(foob(7).value, 7)
+        eq_(foob(value=7).value, 7)
+        eq_(foob.__doc__, "make a thingy")
+        eq_(foob.__module__, "sqlalchemy.sql.elements")
+        assert Thingy.__init__.__doc__.startswith(
+            "Construct a new :class:`.Thingy` object.")
+
+
 class ArgInspectionTest(fixtures.TestBase):
 
     def test_get_cls_kwargs(self):