code: def scan_module(self, modpath, node):
          used_origins = self.map.setdefault(modpath, set())
          def get_origins(modpath, name):
              origins = set()
              def walk_origins(modpath, name):
                  for origin in self.import_map.get_origins(modpath, name):
                      if origin not in origins:
                          origins.add(origin)
                          if '.' in origin:
                              walk_origins(*origin.rsplit('.', 1))
              walk_origins(modpath, name)
              return origins
          def get_origins_for_node(node):
              if node_type(node) == 'Name' and node_type(node.ctx) == 'Load':
                  return {modpath + '.' + node.id} | get_origins(modpath, node.id)
              if node_type(node) == 'Attribute' and node_type(node.ctx) == 'Load':
                  return set.union(set(), *[
                      {parent + '.' + node.attr} | get_origins(parent, node.attr)
                      for parent in get_origins_for_node(node.value)])
              return set()
          def get_origins_used_by_node(node):
              if node_type(node) == 'Name':
                  return get_origins_for_node(node)
              if node_type(node) == 'Attribute':
                  return set.union(get_origins_used_by_node(node.value),
                                   get_origins_for_node(node))
              return set()
          def scan_loads(node):
              if node_type(node) in ['Name', 'Attribute']:
                  used_origins.update(get_origins_used_by_node(node))
              for_each_child(node, scan_loads)
          for_each_child(node, scan_loads)
          intermediate_origins = set()
          for origin in used_origins:
              parts = origin.split('.')
              for i in range(1, len(parts)):
                  intermediate_origins.add('.'.join(parts[:i]))
          used_origins.update(intermediate_origins)