def trace(self, fnames, _refresh=False):
<EOL>if fnames and (not isinstance(fnames, list)):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>if fnames and any([not isinstance(item, str) for item in fnames]):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>for fname in fnames:<EOL><INDENT>if not os.path.exists(fname):<EOL><INDENT>raise OSError("<STR_LIT>".format(fname))<EOL><DEDENT><DEDENT>fnames = [item.replace("<STR_LIT>", "<STR_LIT>") for item in fnames]<EOL>bobj = collections.namedtuple("<STR_LIT>", ["<STR_LIT>", "<STR_LIT>"])<EOL>for fname in fnames:<EOL><INDENT>if (fname not in self._fnames) or (<EOL>_refresh<EOL>and (fname in self._fnames)<EOL>and (self._fnames[fname]["<STR_LIT:date>"] < os.path.getmtime(fname))<EOL>):<EOL><INDENT>module_name = (<EOL>_get_module_name_from_fname(fname)<EOL>if not _refresh<EOL>else self._fnames[fname]["<STR_LIT:name>"]<EOL>)<EOL>if _refresh:<EOL><INDENT>self._module_names.pop(self._module_names.index(module_name))<EOL>for cls in self._fnames[fname]["<STR_LIT>"]:<EOL><INDENT>self._class_names.pop(self._class_names.index(cls))<EOL><DEDENT>dlist = []<EOL>for key, value in self._reverse_callables_db.items():<EOL><INDENT>if key[<NUM_LIT:0>] == fname:<EOL><INDENT>dlist.append(key)<EOL>try:<EOL><INDENT>del self._callables_db[value]<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>for item in set(dlist):<EOL><INDENT>del self._reverse_callables_db[item]<EOL><DEDENT><DEDENT>lines = _readlines(fname)<EOL>for num, char in enumerate(lines[<NUM_LIT:0>]):  <EOL><INDENT>if not _unicode_char(char):<EOL><INDENT>break<EOL><DEDENT><DEDENT>lines[<NUM_LIT:0>] = lines[<NUM_LIT:0>][num:]<EOL>tree = ast.parse("<STR_LIT>".join(lines))<EOL>aobj = _AstTreeScanner(module_name, fname, lines)<EOL>aobj.visit(tree)<EOL>fake_node = bobj(len(lines) + <NUM_LIT:1>, -<NUM_LIT:1>)<EOL>aobj._close_callable(fake_node, force=True)<EOL>self._class_names += aobj._class_names[:]<EOL>self._module_names.append(module_name)<EOL>self._callables_db.update(aobj._callables_db)<EOL>self._reverse_callables_db.update(aobj._reverse_callables_db)<EOL>self._modules_dict[module_name] = []<EOL>iobj = [<EOL>item<EOL>for item in self._callables_db.values()<EOL>if item["<STR_LIT:name>"].startswith(module_name + "<STR_LIT:.>")<EOL>]<EOL>for entry in iobj:<EOL><INDENT>self._modules_dict[module_name].append(entry)<EOL><DEDENT>self._fnames[fname] = {<EOL>"<STR_LIT:name>": module_name,<EOL>"<STR_LIT:date>": os.path.getmtime(fname),<EOL>"<STR_LIT>": aobj._class_names[:],<EOL>}<EOL><DEDENT><DEDENT>
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)