]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Do not register the GenericFunction in sql.functions._registry
authorAdrien Berchet <adrien.berchet@gmail.com>
Fri, 3 May 2019 16:02:17 +0000 (12:02 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 6 May 2019 21:42:18 +0000 (17:42 -0400)
Fixed that the :class:`.GenericFunction` class was inadvertently
registering itself as one of the named functions.  Pull request courtesy
Adrien Berchet.

Fixes: #4653
Closes: #4654
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4654
Pull-request-sha: 1112b89f0d5af8cd5ba88cef744698a79dbdb963

Change-Id: Ia0d366d3bff44a763aa496287814278dff732a19
(cherry picked from commit 61c47cbdc6058c040b301caa0864710a8d85d3a4)

doc/build/changelog/unreleased_13/4653.rst [new file with mode: 0644]
lib/sqlalchemy/sql/functions.py
test/sql/test_functions.py

diff --git a/doc/build/changelog/unreleased_13/4653.rst b/doc/build/changelog/unreleased_13/4653.rst
new file mode 100644 (file)
index 0000000..67e198c
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 4653
+
+    Fixed that the :class:`.GenericFunction` class was inadvertently
+    registering itself as one of the named functions.  Pull request courtesy
+    Adrien Berchet.
\ No newline at end of file
index cb503892c84b355f24739a1cc8b11fa15cd180c2..334045144024431dcb541bb0ab71a901a5e2d98f 100644 (file)
@@ -635,7 +635,17 @@ class _GenericMeta(VisitableType):
             # legacy
             if "__return_type__" in clsdict:
                 cls.type = clsdict["__return_type__"]
-            register_function(identifier, cls, package)
+
+            # Check _register attribute status
+            cls._register = getattr(cls, '_register', True)
+
+            # Register the function if required
+            if cls._register:
+                register_function(identifier, cls, package)
+            else:
+                # Set _register to True to register child classes by default
+                cls._register = True
+
         super(_GenericMeta, cls).__init__(clsname, bases, clsdict)
 
 
@@ -703,6 +713,7 @@ class GenericFunction(util.with_metaclass(_GenericMeta, Function)):
     """
 
     coerce_arguments = True
+    _register = False
 
     def __init__(self, *args, **kwargs):
         parsed_args = kwargs.pop("_parsed_args", None)
index b03b156bc1247a2f64964bd506348c1eff0befc7..7f7ba14e23029018cc0168c4bc5e8a945629c30c 100644 (file)
@@ -1057,3 +1057,43 @@ def exec_sorted(statement, *args, **kw):
     return sorted(
         [tuple(row) for row in statement.execute(*args, **kw).fetchall()]
     )
+
+
+class RegisterTest(fixtures.TestBase, AssertsCompiledSQL):
+    __dialect__ = "default"
+
+    def setup(self):
+        self._registry = deepcopy(functions._registry)
+
+    def teardown(self):
+        functions._registry = self._registry
+
+    def test_GenericFunction_is_registered(self):
+        assert 'GenericFunction' not in functions._registry['_default']
+
+    def test_register_function(self):
+
+        # test generic function registering
+        class registered_func(GenericFunction):
+            _register = True
+
+            def __init__(self, *args, **kwargs):
+                GenericFunction.__init__(self, *args, **kwargs)
+
+        class registered_func_child(registered_func):
+            type = sqltypes.Integer
+
+        assert 'registered_func' in functions._registry['_default']
+        assert isinstance(func.registered_func_child().type, Integer)
+
+        class not_registered_func(GenericFunction):
+            _register = False
+
+            def __init__(self, *args, **kwargs):
+                GenericFunction.__init__(self, *args, **kwargs)
+
+        class not_registered_func_child(not_registered_func):
+            type = sqltypes.Integer
+
+        assert 'not_registered_func' not in functions._registry['_default']
+        assert isinstance(func.not_registered_func_child().type, Integer)