Skip to content

Hybrid decorators are missing getter decorator #3911

Closed
@sqlalchemy-bot

Description

@sqlalchemy-bot
Collaborator

Migrated issue, originally created by Markus Meskanen (@Mahi)

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

Activity

sqlalchemy-bot

sqlalchemy-bot commented on Feb 13, 2017

@sqlalchemy-bot
CollaboratorAuthor

Changes by Markus Meskanen (@Mahi):

  • edited description
sqlalchemy-bot

sqlalchemy-bot commented on Feb 13, 2017

@sqlalchemy-bot
CollaboratorAuthor

Michael Bayer (@zzzeek) wrote:

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.

sqlalchemy-bot

sqlalchemy-bot commented on Feb 13, 2017

@sqlalchemy-bot
CollaboratorAuthor

Changes by Michael Bayer (@zzzeek):

  • set milestone to "1.2"
sqlalchemy-bot

sqlalchemy-bot commented on Mar 16, 2017

@sqlalchemy-bot
CollaboratorAuthor

diana clarke wrote:

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.

sqlalchemy-bot

sqlalchemy-bot commented on Mar 16, 2017

@sqlalchemy-bot
CollaboratorAuthor

Michael Bayer (@zzzeek) wrote:

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

sqlalchemy-bot

sqlalchemy-bot commented on Mar 16, 2017

@sqlalchemy-bot
CollaboratorAuthor

diana clarke wrote:

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!

sqlalchemy-bot

sqlalchemy-bot commented on Mar 16, 2017

@sqlalchemy-bot
CollaboratorAuthor

diana clarke wrote:

Yup, shamelessly stealing these [1] from Hettinger fixed it :)

def getter(self, fget):
    return type(self)(fget, self.fset, self.fdel, self.__doc__)

def setter(self, fset):
    return type(self)(self.fget, fset, self.fdel, self.__doc__)

def deleter(self, fdel):
    return type(self)(self.fget, self.fset, fdel, self.__doc__)

[1] https://github.com/python/cpython/blob/master/Doc/howto/descriptor.rst#properties

sqlalchemy-bot

sqlalchemy-bot commented on Mar 16, 2017

@sqlalchemy-bot
CollaboratorAuthor

diana clarke wrote:

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

sqlalchemy-bot

sqlalchemy-bot commented on Mar 21, 2017

@sqlalchemy-bot
CollaboratorAuthor

Michael Bayer (@zzzeek) wrote:

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

caeb274

sqlalchemy-bot

sqlalchemy-bot commented on Mar 21, 2017

@sqlalchemy-bot
CollaboratorAuthor

Changes by Michael Bayer (@zzzeek):

  • changed status to closed
added this to the 1.2 milestone on Nov 27, 2018

1 remaining item

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @sqlalchemy-bot

        Issue actions

          Hybrid decorators are missing `getter` decorator · Issue #3911 · sqlalchemy/sqlalchemy