micropython

Changeset

528:d486a4cf1730
2012-06-09 Paul Boddie raw files shortlog changelog graph Improved contributor and usage discovery where contribution loops are encountered. Added a test of nested conditional statements. Updated the "to do" list.
TO_DO.txt (file) micropython/data.py (file) tests/attribute_access_type_restriction_conditional_nested.py (file)
     1.1 --- a/TO_DO.txt	Tue Jun 05 01:54:54 2012 +0200
     1.2 +++ b/TO_DO.txt	Sat Jun 09 02:01:56 2012 +0200
     1.3 @@ -94,8 +94,6 @@
     1.4  Self-related Usage
     1.5  ------------------
     1.6  
     1.7 -Usage of self to restrict attribute usage observations and coverage.
     1.8 -
     1.9  Perform attribute usage on attributes of self as names, potentially combining observations
    1.10  across methods.
    1.11  
     2.1 --- a/micropython/data.py	Tue Jun 05 01:54:54 2012 +0200
     2.2 +++ b/micropython/data.py	Sat Jun 09 02:01:56 2012 +0200
     2.3 @@ -390,7 +390,6 @@
     2.4                  # usage with the usage recorded directly on the user.
     2.5  
     2.6                  self.get_usage_from_contributors(user)
     2.7 -                self.set_contributors(user)
     2.8  
     2.9                  # Record the defining user on each contributor.
    2.10  
    2.11 @@ -485,21 +484,6 @@
    2.12                  attrtypes[name] = objtypes
    2.13          return attrtypes
    2.14  
    2.15 -    def set_contributors(self, node):
    2.16 -        if not hasattr(node, "_attrcontributors"):
    2.17 -            node._attrcontributors = None
    2.18 -            all_contributors = set()
    2.19 -
    2.20 -            for contributor in node._attrbranches:
    2.21 -                all_contributors.add(contributor)
    2.22 -                self.set_contributors(contributor)
    2.23 -
    2.24 -                contributors = contributor._attrcontributors
    2.25 -                if contributors is not None:
    2.26 -                    all_contributors.update(contributors)
    2.27 -
    2.28 -            node._attrcontributors = all_contributors
    2.29 -
    2.30      def get_usage_from_contributors(self, node):
    2.31  
    2.32          """
    2.33 @@ -513,6 +497,7 @@
    2.34  
    2.35          if not hasattr(node, "_attrcombined"):
    2.36              node._attrcombined = None
    2.37 +            node._attrcontributors = None
    2.38  
    2.39              for contributor in node._attrbranches:
    2.40  
    2.41 @@ -522,23 +507,33 @@
    2.42  
    2.43                  # Collect unfinished contributors and affected nodes.
    2.44  
    2.45 -                if node._attrcombined is None:
    2.46 +                # Where the contributor is already set to None, a loop has
    2.47 +                # occurred and this node will need to have its usage
    2.48 +                # recalculated later for the unfinished contributor.
    2.49 +
    2.50 +                if contributor._attrcombined is None:
    2.51                      if not unfinished.has_key(contributor):
    2.52                          unfinished[contributor] = []
    2.53                      unfinished[contributor].append(node)
    2.54                      continue
    2.55  
    2.56 +                # Where the contributor provides usage details, it may also
    2.57 +                # communicate unfinished contributor information. As a
    2.58 +                # consequence, this node is also affected.
    2.59 +
    2.60                  for unfinished_contributor, nodes in unfinished_contributors.items():
    2.61                      if not unfinished.has_key(unfinished_contributor):
    2.62                          unfinished[unfinished_contributor] = nodes
    2.63                      else:
    2.64                          unfinished[unfinished_contributor] += nodes
    2.65  
    2.66 -                unfinished[contributor].append(node)
    2.67 +                    if node not in unfinished[unfinished_contributor]:
    2.68 +                        unfinished[unfinished_contributor].append(node)
    2.69  
    2.70              # Set the current state of the usage on this node.
    2.71  
    2.72 -            node._attrcombined = self.get_usage_from_contributors_for_node(node)
    2.73 +            node._attrcombined, node._attrcontributors = \
    2.74 +                self.get_usage_from_contributors_for_node(node)
    2.75  
    2.76              # Complete unfinished contributors relying on this node.
    2.77  
    2.78 @@ -547,7 +542,10 @@
    2.79                  for contributor in unfinished[node]:
    2.80                      if not contributor in processed:
    2.81                          processed.add(contributor)
    2.82 -                        contributor._attrcombined = self.get_usage_from_contributors_for_node(contributor)
    2.83 +
    2.84 +                        contributor._attrcombined, contributor._attrcontributors = \
    2.85 +                            self.get_usage_from_contributors_for_node(contributor)
    2.86 +
    2.87                  del unfinished[node]
    2.88  
    2.89          return unfinished
    2.90 @@ -558,12 +556,18 @@
    2.91  
    2.92          contributor_usage = {}
    2.93          all_contributions = []
    2.94 +        all_contributors = set()
    2.95  
    2.96          for contributor in node._attrbranches:
    2.97              usage = contributor._attrcombined
    2.98              if usage is not None:
    2.99                  all_contributions.append(usage)
   2.100  
   2.101 +            all_contributors.add(contributor)
   2.102 +            contributors = contributor._attrcontributors
   2.103 +            if contributors is not None:
   2.104 +                all_contributors.update(contributors)
   2.105 +
   2.106          # Get contributed usage for each contributor.
   2.107          # This gathers usage for each name such as {(a, b), (c, d)} and
   2.108          # {(a, b), (e, f)} into a single set {(a, b), (c, d), (e, f)}.
   2.109 @@ -578,7 +582,7 @@
   2.110          # Thus, usage of {(f, g)} combined with {(a, b), (c, d)} would give
   2.111          # {(f, g, a, b), (f, g, c, d)}.
   2.112  
   2.113 -        return combine_mapping_dicts(deepen_mapping_dict(node._attrnames), contributor_usage)
   2.114 +        return combine_mapping_dicts(deepen_mapping_dict(node._attrnames), contributor_usage), all_contributors
   2.115  
   2.116      def use_attribute(self, name, attrname, value=None):
   2.117  
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tests/attribute_access_type_restriction_conditional_nested.py	Sat Jun 09 02:01:56 2012 +0200
     3.3 @@ -0,0 +1,25 @@
     3.4 +#!/usr/bin/env python
     3.5 +
     3.6 +class C:
     3.7 +    def f(self):
     3.8 +        return 1
     3.9 +    def g(self):
    3.10 +        return 2
    3.11 +
    3.12 +class D:
    3.13 +    def g(self):
    3.14 +        return 3
    3.15 +
    3.16 +def test_conditional(x, obj):
    3.17 +    obj.f()
    3.18 +    if x:
    3.19 +        if x:
    3.20 +            a = obj.g()
    3.21 +        return a
    3.22 +    return 1
    3.23 +
    3.24 +c = C()
    3.25 +d = D()
    3.26 +result1_2 = test_conditional(1, c)
    3.27 +
    3.28 +# vim: tabstop=4 expandtab shiftwidth=4