From f10eb28d90cbf73f4757897f52bf26722f98372e Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 23 Jun 2014 19:50:23 -0400 Subject: - reverse course in #3061 so that we instead no longer set None in the attribute when we do a get; we return the None as always but we leave the dict blank and the loader callable still in place. The case for this implicit get on a pending object is not super common and there really should be no change in state at all when this operation proceeds. This change is more dramatic as it reverses a behavior SQLA has had since the first release. fixes #3061 --- doc/build/changelog/changelog_10.rst | 13 +++++-------- doc/build/changelog/migration_10.rst | 12 +++--------- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'doc') diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 9004f5681..862d4103a 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -35,14 +35,11 @@ Adjustment to attribute mechanics concerning when a value is implicitly initialized to None via first access; this action, which has always resulted in a population of the attribute, - now emits an attribute event just like any other attribute set - operation and generates the same kind of history as one. Additionally, - many mapper internal operations will no longer implicitly generate - these "None" values when various never-set attributes are checked. - These are subtle behavioral fixes to attribute mechanics which provide - a better solution to the problem of :ticket:`3060`, which also - involves recognition of attributes explicitly set to ``None`` - vs. attributes that were never set. + no longer does so; the None value is returned but the underlying + attribute receives no set event. This is consistent with how collections + work and allows attribute mechanics to behave more consistently; + in particular, getting an attribute with no value does not squash + the event that should proceed if the value is actually set to None. .. seealso:: diff --git a/doc/build/changelog/migration_10.rst b/doc/build/changelog/migration_10.rst index 1e5156dce..43830197e 100644 --- a/doc/build/changelog/migration_10.rst +++ b/doc/build/changelog/migration_10.rst @@ -62,13 +62,14 @@ attribute first instead:: The above means that the behavior of our "set" operation can be corrupted by the fact that the value was accessed via "get" earlier. In 1.0, this -inconsistency has been resolved:: +inconsistency has been resolved, by no longer actually setting anything +when the default "getter" is used. >>> obj = Foo() >>> obj.someattr None >>> inspect(obj).attrs.someattr.history - History(added=[None], unchanged=(), deleted=()) # 1.0 + History(added=(), unchanged=(), deleted=()) # 1.0 >>> obj.someattr = None >>> inspect(obj).attrs.someattr.history History(added=[None], unchanged=(), deleted=()) @@ -94,13 +95,6 @@ if the primary key attributes have no setting at all, whereas the value would be ``None`` before, it will now be the :data:`.orm.attributes.NEVER_SET` symbol, and no change to the object's state occurs. -Performance-wise, the change has the tradeoff that an attribute will need -to be considered in a unit of work flush process in more cases than before, if it has -been accessed and populated with a default value. However, performance -is improved in the case where the unit of work inspects a pending object for -an existing primary key value, as the state of the object won't change -in the common case that none was set. - :ticket:`3061` .. _behavioral_changes_core_10: -- cgit v1.2.1