Hybrid decorators are missing `getter` decorator

Issue #3911 resolved
Markus Meskanen
created an issue

As it stands, if you want to override super class's hybrid_decorator's getter, you end up having to re-write the whole decorator, since there's no getter() method.

For example, you can't do this:

class Foo(Model):
    first_name = Column(String)

    @hybrid_property
    def name(self):
        return self.first_name

class Bar(Foo):
    last_name = Column(String)

    @Foo.name.getter
    def name(self):
        return self.first_name + ' ' + self.last_name

In the example above it doesn't matter since there's only getter, but if we had setter, expression, and deleter defined, we would have to manually copy them over to Bar since we have to create a new hybrid_property instead of calling .getter on the super class.

Python's built-in property also supports this, for what it's worth:

>>> class Foo:
...   _x = 0
...   @property
...   def x(self):
...     return self._x
...   @x.setter
...   def x(self, value):
...     self._x = value
... 
>>> class Bar(Foo):
...   @Foo.x.getter
...   def x(self):
...     return self._x - 1
... 
>>> b = Bar()
>>> b._x
0
>>> b.x
-1

Comments (9)

  1. diana clarke

    Hmmm... perhaps I just haven't had enough coffee yet, but this isn't working the way I would have expected (differs from the python behaviour).

    Compare the output from Person/LoudPerson with PythonPerson/PythonLoudPerson, where the classes prefixed with "Python" are just plain old python classes and the others are sqlalchemy models.

  2. diana clarke

    The above approach isn't going to work if you want to override more than one of setter/getter/deleter, but then again it doesn't work in the plain old python case either. My batting average isn't great this week ;)

  3. Michael Bayer repo owner

    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

    → <<cset caeb274e287f>>

  4. Log in to comment