1.1 --- a/micropython/inspect.py Tue Jan 29 01:01:11 2008 +0100
1.2 +++ b/micropython/inspect.py Sat Feb 02 01:53:22 2008 +0100
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Inspect source files, obtaining details of classes and attributes.
1.6
1.7 -Copyright (C) 2007 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007, 2008 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 @@ -36,7 +36,7 @@
1.13 to distinguish between certain kinds of attributes:
1.14
1.15 * Class: (class|all_class|instance|all)_attributes
1.16 - * Function: parameters, locals
1.17 + * Function: parameters, locals, all_locals
1.18 * Module: module_attributes
1.19
1.20 These specific methods are useful in certain situations.
1.21 @@ -58,6 +58,49 @@
1.22
1.23 pass
1.24
1.25 +class AtLeast:
1.26 +
1.27 + "A special representation for numbers of a given value or greater."
1.28 +
1.29 + def __init__(self, count):
1.30 + self.count = count
1.31 +
1.32 + def __eq__(self, other):
1.33 + return 0
1.34 +
1.35 + __lt__ = __le__ = __eq__
1.36 +
1.37 + def __ne__(self, other):
1.38 + return 1
1.39 +
1.40 + def __gt__(self, other):
1.41 + if isinstance(other, AtLeast):
1.42 + return 0
1.43 + else:
1.44 + return self.count > other
1.45 +
1.46 + def __ge__(self, other):
1.47 + if isinstance(other, AtLeast):
1.48 + return 0
1.49 + else:
1.50 + return self.count >= other
1.51 +
1.52 + def __iadd__(self, other):
1.53 + if isinstance(other, AtLeast):
1.54 + self.count += other.count
1.55 + else:
1.56 + self.count += other
1.57 + return self
1.58 +
1.59 + def __radd__(self, other):
1.60 + if isinstance(other, AtLeast):
1.61 + return AtLeast(self.count + other.count)
1.62 + else:
1.63 + return AtLeast(self.count + other)
1.64 +
1.65 + def __repr__(self):
1.66 + return "AtLeast(%r)" % self.count
1.67 +
1.68 # Mix-ins and abstract classes.
1.69
1.70 class NamespaceDict:
1.71 @@ -80,19 +123,31 @@
1.72 return self.namespace.get(name, default)
1.73
1.74 def __setitem__(self, name, value):
1.75 +
1.76 + # Use a special method to access the namespace.
1.77 +
1.78 if name not in self.globals:
1.79 - self.namespace[name] = value
1.80 + self.set(name, value)
1.81 + else:
1.82 + self.global_namespace.set(name, value, 1)
1.83 +
1.84 + def set(self, name, value, global_assignment=0):
1.85 + self.namespace[name] = value
1.86
1.87 - # Record the number of assignments to each name.
1.88 - # NOTE: Insist on assignments with known values.
1.89 + # Record the number of assignments to each name.
1.90 + # NOTE: Insist on assignments with known values.
1.91
1.92 - if value is not None:
1.93 - if not self.assignments.has_key(name):
1.94 + if value is not None:
1.95 + if not self.assignments.has_key(name):
1.96 + if global_assignment:
1.97 + self.assignments[name] = AtLeast(1)
1.98 + else:
1.99 self.assignments[name] = 1
1.100 + else:
1.101 + if global_assignment:
1.102 + self.assignments[name] += AtLeast(1)
1.103 else:
1.104 self.assignments[name] += 1
1.105 - else:
1.106 - self.global_namespace[name] = value
1.107
1.108 def __delitem__(self, name):
1.109 del self.namespace[name]
1.110 @@ -213,7 +268,7 @@
1.111 self.classattr_names = self.keys()
1.112
1.113 for i, name in enumerate(self.classattr_names):
1.114 - self.classattr[name] = Attr(i, self, self.assignments[name], self[name])
1.115 + self.classattr[name] = Attr(i, self, self.assignments.get(name), self[name])
1.116
1.117 return self.classattr
1.118
1.119 @@ -452,7 +507,7 @@
1.120 self.modattr = {}
1.121 self.modattr_names = self.keys()
1.122 for i, name in enumerate(self.modattr_names):
1.123 - self.modattr[name] = Attr(i, self, self.assignments[name], self[name])
1.124 + self.modattr[name] = Attr(i, self, self.assignments.get(name), self[name])
1.125
1.126 return self.modattr
1.127