1.1 --- a/micropython/data.py Wed Jul 04 00:27:29 2012 +0200
1.2 +++ b/micropython/data.py Wed Jul 04 00:42:04 2012 +0200
1.3 @@ -2015,12 +2015,11 @@
1.4
1.5 self.all_objects = set()
1.6
1.7 - # A dictionary mapping functions to global names that cannot support
1.8 - # combined attribute usage observations because they may be modified in
1.9 - # the given functions during initialisation. Functions could be
1.10 - # eliminated from this dictionary if not thought to be used.
1.11 -
1.12 - self.modified_names = {}
1.13 + # A set of global names that cannot support combined attribute usage
1.14 + # observations because they may be modified within functions during
1.15 + # initialisation.
1.16 +
1.17 + self.modified_names = set()
1.18
1.19 # Keyword records.
1.20
1.21 @@ -2065,79 +2064,23 @@
1.22 # Attribute usage methods that apply to module globals in certain
1.23 # circumstances.
1.24
1.25 - def finalise_users(self, objtable):
1.26 -
1.27 - """
1.28 - Finalise attribute users, first revoking usage for any global names
1.29 - that might be modified during initialisation.
1.30 - """
1.31 -
1.32 - NamespaceDict.finalise_users(self, objtable)
1.33 -
1.34 - # Collect modified names and revoke attribute usage details for those
1.35 - # names.
1.36 -
1.37 - names = set()
1.38 - for function_names in self.modified_names.values():
1.39 - names.update(function_names)
1.40 -
1.41 - self.revoke_attribute_usage(names)
1.42 -
1.43 - def revoke_attribute_usage(self, names):
1.44 -
1.45 - """
1.46 - The definition of attribute users may be overridden or ignored if the
1.47 - module is found to be involved in circular imports where externally
1.48 - initiated modification occurs or if a function in the module may rebind
1.49 - globals, potentially during initialisation.
1.50 - """
1.51 -
1.52 - for user in self.all_attribute_users:
1.53 -
1.54 - # Remove user details for each name.
1.55 -
1.56 - for name in names:
1.57 -
1.58 - # Remove annotations derived from the combined observations.
1.59 -
1.60 - if user._attrtypes.has_key(name):
1.61 - del user._attrtypes[name]
1.62 - if user._attrspecifictypes.has_key(name):
1.63 - del user._attrspecifictypes[name]
1.64 - if user._attrmerged.has_key(name):
1.65 - del user._attrmerged[name]
1.66 -
1.67 - # Usage nodes that can no longer support combined observations
1.68 - # of attribute usage must instead support isolated observations.
1.69 -
1.70 - if not user._attrcombined.has_key(name):
1.71 - continue
1.72 -
1.73 - usage = user._attrcombined[name]
1.74 -
1.75 - # Usage is defined as a collection of attribute name
1.76 - # observations.
1.77 -
1.78 - for attrnames in usage:
1.79 -
1.80 - # Each attribute name may have values associated with it
1.81 - # where such values have been assigned to an attribute of
1.82 - # the given name.
1.83 -
1.84 - for attrname, attrvalues in usage.items():
1.85 - if attrvalues:
1.86 - for value in attrvalues:
1.87 - self.importer.use_name(attrname, self.full_name(), value)
1.88 - else:
1.89 - self.importer.use_name(attrname, self.full_name())
1.90 -
1.91 - del user._attrcombined[name]
1.92 -
1.93 - # Remove annotations on contributors.
1.94 -
1.95 - for contributor in user._attrcontributors:
1.96 - if contributor._attrusers.has_key(name):
1.97 - del contributor._attrusers[name]
1.98 + def _use_attribute(self, name, attrname, value=None):
1.99 + if name not in self.modified_names:
1.100 + return NamespaceDict._use_attribute(self, name, attrname, value)
1.101 + else:
1.102 + return []
1.103 +
1.104 + def _define_attribute_user_for_name(self, node, name):
1.105 + if name not in self.modified_names:
1.106 + NamespaceDict._define_attribute_user_for_name(self, node, name)
1.107 +
1.108 + def _init_attribute_user_for_name(self, node, name):
1.109 + if name not in self.modified_names:
1.110 + NamespaceDict._init_attribute_user_for_name(self, node, name)
1.111 +
1.112 + def _define_attribute_accessor(self, name, attrname, node, value):
1.113 + if name not in self.modified_names:
1.114 + NamespaceDict._define_attribute_accessor(self, name, attrname, node, value)
1.115
1.116 # Pre-made instances.
1.117
2.1 --- a/micropython/inspect.py Wed Jul 04 00:27:29 2012 +0200
2.2 +++ b/micropython/inspect.py Wed Jul 04 00:42:04 2012 +0200
2.3 @@ -200,6 +200,8 @@
2.4 # NOTE: point and just set an instance instead.
2.5
2.6 self.set(name, make_instance(), False)
2.7 + self.modified_names.add(name)
2.8 +
2.9 else:
2.10 self.process_globals(n)
2.11
2.12 @@ -1079,19 +1081,6 @@
2.13
2.14 # The name is recorded in an earlier process.
2.15
2.16 - # Since the presence of a global declaration may
2.17 - # indicate the modification of a name, and this may
2.18 - # happen during initialisation, the name is recorded
2.19 - # and any usage observations ultimately revoked.
2.20 -
2.21 - # NOTE: Actual modification could be detected by
2.22 - # NOTE: establishing a path from the module top-level to
2.23 - # NOTE: an actual assignment.
2.24 -
2.25 - if not self.modified_names.has_key(ns):
2.26 - self.modified_names[ns] = set()
2.27 - self.modified_names[ns].add(name)
2.28 -
2.29 def visitIf(self, node):
2.30 self.use_name("__bool__", node)
2.31 self.new_branchpoint()
3.1 --- a/tests/changed_globals_function.py Wed Jul 04 00:27:29 2012 +0200
3.2 +++ b/tests/changed_globals_function.py Wed Jul 04 00:42:04 2012 +0200
3.3 @@ -12,11 +12,15 @@
3.4 global x
3.5 x = D
3.6
3.7 +def use(y):
3.8 + return y.p # usage of p
3.9 +
3.10 def f():
3.11 - return x.p
3.12 + return x.p # ambiguous
3.13
3.14 change()
3.15 result1_456 = x.p
3.16 result2_456 = f()
3.17 +result3_456 = use(x)
3.18
3.19 # vim: tabstop=4 expandtab shiftwidth=4