AttributeExtension.set broken behavior for replacements partially tracked by session

Issue #1508 resolved
Former user created an issue

The AttributeExtension's set method has problems if attributes are replaced where the old value is not yet tracked by the session. Imagine an attribute extension like this:

class AnswerSetterExtension(AttributeExtension):
    active_history = True

    def set(self, state, value, oldvalue, initiator):
        if value is not None:
            value.is_answer = True
        if oldvalue is not None and oldvalue != value:
            oldvalue.is_answer = False
        return value

(I'm also unsure if active_history works as documented)

If the code is triggered like this:

topic.answer = post

And topic.answer was not yet in the session, oldvalue will have an invalid value. It appears that oldvalue is the same as value, at least in some more complex cases. If you call it like this:

topic.answer
topic.answer = post

The loading is enforced and the set method works like documented.

Comments (2)

  1. Mike Bayer repo owner

    Replying to guest:

    The AttributeExtension's set method has problems if attributes are replaced where the old value is not yet tracked by the session. Imagine an attribute extension like this:

    {{{ #!python class AnswerSetterExtension(AttributeExtension): active_history = True

    def set(self, state, value, oldvalue, initiator):
        if value is not None:
            value.is_answer = True
        if oldvalue is not None and oldvalue != value:
            oldvalue.is_answer = False
        return value
    

    }}}

    (I'm also unsure if active_history works as documented)

    it does. its covered by test.orm.test_attributes.AttributesTest.test_scalar_listener and test.orm.test_backref_mutations.O2OScalarOrphanTest.test_m2o_event.

    If the code is triggered like this: {{{ #!python topic.answer = post }}} And topic.answer was not yet in the session, oldvalue will have an invalid value.

    assuming you mean, the already present value of topic.answer ? why invalid ? do you mean, "unloaded"? not if active_history is true - it will load the old value and give you that. if this is not the case provide a test how you are causing that result (also you're on 0.6 ? this logic has been changed from 0.5 to 0.6).

    It appears that oldvalue is the same as value, at least in some more complex cases.

    I dont really know what that means. the calling of the extension is pretty clear - the pre-existing value is "oldvalue" the incoming is "value".

  2. Log in to comment