Bug #524
uWeb Model comparison deeploading and dictionary assumption
Status:
Closed
Priority:
Normal
Assignee:
Elmer de Looff
Category:
Model
Target version:
-
Description
The uWeb Model automatically deeploads all items when comparing two records. This is a bug that was introduced when deeploading became available, and triggers because of the list-conversion that is done in eq. Triggering extra SQL queries at compare-time is very bad behaviour.
The secondary is a more rare bug. In most cases, two dictionaries will have the exact same key order, but this is not at all guaranteed. Observe the following:
>>> d1 = {'directory': u'/root/some/path', 'package': u'foo', 'ID': 1, 'description': u'Empty test thingy'}
>>> d2 = {'directory': u'/root/some/path', 'ID': 1, 'description': u'Empty test thingy', 'package': u'foo'}
>>> d1
{'directory': u'/root/some/path', 'description': u'Empty test thingy', 'ID': 1, 'package': u'foo'}
>>> d2
{'directory': u'/root/some/path', 'package': u'foo', 'ID': 1, 'description': u'Empty test thingy'}
>>> d1 == d2
True
As can be seen, the dictionaries compare equal, but their internal order is different (This exact behaviour shows on Python2.6.6 but is likely prevalent). Substituting the basic dicts for a Record here makes the comparison break. This is because the Record class performs its equality check on the lists of values from both records. This is bad for two reasons:
- Key names are not compared at all, leading to false positives;
- Key (and thus value) ordering is not guaranteed, leading to false negatives.
Associated revisions
History
#1 Updated by Elmer de Looff about 13 years ago
- Category set to Model
- Status changed from New to Resolved
- % Done changed from 0 to 70
This has been resolved in r3092.
Comparisons will no longer trigger deeploading, and differently ordered Records can be compared properly:
>>> r1 = Record(None, {'directory': u'/root/some/path', 'package': u'foo', 'description': u'Empty test thingy', 'ID': 1})
>>> r2 = Record(None, {'directory': u'/root/some/path', 'description': u'Empty test thingy', 'ID': 1, 'package': u'foo'})
>>> r1
Record({'directory': u'/root/some/path', 'package': u'foo', 'description': u'Empty test thingy', 'ID': 1})
>>> r2
Record({'directory': u'/root/some/path', 'description': u'Empty test thingy', 'ID': 1, 'package': u'foo'})
>>> r1 == r2
True
#2 Updated by Elmer de Looff about 13 years ago
- Status changed from Resolved to Closed
- % Done changed from 70 to 100
Fixed bug in the uWeb model where Record comparisons needlessly deeploaded the entire tree of both records, and relied on an assumed dictionary order that is not guaranteed. This resolves #524.