code: def get_canonical_path(project, resource, offset):
      
      # Retrieve the PyName.
      pymod = project.get_pymodule(resource)
      pyname = rope.base.evaluate.eval_location(pymod, offset)
  
      # Now get the location of the definition and its containing scope.
      defmod, lineno = pyname.get_definition_location()
      if not defmod:
          return None
      scope = defmod.get_scope().get_inner_scope_for_line(lineno)
  
      # Start with the name of the object we're interested in.
      names = []
      if isinstance(pyname, pynamesdef.ParameterName):
          names = [(worder.get_name_at(pymod.get_resource(), offset),
                    'PARAMETER') ]
      elif isinstance(pyname, pynamesdef.AssignedName):
          names = [(worder.get_name_at(pymod.get_resource(), offset),
                    'VARIABLE')]
  
      # Collect scope names.
      while scope.parent:
          if isinstance(scope, pyscopes.FunctionScope):
              scope_type = 'FUNCTION'
          elif isinstance(scope, pyscopes.ClassScope):
              scope_type = 'CLASS'
          else:
              scope_type = None
          names.append((scope.pyobject.get_name(), scope_type))
          scope = scope.parent
  
      names.append((defmod.get_resource().real_path, 'MODULE'))
      names.reverse()
      return names
docs: Get the canonical path to an object.
  
      Given the offset of the object, this returns a list of
      (name, name_type) tuples representing the canonical path to the
      object. For example, the 'x' in the following code:
  
          class Foo(object):
              def bar(self):
                  class Qux(object):
                      def mux(self, x):
                          pass
  
      we will return:
  
          [('Foo', 'CLASS'), ('bar', 'FUNCTION'), ('Qux', 'CLASS'),
           ('mux', 'FUNCTION'), ('x', 'PARAMETER')]
  
      `resource` is a `rope.base.resources.Resource` object.
  
      `offset` is the offset of the pyname you want the path to.