Typing support for both "modes" of single-function hybrid_method/hybrid_property #13249
Replies: 1 comment 6 replies
-
|
hi ive converted to discussion since this issue is basically "the default way hybrids work can leave holes in typing", there's no "bug" to fix here, typing is typing. meaning, if the code that you want the type checker to look at doesnt exist, it can't look at it :) even though hybrids started as this neato way to have a single method double as an instance-level, class-level method at the same time, there's no requirement whatsoever that you have to use it that way, you are free to implement class SomeModel(DeclarativeBase):
ID: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
archived_at: Mapped[datetime | None] = mapped_column()
@hybrid_property
def archived(self) -> bool:
return is_not_none(self, self.archived_at)
@archived.inplace.expression
@classmethod
def _archived(cls) -> ColumnElement[bool]:
return is_not_none(cls, cls.archived_at)this follows the example given at https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html#using-inplace-to-create-pep-484-compliant-hybrid-properties now is the request, "can we add a doc note to that section clarifying that these methods may be required for typing support" ? that's a doc issue sure, though not a typing bug.
The critique "kinda hacky" suggests there's some other way to write a method that works as self- or cls- at the same time, without writing two methods, that is not "kinda hacky". Python is pretty strict about "this method is an instance method, that method is a classmethod". There's no explicit concept I'm aware of which implicitly allows "it's both", you can of course put the implementation in some common function but one method needs to have |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Ensure stubs packages are not installed
sqlalchemy-stubsandsqlalchemy2-stubsare not compatible with v2)Verify if the api is typed
Describe the typing issue
In the project I'm working on I have decided we should write some helper functions for hybrid methods/properties to allow us to, wherever possible, write them as single implementations. This is to avoid potential implementation drift between the Python and SQL Expression versions of these implementations.
However, the advertised way in sqlalchemy to implement one hybrid method that covers both cases is kinda hacky. As far as I can tell you are basically writing it as a method, but having the same function also run as a classmethod with the model type passed instead of a model instance when you want to run in Expression mode.
This obviously means that while it might work fine, when implementing a hybrid_method/hybrid_property as a single function, the expression variant remains completely un-type checked.
I was wondering if there is any way of supporting type checking of both variants somehow? Is this even possible? Maybe the answer is explicitly typing the first argument (ie what would normally be
self/cls) and having overloads. Any suggestions from those who have done it?I'm mostly filing this as an issue as I think if it's currently possible, the docs should make clear how to do it; and if it's not currently possible, but it is something that could potentially be implemented, it'd be nice to see it.
To Reproduce
Error
No error, the issue is just that one substantial code path is not being type checked.
Versions
Additional context
No response
Beta Was this translation helpful? Give feedback.
All reactions