1.1 --- a/micropython/branch.py Mon Jan 13 23:58:23 2014 +0100
1.2 +++ b/micropython/branch.py Mon Jan 13 23:58:56 2014 +0100
1.3 @@ -1,7 +1,7 @@
1.4 #!/usr/bin/env python
1.5
1.6 """
1.7 -Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -414,6 +414,13 @@
1.13
1.14 self.scope_usage[-1][name] = scope
1.15
1.16 + def defined_as_local(self, name):
1.17 +
1.18 + "Return the scope defined for 'name' or None if it is not yet defined."
1.19 +
1.20 + scope = self.scope_usage[-1].get(name)
1.21 + return scope and (scope == "local" or isinstance(scope, ScopeConflict) and scope.is_benign())
1.22 +
1.23 def note_scope(self, name, scope):
1.24
1.25 """
1.26 @@ -426,8 +433,11 @@
1.27 if scope_usage.has_key(name):
1.28 found_scope = scope_usage[name]
1.29 if isinstance(found_scope, ScopeConflict):
1.30 - raise InspectError("Scope conflict for %r: defined as %s." % (
1.31 - name, ", ".join(found_scope.scopes)))
1.32 + if not found_scope.is_benign():
1.33 + raise InspectError("Scope conflict for %r: defined as %s." % (
1.34 + name, ", ".join(found_scope.scopes)))
1.35 + else:
1.36 + print >>sys.stderr, "Warning: name %r in %s may not be defined in all cases." % (name, self.full_name())
1.37
1.38 scope_usage[name] = scope
1.39
1.40 @@ -645,6 +655,8 @@
1.41
1.42 else:
1.43 attr, scope, full_name = self._get_with_scope(name, external=1)
1.44 + if not attr:
1.45 + scope = "unset"
1.46
1.47 # Attempt to record the scope, testing for conflicts.
1.48
1.49 @@ -748,13 +760,21 @@
1.50 class ScopeConflict:
1.51
1.52 """
1.53 - A scope conflict caused when different code branches contribute different
1.54 - sources of names.
1.55 + A class whose instances provide a collection of scope alternatives, either
1.56 + potentially benign or indicating a serious problem.
1.57 +
1.58 + A scope conflict is caused when different code branches contribute different
1.59 + sources of names or where branches neglect to contribute names at all. Where
1.60 + the sources (scopes) indicated are different, a serious problem exists
1.61 + because the name has no single way of being accessed.
1.62 """
1.63
1.64 def __init__(self, scopes):
1.65 self.scopes = scopes
1.66
1.67 + def is_benign(self):
1.68 + return len(self.scopes) == 2 and "unset" in self.scopes
1.69 +
1.70 class UnsetType:
1.71
1.72 "A None-like value."