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. Mike Bayer repo owner
    • changed milestone to 1.2

    this is fair and would be bundled with #3912 as an enhancement package. targeting for 1.2 but this may move out unless I can get contributions including tests.

  2. 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.

  3. Mike Bayer repo owner

    ok.... this is overriding setter, is this after patching like in #3912 ? the hybrid doesn't yet copy itself the way @property does.

  4. diana clarke

    Ah, I had wondered after I posted that question, if I should start with #3912 instead (I didn't really read that one deeply). I'll do that. Thanks!

  5. 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 ;)

  6. Mike 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>>

  7. Log in to comment