def load_aspell_whitelist(): """ Load words that are excluded from Aspell output """ pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) efile = os.path.join(pkg_dir, 'data', 'aspell-whitelist') words = [item.strip() for item in _readlines(efile) if item.strip()] return sorted(list(set(words)))
def trace(self, fnames, _refresh=False): r""" Generates a list of module callables (functions, classes, methods and class properties) and gets their attributes (callable type, file name, 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[:] }