From ea85c7053dc9532a95fd487628768fdfc1ca5c30 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 13 Aug 2014 19:20:44 -0400 Subject: [PATCH] - The :meth:`.InspectionAttr.info` collection is now moved down to :class:`.InspectionAttr`, where in addition to being available on all :class:`.MapperProperty` objects, it is also now available on hybrid properties, association proxies, when accessed via :attr:`.Mapper.all_orm_descriptors`. fixes #2971 --- doc/build/changelog/changelog_10.rst | 10 ++++++++++ lib/sqlalchemy/orm/base.py | 26 ++++++++++++++++++++++++++ lib/sqlalchemy/orm/interfaces.py | 22 ---------------------- test/ext/test_hybrid.py | 18 ++++++++++++++++++ 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 20023af44d..c59d7c912d 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -16,6 +16,16 @@ .. changelog:: :version: 1.0.0 + .. change:: + :tags: orm, feature + :tickets: 2971 + + The :meth:`.InspectionAttr.info` collection is now moved down to + :class:`.InspectionAttr`, where in addition to being available + on all :class:`.MapperProperty` objects, it is also now available + on hybrid properties, association proxies, when accessed via + :attr:`.Mapper.all_orm_descriptors`. + .. change:: :tags: sql, feature :tickets: 3027 diff --git a/lib/sqlalchemy/orm/base.py b/lib/sqlalchemy/orm/base.py index 3097b8590f..3390ceec4c 100644 --- a/lib/sqlalchemy/orm/base.py +++ b/lib/sqlalchemy/orm/base.py @@ -488,6 +488,32 @@ class InspectionAttr(object): """ + @util.memoized_property + def info(self): + """Info dictionary associated with the object, allowing user-defined + data to be associated with this :class:`.InspectionAttr`. + + The dictionary is generated when first accessed. Alternatively, + it can be specified as a constructor argument to the + :func:`.column_property`, :func:`.relationship`, or :func:`.composite` + functions. + + .. versionadded:: 0.8 Added support for .info to all + :class:`.MapperProperty` subclasses. + + .. versionchanged:: 1.0.0 :attr:`.InspectionAttr.info` moved + from :class:`.MapperProperty` so that it can apply to a wider + variety of ORM and extension constructs. + + .. seealso:: + + :attr:`.QueryableAttribute.info` + + :attr:`.SchemaItem.info` + + """ + return {} + class _MappedAttribute(object): """Mixin for attributes which should be replaced by mapper-assigned diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 2dfaf62430..49ec99ce45 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -109,28 +109,6 @@ class MapperProperty(_MappedAttribute, InspectionAttr): def instrument_class(self, mapper): # pragma: no-coverage raise NotImplementedError() - @util.memoized_property - def info(self): - """Info dictionary associated with the object, allowing user-defined - data to be associated with this :class:`.MapperProperty`. - - The dictionary is generated when first accessed. Alternatively, - it can be specified as a constructor argument to the - :func:`.column_property`, :func:`.relationship`, or :func:`.composite` - functions. - - .. versionadded:: 0.8 Added support for .info to all - :class:`.MapperProperty` subclasses. - - .. seealso:: - - :attr:`.QueryableAttribute.info` - - :attr:`.SchemaItem.info` - - """ - return {} - _configure_started = False _configure_finished = False diff --git a/test/ext/test_hybrid.py b/test/ext/test_hybrid.py index e7f392a338..b895d2fb2b 100644 --- a/test/ext/test_hybrid.py +++ b/test/ext/test_hybrid.py @@ -5,6 +5,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext import hybrid from sqlalchemy.testing import eq_, AssertsCompiledSQL, assert_raises_message from sqlalchemy.testing import fixtures +from sqlalchemy import inspect class PropertyComparatorTest(fixtures.TestBase, AssertsCompiledSQL): __dialect__ = 'default' @@ -140,6 +141,14 @@ class PropertyExpressionTest(fixtures.TestBase, AssertsCompiledSQL): return A, B + def test_info(self): + A = self._fixture() + inspect(A).all_orm_descriptors.value.info["some key"] = "some value" + eq_( + inspect(A).all_orm_descriptors.value.info, + {"some key": "some value"} + ) + def test_set_get(self): A = self._fixture() a1 = A(value=5) @@ -267,6 +276,15 @@ class MethodExpressionTest(fixtures.TestBase, AssertsCompiledSQL): "foo(a.value, :foo_1) + :foo_2" ) + def test_info(self): + A = self._fixture() + inspect(A).all_orm_descriptors.value.info["some key"] = "some value" + eq_( + inspect(A).all_orm_descriptors.value.info, + {"some key": "some value"} + ) + + def test_aliased_expression(self): A = self._fixture() self.assert_compile( -- 2.47.3