# HG changeset patch # User Paul Boddie # Date 1485014635 -3600 # Node ID a89ee0f5895d7d0abe85b6f26f9804ea1b08b1b8 # Parent 26dcaef4d7a9f33bfa310b32b5bdf5569bca4b14 Made class and function instance __name__ attributes leafnames, introducing a separate __mname__ attribute on classes and function instances to help support the reproduction of the full path of those objects. Updated the visitor example to use the __name__ attributes of node classes instead of special name attributes. diff -r 26dcaef4d7a9 -r a89ee0f5895d generator.py --- a/generator.py Sat Jan 21 00:03:13 2017 +0100 +++ b/generator.py Sat Jan 21 17:03:55 2017 +0100 @@ -918,9 +918,26 @@ path = ref.get_origin() value_type = self.string_type + # Provide constant values. These must match the values + # originally recorded during inspection. + if attrname == "__file__": module = self.importer.get_module(path) value = module.filename + + # Function and class names are leafnames. + + elif attrname in ("__fname__", "__name__"): + value = path.rsplit(".", 1)[-1] + + # Module names of classes and functions are derived from + # their object paths. + + elif attrname == "__mname__" and not ref.has_kind(""): + value = self.importer.get_module_provider(ref) + + # All other names just use the object path information. + else: value = path diff -r 26dcaef4d7a9 -r a89ee0f5895d inspector.py --- a/inspector.py Sat Jan 21 00:03:13 2017 +0100 +++ b/inspector.py Sat Jan 21 17:03:55 2017 +0100 @@ -524,7 +524,10 @@ self.set_name("__fn__") # special instantiator attribute self.set_name("__args__") # special instantiator attribute - self.set_name("__name__", self.get_constant("string", class_name).reference()) + # Provide leafname and module name attributes. + + self.set_name("__name__", self.get_constant("string", class_name.rsplit(".", 1)[-1]).reference()) + self.set_name("__mname__", self.get_constant("string", self.name).reference()) self.process_structure_node(n.code) self.exit_namespace() @@ -643,10 +646,11 @@ self.enter_namespace(name) - # Define a name attribute value for the function instance. + # Define leafname and module name attribute values for the function instance. ref = self.get_builtin_class("string") - self.reserve_constant(function_name, function_name, ref.get_origin()) + self.reserve_constant(function_name, name, ref.get_origin()) + self.reserve_constant(function_name, self.name, ref.get_origin()) # Track attribute usage within the namespace. diff -r 26dcaef4d7a9 -r a89ee0f5895d lib/__builtins__/core.py --- a/lib/__builtins__/core.py Sat Jan 21 00:03:13 2017 +0100 +++ b/lib/__builtins__/core.py Sat Jan 21 17:03:55 2017 +0100 @@ -41,7 +41,7 @@ "Return a string representation." - return str(buffer(["<", self.__name__, " instance>"])) + return str(buffer(["<", self.__mname__, ".", self.__name__, " instance>"])) __repr__ = __str__ @@ -82,6 +82,7 @@ self.__fn__ = None self.__args__ = None self.__fname__ = None + self.__mname__ = None def __bool__(self): @@ -93,7 +94,7 @@ "Return a string representation." - return self.__fname__ + return str(buffer([self.__mname__, ".", self.__fname__])) __repr__ = __str__ diff -r 26dcaef4d7a9 -r a89ee0f5895d tests/getattr_visitor.py --- a/tests/getattr_visitor.py Sat Jan 21 00:03:13 2017 +0100 +++ b/tests/getattr_visitor.py Sat Jan 21 17:03:55 2017 +0100 @@ -2,8 +2,6 @@ "An expression." - name = "Expr" - def __init__(self, ops): self.ops = ops @@ -14,8 +12,6 @@ "A binary operator." - name = "Binary" - def __init__(self, left, op, right): self.left = left self.op = op @@ -28,8 +24,6 @@ "A unary operator." - name = "Unary" - def __init__(self, op, operand): self.op = op self.operand = operand @@ -41,8 +35,6 @@ "A general value." - name = "Value" - def __init__(self, value): self.value = value @@ -60,7 +52,7 @@ # Obtain the method for the node name. - fn = getattr(self, node.name) + fn = getattr(self, node.__name__) # Call the method. diff -r 26dcaef4d7a9 -r a89ee0f5895d tests/name_attribute.py --- a/tests/name_attribute.py Sat Jan 21 00:03:13 2017 +0100 +++ b/tests/name_attribute.py Sat Jan 21 17:03:55 2017 +0100 @@ -4,13 +4,16 @@ pass c = C() -print c.__name__ # __main__.C -print C.__name__ # __main__.C +print c.__name__ # C +print c.__mname__ # __main__ +print C.__name__ # C +print C.__mname__ # __main__ -# If it were defined, operator.__name__ would be __builtins__.core.module. +# If it were defined, operator.__name__ would be module. -print operator.__mname__ +print operator.__mname__ # operator -# If it were defined, operator.add.__name__ would be __builtins__.core.function. +# If it were defined, operator.add.__name__ would be function. -print operator.add.__fname__ +print operator.add.__fname__ # add +print operator.add.__mname__ # operator.binary