]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Discontinue dynamic __visit_name__
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 28 Feb 2020 19:56:25 +0000 (14:56 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 2 Mar 2020 00:32:48 +0000 (19:32 -0500)
Removed very antiquated logic that checks if __visit_name__
is a property.  There's no need for this as the compiler can handle
switching between implementations.  Convert _compile_dispatch()
to be fully inlined.

Change-Id: Ic0c7247c2d7dfed93a27f09250a8ed6352370764

lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/schema.py
lib/sqlalchemy/sql/visitors.py
test/profiles.txt
test/sql/test_compiler.py

index 04ae2532bf8e0c8b67795c44d4423bad787b19fd..9c1f50ce13e2dd789c1f096dc053dd27e8e08377 100644 (file)
@@ -3542,6 +3542,12 @@ class DDLCompiler(Compiled):
         else:
             return None
 
+    def visit_table_or_column_check_constraint(self, constraint, **kw):
+        if constraint.is_column_level:
+            return self.visit_column_check_constraint(constraint)
+        else:
+            return self.visit_check_constraint(constraint)
+
     def visit_check_constraint(self, constraint):
         text = ""
         if constraint.name is not None:
index 7cece42d062f9289aefb3388d283bc353dfd85e2..e6d3a6b059c25c7e2d24b059da3f0307e2a67916 100644 (file)
@@ -2238,14 +2238,6 @@ class ColumnDefault(DefaultGenerator):
                 "positional arguments"
             )
 
-    def _visit_name(self):
-        if self.for_update:
-            return "column_onupdate"
-        else:
-            return "column_default"
-
-    __visit_name__ = property(_visit_name)
-
     def __repr__(self):
         return "ColumnDefault(%r)" % (self.arg,)
 
@@ -2861,6 +2853,8 @@ class CheckConstraint(ColumnCollectionConstraint):
 
     _allow_multiple_tables = True
 
