detecting containers during object introspection
David C. Fox
davidcfox at post.harvard.edu
Tue Jul 22 11:03:11 EDT 2003
Steven Taschuk wrote:
> Quoth David C. Fox:
> [...]
>
>>However, the real problem occurs if the developer makes a change like
>>this (or even just adds a new attribute which is a non-standard
>>container), and does increment the version number. Because the version
>>number was incremented, the regression test would *expect* some of the
>>dictionary elements to change type or structure, and would simply update
>>the standard example dictionary. Then, any *subsequent* changes to the
>>structure of the values in that container would go undetected (unless
>>the developer had also updated the recursive comparison operation to
>>take into account that the unknown object was a container).
>
>
> Yes, I see. Thorny.
>
> What if your recursive comparison operation choked on values of
> unknown types rather than falling back on the weak "have same
> type" criterion? That way, the developer who changes the
> structure by introducing values of (e.g.) a new dict work-alike
> type would see tests fail, which would remind her to add to that
> comparison operation the necessary knowledge of the new type.
>
> Fail safe, in other words, where "safe" means "no false positives
> from the regression test".
>
That's one possibility. My original reaction to it was that requiring
developers to write comparison operations for every class whose
instances are found in the stored dictionary seemed like overkill. Then
I started think about what classes actually were found there. Many of
them contain lists or dictionaries, and changes to the internal
structure of those classes would cause the same problems described
above. Therefore, just noting that the old and new versions had an
attribute with the same class wouldn't be sufficient.
Then, I recalled that any object instance *has* a dictionary of
attributes: __dict__. So, instead of writing custom comparison
operators for each class, I should be able to define a generic
comparison operator cmp_struct(x, y) which returns true iff
1) type(x) == type(y), and
2) one of the following is true:
a) type(x) == type({}), and
x.keys() and y.keys() match, and
for each key, cmp_struct(x[key], y[key]) is true
b) type(x) == type([]), and
for each pair of items in x and y, cmp_struct returns true
c) type(x) == types.InstanceType, and
cmp_struct(x.__dict__, y.__dict__) is true
d) type(x) is not any of the above
Thanks for your advice. It is really nice to have someone to bounce
ideas off of.
David
More information about the Python-list
mailing list