1.1 --- a/internal_tests/objectset.py Mon Oct 24 23:57:02 2011 +0200
1.2 +++ b/internal_tests/objectset.py Mon Oct 31 19:09:47 2011 +0100
1.3 @@ -1,6 +1,6 @@
1.4 #!/usr/bin/env python
1.5
1.6 -from micropython.common import ObjectSet
1.7 +from micropython.common import ObjectSet, combine_mapping_dicts
1.8
1.9 o1 = ObjectSet()
1.10 o1.add("a")
1.11 @@ -47,4 +47,16 @@
1.12 o3["c"].append("y")
1.13 print "o3 =", o3
1.14
1.15 +d1 = {'a' : [ObjectSet(['f', 'g']), ObjectSet(['f', 'h'])]}
1.16 +d2 = {'a' : [ObjectSet(['f']), ObjectSet(['e', 'f', 'g'])]}
1.17 +d3 = combine_mapping_dicts(d1, d2)
1.18 +print "d1 =", d1
1.19 +print "d2 =", d2
1.20 +print "d3 =", d3
1.21 +
1.22 +d4 = {'a' : None}
1.23 +d5 = combine_mapping_dicts(d1, d4)
1.24 +print "d4 =", d4
1.25 +print "d5 =", d5
1.26 +
1.27 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/micropython/common.py Mon Oct 24 23:57:02 2011 +0200
2.2 +++ b/micropython/common.py Mon Oct 31 19:09:47 2011 +0100
2.3 @@ -128,7 +128,10 @@
2.4
2.5 new_dict = {}
2.6 for key, value in d.items():
2.7 - new_dict[key] = set([value])
2.8 + if value is None:
2.9 + new_dict[key] = None
2.10 + else:
2.11 + new_dict[key] = set([value])
2.12 return new_dict
2.13
2.14 def merge_mapping_dicts(dicts):
2.15 @@ -145,10 +148,11 @@
2.16
2.17 for old_dict in dicts:
2.18 for key, value in old_dict.items():
2.19 - if not new_dict.has_key(key):
2.20 - new_dict[key] = ObjectSet(value)
2.21 - else:
2.22 - new_dict[key].update(value)
2.23 + if value is not None:
2.24 + if not new_dict.has_key(key):
2.25 + new_dict[key] = ObjectSet(value)
2.26 + else:
2.27 + new_dict[key].update(value)
2.28
2.29 def combine_mapping_dicts(d1, d2):
2.30
2.31 @@ -163,22 +167,31 @@
2.32 d1: {'a' : [{'f', 'g'}, {'f', 'h'}], ...}
2.33 d2: {'a' : [{'f'}, {'e', 'f', 'g'}], ...}
2.34 -> {'a' : [{'f', 'g'}, {'f', 'h'}, {'e', 'f', 'g'}, {'e', 'f', 'g', 'h'}], ...}
2.35 +
2.36 + Note that items of 'd2' whose keys are not in 'd1' are not added to 'd1'
2.37 + since this, in the context of propagating attribute usage observations,
2.38 + would result in spurious usage details being made available in places where
2.39 + the names may not have been defined.
2.40 """
2.41
2.42 - return combine(d1, d2, {}, combine_object_set_lists)
2.43 + return combine(d1, d2, {}, combine_object_set_lists, True)
2.44
2.45 -def combine(d1, d2, combined, combine_op):
2.46 +def combine(d1, d2, combined, combine_op, only_d1_keys=False):
2.47
2.48 """
2.49 Combine dictionaries 'd1' and 'd2' in the 'combined' object provided, using
2.50 the 'combine_op' to merge values from the dictionaries.
2.51 +
2.52 + If 'only_d1_keys' is set to a true value, items from 'd2' employing keys not
2.53 + in 'd1' will not be added to 'd1'.
2.54 """
2.55
2.56 d2_keys = d2.keys()
2.57
2.58 for key in d2_keys:
2.59 if not d1.has_key(key):
2.60 - combined[key] = d2[key]
2.61 + if not only_d1_keys:
2.62 + combined[key] = d2[key]
2.63 else:
2.64 combined[key] = combine_op(d1[key], d2[key])
2.65
2.66 @@ -195,6 +208,14 @@
2.67 members.
2.68 """
2.69
2.70 + if l1 is None:
2.71 + if l2 is None:
2.72 + return None
2.73 + else:
2.74 + return l2
2.75 + elif l2 is None:
2.76 + return l1
2.77 +
2.78 combined = set([])
2.79 for i1 in l1:
2.80 for i2 in l2:
3.1 --- a/micropython/data.py Mon Oct 24 23:57:02 2011 +0200
3.2 +++ b/micropython/data.py Mon Oct 31 19:09:47 2011 +0100
3.3 @@ -404,10 +404,7 @@
3.4
3.5 # Skip reporting where no actual usage occurs.
3.6
3.7 - for attrnames in usage:
3.8 - if attrnames:
3.9 - break
3.10 - else:
3.11 + if usage is None:
3.12 continue
3.13
3.14 # Eliminate non-usage.
3.15 @@ -513,6 +510,8 @@
3.16 if users.has_key(name):
3.17 for user in users[name]:
3.18 values = user._attrnames[name]
3.19 + if values is None:
3.20 + values = user._attrnames[name] = ObjectSet()
3.21
3.22 # Add an entry for the attribute, optionally with an assigned
3.23 # value.
3.24 @@ -558,7 +557,7 @@
3.25 "Make sure that 'node' is initialised for 'name'."
3.26
3.27 self._init_attribute_user(node)
3.28 - node._attrnames[name] = ObjectSet()
3.29 + node._attrnames[name] = None
3.30
3.31 def _init_attribute_user(self, node):
3.32
3.33 @@ -1886,7 +1885,8 @@
3.34 for user in self.all_attribute_users:
3.35 user._attrtypes = {}
3.36 for name, usage in user._attrcombined.items():
3.37 - user._attrtypes[name] = get_object_types_for_usage(usage, objtable, name, self.full_name())
3.38 + if usage is not None:
3.39 + user._attrtypes[name] = get_object_types_for_usage(usage, objtable, name, self.full_name())
3.40
3.41 def as_instantiator(self):
3.42