summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDiana Clarke <diana.joan.clarke@gmail.com>2017-03-16 16:05:18 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-03-21 15:42:42 -0400
commitcaeb274e287f514a50524fc9fe4aeedcb3740147 (patch)
tree0668af2a6bbe4dce44ee4ea1c611a5f6ed856b31 /test
parentf881dae8179b94f72ab0dc85d8f62be8c9ce2fe0 (diff)
downloadsqlalchemy-caeb274e287f514a50524fc9fe4aeedcb3740147.tar.gz
Allow reuse of hybrid_property across subclasses
The :class:`sqlalchemy.ext.hybrid.hybrid_property` class now supports calling mutators like ``@setter``, ``@expression`` etc. multiple times across subclasses, and now provides a ``@getter`` mutator, so that a particular hybrid can be repurposed across subclasses or other classes. This now matches the behavior of ``@property`` in standard Python. Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com> Fixes: #3911 Fixes: #3912 Change-Id: Iff033d8ccaae20ded9289cbfa789c376759381f5
Diffstat (limited to 'test')
-rw-r--r--test/ext/test_hybrid.py113
1 files changed, 113 insertions, 0 deletions
diff --git a/test/ext/test_hybrid.py b/test/ext/test_hybrid.py
index aefcec405..20a76d6d2 100644
--- a/test/ext/test_hybrid.py
+++ b/test/ext/test_hybrid.py
@@ -120,6 +120,7 @@ class PropertyExpressionTest(fixtures.TestBase, AssertsCompiledSQL):
return A
+
def _relationship_fixture(self):
Base = declarative_base()
@@ -265,6 +266,118 @@ class PropertyValueTest(fixtures.TestBase, AssertsCompiledSQL):
eq_(a1._value, 10)
+class PropertyOverrideTest(fixtures.TestBase, AssertsCompiledSQL):
+ __dialect__ = 'default'
+
+ def _fixture(self):
+ Base = declarative_base()
+
+ class Person(Base):
+ __tablename__ = 'person'
+ id = Column(Integer, primary_key=True)
+ _name = Column(String)
+
+ @hybrid.hybrid_property
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ self._name = value.title()
+
+ class OverrideSetter(Person):
+ __tablename__ = 'override_setter'
+ id = Column(Integer, ForeignKey('person.id'), primary_key=True)
+ other = Column(String)
+
+ @Person.name.setter
+ def name(self, value):
+ self._name = value.upper()
+
+ class OverrideGetter(Person):
+ __tablename__ = 'override_getter'
+ id = Column(Integer, ForeignKey('person.id'), primary_key=True)
+ other = Column(String)
+
+ @Person.name.getter
+ def name(self):
+ return "Hello " + self._name
+
+ class OverrideExpr(Person):
+ __tablename__ = 'override_expr'
+ id = Column(Integer, ForeignKey('person.id'), primary_key=True)
+ other = Column(String)
+
+ @Person.name.overrides.expression
+ def name(self):
+ return func.concat("Hello", self._name)
+
+ class FooComparator(hybrid.Comparator):
+ def __clause_element__(self):
+ return func.concat("Hello", self.expression._name)
+
+ class OverrideComparator(Person):
+ __tablename__ = 'override_comp'
+ id = Column(Integer, ForeignKey('person.id'), primary_key=True)
+ other = Column(String)
+
+ @Person.name.overrides.comparator
+ def name(self):
+ return FooComparator(self)
+
+ return (
+ Person, OverrideSetter, OverrideGetter,
+ OverrideExpr, OverrideComparator
+ )
+
+ def test_property(self):
+ Person, _, _, _, _ = self._fixture()
+ p1 = Person()
+ p1.name = 'mike'
+ eq_(p1._name, 'Mike')
+ eq_(p1.name, 'Mike')
+
+ def test_override_setter(self):
+ _, OverrideSetter, _, _, _ = self._fixture()
+ p1 = OverrideSetter()
+ p1.name = 'mike'
+ eq_(p1._name, 'MIKE')
+ eq_(p1.name, 'MIKE')
+
+ def test_override_getter(self):
+ _, _, OverrideGetter, _, _ = self._fixture()
+ p1 = OverrideGetter()
+ p1.name = 'mike'
+ eq_(p1._name, 'Mike')
+ eq_(p1.name, 'Hello Mike')
+
+ def test_override_expr(self):
+ Person, _, _, OverrideExpr, _ = self._fixture()
+
+ self.assert_compile(
+ Person.name.__clause_element__(),
+ "person._name"
+ )
+
+ self.assert_compile(
+ OverrideExpr.name.__clause_element__(),
+ "concat(:concat_1, person._name)"
+ )
+
+ def test_override_comparator(self):
+ Person, _, _, _, OverrideComparator = self._fixture()
+
+ self.assert_compile(
+ Person.name.__clause_element__(),
+ "person._name"
+ )
+
+ self.assert_compile(
+ OverrideComparator.name.__clause_element__(),
+ "concat(:concat_1, person._name)"
+ )
+
+
class PropertyMirrorTest(fixtures.TestBase, AssertsCompiledSQL):
__dialect__ = 'default'