[Sqlalchemy-tickets] [sqlalchemy] #2872: AliasedClass.__getattr__() creates malformed QueryableAttr
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2013-11-23 02:04:40
|
#2872: AliasedClass.__getattr__() creates malformed QueryableAttribute
--------------------+-----------------------------------------
Reporter: elic | Owner: zzzeek
Type: defect | Status: new
Priority: medium | Milestone: 0.9.xx
Component: orm | Severity: no triage selected yet
Keywords: | Progress State: awaiting triage
--------------------+-----------------------------------------
This an odd border case that few others will probably find themselves in,
but I ''think'' it's a bug in `sqlalchemy.orm.util.AliasedClass` (even
it's not, I'd still love if the behavior could be slightly tweaked).
Under 0.8.3 & 0.9b1, when `AliasedClass.__getattr__()` is retrieving the
attr's value, if it encounters a `QueryableAttribute`, it adapts it
accordingly. If it encounters a foreign descriptor, it calls
`descriptor.__get__(None, cls)`, then adapts the result if it's a
`PropComparator`, but otherwise returns it unchanged.
The situation I find myself in is that I have a descriptor which is itself
returning a `QueryableAttribute` instance (in particular, it's storing and
returning the `InstrumentedAttribute` that the mapper sets on the class
attribute). Since `QueryableAttribute` inherits from `PropComparator`,
the current code tries to adapt it as one, which results in a wildly
messed-up object, since `QueryableAttribute`'s call signature is very
different from what the `PropComparator`-adapter code is expecting.
My proposed change adds a check for descriptors returning
`QueryableAttribute` instances, and adapts them the same as if they were
stored directly in the class. Attached is a patch (`queryable.patch`) for
0.9, and a similar change seems to fix 0.8.
I'm happy to explain in more detail how I arrived at this situation, but I
didn't want to make this bug report overly long. Also attached is
`test_proxy_descriptor.py`, which was distilled from my actual use case,
and which demonstrates the error.
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2872>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|