+    __visit_name__ = "table_or_column_check_constraint"
+
     @_document_text_coercion(
         "sqltext",
         ":class:`.CheckConstraint`",
@@ -2925,13 +2919,9 @@ class CheckConstraint(ColumnCollectionConstraint):
         if table is not None:
             self._set_parent_with_dispatch(table)
 
-    def __visit_name__(self):
-        if isinstance(self.parent, Table):
-            return "check_constraint"
-        else:
-            return "column_check_constraint"
-
-    __visit_name__ = property(__visit_name__)
+    @property
+    def is_column_level(self):
+        return not isinstance(self.parent, Table)
 
     def copy(self, target_table=None, **kw):
         if target_table is not None:
index c946bb4ab24ee9c985b78b4488ed6ae2836fca58..77e6b53a8ad9a6deaaf97cd820e058eed8b6eb3b 100644 (file)
@@ -24,7 +24,6 @@ http://techspot.zzzeek.org/2008/01/23/expression-transformations/ .
 """
 
 from collections import deque
-import operator
 
 from .. import exc
 from .. import util
@@ -53,32 +52,26 @@ def _generate_compiler_dispatch(cls):
     """
     visit_name = cls.__visit_name__
 
-    if isinstance(visit_name, util.compat.string_types):
-        # There is an optimization opportunity here because the
-        # the string name of the class's __visit_name__ is known at
-        # this early stage (import time) so it can be pre-constructed.
-        getter = operator.attrgetter("visit_%s" % visit_name)
-
-        def _compiler_dispatch(self, visitor, **kw):
-            try:
-                meth = getter(visitor)
-            except AttributeError:
-                raise exc.UnsupportedCompilationError(visitor, cls)
-            else:
-                return meth(self, **kw)
-
-    else:
-        # The optimization opportunity is lost for this case because the
-        # __visit_name__ is not yet a string. As a result, the visit
-        # string has to be recalculated with each compilation.
-        def _compiler_dispatch(self, visitor, **kw):
-            visit_attr = "visit_%s" % self.__visit_name__
-            try:
-                meth = getattr(visitor, visit_attr)
-            except AttributeError:
-                raise exc.UnsupportedCompilationError(visitor, cls)
-            else:
-                return meth(self, **kw)
+    if not isinstance(visit_name, util.compat.string_types):
+        raise exc.InvalidRequestError(
+            "__visit_name__ on class %s must be a string at the class level"
+            % cls.__name__
+        )
+
+    code = (
+        "def _compiler_dispatch(self, visitor, **kw):\n"
+        "    try:\n"
+        "        meth = visitor.visit_%(name)s\n"
+        "    except AttributeError:\n"
+        "        util.raise_from_cause(\n"
+        "            exc.UnsupportedCompilationError(visitor, cls))\n"
+        "    else:\n"
+        "        return meth(self, **kw)\n"
+    ) % {"name": visit_name}
+
+    _compiler_dispatch = langhelpers._exec_code_in_env(
+        code, {"exc": exc, "cls": cls, "util": util}, "_compiler_dispatch"
+    )
 
     _compiler_dispatch.__doc__ = """Look for an attribute named "visit_"
         + self.__visit_name__ on the visitor, and call it with the same
index 4244e126636a1b1cb2080dc0e21061e284dd6793..a6e4b184507af40d148afdf237a08d1cbd609c52 100644 (file)
@@ -121,30 +121,30 @@ test.aaa_profiling.test_compiler.CompileTest.test_update 3.7_sqlite_pysqlite_dba
 
 # TEST: test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause
 
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mssql_pyodbc_dbapiunicode_cextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mssql_pyodbc_dbapiunicode_nocextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_mysqldb_dbapiunicode_cextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_mysqldb_dbapiunicode_nocextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_pymysql_dbapiunicode_cextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_pymysql_dbapiunicode_nocextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_oracle_cx_oracle_dbapiunicode_cextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_oracle_cx_oracle_dbapiunicode_nocextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_postgresql_psycopg2_dbapiunicode_cextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_postgresql_psycopg2_dbapiunicode_nocextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_sqlite_pysqlite_dbapiunicode_cextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_sqlite_pysqlite_dbapiunicode_nocextensions 159
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mssql_pyodbc_dbapiunicode_cextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mssql_pyodbc_dbapiunicode_nocextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_mysqldb_dbapiunicode_cextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_mysqldb_dbapiunicode_nocextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_pymysql_dbapiunicode_cextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_pymysql_dbapiunicode_nocextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_oracle_cx_oracle_dbapiunicode_cextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_oracle_cx_oracle_dbapiunicode_nocextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_postgresql_psycopg2_dbapiunicode_cextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_postgresql_psycopg2_dbapiunicode_nocextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_sqlite_pysqlite_dbapiunicode_cextensions 164
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_sqlite_pysqlite_dbapiunicode_nocextensions 164
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mssql_pyodbc_dbapiunicode_cextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mssql_pyodbc_dbapiunicode_nocextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_mysqldb_dbapiunicode_cextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_mysqldb_dbapiunicode_nocextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_pymysql_dbapiunicode_cextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_mysql_pymysql_dbapiunicode_nocextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_oracle_cx_oracle_dbapiunicode_cextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_oracle_cx_oracle_dbapiunicode_nocextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_postgresql_psycopg2_dbapiunicode_cextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_postgresql_psycopg2_dbapiunicode_nocextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_sqlite_pysqlite_dbapiunicode_cextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 2.7_sqlite_pysqlite_dbapiunicode_nocextensions 151
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mssql_pyodbc_dbapiunicode_cextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mssql_pyodbc_dbapiunicode_nocextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_mysqldb_dbapiunicode_cextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_mysqldb_dbapiunicode_nocextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_pymysql_dbapiunicode_cextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_mysql_pymysql_dbapiunicode_nocextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_oracle_cx_oracle_dbapiunicode_cextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_oracle_cx_oracle_dbapiunicode_nocextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_postgresql_psycopg2_dbapiunicode_cextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_postgresql_psycopg2_dbapiunicode_nocextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_sqlite_pysqlite_dbapiunicode_cextensions 156
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.7_sqlite_pysqlite_dbapiunicode_nocextensions 156
 
 # TEST: test.aaa_profiling.test_misc.CacheKeyTest.test_statement_one
 
index 6f16f0514959ebf9e88c8f275eb87599b056a5ee..5030f9df847af0da964e3aaaf4c42cd32800ae9f 100644 (file)
@@ -3642,16 +3642,17 @@ class UnsupportedTest(fixtures.TestBase):
     def test_unsupported_element_meth_visit_name(self):
         from sqlalchemy.sql.expression import ClauseElement
 
-        class SomeElement(ClauseElement):
-            @classmethod
-            def __visit_name__(cls):
-                return "some_element"
+        def go():
+            class SomeElement(ClauseElement):
+                @classmethod
+                def __visit_name__(cls):
+                    return "some_element"
 
         assert_raises_message(
-            exc.UnsupportedCompilationError,
-            r"Compiler <sqlalchemy.sql.compiler.StrSQLCompiler .*"
-            r"can't render element of type <class '.*SomeElement'>",
-            SomeElement().compile,
+            exc.InvalidRequestError,
+            r"__visit_name__ on class SomeElement must be a string at "
+            r"the class level",
+            go,
         )
 
     def test_unsupported_operator(self):