1.1 --- a/deducer.py Tue Sep 20 23:14:43 2016 +0200
1.2 +++ b/deducer.py Tue Sep 20 23:56:38 2016 +0200
1.3 @@ -26,7 +26,8 @@
1.4 encode_constrained, encode_location, encode_usage, \
1.5 get_kinds, test_for_kinds, test_for_types
1.6 from os.path import join
1.7 -from referencing import Reference
1.8 +from referencing import combine_types, is_single_class_type, separate_types, \
1.9 + Reference
1.10
1.11 class Deducer(CommonOutput):
1.12
1.13 @@ -387,7 +388,7 @@
1.14 # Collect specific and general type information.
1.15
1.16 self.provider_all_types[location] = all_types = \
1.17 - self.combine_types(class_types, instance_types, module_types)
1.18 + combine_types(class_types, instance_types, module_types)
1.19
1.20 # Accessor information.
1.21
1.22 @@ -406,10 +407,10 @@
1.23 # Collect specific and general type information.
1.24
1.25 self.accessor_all_types[location] = all_types = \
1.26 - self.combine_types(class_types, instance_types, module_types)
1.27 + combine_types(class_types, instance_types, module_types)
1.28
1.29 self.accessor_all_general_types[location] = all_general_types = \
1.30 - self.combine_types(general_class_types, general_instance_types, general_module_types)
1.31 + combine_types(general_class_types, general_instance_types, general_module_types)
1.32
1.33 # Record guard information.
1.34
1.35 @@ -419,14 +420,14 @@
1.36
1.37 if len(all_types) == 1:
1.38 self.accessor_guard_tests[location] = test_for_types("specific", all_types)
1.39 - elif self.is_single_class_type(all_types):
1.40 + elif is_single_class_type(all_types):
1.41 self.accessor_guard_tests[location] = "specific-object"
1.42
1.43 # Record common type guard details.
1.44
1.45 elif len(all_general_types) == 1:
1.46 self.accessor_guard_tests[location] = test_for_types("common", all_types)
1.47 - elif self.is_single_class_type(all_general_types):
1.48 + elif is_single_class_type(all_general_types):
1.49 self.accessor_guard_tests[location] = "common-object"
1.50
1.51 # Otherwise, no convenient guard can be defined.
1.52 @@ -470,14 +471,14 @@
1.53
1.54 guarded = (
1.55 len(all_accessor_types) == 1 or
1.56 - self.is_single_class_type(all_accessor_types) or
1.57 + is_single_class_type(all_accessor_types) or
1.58 len(all_accessor_general_types) == 1 or
1.59 - self.is_single_class_type(all_accessor_general_types)
1.60 + is_single_class_type(all_accessor_general_types)
1.61 )
1.62
1.63 if guarded:
1.64 (guard_class_types, guard_instance_types, guard_module_types,
1.65 - _function_types, _var_types) = self.separate_types(all_provider_types)
1.66 + _function_types, _var_types) = separate_types(all_provider_types)
1.67
1.68 # Attribute information, both name-based and anonymous.
1.69
1.70 @@ -535,11 +536,11 @@
1.71 if guarded and all_accessed_attrs.issubset(guard_attrs):
1.72 if len(all_accessor_types) == 1:
1.73 self.reference_test_types[location] = test_for_types("guarded-specific", all_accessor_types)
1.74 - elif self.is_single_class_type(all_accessor_types):
1.75 + elif is_single_class_type(all_accessor_types):
1.76 self.reference_test_types[location] = "guarded-specific-object"
1.77 elif len(all_accessor_general_types) == 1:
1.78 self.reference_test_types[location] = test_for_types("guarded-common", all_accessor_general_types)
1.79 - elif self.is_single_class_type(all_accessor_general_types):
1.80 + elif is_single_class_type(all_accessor_general_types):
1.81 self.reference_test_types[location] = "guarded-common-object"
1.82
1.83 # Provide active test types.
1.84 @@ -592,71 +593,6 @@
1.85 l.append((attrtype, attrs))
1.86 return l
1.87
1.88 - # Type handling methods.
1.89 -
1.90 - def is_single_class_type(self, all_types):
1.91 -
1.92 - """
1.93 - Return whether 'all_types' is a mixture of class and instance kinds for
1.94 - a single class type.
1.95 - """
1.96 -
1.97 - kinds = set()
1.98 - types = set()
1.99 -
1.100 - for type in all_types:
1.101 - kinds.add(type.get_kind())
1.102 - types.add(type.get_origin())
1.103 -
1.104 - return len(types) == 1 and kinds == set(["<class>", "<instance>"])
1.105 -
1.106 - def get_types_for_reference(self, ref):
1.107 -
1.108 - "Return class, instance-only and module types for 'ref'."
1.109 -
1.110 - class_types = ref.has_kind("<class>") and [ref.get_origin()] or []
1.111 - instance_types = []
1.112 - module_types = ref.has_kind("<module>") and [ref.get_origin()] or []
1.113 - return class_types, instance_types, module_types
1.114 -
1.115 - def combine_types(self, class_types, instance_types, module_types):
1.116 -
1.117 - """
1.118 - Combine 'class_types', 'instance_types', 'module_types' into a single
1.119 - list of references.
1.120 - """
1.121 -
1.122 - all_types = []
1.123 - for kind, l in [("<class>", class_types), ("<instance>", instance_types), ("<module>", module_types)]:
1.124 - for t in l:
1.125 - all_types.append(Reference(kind, t))
1.126 - return all_types
1.127 -
1.128 - def separate_types(self, refs):
1.129 -
1.130 - """
1.131 - Separate 'refs' into type-specific lists, returning a tuple containing
1.132 - lists of class types, instance types, module types, function types and
1.133 - unknown "var" types.
1.134 - """
1.135 -
1.136 - class_types = []
1.137 - instance_types = []
1.138 - module_types = []
1.139 - function_types = []
1.140 - var_types = []
1.141 -
1.142 - for kind, l in [
1.143 - ("<class>", class_types), ("<instance>", instance_types), ("<module>", module_types),
1.144 - ("<function>", function_types), ("<var>", var_types)
1.145 - ]:
1.146 -
1.147 - for ref in refs:
1.148 - if ref.get_kind() == kind:
1.149 - l.append(ref.get_origin())
1.150 -
1.151 - return class_types, instance_types, module_types, function_types, var_types
1.152 -
1.153 # Initialisation methods.
1.154
1.155 def init_descendants(self):
1.156 @@ -1171,7 +1107,7 @@
1.157 self.referenced_attrs[access_location] = [(accessor.get_kind(), accessor.get_origin(), ref)]
1.158 self.access_constrained.add(access_location)
1.159
1.160 - class_types, instance_types, module_types = self.get_types_for_reference(accessor)
1.161 + class_types, instance_types, module_types = accessor.get_types()
1.162 self.record_reference_types(accessor_location, class_types, instance_types, module_types, True, True)
1.163 continue
1.164
1.165 @@ -1191,7 +1127,7 @@
1.166 self.init_access_details(access_location)
1.167 self.init_definition_details(accessor_location)
1.168
1.169 - class_types, instance_types, module_types = self.get_types_for_reference(ref)
1.170 + class_types, instance_types, module_types = ref.get_types()
1.171
1.172 self.identify_reference_attributes(access_location, attrname, class_types, instance_types, module_types, True)
1.173 self.record_reference_types(accessor_location, class_types, instance_types, module_types, True, True)
1.174 @@ -1239,7 +1175,7 @@
1.175 ref = self.get_initialised_name(location)
1.176 if ref:
1.177 (class_types, only_instance_types, module_types,
1.178 - _function_types, _var_types) = self.separate_types([ref])
1.179 + _function_types, _var_types) = separate_types([ref])
1.180 return class_types, only_instance_types, module_types, True, False
1.181
1.182 # Retrieve the recorded types for the usage.
1.183 @@ -1450,7 +1386,7 @@
1.184 # Separate the different attribute types.
1.185
1.186 (class_types, instance_types, module_types,
1.187 - function_types, var_types) = self.separate_types(attrs)
1.188 + function_types, var_types) = separate_types(attrs)
1.189
1.190 # Where non-accessor types are found, do not attempt to refine
1.191 # the defined accessor types.
1.192 @@ -1470,7 +1406,7 @@
1.193 attr = self.get_initialised_name(access_location)
1.194 if attr:
1.195 (class_types, instance_types, module_types,
1.196 - _function_types, _var_types) = self.separate_types([attr])
1.197 + _function_types, _var_types) = separate_types([attr])
1.198
1.199 # Where no further information is found, do not attempt to
1.200 # refine the defined accessor types.
1.201 @@ -1510,7 +1446,7 @@
1.202 class_types = self.provider_class_types[access_location]
1.203 instance_types = self.provider_instance_types[access_location]
1.204 module_types = self.provider_module_types[access_location]
1.205 - attrs = self.combine_types(class_types, instance_types, module_types)
1.206 + attrs = combine_types(class_types, instance_types, module_types)
1.207 if attrs:
1.208 refs.update(attrs)
1.209
2.1 --- a/referencing.py Tue Sep 20 23:14:43 2016 +0200
2.2 +++ b/referencing.py Tue Sep 20 23:56:38 2016 +0200
2.3 @@ -163,6 +163,15 @@
2.4
2.5 return ancestors
2.6
2.7 + def get_types(self):
2.8 +
2.9 + "Return class, instance-only and module types for this reference."
2.10 +
2.11 + class_types = self.has_kind("<class>") and [self.get_origin()] or []
2.12 + instance_types = []
2.13 + module_types = self.has_kind("<module>") and [self.get_origin()] or []
2.14 + return class_types, instance_types, module_types
2.15 +
2.16 def decode_reference(s, name=None):
2.17
2.18 "Decode 's', making a reference."
2.19 @@ -191,4 +200,62 @@
2.20 else:
2.21 return Reference("<module>", s, name)
2.22
2.23 +
2.24 +
2.25 +# Type/reference collection functions.
2.26 +
2.27 +def is_single_class_type(all_types):
2.28 +
2.29 + """
2.30 + Return whether 'all_types' is a mixture of class and instance kinds for
2.31 + a single class type.
2.32 + """
2.33 +
2.34 + kinds = set()
2.35 + types = set()
2.36 +
2.37 + for type in all_types:
2.38 + kinds.add(type.get_kind())
2.39 + types.add(type.get_origin())
2.40 +
2.41 + return len(types) == 1 and kinds == set(["<class>", "<instance>"])
2.42 +
2.43 +def combine_types(class_types, instance_types, module_types):
2.44 +
2.45 + """
2.46 + Combine 'class_types', 'instance_types', 'module_types' into a single
2.47 + list of references.
2.48 + """
2.49 +
2.50 + all_types = []
2.51 + for kind, l in [("<class>", class_types), ("<instance>", instance_types), ("<module>", module_types)]:
2.52 + for t in l:
2.53 + all_types.append(Reference(kind, t))
2.54 + return all_types
2.55 +
2.56 +def separate_types(refs):
2.57 +
2.58 + """
2.59 + Separate 'refs' into type-specific lists, returning a tuple containing
2.60 + lists of class types, instance types, module types, function types and
2.61 + unknown "var" types.
2.62 + """
2.63 +
2.64 + class_types = []
2.65 + instance_types = []
2.66 + module_types = []
2.67 + function_types = []
2.68 + var_types = []
2.69 +
2.70 + for kind, l in [
2.71 + ("<class>", class_types), ("<instance>", instance_types), ("<module>", module_types),
2.72 + ("<function>", function_types), ("<var>", var_types)
2.73 + ]:
2.74 +
2.75 + for ref in refs:
2.76 + if ref.get_kind() == kind:
2.77 + l.append(ref.get_origin())
2.78 +
2.79 + return class_types, instance_types, module_types, function_types, var_types
2.80 +
2.81 # vim: tabstop=4 expandtab shiftwidth=4