diff options
| -rw-r--r-- | doc/build/changelog/unreleased_12/4221.rst | 10 | ||||
| -rw-r--r-- | lib/sqlalchemy/ext/declarative/api.py | 5 | ||||
| -rw-r--r-- | test/ext/declarative/test_mixin.py | 13 |
3 files changed, 26 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_12/4221.rst b/doc/build/changelog/unreleased_12/4221.rst new file mode 100644 index 000000000..3ce722a80 --- /dev/null +++ b/doc/build/changelog/unreleased_12/4221.rst @@ -0,0 +1,10 @@ +.. change:: + :tags: bug, declarative + :tickets: 4221 + + Removed a warning that would be emitted when calling upon + ``__table_args__``, ``__mapper_args__`` as named with a ``@declared_attr`` + method, when called from a non-mapped declarative mixin. Calling these + directly is documented as the approach to use when one is overidding one + of these methods on a mapped class. The warning still emits for regular + attribute names. diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index 77a03bc4a..b08d3ce30 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -17,6 +17,7 @@ from ...util import OrderedDict, hybridmethod, hybridproperty from ... import util from ... import exc import weakref +import re from .base import _as_declarative, \ _declarative_constructor,\ @@ -189,8 +190,8 @@ class declared_attr(interfaces._MappedAttribute, property): def __get__(desc, self, cls): reg = cls.__dict__.get('_sa_declared_attr_reg', None) if reg is None: - manager = attributes.manager_of_class(cls) - if manager is None: + if not re.match(r'^__.+__$', desc.fget.__name__) and \ + attributes.manager_of_class(cls) is None: util.warn( "Unmanaged access of declarative attribute %s from " "non-mapped class %s" % diff --git a/test/ext/declarative/test_mixin.py b/test/ext/declarative/test_mixin.py index 0b1b117fb..07c790dc4 100644 --- a/test/ext/declarative/test_mixin.py +++ b/test/ext/declarative/test_mixin.py @@ -1540,6 +1540,19 @@ class DeclaredAttrTest(DeclarativeTestBase, testing.AssertsCompiledSQL): getattr, Mixin, "my_prop" ) + def test_can_we_access_the_mixin_straight_special_names(self): + class Mixin(object): + @declared_attr + def __table_args__(cls): + return (1, 2, 3) + + @declared_attr + def __arbitrary__(cls): + return (4, 5, 6) + + eq_(Mixin.__table_args__, (1, 2, 3)) + eq_(Mixin.__arbitrary__, (4, 5, 6)) + def test_non_decl_access(self): counter = mock.Mock() |
