1.1 --- a/micropython/__init__.py Sat Jul 14 01:37:42 2012 +0200
1.2 +++ b/micropython/__init__.py Sat Jul 14 17:42:42 2012 +0200
1.3 @@ -48,7 +48,7 @@
1.4 import micropython.table
1.5 import bisect
1.6 import os
1.7 -#import sys
1.8 +import sys
1.9
1.10 try:
1.11 set
1.12 @@ -444,6 +444,10 @@
1.13 self.attribute_users_visited = set()
1.14 self.attributes_to_visit = {}
1.15
1.16 + # Attribute usage type deduction failures.
1.17 +
1.18 + self.attribute_usage_failures = set()
1.19 +
1.20 # Status information.
1.21
1.22 self.completed = False
1.23 @@ -689,9 +693,9 @@
1.24 # Using all attribute names for a particular name, attempt to get
1.25 # specific object types.
1.26
1.27 - all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, True)
1.28 + all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, True, self)
1.29 if not all_objtypes:
1.30 - all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, False)
1.31 + all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, False, self)
1.32
1.33 # Where the name through which the attributes are accessed is the
1.34 # special "self" name, restrict the possibilities to types
1.35 @@ -821,6 +825,18 @@
1.36 else:
1.37 self.add_attribute_to_visit(parentname, attrname)
1.38
1.39 + def add_usage_failure(self, all_attributes, unit_name, name, attrnames):
1.40 +
1.41 + """
1.42 + Record a type deduction failure based on 'all_attributes' (where true
1.43 + indicates that all attribute names were required; false indicating that
1.44 + any were required) within the given 'unit_name' for the variable of the
1.45 + given 'name' and for the specified 'attrnames'.
1.46 + """
1.47 +
1.48 + attrnames = tuple(attrnames)
1.49 + self.attribute_usage_failures.add((unit_name, name, attrnames, all_attributes))
1.50 +
1.51 # Constant accounting.
1.52
1.53 def use_constant(self, const, from_name):
2.1 --- a/micropython/data.py Sat Jul 14 01:37:42 2012 +0200
2.2 +++ b/micropython/data.py Sat Jul 14 17:42:42 2012 +0200
2.3 @@ -460,7 +460,7 @@
2.4 attrtypes = {}
2.5 for name, combined_usage in usage.items():
2.6 if combined_usage is not None:
2.7 - objtypes = get_object_types_for_usage(combined_usage, objtable, name, self.full_name(), True)
2.8 + objtypes = get_object_types_for_usage(combined_usage, objtable, name, self.full_name(), True, self.module.importer)
2.9 if objtypes:
2.10 if isinstance(self, Function) and self.is_method() and name == "self":
2.11 objtypes = filter_using_self(objtypes, self.parent)
3.1 --- a/micropython/inspect.py Sat Jul 14 01:37:42 2012 +0200
3.2 +++ b/micropython/inspect.py Sat Jul 14 17:42:42 2012 +0200
3.3 @@ -839,7 +839,6 @@
3.4
3.5 elif isinstance(value, Module):
3.6 self.store_module_attr(attrname, value)
3.7 - print >>sys.stderr, "Warning: attribute %r of module %r set outside the module." % (node.attrname, expr.get_value().name)
3.8
3.9 elif isinstance(value, Class):
3.10 self.store_class_attr(attrname, value)
4.1 --- a/micropython/types.py Sat Jul 14 01:37:42 2012 +0200
4.2 +++ b/micropython/types.py Sat Jul 14 17:42:42 2012 +0200
4.3 @@ -26,7 +26,7 @@
4.4 except NameError:
4.5 from sets import Set as set
4.6
4.7 -def get_object_types_for_usage(usage, objtable, name, unit_name, all_attributes):
4.8 +def get_object_types_for_usage(usage, objtable, name, unit_name, all_attributes, importer=None):
4.9
4.10 """
4.11 Return for the given attribute 'usage', using the 'objtable', the object
4.12 @@ -38,6 +38,9 @@
4.13 list must be matched to provide object types. Otherwise, the presence of any
4.14 attribute from a usage list in a type's set of attributes will be enough to
4.15 provide that type as a suitable object type.
4.16 +
4.17 + If 'importer' is specified and not None, it will be used to record warnings
4.18 + about unsatisfiable usage situations.
4.19 """
4.20
4.21 all_objtypes = set()
4.22 @@ -49,14 +52,10 @@
4.23
4.24 if all_attributes:
4.25 objtypes = objtable.all_possible_objects_plus_status(attrnames)
4.26 - if not objtypes:
4.27 - print >>sys.stderr, "Warning: usage in %r for %r finds no object supporting all attributes %r" % (
4.28 - unit_name, name, attrnames.keys())
4.29 else:
4.30 objtypes = objtable.any_possible_objects_plus_status(attrnames)
4.31 - if not objtypes:
4.32 - print >>sys.stderr, "Warning: usage in %r for %r finds no object supporting any attributes %r" % (
4.33 - unit_name, name, attrnames.keys())
4.34 + if not objtypes and importer:
4.35 + importer.add_usage_failure(all_attributes, unit_name, name, attrnames.keys())
4.36
4.37 all_objtypes.update(objtypes)
4.38
5.1 --- a/test.py Sat Jul 14 01:37:42 2012 +0200
5.2 +++ b/test.py Sat Jul 14 17:42:42 2012 +0200
5.3 @@ -22,6 +22,15 @@
5.4 print "%6d" % (len(table_slice) - table_slice.count(None)), \
5.5 "".join(entry and "#" or "_" for entry in table_slice)
5.6
5.7 +def show_warnings(attribute_usage_failures):
5.8 + failures = list(attribute_usage_failures)
5.9 + failures.sort()
5.10 + for unit_name, name, attrnames, all_attributes in failures:
5.11 + attrnames = list(attrnames)
5.12 + attrnames.sort()
5.13 + print >>sys.stderr, "%s: Name %r with %s attributes %r" % (
5.14 + unit_name, name, all_attributes and "all" or "any", ", ".join(attrnames))
5.15 +
5.16 def attrs(obj):
5.17 for name, attr in obj.items():
5.18 print name, attr
5.19 @@ -61,6 +70,17 @@
5.20 m = i.load_from_file(filename)
5.21
5.22 p.finalise()
5.23 +
5.24 + # Show warnings.
5.25 +
5.26 + if "-w" in sys.argv:
5.27 + print >>sys.stderr
5.28 + print >>sys.stderr, "Warnings:"
5.29 + show_warnings(i.attribute_usage_failures)
5.30 + print >>sys.stderr
5.31 +
5.32 + # Make the builtins module available through a variable.
5.33 +
5.34 b = i.get_module("__builtins__")
5.35
5.36 # Make a report.