docs: def trace(self, fnames, _refresh=False):
          r"""
          Generate a list of module callables and gets their attributes.
  
          Callables are functions, classes, methods and class properties; their
          attributes are callable type, file name, and lines span
  
          :param fnames: File names of the modules to trace
          :type  fnames: list
  
          :raises:
           * OSError (File *[fname]* could not be found)
  
           * RuntimeError (Argument \`fnames\` is not valid)
          """
          # pylint: disable=R0101
          if fnames and (not isinstance(fnames, list)):
              raise RuntimeError("Argument `fnames` is not valid")
          if fnames and any([not isinstance(item, str) for item in fnames]):
              raise RuntimeError("Argument `fnames` is not valid")
          for fname in fnames:
              if not os.path.exists(fname):
                  raise OSError("File {0} could not be found".format(fname))
          fnames = [item.replace(".pyc", ".py") for item in fnames]
          bobj = collections.namedtuple("Bundle", ["lineno", "col_offset"])
          for fname in fnames:
              if (fname not in self._fnames) or (
                  _refresh
                  and (fname in self._fnames)
                  and (self._fnames[fname]["date"] < os.path.getmtime(fname))
              ):
                  module_name = (
                      _get_module_name_from_fname(fname)
                      if not _refresh
                      else self._fnames[fname]["name"]
                  )
                  # Remove old module information if it is going to be refreshed
                  if _refresh:
                      self._module_names.pop(self._module_names.index(module_name))
                      for cls in self._fnames[fname]["classes"]:
                          self._class_names.pop(self._class_names.index(cls))
                      dlist = []
                      for key, value in self._reverse_callables_db.items():
                          if key[0] == fname:
                              dlist.append(key)
                              try:
                                  del self._callables_db[value]
                              except KeyError:
                                  pass
                      for item in set(dlist):
                          del self._reverse_callables_db[item]
                  lines = _readlines(fname)
                  # Eliminate all Unicode characters till the first ASCII
                  # character is found in first line of file, to deal with
                  # Unicode-encoded source files
                  for num, char in enumerate(lines[0]):  # pragma: no cover
                      if not _unicode_char(char):
                          break
                  lines[0] = lines[0][num:]
                  tree = ast.parse("".join(lines))
                  aobj = _AstTreeScanner(module_name, fname, lines)
                  aobj.visit(tree)
                  # Create a fake callable at the end of the file to properly
                  # 'close', i.e. assign a last line number to the last
                  # callable in file
                  fake_node = bobj(len(lines) + 1, -1)
                  aobj._close_callable(fake_node, force=True)
                  self._class_names += aobj._class_names[:]
                  self._module_names.append(module_name)
                  self._callables_db.update(aobj._callables_db)
                  self._reverse_callables_db.update(aobj._reverse_callables_db)
                  # Split into modules
                  self._modules_dict[module_name] = []
                  iobj = [
                      item
                      for item in self._callables_db.values()
                      if item["name"].startswith(module_name + ".")
                  ]
                  for entry in iobj:
                      self._modules_dict[module_name].append(entry)
                  self._fnames[fname] = {
                      "name": module_name,
                      "date": os.path.getmtime(fname),
                      "classes": aobj._class_names[:],
                  }