# HG changeset patch # User Paul Boddie # Date 1481983159 -3600 # Node ID 4da19143cdf2ec8799cf812348a5de58eb584455 # Parent b59c5fc87a581b7f6a95bdcc96706a97768a3b38 Make function and method initialisation depend on module initialisation. Broadened dynamic attribute and parameter testing to consider predefined constants such as None, True and False. diff -r b59c5fc87a58 -r 4da19143cdf2 importer.py --- a/importer.py Sat Dec 17 01:51:10 2016 +0100 +++ b/importer.py Sat Dec 17 14:59:19 2016 +0100 @@ -528,10 +528,22 @@ if self.is_dynamic_callable(name): # Make functions with defaults requiring initialisation depend - # on the parent scope. + # on the parent scope, if a function, or the module scope. ref = Reference("", name) - self.add_dependency(name, ref.parent()) + parent_ref = self.get_object(ref.parent()) + + # Function no longer present in the program. + + if not parent_ref: + continue + + if parent_ref.has_kind(""): + parent = self.get_module_provider(parent_ref) + else: + parent = parent_ref.get_origin() + + self.add_dependency(name, parent) def add_module_dependencies(self): @@ -594,6 +606,9 @@ special_attributes = ("__args__", "__file__", "__fn__", "__fname__", "__mname__", "__name__") + def is_dynamic(self, ref): + return not ref or not ref.static() and not ref.is_constant_alias() and not ref.is_predefined_value() + def is_dynamic_class(self, name): """ @@ -609,7 +624,8 @@ for attrname, attr in attrs.items(): if attrname in self.special_attributes: continue - if not attr or not self.get_object(attr).static(): + ref = attr and self.get_object(attr) + if self.is_dynamic(ref): return True return False @@ -630,7 +646,7 @@ # Identify non-constant defaults. for name, ref in defaults: - if not ref.static() and not ref.is_constant_alias(): + if self.is_dynamic(ref): return True return False diff -r b59c5fc87a58 -r 4da19143cdf2 referencing.py --- a/referencing.py Sat Dec 17 01:51:10 2016 +0100 +++ b/referencing.py Sat Dec 17 14:59:19 2016 +0100 @@ -213,6 +213,14 @@ name = self.get_name() return name and name.rsplit(".")[-1].startswith("$c") + def is_predefined_value(self): + + "Return whether this reference identifies a predefined value." + + # NOTE: Details of built-in types employed. + + return self.get_origin() in ("__builtins__.none.NoneType", "__builtins__.boolean.boolean") + def get_types(self): "Return class, instance-only and module types for this reference."