- edited description
Hybrid decorators are missing `getter` decorator
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)
-
reporter -
repo owner - changed milestone to 1.2
this is fair and would be bundled with
#3912as an enhancement package. targeting for 1.2 but this may move out unless I can get contributions including tests. -
-
assigned issue to
-
assigned issue to
-
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.
-
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. -
Ah, I had wondered after I posted that question, if I should start with
#3912instead (I didn't really read that one deeply). I'll do that. Thanks! -
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
-
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 ;)
-
repo owner - changed status to resolved
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:
#3911Fixes:#3912Change-Id: Iff033d8ccaae20ded9289cbfa789c376759381f5→ <<cset caeb274e287f>>
- Log in to comment