[Pydev-cvs] org.python.pydev/PySrc/ThirdParty/logilab/common textutils.py,1.3,1.4 logservice.py,1.2,
Brought to you by:
fabioz
Update of /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7532/PySrc/ThirdParty/logilab/common Modified Files: textutils.py logservice.py html.py vcgutils.py configuration.py db.py daemon.py shellutils.py sqlgen.py patricia.py __init__.py astutils.py setup.py cli.py PKG-INFO twisted_distutils.py ChangeLog fileutils.py __pkginfo__.py table.py visitor.py modutils.py interface.py optik_ext.py tree.py cache.py bind.py xmlrpcutils.py testlib.py compat.py logger.py corbautils.py Log Message: New pylint version Index: fileutils.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/fileutils.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** fileutils.py 21 Jan 2005 17:42:05 -0000 1.3 --- fileutils.py 16 Feb 2005 16:45:43 -0000 1.4 *************** *** 1,26 **** ! # Copyright (c) 2000-2003 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:co...@lo... ! # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. ! # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ ! Some file / file path manipulation utilities ! """ __revision__ = "$Id$" - from __future__ import nested_scopes import sys - import re import shutil import mimetypes --- 1,48 ---- ! # Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:co...@lo... ! # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. ! # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + """Some file / file path manipulation utilities. + + :version: $Revision$ + :author: Logilab + :copyright: 2003-2005 LOGILAB S.A. (Paris, FRANCE) + :contact: http://www.logilab.fr/ -- mailto:pyt...@lo... + + :group path manipulation: first_level_directory, relative_path, is_binary,\ + files_by_ext, include_files_by_ext, exclude_files_by_ext, get_by_ext + :group file manipulation: norm_read, norm_open, lines, stream_lines, lines,\ + write_open_mode, ensure_fs_mode, export + :sort: path manipulation, file manipulation + + + + :type BASE_BLACKLIST: tuple + :var BASE_BLACKLIST: + list files or directories ignored by default by the `export` function + + :type IGNORED_EXTENSIONS: tuple + :var IGNORED_EXTENSIONS: + list file extensions ignored by default by the `export` function + """ ! ! from __future__ import nested_scopes __revision__ = "$Id$" + __docformat__ = "restructuredtext en" import sys import shutil import mimetypes *************** *** 29,40 **** from stat import ST_MODE from cStringIO import StringIO ! from sys import version_info ! ! HAS_UNIV_OPEN = version_info[:2] >= (2, 3) - LINE_RGX = re.compile('\r\n|\r+|\n') def first_level_directory(path): ! """return the first level directory of a path""" head, tail = split(path) while head and tail: --- 51,74 ---- from stat import ST_MODE from cStringIO import StringIO ! from warnings import warn def first_level_directory(path): ! """return the first level directory of a path ! ! >>> first_level_directory('home/syt/work') ! 'home' ! >>> first_level_directory('/home/syt/work') ! '/' ! >>> first_level_directory('work') ! 'work' ! >>> ! ! :type path: str ! :param path: the path for which we want the first level directory ! ! :rtype: str ! :return: the first level directory appearing in `path` ! """ head, tail = split(path) while head and tail: *************** *** 45,92 **** return head def is_binary(filename): ! """return true if filename may be a binary file, according to it's extension """ ! return not mimetypes.guess_type(filename)[0].startswith('text') ! def get_mode(filename): ! """return the write mode that should used to open file""" if is_binary(filename): return 'wb' return 'w' class UnresolvableError(Exception): ! """exception raise by relative path when it's unable to compute relative path between two paths """ def relative_path(from_file, to_file): ! """try to get a relative path from from <from_file> to <to_file> ! (path will be absolute if to_file is an absolute file). If both files are relative, they're expected to be relative to the same directory. - EXAMPLES: - >>> relative_path( from_file='toto/index.html', to_file='index.html') '../index.html' - >>> relative_path( from_file='index.html', to_file='toto/index.html') 'toto/index.html' - >>> relative_path( from_file='tutu/index.html', to_file='toto/index.html') '../toto/index.html' - >>> relative_path( from_file='toto/index.html', to_file='/index.html') '/index.html' - >>> relative_path( from_file='/toto/index.html', to_file='/index.html') ! '/index.html' ! >>> relative_path( from_file='index.html', to_file='index.html') '' - >>> relative_path( from_file='/index.html', to_file='toto/index.html') Traceback (most recent call last): --- 79,168 ---- return head + def is_binary(filename): ! """return true if filename may be a binary file, according to it's ! extension ! ! :type filename: str ! :param filename: the name of the file ! ! :rtype: bool ! :return: ! true if the file is a binary file (actually if it's mime type ! isn't begining by text/) """ ! try: ! return not mimetypes.guess_type(filename)[0].startswith('text') ! except AttributeError: ! return 1 ! ! def write_open_mode(filename): ! """return the write mode that should used to open file ! ! :type filename: str ! :param filename: the name of the file ! ! :rtype: str ! :return: the mode that should be use to open the file ('w' or 'wb') ! """ if is_binary(filename): return 'wb' return 'w' + # backward compat + def get_mode(*args, **kwargs): + """deprecated, use `files_by_ext` instead""" + warn('logilab.common.fileutils.get_mode() is deprecated, use ' + 'write_open_mode() instead', DeprecationWarning) + return write_open_mode(*args, **kwargs) + + def ensure_fs_mode(filepath, desired_mode): + """check that the given file has the given mode(s) set, else try to + set it + + :type filepath: str + :param filepath: path of the file + + :type desired_mode: int + :param desired_mode: + ORed flags describing the desired mode. Use constants from the + `stat` module for file permission's modes + """ + mode = stat(filepath)[ST_MODE] + if not mode & desired_mode: + chmod(filepath, mode | desired_mode) + + ensure_mode = ensure_fs_mode # backward compat + class UnresolvableError(Exception): ! """exception raised by relative path when it's unable to compute relative path between two paths """ def relative_path(from_file, to_file): ! """try to get a relative path from from `from_file` to `to_file` ! (path will be absolute if to_file is an absolute file). This function ! is useful to create link in `from_file` to `to_file`. This typical use ! case is used in this function description. If both files are relative, they're expected to be relative to the same directory. >>> relative_path( from_file='toto/index.html', to_file='index.html') '../index.html' >>> relative_path( from_file='index.html', to_file='toto/index.html') 'toto/index.html' >>> relative_path( from_file='tutu/index.html', to_file='toto/index.html') '../toto/index.html' >>> relative_path( from_file='toto/index.html', to_file='/index.html') '/index.html' >>> relative_path( from_file='/toto/index.html', to_file='/index.html') ! '../index.html' ! >>> relative_path( from_file='/toto/index.html', to_file='/toto/summary.html') ! 'summary.html' >>> relative_path( from_file='index.html', to_file='index.html') '' >>> relative_path( from_file='/index.html', to_file='toto/index.html') Traceback (most recent call last): *************** *** 94,101 **** File "<stdin>", line 37, in relative_path UnresolvableError - >>> relative_path( from_file='/index.html', to_file='/index.html') '' """ from_file = normpath(from_file) --- 170,187 ---- File "<stdin>", line 37, in relative_path UnresolvableError >>> relative_path( from_file='/index.html', to_file='/index.html') '' + >>> + + :type from_file: str + :param from_file: source file (where links will be inserted) + + :type to_file: str + :param to_file: target file (on which links point) + :raise UnresolvableError: if it has been unable to guess a correct path + + :rtype: str + :return: the relative path of `to_file` from `from_file` """ from_file = normpath(from_file) *************** *** 104,109 **** return '' if isabs(to_file): ! return to_file ! if isabs(from_file): raise UnresolvableError() from_parts = from_file.split(sep) --- 190,196 ---- return '' if isabs(to_file): ! if not isabs(from_file): ! return to_file ! elif isabs(from_file): raise UnresolvableError() from_parts = from_file.split(sep) *************** *** 120,143 **** result += to_parts return sep.join(result) - ! def norm_read(path, linesep=linesep): ! """open a file, an normalize line feed""" ! if HAS_UNIV_OPEN: return open(path, 'U').read() ! stream = open(path) ! return LINE_RGX.sub(linesep, stream.read()) ! def norm_open(path, linesep=linesep): ! """open a file in universal mode""" ! if HAS_UNIV_OPEN: ! return open(path, 'U') ! stream = open(path) ! return StringIO(LINE_RGX.sub(linesep, stream.read())) ! def lines(path, comments=None): ! """return a list of non empty lines in <filename>""" stream = norm_open(path) result = stream_lines(stream, comments) --- 207,262 ---- result += to_parts return sep.join(result) ! ! from logilab.common.textutils import _LINE_RGX ! from sys import version_info ! _HAS_UNIV_OPEN = version_info[:2] >= (2, 3) ! del version_info ! ! def norm_read(path): ! """return the content of the file with normalized line feeds ! ! :type path: str ! :param path: path to the file to read ! ! :rtype: str ! :return: the content of the file with normalized line feeds ! """ ! if _HAS_UNIV_OPEN: return open(path, 'U').read() ! return _LINE_RGX.sub('\n', open(path).read()) ! def norm_open(path): ! """return a stream for a file with content with normalized line feeds + :type path: str + :param path: path to the file to open ! :rtype: file or StringIO ! :return: the opened file with normalized line feeds ! """ ! if _HAS_UNIV_OPEN: ! return open(path, 'U') ! return StringIO(_LINE_RGX.sub('\n', open(path).read())) ! ! def lines(path, comments=None): ! """return a list of non empty lines in the file located at `path` ! ! :type path: str ! :param path: path to the file ! ! :type comments: str or None ! :param comments: ! optional string which can be used to comment a line in the file ! (ie lines starting with this string won't be returned) ! ! :rtype: list ! :return: ! a list of stripped line in the file, without empty and commented ! lines ! ! :warning: at some point this function will probably return an iterator ! """ stream = norm_open(path) result = stream_lines(stream, comments) *************** *** 145,159 **** return result - def file_content(filepath, mode='r'): - """returns <filepath>'s content""" - stream = file(filepath, mode) - data = stream.read() - stream.close() - return data - def stream_lines(stream, comments=None): ! """return a list of non empty lines in <stream>""" result = [] ! for line in stream.readlines(): line = line.strip() if line and (comments is None or not line.startswith(comments)): --- 264,291 ---- return result def stream_lines(stream, comments=None): ! """return a list of non empty lines in the given `stream` ! ! :type stream: object implementing 'xreadlines' or 'readlines' ! :param stream: file like object ! ! :type comments: str or None ! :param comments: ! optional string which can be used to comment a line in the file ! (ie lines starting with this string won't be returned) ! ! :rtype: list ! :return: ! a list of stripped line in the file, without empty and commented ! lines ! ! :warning: at some point this function will probably return an iterator ! """ ! try: ! readlines = stream.xreadlines ! except AttributeError: ! readlines = stream.readlines result = [] ! for line in readlines(): line = line.strip() if line and (comments is None or not line.startswith(comments)): *************** *** 163,176 **** ! BASE_BLACKLIST = ('CVS', 'debian', 'dist', 'build', '__buildlog') ! IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc') def export(from_dir, to_dir, blacklist=BASE_BLACKLIST, ! ignore_ext=IGNORED_EXTENSIONS): ! """make a mirror of from_dir in to_dir, omitting directories and files ! listed in the black list """ ! def make_mirror(arg, directory, fnames): """walk handler""" for norecurs in blacklist: --- 295,331 ---- ! BASE_BLACKLIST = ('CVS', '.svn', 'debian', 'dist', 'build', '__buildlog') ! IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~') def export(from_dir, to_dir, blacklist=BASE_BLACKLIST, ! ignore_ext=IGNORED_EXTENSIONS, ! verbose=0): ! """make a mirror of `from_dir` in `to_dir`, omitting directories and ! files listed in the black list or ending with one of the given ! extensions ! ! :type from_dir: str ! :param from_dir: directory to export ! ! :type to_dir: str ! :param to_dir: destination directory ! ! :type blacklist: list or tuple ! :param blacklist: ! list of files or directories to ignore, default to the content of ! `BASE_BLACKLIST` ! ! :type ignore_ext: list or tuple ! :param ignore_ext: ! list of extensions to ignore, default to the content of ! `IGNORED_EXTENSIONS` ! ! :type verbose: bool ! :param verbose: ! flag indicating wether information about exported files should be ! printed to stderr, default to True """ ! def make_mirror(_, directory, fnames): """walk handler""" for norecurs in blacklist: *************** *** 181,198 **** for filename in fnames: # don't include binary files ! if filename[-4:] in ignore_ext: ! continue ! if filename[-1] == '~': ! continue ! src = '%s/%s' % (directory, filename) ! dest = to_dir + src[len(from_dir):] ! print >> sys.stderr, src, '->', dest ! if isdir(src): ! if not exists(dest): ! mkdir(dest) else: ! if exists(dest): ! remove(dest) ! shutil.copy2(src, dest) try: mkdir(to_dir) --- 336,354 ---- for filename in fnames: # don't include binary files ! for ext in ignore_ext: ! if filename.endswith(ext): ! break else: ! src = join(directory, filename) ! dest = to_dir + src[len(from_dir):] ! if verbose: ! print >> sys.stderr, src, '->', dest ! if isdir(src): ! if not exists(dest): ! mkdir(dest) ! else: ! if exists(dest): ! remove(dest) ! shutil.copy2(src, dest) try: mkdir(to_dir) *************** *** 201,245 **** walk(from_dir, make_mirror, None) - def get_by_ext(directory, include_exts=(), exclude_exts=()): - """return a list of files in a directory matching some extensions ! subdirectories are processed recursivly. """ assert not (include_exts and exclude_exts) ! result = [] if exclude_exts: ! for fname in listdir(directory): ! absfile = join(directory, fname) ! for ext in exclude_exts: ! if fname.endswith(ext) or fname == 'makefile': ! break ! else: ! if isdir(absfile): ! if fname in ('CVS', '.svn'): ! continue ! result += get_by_ext(absfile, ! include_exts, exclude_exts) ! else: ! result.append(join(directory, fname)) ! else: ! for fname in listdir(directory): ! absfile = join(directory, fname) ! for ext in include_exts: ! if fname.endswith(ext): ! result.append(join(directory, fname)) ! break ! else: ! if isdir(absfile) and fname != 'CVS': ! result += get_by_ext(join(directory, fname), ! include_exts, exclude_exts) return result ! def ensure_mode(filepath, desired_mode): ! """check that the given file has the given mode set, else try to set it ! use constants from the `stat` module for file permission's modes """ ! mode = stat(filepath)[ST_MODE] ! if not mode & desired_mode: ! chmod(filepath, mode | desired_mode) --- 357,460 ---- walk(from_dir, make_mirror, None) ! def files_by_ext(directory, include_exts=None, exclude_exts=None, ! exclude_dirs=('CVS', '.svn')): ! """return a list of files in a directory matching (or not) some ! extensions: you should either give the `include_exts` argument (and ! only files ending with one of the listed extensions will be ! considered) or the `exclude_exts` argument (and only files not ! ending by one of the listed extensions will be considered). ! Subdirectories are processed recursivly. ! ! :type directory: str ! :param directory: directory where files should be searched ! ! :type include_exts: list or tuple or None ! :param include_exts: list of file extensions to consider ! ! :type exclude_exts: list or tuple or None ! :param exclude_exts: list of file extensions to ignore ! ! :type exclude_dirs: list or tuple or None ! :param exclude_dirs: list of directory where we should not recurse ! ! :rtype: list ! :return: the list of files matching input criteria """ assert not (include_exts and exclude_exts) ! if directory in exclude_dirs: ! return [] if exclude_exts: ! return exclude_files_by_ext(directory, exclude_exts, exclude_dirs) ! return include_files_by_ext(directory, include_exts, exclude_dirs) ! ! # backward compat ! def get_by_ext(*args, **kwargs): ! """deprecated, use `files_by_ext` instead""" ! warn('logilab.common.fileutils.get_by_ext() is deprecated, use ' ! 'files_by_ext() instead', DeprecationWarning) ! return files_by_ext(*args, **kwargs) ! ! ! def include_files_by_ext(directory, include_exts, ! exclude_dirs=('CVS', '.svn')): ! """return a list of files in a directory matching some extensions ! ! :type directory: str ! :param directory: directory where files should be searched ! ! :type include_exts: list or tuple or None ! :param include_exts: list of file extensions to consider ! ! :type exclude_dirs: list or tuple or None ! :param exclude_dirs: list of directory where we should not recurse ! ! :rtype: list ! :return: the list of files matching input criteria ! """ ! result = [] ! for fname in listdir(directory): ! absfile = join(directory, fname) ! for ext in include_exts: ! if fname.endswith(ext): ! result.append(join(directory, fname)) ! break ! else: ! if isdir(absfile): ! if fname in exclude_dirs: ! continue ! result += include_files_by_ext(join(directory, fname), ! include_exts, exclude_dirs) return result + def exclude_files_by_ext(directory, exclude_exts, + exclude_dirs=('CVS', '.svn')): + """return a list of files in a directory not matching some extensions ! :type directory: str ! :param directory: directory where files should be searched ! :type exclude_exts: list or tuple or None ! :param exclude_exts: list of file extensions to ignore ! ! :type exclude_dirs: list or tuple or None ! :param exclude_dirs: list of directory where we should not recurse ! ! :rtype: list ! :return: the list of files matching input criteria """ ! result = [] ! for fname in listdir(directory): ! absfile = join(directory, fname) ! for ext in exclude_exts: ! if fname.endswith(ext) or fname == 'makefile': ! break ! else: ! if isdir(absfile): ! if fname in exclude_dirs: ! continue ! result += exclude_files_by_ext(absfile, exclude_exts, ! exclude_dirs) ! else: ! result.append(join(directory, fname)) ! return result Index: table.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/table.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** table.py 21 Jan 2005 17:42:05 -0000 1.3 --- table.py 16 Feb 2005 16:45:43 -0000 1.4 *************** *** 30,38 **** """Appends col_names to the list of existing columns """ - self.col_names.extend(col_names) for col_name in col_names: ! for row in self.data: ! row.append(0) ! def create_row(self, row_name): --- 30,35 ---- """Appends col_names to the list of existing columns """ for col_name in col_names: ! self.create_column(col_name) def create_row(self, row_name): *************** *** 247,251 **** """Returns a tuple which represents the table's size """ ! return len(self.col_names), len(self.row_names) --- 244,248 ---- """Returns a tuple which represents the table's size """ ! return len(self.row_names), len(self.col_names) *************** *** 386,390 **** self.units['__row_column__'] = '' ! def set_size(self, value, col_id): """Sets the size of the specified col_id to value --- 383,387 ---- self.units['__row_column__'] = '' ! # XXX FIXME : params order should be reversed for all set() methods def set_size(self, value, col_id): """Sets the size of the specified col_id to value *************** *** 405,409 **** ! def set_aligment(self, value, col_id): """Sets the alignment of the specified col_id to value """ --- 402,406 ---- ! def set_alignment(self, value, col_id): """Sets the alignment of the specified col_id to value """ *************** *** 518,527 **** def __init__(self, rules = None): ! self.rules = rules or [] self.instructions = [] ! for rule in self.rules: ! self.instructions.append(compile( ! CELL_PROG.sub(r'self.data[\1][\2]', rule), ! 'table.py', 'exec')) --- 515,523 ---- def __init__(self, rules = None): ! rules = rules or [] ! self.rules = [] self.instructions = [] ! for rule in rules: ! self.add_rule(rule) Index: db.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/db.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** db.py 21 Jan 2005 17:42:03 -0000 1.3 --- db.py 16 Feb 2005 16:45:42 -0000 1.4 *************** *** 266,270 **** """Handles psycopg connexion format""" kwargs = {'host' : host, 'db' : database, ! 'user' : user, 'password' : password or None} return self._native_module.connect(**kwargs) --- 266,270 ---- """Handles psycopg connexion format""" kwargs = {'host' : host, 'db' : database, ! 'user' : user, 'passwd' : password or None} return self._native_module.connect(**kwargs) Index: textutils.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/textutils.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** textutils.py 21 Jan 2005 17:42:03 -0000 1.3 --- textutils.py 16 Feb 2005 16:45:42 -0000 1.4 *************** *** 1,22 **** ! # Copyright (c) 2000-2003 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:co...@lo... ! # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. ! # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! """ ! Some text manipulation utilities """ __revision__ = "$Id$" import re --- 1,52 ---- ! # Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:co...@lo... ! # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. ! # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! """Some text manipulation utility functions. ! ! :version: $Revision$ ! :author: Logilab ! :copyright: 2003-2005 LOGILAB S.A. (Paris, FRANCE) ! :contact: http://www.logilab.fr/ -- mailto:pyt...@lo... ! ! :group text formatting: normalize_text, normalize_paragraph, pretty_match,\ ! unquote, colorize_ansi ! :group text manipulation: searchall, get_csv ! :sort: text formatting, text manipulation ! ! ! ! :type ANSI_STYLES: dict(str) ! :var ANSI_STYLES: dictionary mapping style identifier to ANSI terminal code ! ! :type ANSI_COLORS: dict(str) ! :var ANSI_COLORS: dictionary mapping color identifier to ANSI terminal code ! ! :type ANSI_PREFIX: str ! :var ANSI_PREFIX: ! ANSI terminal code notifing the start of an ANSI escape sequence ! ! :type ANSI_END: str ! :var ANSI_END: ! ANSI terminal code notifing the end of an ANSI escape sequence ! ! :type ANSI_RESET: str ! :var ANSI_RESET: ! ANSI terminal code reseting format defined by a previous ANSI escape sequence """ __revision__ = "$Id$" + __docformat__ = "restructuredtext en" import re *************** *** 24,41 **** from warnings import warn - NORM_SPACES = re.compile('[ \t\f]+') - - def unquote(string): - """return the unquoted string""" - if not string: - return string - if string[0] in '"\'': - string = string[1:] - if string[-1] in '"\'': - string = string[:-1] - return string def searchall(rgx, data): """apply a regexp using "search" until no more match is found """ warn('logilab.common.textutils.searchall() is deprecated, use ' --- 54,62 ---- from warnings import warn def searchall(rgx, data): """apply a regexp using "search" until no more match is found + + This function is deprecated, use re.finditer() instead. """ warn('logilab.common.textutils.searchall() is deprecated, use ' *************** *** 48,67 **** return result def normalize_text(text, line_len=80, indent=''): ! """normalize a text to display it with a maximum line size and optionaly ! indentation. Blank lines are conserved. """ result = [] ! for text in text.split('\n\n'): result.append(normalize_paragraph(text, line_len, indent)) ! return ('\n%s\n' % indent).join(result) def normalize_paragraph(text, line_len=80, indent=''): ! """normalize a text paragraph to display it with a maximum line size ! and optional indentation (the indentation may be used top insert a ! comment mark for instance) """ ! text = text.replace(linesep, ' ') ! text = NORM_SPACES.sub(' ', text) lines = [] while text: --- 69,144 ---- return result + + def unquote(string): + """remove optional quotes (simple or double) from the string + + :type string: str or unicode + :param string: an optionaly quoted string + + :rtype: str or unicode + :return: the unquoted string (or the input string if it wasn't quoted) + """ + if not string: + return string + if string[0] in '"\'': + string = string[1:] + if string[-1] in '"\'': + string = string[:-1] + return string + + + _BLANKLINES_RGX = re.compile('\r?\n\r?\n') + _NORM_SPACES_RGX = re.compile('\s+') + def normalize_text(text, line_len=80, indent=''): ! """normalize a text to display it with a maximum line size and ! optionaly arbitrary indentation. Line jumps are normalized but blank ! lines are kept. The indentation string may be used top insert a ! comment mark for instance. ! ! :type text: str or unicode ! :param text: the input text to normalize ! ! :type line_len: int ! :param line_len: expected maximum line's length, default to 80 ! ! :type indent: str or unicode ! :param indent: optional string to use as indentation ! ! :rtype: str or unicode ! :return: ! the input text normalized to fit on lines with a maximized size ! inferior to `line_len`, and optionally prefixed by an ! indentation string """ result = [] ! for text in _BLANKLINES_RGX.split(text): result.append(normalize_paragraph(text, line_len, indent)) ! return ('%s%s%s' % (linesep, indent, linesep)).join(result) def normalize_paragraph(text, line_len=80, indent=''): ! """normalize a text to display it with a maximum line size and ! optionaly arbitrary indentation. Line jumps are normalized. The ! indentation string may be used top insert a comment mark for ! instance. ! ! ! :type text: str or unicode ! :param text: the input text to normalize ! ! :type line_len: int ! :param line_len: expected maximum line's length, default to 80 ! ! :type indent: str or unicode ! :param indent: optional string to use as indentation ! ! :rtype: str or unicode ! :return: ! the input text normalized to fit on lines with a maximized size ! inferior to `line_len`, and optionally prefixed by an ! indentation string """ ! #text = text.replace(linesep, ' ') ! text = _NORM_SPACES_RGX.sub(' ', text) lines = [] while text: *************** *** 81,96 **** return linesep.join(lines) - def get_csv(string): - """return a list of string in a csv format""" - return [word.strip() for word in string.split(',') if word.strip()] ! LINE_RGX = re.compile('\r\n|\r|\n') def pretty_match(match, string, underline_char='^'): ! """return a string whith the match location underlined """ start = match.start() end = match.end() ! string = LINE_RGX.sub(linesep, string) start_line_pos = string.rfind(linesep, 0, start) if start_line_pos == -1: --- 158,215 ---- return linesep.join(lines) ! def get_csv(string, sep=','): ! """return a list of string in from a csv formatted line ! ! >>> get_csv('a, b, c , 4') ! ['a', 'b', 'c', '4'] ! >>> get_csv('a') ! ['a'] ! >>> ! ! :type string: str or unicode ! :param string: a csv line ! ! :type sep: str or unicode ! :param sep: field separator, default to the comma (',') ! ! :rtype: str or unicode ! :return: the unquoted string (or the input string if it wasn't quoted) ! """ ! return [word.strip() for word in string.split(sep) if word.strip()] ! ! ! _LINE_RGX = re.compile('\r\n|\r+|\n') def pretty_match(match, string, underline_char='^'): ! """return a string with the match location underlined: ! ! >>> import re ! >>> print pretty_match(re.search('mange', 'il mange du bacon'), 'il mange du bacon') ! il mange du bacon ! ^^^^^ ! >>> ! ! :type match: _sre.SRE_match ! :param match: object returned by re.match, re.search or re.finditer ! ! :type string: str or unicode ! :param string: ! the string on which the regular expression has been applied to ! obtain the `match` object ! ! :type underline_char: str or unicode ! :param underline_char: ! character to use to underline the matched section, default to the ! carret '^' ! ! :rtype: str or unicode ! :return: ! the original string with an inserted line to underline the match ! location """ start = match.start() end = match.end() ! string = _LINE_RGX.sub(linesep, string) start_line_pos = string.rfind(linesep, 0, start) if start_line_pos == -1: *************** *** 116,120 **** ! ## Ansi colorization ################################################# ANSI_STYLES = { 'reset' : "0", --- 235,243 ---- ! # Ansi colorization ########################################################### ! ! ANSI_PREFIX = '\033[' ! ANSI_END = 'm' ! ANSI_RESET = '\033[0m' ANSI_STYLES = { 'reset' : "0", *************** *** 126,131 **** 'strike' : "9", } - - ANSI_COLORS = { 'reset' : "0", --- 249,252 ---- *************** *** 141,182 **** ! ANSI_PREFIX = '\033[' ! ANSI_END = 'm' ! ANSI_RESET = '\033[0m' ! ! ! def _get_ansi_code(color, style = None): ! """Returns ansi escape code corresponding to color and style ! ! :type color: str ! :param color: a string representing the color ! :type style: str ! :param style: a string representing style. Can define several ! style effect at the same time, (juste use coma ! as separator) :rtype: str ! :return: The built escape code or '' in case of unmatched color / style """ ansi_code = [] ! if style is not None: ! style_attrs = [attr.strip() for attr in style.split(',')] for effect in style_attrs: ! try: ! ansi_code.append(ANSI_STYLES[effect]) ! except KeyError: ! pass ! try: ansi_code.append(ANSI_COLORS[color]) - except KeyError: - pass if ansi_code: return ANSI_PREFIX + ';'.join(ansi_code) + ANSI_END return '' ! def colorize_ansi(msg, color, style = None): ! """Colorize message by wrapping it with ansi escape codes""" # If both color and style are not defined, then leave the text as is if color is None and style is None: --- 262,313 ---- ! def _get_ansi_code(color=None, style=None): ! """return ansi escape code corresponding to color and style ! ! :type color: str or None ! :param color: ! the color identifier (see `ANSI_COLORS` for available values) ! :type style: str or None ! :param style: ! style string (see `ANSI_COLORS` for available values). To get ! several style effects at the same time, use a coma as separator. + :raise KeyError: if an unexistant color or style identifier is given + :rtype: str ! :return: the built escape code """ ansi_code = [] ! if style: ! style_attrs = get_csv(style) for effect in style_attrs: ! ansi_code.append(ANSI_STYLES[effect]) ! if color: ansi_code.append(ANSI_COLORS[color]) if ansi_code: return ANSI_PREFIX + ';'.join(ansi_code) + ANSI_END return '' + def colorize_ansi(msg, color=None, style=None): + """colorize message by wrapping it with ansi escape codes ! :type msg: str or unicode ! :param msg: the message string to colorize ! ! :type color: str or None ! :param color: ! the color identifier (see `ANSI_COLORS` for available values) ! ! :type style: str or None ! :param style: ! style string (see `ANSI_COLORS` for available values). To get ! several style effects at the same time, use a coma as separator. ! ! :raise KeyError: if an unexistant color or style identifier is given ! ! :rtype: str or unicode ! :return: the ansi escaped string ! """ # If both color and style are not defined, then leave the text as is if color is None and style is None: *************** *** 185,189 **** # If invalid (or unknown) color, don't wrap msg with ansi codes if escape_code: ! return escape_code + msg + ANSI_RESET return msg --- 316,320 ---- # If invalid (or unknown) color, don't wrap msg with ansi codes if escape_code: ! return '%s%s%s' % (escape_code, msg, ANSI_RESET) return msg Index: testlib.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/testlib.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** testlib.py 21 Jan 2005 17:42:05 -0000 1.3 --- testlib.py 16 Feb 2005 16:45:43 -0000 1.4 *************** *** 17,20 **** --- 17,21 ---- -t: testdir -- directory where the tests will be found -x: exclude -- add a test to exclude + -p: profile -- profiled execution If no non-option arguments are present, prefixes used are 'test', *************** *** 66,70 **** try: ! opts, args = getopt.getopt(sys.argv[1:], 'vqx:t:') except getopt.error, msg: print msg --- 67,71 ---- try: ! opts, args = getopt.getopt(sys.argv[1:], 'vqx:t:p') except getopt.error, msg: print msg *************** *** 73,76 **** --- 74,78 ---- verbose = 0 quiet = 0 + profile = 0 exclude = [] for o, a in opts: *************** *** 84,87 **** --- 86,91 ---- elif o == '-t': testdir = a + elif o == '-p': + profile = 1 elif o == '-h': print __doc__ *************** *** 95,99 **** for i in range(len(exclude)): # Strip trailing ".py" from arguments ! if args[i][-3:] == '.py': exclude[i] = exclude[i][:-3] tests = find_tests(testdir, args or DEFAULT_PREFIXES, excludes=exclude) --- 99,103 ---- for i in range(len(exclude)): # Strip trailing ".py" from arguments ! if exclude[i][-3:] == '.py': exclude[i] = exclude[i][:-3] tests = find_tests(testdir, args or DEFAULT_PREFIXES, excludes=exclude) *************** *** 101,105 **** # Tell tests to be moderately quiet test_support.verbose = verbose ! good, bad, skipped, all_result = run_tests(tests, quiet, verbose) if not quiet: print '*'*80 --- 105,116 ---- # Tell tests to be moderately quiet test_support.verbose = verbose ! if profile: ! print >> sys.stderr, '** profiled run' ! from hotshot import Profile ! prof = Profile('stones.prof') ! good, bad, skipped, all_result = prof.runcall(run_tests, tests, quiet, verbose) ! prof.close() ! else: ! good, bad, skipped, all_result = run_tests(tests, quiet, verbose) if not quiet: print '*'*80 *************** *** 121,124 **** --- 132,140 ---- print _count(len(skipped), "test"), "skipped:", print ', '.join(['%s (%s)' % (test, msg) for test, msg in skipped]) + if profile: + from hotshot import stats + stats = stats.load('stones.prof') + stats.sort_stats('time', 'calls') + stats.print_stats(30) sys.exit(len(bad) + len(skipped)) *************** *** 220,223 **** --- 236,241 ---- # test utils ################################################################## + from xml.sax import make_parser, SAXParseException + from cStringIO import StringIO class TestCase(unittest.TestCase): *************** *** 226,229 **** --- 244,252 ---- def assertDictEquals(self, d1, d2): + """compares two dicts + + If the two dict differ, the first difference is shown in the error + message + """ d1 = d1.copy() for key, value in d2.items(): *************** *** 238,241 **** --- 261,269 ---- def assertListEquals(self, l1, l2): + """compares two lists + + If the two list differ, the first difference is shown in the error + message + """ l1 = l1[:] for value in l2: *************** *** 252,256 **** --- 280,300 ---- def assertLinesEquals(self, l1, l2): + """assert list of lines are equal""" self.assertListEquals(l1.splitlines(), l2.splitlines()) + + def assertXMLValid(self, stream): + """asserts the XML stream is well-formed (no DTD conformance check)""" + parser = make_parser() + try: + parser.parse(stream) + except SAXParseException: + self.fail('XML stream not well formed') + + def assertXMLStringValid(self, xml_string): + """asserts the XML string is well-formed (no DTD conformance check)""" + stream = StringIO(xml_string) + self.assertXMLValid(stream) + + import doctest *************** *** 261,271 **** without this hack """ ! def run(self, result=None): return doctest.DocTestSuite(self.module).run(result) def test(self): """just there to trigger test execution""" - MAILBOX = None --- 305,315 ---- without this hack """ ! def __call__(self, result=None): return doctest.DocTestSuite(self.module).run(result) + run = __call__ def test(self): """just there to trigger test execution""" MAILBOX = None Index: __pkginfo__.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/__pkginfo__.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** __pkginfo__.py 21 Jan 2005 17:42:05 -0000 1.3 --- __pkginfo__.py 16 Feb 2005 16:45:43 -0000 1.4 *************** *** 1,3 **** ! # Copyright (c) 2000-2005 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:co...@lo... --- 1,3 ---- ! # Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:co...@lo... *************** *** 21,25 **** modname = 'common' ! numversion = (0, 9, 0) version = '.'.join([str(num) for num in numversion]) --- 21,25 ---- modname = 'common' ! numversion = (0, 9, 2) version = '.'.join([str(num) for num in numversion]) Index: xmlrpcutils.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/xmlrpcutils.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** xmlrpcutils.py 21 Jan 2005 17:42:05 -0000 1.3 --- xmlrpcutils.py 16 Feb 2005 16:45:43 -0000 1.4 *************** *** 21,66 **** import xmlrpclib from base64 import encodestring ! from cStringIO import StringIO ProtocolError = xmlrpclib.ProtocolError ! class BasicAuthTransport(xmlrpclib.Transport): ! def __init__(self, username=None, password=None): ! self.username = username ! self.password = password ! self.verbose = None ! self.has_ssl = httplib.__dict__.has_key("HTTPConnection") ! def request(self, host, handler, request_body, verbose=None): ! # issue XML-RPC request ! if self.has_ssl: ! if host.startswith("https:"): h = httplib.HTTPSConnection(host) ! else: h = httplib.HTTPConnection(host) ! else: h = httplib.HTTP(host) ! h.putrequest("POST", handler) ! # required by HTTP/1.1 ! if not self.has_ssl: # HTTPConnection already does 1.1 ! h.putheader("Host", host) ! h.putheader("Connection", "close") ! if request_body: h.send(request_body) ! if self.has_ssl: ! response = h.getresponse() ! if response.status != 200: ! raise xmlrpclib.ProtocolError(host + handler, ! response.status, ! response.reason, ! response.msg) ! file = response.fp ! else: ! errcode, errmsg, headers = h.getreply() ! if errcode != 200: ! raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) ! file = h.getfile() ! return self.parse_response(file) --- 21,66 ---- import xmlrpclib from base64 import encodestring ! #from cStringIO import StringIO ProtocolError = xmlrpclib.ProtocolError ! ## class BasicAuthTransport(xmlrpclib.Transport): ! ## def __init__(self, username=None, password=None): ! ## self.username = username ! ## self.password = password ! ## self.verbose = None ! ## self.has_ssl = httplib.__dict__.has_key("HTTPConnection") ! ## def request(self, host, handler, request_body, verbose=None): ! ## # issue XML-RPC request ! ## if self.has_ssl: ! ## if host.startswith("https:"): h = httplib.HTTPSConnection(host) ! ## else: h = httplib.HTTPConnection(host) ! ## else: h = httplib.HTTP(host) ! ## h.putrequest("POST", handler) ! ## # required by HTTP/1.1 ! ## if not self.has_ssl: # HTTPConnection already does 1.1 ! ## h.putheader("Host", host) ! ## h.putheader("Connection", "close") ! ## if request_body: h.send(request_body) ! ## if self.has_ssl: ! ## response = h.getresponse() ! ## if response.status != 200: ! ## raise xmlrpclib.ProtocolError(host + handler, ! ## response.status, ! ## response.reason, ! ## response.msg) ! ## file = response.fp ! ## else: ! ## errcode, errmsg, headers = h.getreply() ! ## if errcode != 200: ! ## raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) ! ## file = h.getfile() ! ## return self.parse_response(file) Index: modutils.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/PySrc/ThirdParty/logilab/common/modutils.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** modutils.py 21 Jan 2005 17:42:03 -0000 1.4 --- modutils.py 16 Feb 2005 16:45:43 -0000 1.5 *************** *** 1,2 **** --- 1,5 ---- + # Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). + # http://www.logilab.fr/ -- mailto:co...@lo... + # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software *************** *** 11,39 **** # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! """ Copyright (c) 2002-2003 LOGILAB S.A. (Paris, FRANCE). ! http://www.logilab.fr/ -- mailto:co...@lo... ! module manipulation utilities """ __revision__ = "$Id$" - from __future__ import nested_scopes - import os import sys from os.path import walk, splitext, join, abspath, isdir, dirname, exists ! from imp import find_module, load_module ! # get standard library directory for the running python version ! STD_LIB_DIR = join(sys.prefix, 'lib', 'python%s' % sys.version[:3]) def load_module_from_name(dotted_name, path=None, use_sys=1): ! """ load a python module from it's name """ return load_module_from_parts(dotted_name.split('.'), path, use_sys) ! def load_module_from_parts(parts, path=None, use_sys=1, prefix=None): ! """ load a python module from it's splitted name """ ! if prefix is None and use_sys: # make tricks like "import os.path" working try: --- 14,116 ---- # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! """Python modules manipulation utility functions. ! :version: $Revision$ ! :author: Logilab ! :copyright: 2003-2005 LOGILAB S.A. (Paris, FRANCE) ! :contact: http://www.logilab.fr/ -- mailto:pyt...@lo... ! ! ! ! :type PY_SOURCE_EXTS: tuple(str) ! :var PY_SOURCE_EXTS: list of possible python source file extension ! ! :type STD_LIB_DIR: str ! :var STD_LIB_DIR: directory where standard modules are located ! ! :type BUILTIN_MODULES: dict ! :var BUILTIN_MODULES: dictionary with builtin module names has key """ + from __future__ import nested_scopes + __revision__ = "$Id$" + __docformat__ = "restructuredtext en" import sys + import os from os.path import walk, splitext, join, abspath, isdir, dirname, exists ! from imp import find_module, load_module, C_BUILTIN, PY_COMPILED, PKG_DIRECTORY ! ! if sys.platform.startswith('win'): ! PY_SOURCE_EXTS = ('py', 'pyw') ! PY_COMPILED_EXTS = ('dll', 'pyd') ! STD_LIB_DIR = join(sys.prefix, 'lib') ! else: ! PY_SOURCE_EXTS = ('py',) ! PY_COMPILED_EXTS = ('so',) ! STD_LIB_DIR = join(sys.prefix, 'lib', 'python%s' % sys.version[:3]) ! ! BUILTIN_MODULES = dict(zip(sys.builtin_module_names, ! [1]*len(sys.builtin_module_names))) ! ! ! class NoSourceFile(Exception): ! """exception raised when we are not able to get a python ! source file for a precompiled file ! """ def load_module_from_name(dotted_name, path=None, use_sys=1): ! """load a Python module from it's name ! ! :type dotted_name: str ! :param dotted_name: python name of a module or package ! ! :type path: list or None ! :param path: ! optional list of path where the module or package should be ! searched (use sys.path if nothing or None is given) ! ! :type use_sys: bool ! :param use_sys: ! boolean indicating whether the sys.modules dictionary should be ! used or not ! ! ! :raise ImportError: if the module or package is not found ! ! :rtype: module ! :return: the loaded module ! """ return load_module_from_parts(dotted_name.split('.'), path, use_sys) ! ! def load_module_from_modpath(parts, path=None, use_sys=1, _prefix=None): ! """load a python module from it's splitted name ! ! :type parts: list(str) or tuple(str) ! :param parts: ! python name of a module or package splitted on '.' ! ! :type path: list or None ! :param path: ! optional list of path where the module or package should be ! searched (use sys.path if nothing or None is given) ! ! :type use_sys: bool ! :param use_sys: ! boolean indicating whether the sys.modules dictionary should be used or not ! ! :param _prefix: used internally, should not be specified ! ! ! :raise ImportError: if the module or package is not found ! ! :rtype: module ! :return: the loaded module ! """ ! if _prefix is None and use_sys: # make tricks like "import os.path" working try: *************** *** 41,49 **** except KeyError: pass ! if prefix: ! name = '%s.%s' % (prefix, parts[0]) else: name = parts[0] - mp_file, mp_filename, mp_desc = find_module(parts[0], path) module = load_module(name, mp_file, mp_filename, mp_desc) if len(parts) == 1: --- 118,126 ---- except KeyError: pass ! mp_file, mp_filename, mp_desc = find_module(parts[0], path) ! if _prefix: ! name = '%s.%s' % (_prefix, parts[0]) else: name = parts[0] module = load_module(name, mp_file, mp_filename, mp_desc) if len(parts) == 1: *************** *** 52,60 **** use_sys, name) def modpath_from_file(filename): ! """given an absolute file path return the python module's path as a list """ ! base, ext = splitext(abspath(filename)) for path in sys.path: path = abspath(path) --- 129,151 ---- use_sys, name) + load_module_from_parts = load_module_from_modpath # backward compat + + def modpath_from_file(filename): ! """given a file path return the corresponding splitted module's name ! (i.e name of a module or package splitted on '.') ! ! :type filename: str ! :param filename: file's path for which we want the module's name ! ! ! :raise ImportError: ! if the corresponding module's name has not been found ! ! :rtype: list(str) ! :return: the corresponding splitted module's name """ ! base = splitext(abspath(filename))[0] for path in sys.path: path = abspath(path) *************** *** 63,157 **** path.find('site-packages') == -1: continue ! mod_path = [module for module in base[len(path):].split(os.sep) if module] if len(mod_path) > 1: ! if not has_init(join(path, mod_path[0])): continue break break else: ! raise Exception('Unable to find module for %s in %s' % ( base, ', \n'.join(sys.path))) return mod_path - _PYEXTS = {'so':1, 'dll':1, 'py':1, 'pyo':1, 'pyc':1} ! _HAS_MOD_CACHE = {} ! def has_module(directory, modname, _exts=_PYEXTS): ! """return the path corresponding to modname in directory if it exists, ! else raise ImportError ! """ ! try: ! if _HAS_MOD_CACHE[(directory, modname)] is None: ! raise ImportError('No module %r in %s' % (modname, directory)) ! return _HAS_MOD_CACHE[(directory, modname)] ! except KeyError: ! pass ! # FIXME: zip import ! ! filepath = join(directory, modname) ! if isdir(filepath) and has_init(filepath): ! _HAS_MOD_CACHE[(directory, modname)] = filepath ! return filepath ! try: ! for filename in os.listdir(directory): ! try: ! basename, ext = filename.split('.', 1)#splitext(filename) ! except ValueError: ! continue ! #basename, ext = splitext(filename) ! if basename == modname and ext in _exts: ! filepath = '%s.%s' % (filepath, ext) ! _HAS_MOD_CACHE[(directory, modname)] = filepath ! return filepath ! except OSError: ! pass ! _HAS_MOD_CACHE[(directory, modname)] = None ! raise ImportError('No module %r in %s' % (modname, directory)) ! def file_from_modpath(modpath, search_path=None): if modpath[0] == 'xml': # handle _xmlplus try: ! return _file_from_modpath(['_xmlplus'] + modpath[1:], search_path) except ImportError: ! pass elif modpath == ['os', 'path']: ! # FIXME: ignore search_path... return os.path.__file__ ! return _file_from_modpath(modpath, search_path) - def _file_from_modpath(modpath, search_path=None): - """given a mod path (i.e. splited module / package name), return the - corresponding file - FIXME: doesn't handle zip archive... - """ - assert len(modpath) > 0 - search_path = search_path or sys.path - for path in search_path: - path = abspath(path) - # ignore bin directory - if path.endswith('/bin'): - continue - try: - found = has_module(path, modpath[0]) - except ImportError: - continue - for part in modpath[1:]: - found = has_module(found, part) - if isdir(found): - found = has_init(found) - return found - raise ImportError('No module %r' % '.'.join(modpath)) - def get_module_part(dotted_name, context_file=None): ! """given a dotted name like 'logilab.common.modutils.get_module', ! return the module part of the name (in the previous example, ! 'logilab.common.modutils' would be returned) ! return None if we are not able at all to import the given name """ # os.path trick --- 154,239 ---- path.find('site-packages') == -1: continue ! mod_path = [module for module in ... [truncated message content] |