1.1 --- a/micropython/inspect.py Sat May 10 02:32:20 2008 +0200
1.2 +++ b/micropython/inspect.py Sun May 11 18:20:27 2008 +0200
1.3 @@ -17,821 +17,12 @@
1.4
1.5 You should have received a copy of the GNU General Public License along with
1.6 this program. If not, see <http://www.gnu.org/licenses/>.
1.7 -
1.8 ---------
1.9 -
1.10 -The central classes in this module are the following:
1.11 -
1.12 - * Class
1.13 - * Function
1.14 - * Module
1.15 - * InspectedModule (derived from Module)
1.16 -
1.17 -All of the above support the Naming interface either explicitly or through
1.18 -general conformance, meaning that all can be asked to provide their 'full_name'
1.19 -using the method of that name.
1.20 -
1.21 -Additionally, all of the above also support a dictionary interface in order to
1.22 -access names within their defined scopes. Specific methods also exist in order
1.23 -to distinguish between certain kinds of attributes:
1.24 -
1.25 - * Class: (class|all_class|instance|all)_attributes
1.26 - * Function: parameters, locals, all_locals
1.27 - * Module: module_attributes
1.28 -
1.29 -These specific methods are useful in certain situations.
1.30 -
1.31 -The above classes also provide a 'node' attribute, indicating the AST node where
1.32 -each such object is defined.
1.33 """
1.34
1.35 from micropython.common import *
1.36 +from micropython.data import *
1.37 import compiler.ast
1.38 from compiler.visitor import ASTVisitor
1.39 -try:
1.40 - set
1.41 -except NameError:
1.42 - from sets import Set as set
1.43 -
1.44 -class InspectError(ProcessingError): pass
1.45 -
1.46 -class AtLeast:
1.47 -
1.48 - "A special representation for numbers of a given value or greater."
1.49 -
1.50 - def __init__(self, count):
1.51 - self.count = count
1.52 -
1.53 - def __eq__(self, other):
1.54 - return 0
1.55 -
1.56 - __lt__ = __le__ = __eq__
1.57 -
1.58 - def __ne__(self, other):
1.59 - return 1
1.60 -
1.61 - def __gt__(self, other):
1.62 - if isinstance(other, AtLeast):
1.63 - return 0
1.64 - else:
1.65 - return self.count > other
1.66 -
1.67 - def __ge__(self, other):
1.68 - if isinstance(other, AtLeast):
1.69 - return 0
1.70 - else:
1.71 - return self.count >= other
1.72 -
1.73 - def __iadd__(self, other):
1.74 - if isinstance(other, AtLeast):
1.75 - self.count += other.count
1.76 - else:
1.77 - self.count += other
1.78 - return self
1.79 -
1.80 - def __radd__(self, other):
1.81 - if isinstance(other, AtLeast):
1.82 - return AtLeast(self.count + other.count)
1.83 - else:
1.84 - return AtLeast(self.count + other)
1.85 -
1.86 - def __repr__(self):
1.87 - return "AtLeast(%r)" % self.count
1.88 -
1.89 -# Mix-ins and abstract classes.
1.90 -
1.91 -class NamespaceDict:
1.92 -
1.93 - "A mix-in providing dictionary methods."
1.94 -
1.95 - def __init__(self, global_namespace=None):
1.96 - self.namespace = {}
1.97 - self.globals = set()
1.98 - self.global_namespace = global_namespace
1.99 -
1.100 - def __getitem__(self, name):
1.101 - return self.namespace[name]
1.102 -
1.103 - def get(self, name, default=None):
1.104 - return self.namespace.get(name, default)
1.105 -
1.106 - def __setitem__(self, name, value):
1.107 - self.set(name, value)
1.108 -
1.109 - def set(self, name, value, single_assignment=1):
1.110 -
1.111 - """
1.112 - A more powerful set operation, making 'name' refer to 'value' whilst
1.113 - indicating whether a 'single_assignment' (true by default) occurs in
1.114 - this operation (or whether the operation covers potentially many
1.115 - assignments in the lifetime of a program).
1.116 - """
1.117 -
1.118 - if name in self.globals:
1.119 - self.global_namespace.set(name, value, 0)
1.120 - else:
1.121 - attr = self._set(name, value)
1.122 -
1.123 - # NOTE: Insist on assignments with known values.
1.124 -
1.125 - if value is not None:
1.126 - attr.update(value, single_assignment)
1.127 -
1.128 - def set_module(self, name, value):
1.129 -
1.130 - """
1.131 - A specialised set operation, making 'name' refer to 'value' in the
1.132 - context of making a module reference available in association with
1.133 - 'name' as part of the import of that module or a submodule of that
1.134 - module.
1.135 - """
1.136 -
1.137 - attr = self._set(name, value)
1.138 - if attr.assignments is None:
1.139 - attr.assignments = 1
1.140 - attr.assignment_values.add(value)
1.141 -
1.142 - def _set(self, name, value):
1.143 -
1.144 - "The underlying set operation associating 'name' with 'value'."
1.145 -
1.146 - if not self.namespace.has_key(name):
1.147 - self.namespace[name] = Attr(None, self, name, value)
1.148 - return self.namespace[name]
1.149 -
1.150 - def __delitem__(self, name):
1.151 - del self.namespace[name]
1.152 -
1.153 - def has_key(self, name):
1.154 - return self.namespace.has_key(name)
1.155 -
1.156 - def keys(self):
1.157 - return self.namespace.keys()
1.158 -
1.159 - def values(self):
1.160 - return self.namespace.values()
1.161 -
1.162 - def items(self):
1.163 - return self.namespace.items()
1.164 -
1.165 - def make_global(self, name):
1.166 - if not self.namespace.has_key(name):
1.167 - self.globals.add(name)
1.168 - else:
1.169 - raise InspectError(self.full_name(), self.node, "Name %r is both global and local in %r" % (name, self.full_name()))
1.170 -
1.171 - def get_assignments(self, name):
1.172 - if self.assignments.has_key(name):
1.173 - return max(self.assignments[name], len(self.assignment_values[name]))
1.174 - else:
1.175 - return None
1.176 -
1.177 - def attributes_as_list(self):
1.178 - self.finalise_attributes()
1.179 - l = [None] * len(self.keys())
1.180 - for attr in self.values():
1.181 - l[attr.position] = attr
1.182 - return l
1.183 -
1.184 - def finalise_attributes(self):
1.185 -
1.186 - "Make sure all attributes are fully defined."
1.187 -
1.188 - # The default action is to assign attribute positions sequentially.
1.189 -
1.190 - for i, attr in enumerate(self.values()):
1.191 - attr.position = i
1.192 -
1.193 -class Naming:
1.194 -
1.195 - "A mix-in providing naming conveniences."
1.196 -
1.197 - def full_name(self):
1.198 - if self.name is not None:
1.199 - return self.parent.full_name() + "." + self.name
1.200 - else:
1.201 - return self.parent.full_name()
1.202 -
1.203 -# Program data structures.
1.204 -
1.205 -class Attr:
1.206 -
1.207 - "An attribute entry having a parent as context."
1.208 -
1.209 - def __init__(self, position, parent, name, value=None, assignments=None):
1.210 - self.position = position
1.211 - self.parent = parent
1.212 - self.name = name
1.213 - self.value = value
1.214 -
1.215 - # Number of assignments per name.
1.216 -
1.217 - self.assignments = assignments
1.218 - self.assignment_values = set()
1.219 -
1.220 - def update(self, value, single_assignment):
1.221 -
1.222 - """
1.223 - Update the attribute, adding the 'value' provided to the known values
1.224 - associated with the attribute, changing the number of assignments
1.225 - according to the 'single_assignment' status of the operation, where
1.226 - a true value indicates that only one assignment is associated with the
1.227 - update, and a false value indicates that potentially many assignments
1.228 - may be involved.
1.229 - """
1.230 -
1.231 - if self.assignments is None:
1.232 - if single_assignment:
1.233 - self.assignments = 1
1.234 - else:
1.235 - self.assignments = AtLeast(1)
1.236 - else:
1.237 - if single_assignment:
1.238 - self.assignments += 1
1.239 - else:
1.240 - self.assignments += AtLeast(1)
1.241 - self.assignment_values.add(value)
1.242 -
1.243 - def __repr__(self):
1.244 - return "Attr(%r, %r, %r, %r, %r)" % (self.position, self.parent, self.name, self.value, self.assignments)
1.245 -
1.246 -class Const:
1.247 -
1.248 - "A constant object with no context."
1.249 -
1.250 - def __init__(self, value):
1.251 - self.value = value
1.252 -
1.253 - # Image generation details.
1.254 -
1.255 - self.location = None
1.256 -
1.257 - def __repr__(self):
1.258 - if self.location is not None:
1.259 - return "Const(%r, location=%r)" % (self.value, self.location)
1.260 - else:
1.261 - return "Const(%r)" % self.value
1.262 -
1.263 - # Support constants as dictionary keys in order to build constant tables.
1.264 -
1.265 - def __eq__(self, other):
1.266 - return self.value == other.value
1.267 -
1.268 - def __hash__(self):
1.269 - return hash(self.value)
1.270 -
1.271 - def value_type_name(self):
1.272 - return "__builtins__." + self.value.__class__.__name__
1.273 -
1.274 -class Class(NamespaceDict, Naming):
1.275 -
1.276 - "An inspected class."
1.277 -
1.278 - def __init__(self, name, parent, global_namespace=None, node=None):
1.279 -
1.280 - """
1.281 - Initialise the class with the given 'name', 'parent' object, optional
1.282 - 'global_namespace' and optional AST 'node'.
1.283 - """
1.284 -
1.285 - NamespaceDict.__init__(self, global_namespace)
1.286 - self.name = name
1.287 - self.parent = parent
1.288 - self.node = node
1.289 -
1.290 - # Superclasses, descendants and attributes.
1.291 -
1.292 - self.bases = []
1.293 - self.descendants = set()
1.294 - self.instattr = set() # instance attributes
1.295 - self.relocated = set() # attributes which do not have the same
1.296 - # position as those of the same name in
1.297 - # some superclasses
1.298 -
1.299 - # Caches.
1.300 -
1.301 - self.all_instattr = None # cache for instance_attributes
1.302 - self.all_instattr_names = None # from all_instattr
1.303 - self.all_classattr = None # cache for all_class_attributes
1.304 - self.all_classattr_names = None # from all_classattr
1.305 - self.allattr = None # cache for all_attributes
1.306 - self.allattr_names = None # from allattr
1.307 -
1.308 - # Add this class to its attributes.
1.309 -
1.310 - self.set("__class__", self)
1.311 -
1.312 - # Image generation details.
1.313 -
1.314 - self.location = None
1.315 - self.code_location = None
1.316 - self.instantiator = None
1.317 -
1.318 - # Program-related details.
1.319 -
1.320 - self.stack_usage = 0
1.321 - self.stack_temp_usage = 0
1.322 - self.stack_local_usage = 0
1.323 -
1.324 - def __repr__(self):
1.325 - if self.location is not None:
1.326 - return "Class(%r, %r, location=%r)" % (self.name, self.parent, self.location)
1.327 - else:
1.328 - return "Class(%r, %r)" % (self.name, self.parent)
1.329 -
1.330 - def finalise_attributes(self):
1.331 -
1.332 - "Make sure that all attributes are fully defined."
1.333 -
1.334 - self.finalise_class_attributes()
1.335 - self.finalise_instance_attributes()
1.336 -
1.337 - def get_instantiator(self):
1.338 -
1.339 - "Return a function which can be used to instantiate the class."
1.340 -
1.341 - if self.instantiator is None:
1.342 - init_method = self.all_class_attributes()["__init__"].value
1.343 - self.instantiator = init_method.function_from_method()
1.344 - return self.instantiator
1.345 -
1.346 - # Class-specific methods.
1.347 -
1.348 - def add_base(self, base):
1.349 - self.bases.append(base)
1.350 - base.add_descendant(self)
1.351 -
1.352 - def add_instance_attribute(self, name):
1.353 - self.instattr.add(name)
1.354 -
1.355 - def add_descendant(self, cls):
1.356 - self.descendants.add(cls)
1.357 - for base in self.bases:
1.358 - base.add_descendant(cls)
1.359 -
1.360 - "Return the attribute names provided by this class only."
1.361 -
1.362 - class_attribute_names = NamespaceDict.keys
1.363 -
1.364 - def class_attributes(self):
1.365 -
1.366 - "Return class attributes provided by this class only."
1.367 -
1.368 - self.finalise_class_attributes()
1.369 - return dict(self)
1.370 -
1.371 - def all_class_attribute_names(self):
1.372 -
1.373 - "Return the attribute names provided by classes in this hierarchy."
1.374 -
1.375 - if self.all_classattr_names is None:
1.376 - self.all_class_attributes()
1.377 - return self.all_classattr_names
1.378 -
1.379 - def all_class_attributes(self):
1.380 -
1.381 - "Return all class attributes, indicating the class which provides them."
1.382 -
1.383 - self.finalise_class_attributes()
1.384 - return self.all_classattr
1.385 -
1.386 - def finalise_class_attributes(self):
1.387 -
1.388 - "Make sure that the class attributes are fully defined."
1.389 -
1.390 - if self.all_classattr is None:
1.391 - self.all_classattr = {}
1.392 - clsattr = {}
1.393 -
1.394 - # Record provisional position information for attributes of this
1.395 - # class.
1.396 -
1.397 - for name in self.class_attributes().keys():
1.398 - clsattr[name] = set() # position not yet defined
1.399 -
1.400 - reversed_bases = self.bases[:]
1.401 - reversed_bases.reverse()
1.402 -
1.403 - # For the bases in reverse order, acquire class attribute details.
1.404 -
1.405 - for cls in reversed_bases:
1.406 - for name, attr in cls.all_class_attributes().items():
1.407 - self.all_classattr[name] = attr
1.408 -
1.409 - # Record previous attribute information.
1.410 -
1.411 - if clsattr.has_key(name):
1.412 - clsattr[name].add(attr.position)
1.413 -
1.414 - # Record class attributes provided by this class and its bases,
1.415 - # along with their positions.
1.416 -
1.417 - self.all_classattr.update(self.class_attributes())
1.418 -
1.419 - if clsattr:
1.420 - for i, name in enumerate(self._get_position_list(clsattr)):
1.421 - self.all_classattr[name].position = i
1.422 -
1.423 - return self.all_classattr
1.424 -
1.425 - def instance_attribute_names(self):
1.426 -
1.427 - "Return the instance attribute names provided by the class."
1.428 -
1.429 - if self.all_instattr_names is None:
1.430 - self.instance_attributes()
1.431 - return self.all_instattr_names
1.432 -
1.433 - def instance_attributes(self):
1.434 -
1.435 - "Return instance-only attributes for instances of this class."
1.436 -
1.437 - self.finalise_instance_attributes()
1.438 - return self.all_instattr
1.439 -
1.440 - def finalise_instance_attributes(self):
1.441 -
1.442 - "Make sure that the instance attributes are fully defined."
1.443 -
1.444 - if self.all_instattr is None:
1.445 - self.all_instattr = {}
1.446 - instattr = {}
1.447 -
1.448 - # Record provisional position information for attributes of this
1.449 - # instance.
1.450 -
1.451 - for name in self.instattr:
1.452 - instattr[name] = set() # position not yet defined
1.453 -
1.454 - reversed_bases = self.bases[:]
1.455 - reversed_bases.reverse()
1.456 -
1.457 - # For the bases in reverse order, acquire instance attribute
1.458 - # details.
1.459 -
1.460 - for cls in reversed_bases:
1.461 - for name, attr in cls.instance_attributes().items():
1.462 -
1.463 - # Record previous attribute information.
1.464 -
1.465 - if instattr.has_key(name):
1.466 - instattr[name].add(attr.position)
1.467 -
1.468 - # Cache the attributes by converting the positioned attributes into
1.469 - # a dictionary.
1.470 -
1.471 - if not instattr:
1.472 - self.all_instattr = {}
1.473 - else:
1.474 - self.all_instattr = self._get_attributes(instattr)
1.475 -
1.476 - self.all_instattr_names = self.all_instattr.keys()
1.477 -
1.478 - return self.all_instattr
1.479 -
1.480 - def _get_position_list(self, positions):
1.481 -
1.482 - """
1.483 - Return a list of attribute names for the given 'positions' mapping from
1.484 - names to positions, indicating the positions of the attributes in the
1.485 - final instance structure.
1.486 - """
1.487 -
1.488 - position_items = positions.items()
1.489 - namearray = [None] * len(position_items)
1.490 -
1.491 - # Get the positions in ascending order of list size, with lists
1.492 - # of the same size ordered according to their smallest position
1.493 - # value.
1.494 -
1.495 - position_items.sort(self._cmp_positions)
1.496 -
1.497 - # Get the names in position order.
1.498 -
1.499 - held = []
1.500 -
1.501 - for name, pos in position_items:
1.502 - pos = list(pos)
1.503 - pos.sort()
1.504 - if pos and pos[0] < len(namearray) and namearray[pos[0]] is None:
1.505 - namearray[pos[0]] = name
1.506 - else:
1.507 - if pos:
1.508 - self.relocated.add(name)
1.509 - held.append((name, pos))
1.510 -
1.511 - for i, attr in enumerate(namearray):
1.512 - if attr is None:
1.513 - name, pos = held.pop()
1.514 - namearray[i] = name
1.515 -
1.516 - #print self.name, positions
1.517 - #print "->", namearray
1.518 - return namearray
1.519 -
1.520 - def _get_attributes(self, positions):
1.521 -
1.522 - """
1.523 - For the given 'positions' mapping from names to positions, return a
1.524 - dictionary mapping names to Attr instances incorporating information
1.525 - about their positions in the final instance structure.
1.526 - """
1.527 -
1.528 - d = {}
1.529 - for i, name in enumerate(self._get_position_list(positions)):
1.530 - d[name] = Attr(i, Instance(), name, None)
1.531 - return d
1.532 -
1.533 - def _cmp_positions(self, a, b):
1.534 -
1.535 - "Compare name plus position list operands 'a' and 'b'."
1.536 -
1.537 - name_a, list_a = a
1.538 - name_b, list_b = b
1.539 - if len(list_a) < len(list_b):
1.540 - return -1
1.541 - elif len(list_a) > len(list_b):
1.542 - return 1
1.543 - elif not list_a:
1.544 - return 0
1.545 - else:
1.546 - return cmp(min(list_a), min(list_b))
1.547 -
1.548 - def all_attribute_names(self):
1.549 -
1.550 - """
1.551 - Return the names of all attributes provided by instances of this class.
1.552 - """
1.553 -
1.554 - self.allattr_names = self.allattr_names or self.all_attributes().keys()
1.555 - return self.allattr_names
1.556 -
1.557 - def all_attributes(self):
1.558 -
1.559 - """
1.560 - Return all attributes for an instance, indicating either the class which
1.561 - provides them or that the instance itself provides them.
1.562 - """
1.563 -
1.564 - if self.allattr is None:
1.565 - self.allattr = {}
1.566 - self.allattr.update(self.all_class_attributes())
1.567 - for name, attr in self.instance_attributes().items():
1.568 - if self.allattr.has_key(name):
1.569 - print "Instance attribute %r in %r overrides class attribute." % (name, self)
1.570 - self.allattr[name] = attr
1.571 - return self.allattr
1.572 -
1.573 -class Function(NamespaceDict, Naming):
1.574 -
1.575 - "An inspected function."
1.576 -
1.577 - def __init__(self, name, parent, argnames, defaults, has_star, has_dstar, global_namespace=None, node=None):
1.578 -
1.579 - """
1.580 - Initialise the function with the given 'name', 'parent', list of
1.581 - 'argnames', list of 'defaults', the 'has_star' flag (indicating the
1.582 - presence of a * parameter), the 'has_dstar' flag (indicating the
1.583 - presence of a ** parameter), optional 'global_namespace', and optional
1.584 - AST 'node'.
1.585 - """
1.586 -
1.587 - NamespaceDict.__init__(self, global_namespace)
1.588 - self.name = name
1.589 - self.parent = parent
1.590 - self.argnames = argnames
1.591 - self.defaults = defaults
1.592 - self.has_star = has_star
1.593 - self.has_dstar = has_dstar
1.594 - self.node = node
1.595 -
1.596 - # Initialise the positional names.
1.597 -
1.598 - self.positional_names = self.argnames[:]
1.599 - if has_dstar:
1.600 - self.dstar_name = self.positional_names[-1]
1.601 - del self.positional_names[-1]
1.602 - if has_star:
1.603 - self.star_name = self.positional_names[-1]
1.604 - del self.positional_names[-1]
1.605 -
1.606 - # Initialise default storage.
1.607 - # NOTE: This must be initialised separately due to the reliance on node
1.608 - # NOTE: visiting.
1.609 -
1.610 - self.default_attrs = []
1.611 -
1.612 - # Caches.
1.613 -
1.614 - self.localnames = None # cache for locals
1.615 -
1.616 - # Add parameters to the namespace.
1.617 -
1.618 - self._add_parameters(argnames)
1.619 -
1.620 - # Image generation details.
1.621 -
1.622 - self.location = None
1.623 - self.code_location = None
1.624 -
1.625 - # Program-related details.
1.626 -
1.627 - self.stack_usage = 0
1.628 - self.stack_temp_usage = 0
1.629 - self.stack_local_usage = 0
1.630 -
1.631 - def _add_parameters(self, argnames):
1.632 - for name in argnames:
1.633 - if isinstance(name, tuple):
1.634 - self._add_parameters(name)
1.635 - else:
1.636 - self.set(name, None)
1.637 -
1.638 - def __repr__(self):
1.639 - if self.location is not None:
1.640 - return "Function(%r, %r, %r, %r, %r, %r, location=%r)" % (
1.641 - self.name, self.parent, self.argnames, self.defaults, self.has_star, self.has_dstar, self.location
1.642 - )
1.643 - else:
1.644 - return "Function(%r, %r, %r, %r, %r, %r)" % (
1.645 - self.name, self.parent, self.argnames, self.defaults, self.has_star, self.has_dstar
1.646 - )
1.647 -
1.648 - def store_default(self, value):
1.649 - attr = Attr(None, self, None, value)
1.650 - attr.update(value, 1)
1.651 - self.default_attrs.append(attr)
1.652 -
1.653 - def make_global(self, name):
1.654 - if name not in self.argnames and not self.has_key(name):
1.655 - self.globals.add(name)
1.656 - else:
1.657 - raise InspectError(self.full_name(), self.node, "Name %r is global and local in %r" % (name, self.full_name()))
1.658 -
1.659 - def parameters(self):
1.660 -
1.661 - """
1.662 - Return a dictionary mapping parameter names to their position in the
1.663 - parameter list.
1.664 - """
1.665 -
1.666 - parameters = {}
1.667 - for i, name in enumerate(self.argnames):
1.668 - parameters[name] = i
1.669 - return parameters
1.670 -
1.671 - def all_locals(self):
1.672 -
1.673 - "Return a dictionary mapping names to local and parameter details."
1.674 -
1.675 - return dict(self)
1.676 -
1.677 - def locals(self):
1.678 -
1.679 - "Return a dictionary mapping names to local details."
1.680 -
1.681 - if self.localnames is None:
1.682 - self.localnames = {}
1.683 - self.localnames.update(self.all_locals())
1.684 - for name in self.argnames:
1.685 - del self.localnames[name]
1.686 - return self.localnames
1.687 -
1.688 - def is_method(self):
1.689 -
1.690 - "Return whether this function is a method."
1.691 -
1.692 - return isinstance(self.parent, Class)
1.693 -
1.694 - def is_relocated(self, name):
1.695 -
1.696 - """
1.697 - Determine whether the given attribute 'name' is relocated for instances
1.698 - having this function as a method.
1.699 - """
1.700 -
1.701 - for cls in self.parent.descendants:
1.702 - if name in cls.relocated:
1.703 - return 1
1.704 - return 0
1.705 -
1.706 - def finalise_attributes(self):
1.707 -
1.708 - """
1.709 - Make sure all attributes (locals) are fully defined. Note that locals
1.710 - are not attributes in the sense of class, module or instance attributes.
1.711 - Defaults are also finalised by this method.
1.712 - """
1.713 -
1.714 - for i, default in enumerate(self.default_attrs):
1.715 - default.position = i
1.716 -
1.717 - i = None
1.718 - for i, name in enumerate(self.argnames):
1.719 - self[name].position = i
1.720 -
1.721 - if i is not None:
1.722 - j = i
1.723 - else:
1.724 - j = 0
1.725 -
1.726 - i = -1
1.727 - for i, attr in enumerate(self.locals().values()):
1.728 - attr.position = i + j
1.729 -
1.730 - self.stack_local_usage = i + 1
1.731 -
1.732 - def function_from_method(self):
1.733 -
1.734 - "Make a function from a method."
1.735 -
1.736 - function = Function(self.name, self.parent, self.argnames[1:], self.defaults,
1.737 - self.has_star, self.has_dstar, self.global_namespace, self.node)
1.738 - function.default_attrs = self.default_attrs
1.739 - return function
1.740 -
1.741 -class UnresolvedName(NamespaceDict):
1.742 -
1.743 - "A module, class or function which was mentioned but could not be imported."
1.744 -
1.745 - def __init__(self, name, parent_name, global_namespace=None):
1.746 - NamespaceDict.__init__(self, global_namespace)
1.747 - self.name = name
1.748 - self.parent_name = parent_name
1.749 -
1.750 - def all_class_attributes(self):
1.751 - return {}
1.752 -
1.753 - def instance_attributes(self):
1.754 - return {}
1.755 -
1.756 - def __repr__(self):
1.757 - return "UnresolvedName(%r, %r)" % (self.name, self.parent_name)
1.758 -
1.759 - def full_name(self):
1.760 - if self.name is not None:
1.761 - return self.parent_name + "." + self.name
1.762 - else:
1.763 - return self.parent_name
1.764 -
1.765 -class Instance:
1.766 -
1.767 - "A placeholder indicating the involvement of an instance."
1.768 -
1.769 - def __repr__(self):
1.770 - return "Instance()"
1.771 -
1.772 -class Module(NamespaceDict):
1.773 -
1.774 - "An inspected module's core details."
1.775 -
1.776 - def __init__(self, name):
1.777 - NamespaceDict.__init__(self, self)
1.778 - self.name = name
1.779 -
1.780 - # Original location details.
1.781 -
1.782 - self.node = None
1.783 -
1.784 - # Complete lists of classes and functions.
1.785 -
1.786 - self.all_objects = set()
1.787 -
1.788 - # Keyword records.
1.789 -
1.790 - self.keyword_names = set()
1.791 -
1.792 - # Image generation details.
1.793 -
1.794 - self.location = None
1.795 - self.code_location = None
1.796 -
1.797 - # Program-related details.
1.798 -
1.799 - self.stack_usage = 0
1.800 - self.stack_temp_usage = 0
1.801 - self.stack_local_usage = 0
1.802 -
1.803 - def full_name(self):
1.804 - return self.name
1.805 -
1.806 - def __repr__(self):
1.807 - if self.location is not None:
1.808 - return "Module(%r, location=%r)" % (self.name, self.location)
1.809 - else:
1.810 - return "Module(%r)" % self.name
1.811 -
1.812 - # Attribute methods.
1.813 -
1.814 - "Return the module attribute names provided by the module."
1.815 -
1.816 - module_attribute_names = NamespaceDict.keys
1.817 -
1.818 - def module_attributes(self):
1.819 -
1.820 - "Return a dictionary mapping names to module attributes."
1.821 -
1.822 - return dict(self)
1.823
1.824 # Program visitors.
1.825