diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-04-29 17:31:12 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-04-30 14:01:52 -0400 |
| commit | ae14861a3197513db5f5a4e3991243482053a46c (patch) | |
| tree | 9d6544fe694e3ffe2304013d43f9b17c6a1b99ea /test/sql | |
| parent | a10a4ea1248902349d789de7f5470bb8e437a584 (diff) | |
| download | sqlalchemy-ae14861a3197513db5f5a4e3991243482053a46c.tar.gz | |
Make the GenericFunction registry fully case insensitive
Registered function names based on :class:`.GenericFunction` are now
retrieved in a case-insensitive fashion in all cases, removing the
deprecation logic from 1.3 which temporarily allowed multiple
:class:`.GenericFunction` objects to exist with differing cases. A
:class:`.GenericFunction` that replaces another on the same name whether or
not it's case sensitive emits a warning before replacing the object.
Fixes: #4649
Change-Id: I265ae19833132db07ed5b5ae40c4d24f659b1ab3
Diffstat (limited to 'test/sql')
| -rw-r--r-- | test/sql/test_deprecations.py | 151 | ||||
| -rw-r--r-- | test/sql/test_functions.py | 26 |
2 files changed, 22 insertions, 155 deletions
diff --git a/test/sql/test_deprecations.py b/test/sql/test_deprecations.py index 08a862e43..7990cd56c 100644 --- a/test/sql/test_deprecations.py +++ b/test/sql/test_deprecations.py @@ -1,17 +1,11 @@ #! coding: utf-8 -from copy import deepcopy - -import pytest - from sqlalchemy import bindparam from sqlalchemy import Column from sqlalchemy import column from sqlalchemy import create_engine -from sqlalchemy import DateTime from sqlalchemy import exc from sqlalchemy import ForeignKey -from sqlalchemy import func from sqlalchemy import Integer from sqlalchemy import MetaData from sqlalchemy import select @@ -23,19 +17,14 @@ from sqlalchemy import text from sqlalchemy import util from sqlalchemy.engine import default from sqlalchemy.schema import DDL -from sqlalchemy.sql import functions from sqlalchemy.sql import util as sql_util -from sqlalchemy.sql.functions import GenericFunction -from sqlalchemy.sql.sqltypes import NullType from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures -from sqlalchemy.testing import in_ from sqlalchemy.testing import mock -from sqlalchemy.testing import not_in_ class DeprecationWarningsTest(fixtures.TestBase): @@ -147,146 +136,6 @@ class DeprecationWarningsTest(fixtures.TestBase): ) -class CaseSensitiveFunctionDeprecationsTest(fixtures.TestBase): - - def setup(self): - self._registry = deepcopy(functions._registry) - self._case_sensitive_registry = deepcopy( - functions._case_sensitive_registry) - functions._registry.clear() - functions._case_sensitive_registry.clear() - - def teardown(self): - functions._registry = self._registry - functions._case_sensitive_registry = self._case_sensitive_registry - - def test_case_sensitive(self): - reg = functions._registry['_default'] - cs_reg = functions._case_sensitive_registry['_default'] - - class MYFUNC(GenericFunction): - type = DateTime - - assert isinstance(func.MYFUNC().type, DateTime) - assert isinstance(func.MyFunc().type, DateTime) - assert isinstance(func.mYfUnC().type, DateTime) - assert isinstance(func.myfunc().type, DateTime) - - in_("myfunc", reg) - not_in_("MYFUNC", reg) - not_in_("MyFunc", reg) - in_("myfunc", cs_reg) - eq_(set(cs_reg['myfunc'].keys()), set(['MYFUNC'])) - - with testing.expect_deprecated( - "GenericFunction 'MyFunc' is already registered with" - " different letter case, so the previously registered function " - "'MYFUNC' is switched into case-sensitive mode. " - "GenericFunction objects will be fully case-insensitive in a " - "future release.", - regex=False - ): - class MyFunc(GenericFunction): - type = Integer - - assert isinstance(func.MYFUNC().type, DateTime) - assert isinstance(func.MyFunc().type, Integer) - with pytest.raises(AssertionError): - assert isinstance(func.mYfUnC().type, Integer) - with pytest.raises(AssertionError): - assert isinstance(func.myfunc().type, Integer) - - eq_(reg["myfunc"], functions._CASE_SENSITIVE) - not_in_("MYFUNC", reg) - not_in_("MyFunc", reg) - in_("myfunc", cs_reg) - eq_(set(cs_reg['myfunc'].keys()), set(['MYFUNC', 'MyFunc'])) - - def test_replace_function_case_sensitive(self): - reg = functions._registry['_default'] - cs_reg = functions._case_sensitive_registry['_default'] - - class replaceable_func(GenericFunction): - type = Integer - identifier = 'REPLACEABLE_FUNC' - - assert isinstance(func.REPLACEABLE_FUNC().type, Integer) - assert isinstance(func.Replaceable_Func().type, Integer) - assert isinstance(func.RePlAcEaBlE_fUnC().type, Integer) - assert isinstance(func.replaceable_func().type, Integer) - - in_("replaceable_func", reg) - not_in_("REPLACEABLE_FUNC", reg) - not_in_("Replaceable_Func", reg) - in_("replaceable_func", cs_reg) - eq_(set(cs_reg['replaceable_func'].keys()), set(['REPLACEABLE_FUNC'])) - - with testing.expect_deprecated( - "GenericFunction 'Replaceable_Func' is already registered with" - " different letter case, so the previously registered function " - "'REPLACEABLE_FUNC' is switched into case-sensitive mode. " - "GenericFunction objects will be fully case-insensitive in a " - "future release.", - regex=False - ): - class Replaceable_Func(GenericFunction): - type = DateTime - identifier = 'Replaceable_Func' - - assert isinstance(func.REPLACEABLE_FUNC().type, Integer) - assert isinstance(func.Replaceable_Func().type, DateTime) - assert isinstance(func.RePlAcEaBlE_fUnC().type, NullType) - assert isinstance(func.replaceable_func().type, NullType) - - eq_(reg["replaceable_func"], functions._CASE_SENSITIVE) - not_in_("REPLACEABLE_FUNC", reg) - not_in_("Replaceable_Func", reg) - in_("replaceable_func", cs_reg) - eq_(set(cs_reg['replaceable_func'].keys()), - set(['REPLACEABLE_FUNC', 'Replaceable_Func'])) - - with testing.expect_warnings( - "The GenericFunction 'REPLACEABLE_FUNC' is already registered and " - "is going to be overriden.", - regex=False - ): - class replaceable_func_override(GenericFunction): - type = DateTime - identifier = 'REPLACEABLE_FUNC' - - with testing.expect_deprecated( - "GenericFunction(s) '['REPLACEABLE_FUNC', 'Replaceable_Func']' " - "are already registered with different letter cases and might " - "interact with 'replaceable_func'. GenericFunction objects will " - "be fully case-insensitive in a future release.", - regex=False - ): - class replaceable_func_lowercase(GenericFunction): - type = String - identifier = 'replaceable_func' - - with testing.expect_warnings( - "The GenericFunction 'Replaceable_Func' is already registered and " - "is going to be overriden.", - regex=False - ): - class Replaceable_Func_override(GenericFunction): - type = Integer - identifier = 'Replaceable_Func' - - assert isinstance(func.REPLACEABLE_FUNC().type, DateTime) - assert isinstance(func.Replaceable_Func().type, Integer) - assert isinstance(func.RePlAcEaBlE_fUnC().type, NullType) - assert isinstance(func.replaceable_func().type, String) - - eq_(reg["replaceable_func"], functions._CASE_SENSITIVE) - not_in_("REPLACEABLE_FUNC", reg) - not_in_("Replaceable_Func", reg) - in_("replaceable_func", cs_reg) - eq_(set(cs_reg['replaceable_func'].keys()), - set(['REPLACEABLE_FUNC', 'Replaceable_Func', 'replaceable_func'])) - - class DDLListenerDeprecationsTest(fixtures.TestBase): def setup(self): self.bind = self.engine = engines.mock_engine() diff --git a/test/sql/test_functions.py b/test/sql/test_functions.py index b03b156bc..ac711c669 100644 --- a/test/sql/test_functions.py +++ b/test/sql/test_functions.py @@ -57,12 +57,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): def setup(self): self._registry = deepcopy(functions._registry) - self._case_sensitive_registry = deepcopy( - functions._case_sensitive_registry) def teardown(self): functions._registry = self._registry - functions._case_sensitive_registry = self._case_sensitive_registry def test_compile(self): for dialect in all_dialects(exclude=("sybase",)): @@ -96,7 +93,6 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): ) functions._registry['_default'].pop('fake_func') - functions._case_sensitive_registry['_default'].pop('fake_func') def test_use_labels(self): self.assert_compile( @@ -261,6 +257,28 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): assert isinstance(func.RePlAcEaBlE_fUnC().type, DateTime) assert isinstance(func.replaceable_func().type, DateTime) + def test_replace_function_case_insensitive(self): + class replaceable_func(GenericFunction): + type = Integer + identifier = 'replaceable_func' + + assert isinstance(func.Replaceable_Func().type, Integer) + assert isinstance(func.RePlAcEaBlE_fUnC().type, Integer) + assert isinstance(func.replaceable_func().type, Integer) + + with expect_warnings( + "The GenericFunction 'replaceable_func' is already registered and " + "is going to be overriden.", + regex=False + ): + class replaceable_func_override(GenericFunction): + type = DateTime + identifier = 'REPLACEABLE_Func' + + assert isinstance(func.Replaceable_Func().type, DateTime) + assert isinstance(func.RePlAcEaBlE_fUnC().type, DateTime) + assert isinstance(func.replaceable_func().type, DateTime) + def test_custom_w_custom_name(self): class myfunc(GenericFunction): name = "notmyfunc" |
