--- a/Utilities/__init__.py Fri Mar 11 08:55:14 2011 +0100 +++ b/Utilities/__init__.py Fri Mar 11 16:51:57 2011 +0100 @@ -4,7 +4,7 @@ # """ -Package implementing various functions/classes needed everywhere within eric5. +Package implementing various functions/classes needed everywhere within eric5. """ import os @@ -16,7 +16,8 @@ import base64 import getpass -def __showwarning(message, category, filename, lineno, file = None, line = ""): + +def __showwarning(message, category, filename, lineno, file=None, line=""): """ Module function to raise a SyntaxError for a SyntaxWarning. @@ -57,31 +58,32 @@ configDir = None codingBytes_regexps = [ - (2, re.compile(br'''coding[:=]\s*([-\w_.]+)''')), - (1, re.compile(br'''<\?xml.*\bencoding\s*=\s*['"]([-\w_.]+)['"]\?>''')), + (2, re.compile(br'''coding[:=]\s*([-\w_.]+)''')), + (1, re.compile(br'''<\?xml.*\bencoding\s*=\s*['"]([-\w_.]+)['"]\?>''')), ] coding_regexps = [ - (2, re.compile(r'''coding[:=]\s*([-\w_.]+)''')), - (1, re.compile(r'''<\?xml.*\bencoding\s*=\s*['"]([-\w_.]+)['"]\?>''')), + (2, re.compile(r'''coding[:=]\s*([-\w_.]+)''')), + (1, re.compile(r'''<\?xml.*\bencoding\s*=\s*['"]([-\w_.]+)['"]\?>''')), ] -supportedCodecs = ['utf-8', - 'iso8859-1', 'iso8859-15', 'iso8859-2', 'iso8859-3', - 'iso8859-4', 'iso8859-5', 'iso8859-6', 'iso8859-7', - 'iso8859-8', 'iso8859-9', 'iso8859-10', 'iso8859-11', - 'iso8859-13', 'iso8859-14', 'iso8859-16', 'latin-1', - 'koi8-r', 'koi8-u', - 'utf-16', 'utf-32', - 'cp037', 'cp424', 'cp437', 'cp500', 'cp737', 'cp775', - 'cp850', 'cp852', 'cp855', 'cp856', 'cp857', 'cp860', - 'cp861', 'cp862', 'cp863', 'cp864', 'cp865', 'cp866', - 'cp869', 'cp874', 'cp875', 'cp932', 'cp949', 'cp950', - 'cp1006', 'cp1026', 'cp1140', 'cp1250', 'cp1251', - 'cp1252', 'cp1253', 'cp1254', 'cp1255', 'cp1256', - 'cp1257', 'cp1258', - 'gb2312', 'gb18030', +supportedCodecs = ['utf-8', + 'iso8859-1', 'iso8859-15', 'iso8859-2', 'iso8859-3', + 'iso8859-4', 'iso8859-5', 'iso8859-6', 'iso8859-7', + 'iso8859-8', 'iso8859-9', 'iso8859-10', 'iso8859-11', + 'iso8859-13', 'iso8859-14', 'iso8859-16', 'latin-1', + 'koi8-r', 'koi8-u', + 'utf-16', 'utf-32', + 'cp037', 'cp424', 'cp437', 'cp500', 'cp737', 'cp775', + 'cp850', 'cp852', 'cp855', 'cp856', 'cp857', 'cp860', + 'cp861', 'cp862', 'cp863', 'cp864', 'cp865', 'cp866', + 'cp869', 'cp874', 'cp875', 'cp932', 'cp949', 'cp950', + 'cp1006', 'cp1026', 'cp1140', 'cp1250', 'cp1251', + 'cp1252', 'cp1253', 'cp1254', 'cp1255', 'cp1256', + 'cp1257', 'cp1258', + 'gb2312', 'gb18030', 'ascii'] + class CodingError(Exception): """ Class implementing an exception, which is raised, if a given coding is incorrect. @@ -90,7 +92,7 @@ """ Constructor """ - self.errorMessage = QCoreApplication.translate("CodingError", + self.errorMessage = QCoreApplication.translate("CodingError", "The coding '{0}' is wrong for the given text.").format(coding) def __repr__(self): @@ -109,6 +111,7 @@ """ return str(self.errorMessage) + def get_codingBytes(text): """ Function to get the coding of a bytes text. @@ -126,6 +129,7 @@ return str(m.group(1), "ascii").lower() return None + def get_coding(text): """ Function to get the coding of a text. @@ -143,6 +147,7 @@ return m.group(1).lower() return None + def readEncodedFile(filename): """ Function to read a file and decode it's contents into proper text. @@ -155,6 +160,7 @@ f.close() return decode(text) + def readEncodedFileWithHash(filename): """ Function to read a file, calculate a hash value and decode it's contents @@ -166,10 +172,11 @@ f = open(filename, "rb") text = f.read() f.close() - hash = str(QCryptographicHash.hash(QByteArray(text), QCryptographicHash.Md5).toHex(), - encoding = "ASCII") + hash = str(QCryptographicHash.hash(QByteArray(text), QCryptographicHash.Md5).toHex(), + encoding="ASCII") return decode(text) + (hash, ) + def decode(text): """ Function to decode some byte text into a string. @@ -232,6 +239,7 @@ # Assume UTF-8 loosing information return str(text, "utf-8", "ignore"), 'utf-8-ignore' + def writeEncodedFile(filename, text, orig_coding): """ Function to write a file with properly encoded text. @@ -249,6 +257,7 @@ return encoding + def encode(text, orig_coding): """ Function to encode text into a byte text. @@ -303,6 +312,7 @@ return etext, encoding + def decodeString(text): """ Function to decode a string containing Unicode encoded characters. @@ -351,6 +361,7 @@ '"': """, } + def escape_entities(m, map=_escape_map): """ Function to encode html entities. @@ -365,6 +376,7 @@ text = "&#{0:d};".format(ord(char)) return text + def html_encode(text, pattern=_escape): """ Function to correctly encode a text for html. @@ -380,6 +392,7 @@ _uescape = re.compile('[\u0080-\uffff]') + def escape_uentities(m): """ Function to encode html entities. @@ -391,6 +404,7 @@ text = "&#{0:d};".format(ord(char)) return text + def html_uencode(text, pattern=_uescape): """ Function to correctly encode a unicode text for html. @@ -404,6 +418,7 @@ text = pattern.sub(escape_uentities, text) return text + def convertLineEnds(text, eol): """ Function to convert the end of line characters. @@ -414,16 +429,17 @@ """ if eol == '\r\n': regexp = re.compile(r"""(\r(?!\n)|(?<!\r)\n)""") - return regexp.sub(lambda m, eol = '\r\n': eol, text) + return regexp.sub(lambda m, eol='\r\n': eol, text) elif eol == '\n': regexp = re.compile(r"""(\r\n|\r)""") - return regexp.sub(lambda m, eol = '\n': eol, text) + return regexp.sub(lambda m, eol='\n': eol, text) elif eol == '\r': regexp = re.compile(r"""(\r\n|\n)""") - return regexp.sub(lambda m, eol = '\r': eol, text) + return regexp.sub(lambda m, eol='\r': eol, text) else: return text + def linesep(): """ Function to return the lineseparator used by the editor. @@ -438,6 +454,7 @@ else: return "\r\n" + def extractFlags(text): """ Function to extract eric specific flags out of the given text. @@ -445,7 +462,7 @@ Flags are contained in comments and are introduced by 'eflag:'. The rest of the line is interpreted as 'key = value'. value is analyzed for being an integer or float value. If that fails, it - is assumed to be a string. If a key does not contain a '=' + is assumed to be a string. If a key does not contain a '=' character, it is assumed to be a boolean flag. Flags are expected at the very end of a file. The search is ended, if a line without the 'eflag:' marker is found. @@ -492,6 +509,7 @@ return flags + def toNativeSeparators(path): """ Function returning a path, that is using native separator characters. @@ -501,6 +519,7 @@ """ return QDir.toNativeSeparators(path) + def fromNativeSeparators(path): """ Function returning a path, that is using "/" separator characters. @@ -510,6 +529,7 @@ """ return QDir.fromNativeSeparators(path) + def normcasepath(path): """ Function returning a path, that is normalized with respect to its case and references. @@ -519,6 +539,7 @@ """ return os.path.normcase(os.path.normpath(path)) + def normabspath(path): """ Function returning a normalized, absolute path. @@ -528,9 +549,10 @@ """ return os.path.abspath(path) + def normcaseabspath(path): """ - Function returning an absolute path, that is normalized with respect to its case + Function returning an absolute path, that is normalized with respect to its case and references. @param path file path (string) @@ -538,6 +560,7 @@ """ return os.path.normcase(os.path.abspath(path)) + def normjoinpath(a, *p): """ Function returning a normalized path of the joined parts passed into it. @@ -548,6 +571,7 @@ """ return os.path.normpath(os.path.join(a, *p)) + def normabsjoinpath(a, *p): """ Function returning a normalized, absolute path of the joined parts passed into it. @@ -558,7 +582,8 @@ """ return os.path.abspath(os.path.join(a, *p)) -def relpath(path, start = os.path.curdir): + +def relpath(path, start=os.path.curdir): """ Return a relative version of a path. @@ -579,6 +604,7 @@ return os.path.curdir return os.path.join(*rel_list) + def isinpath(file): """ Function to check for an executable file. @@ -603,6 +629,7 @@ return False + def getExecutablePath(file): """ Function to build the full path of an executable file from the environment. @@ -632,6 +659,7 @@ return "" + def isExecutable(exe): """ Function to check, if a file is executable. @@ -641,6 +669,7 @@ """ return os.access(exe, os.X_OK) + def samepath(f1, f2): """ Function to compare two paths. @@ -663,6 +692,7 @@ except AttributeError: EXTSEP = "." + def splitPath(name): """ Function to split a pathname into a directory part and a file part. @@ -677,6 +707,7 @@ dn, fn = os.path.split(name) return (dn, fn) + def joinext(prefix, ext): """ Function to join a file extension to a path. @@ -689,10 +720,11 @@ @return the complete filename (string) """ if ext[0] != ".": - ext = ".{0}".format(ext) # require leading separator, to match os.path.splitext + ext = ".{0}".format(ext) # require leading separator, to match os.path.splitext return prefix + EXTSEP + ext[1:] -def compactPath(path, width, measure = len): + +def compactPath(path, width, measure=len): """ Function to return a compacted path fitting inside the given width. @@ -727,6 +759,7 @@ tail = tail[1:] return "" + def direntries(path, filesonly=False, pattern=None, followsymlinks=True, checkStop=None): """ Function returning a list of all files and directories. @@ -738,7 +771,7 @@ should be followed @param checkStop function to be called to check for a stop @return list of all files and directories in the tree rooted - at path. The names are expanded to start with path. + at path. The names are expanded to start with path. """ if filesonly: files = [] @@ -750,11 +783,11 @@ if checkStop and checkStop(): break - if entry in ['CVS', 'cvs', - '.svn', '_svn', - '.hg', '_hg', + if entry in ['CVS', 'cvs', + '.svn', '_svn', + '.hg', '_hg', '.ropeproject', '_ropeproject', - '.eric5project', '_eric5project', + '.eric5project', '_eric5project', '.issues', '_issues']: continue @@ -777,6 +810,7 @@ pass return files + def getDirs(path, excludeDirs): """ Function returning a list of all directories below path. @@ -796,7 +830,7 @@ not os.path.islink(os.path.join(path, name)): exclude = 0 for e in excludeDirs: - if name.split(os.sep,1)[0] == e: + if name.split(os.sep, 1)[0] == e: exclude = 1 break if not exclude: @@ -808,6 +842,7 @@ return dirs + def getTestFileName(fn): """ Function to build the filename of a unittest file. @@ -821,6 +856,7 @@ dn, fn = os.path.split(fn) return os.path.join(dn, "test{0}".format(fn)) + def parseOptionString(s): """ Function used to convert an option string into a list of options. @@ -832,6 +868,7 @@ s = re.sub(r"%[A-Z%]", _percentReplacementFunc, s) return parseString(s, rx) + def parseEnvironmentString(s): """ Function used to convert an environment string into a list of environment settings. @@ -842,6 +879,7 @@ rx = QRegExp(r"""\s(\w+\+?=[^\s]+|\w+="[^"]+"|\w+='[^']+')""") return parseString(s, rx) + def parseString(s, rx): """ Function used to convert a string into a list. @@ -866,6 +904,7 @@ return olist + def _percentReplacementFunc(matchobj): """ Protected function called for replacing % codes. @@ -875,6 +914,7 @@ """ return getPercentReplacement(matchobj.group(0)) + def getPercentReplacement(code): """ Function to get the replacement for code. @@ -951,13 +991,14 @@ # unknown code, just return it return code + def getPercentReplacementHelp(): """ Function to get the help text for the supported %-codes. @returns help text (string) """ - return QCoreApplication.translate("Utilities", + return QCoreApplication.translate("Utilities", """<p>You may use %-codes as placeholders in the string.""" """ Supported codes are:""" """<table>""" @@ -973,6 +1014,7 @@ """</table>""" """</p>""") + def getUserName(): """ Function to get the user name. @@ -984,6 +1026,7 @@ if not user and isWindowsPlatform(): return win32_GetUserName() + def getHomeDir(): """ Function to get a users home directory @@ -992,6 +1035,7 @@ """ return QDir.homePath() + def getPythonModulesDirectory(): """ Function to determine the path to Python's modules directory. @@ -1001,6 +1045,7 @@ import distutils.sysconfig return distutils.sysconfig.get_python_lib(True) + def getPythonLibPath(): """ Function to determine the path to Python's library. @@ -1026,6 +1071,7 @@ return libDir + def getPythonVersion(): """ Function to get the Python version (major, minor) as an integer value. @@ -1034,7 +1080,8 @@ """ return sys.hexversion >> 16 -def compile(file, codestring = ""): + +def compile(file, codestring=""): """ Function to compile one Python source file to Python bytecode. @@ -1052,8 +1099,8 @@ except (UnicodeDecodeError, IOError): return (False, None, None, None, None) - codestring = codestring.replace("\r\n","\n") - codestring = codestring.replace("\r","\n") + codestring = codestring.replace("\r\n", "\n") + codestring = codestring.replace("\r", "\n") if codestring and codestring[-1] != '\n': codestring = codestring + '\n' @@ -1069,9 +1116,10 @@ else: builtins.compile(codestring, file, 'exec') except SyntaxError as detail: - import traceback, re + import traceback + import re lines = traceback.format_exception_only(SyntaxError, detail) - match = re.match('\s*File "(.+)", line (\d+)', + match = re.match('\s*File "(.+)", line (\d+)', lines[0].replace('<string>', '{0}'.format(file))) if match is not None: fn, line = match.group(1, 2) @@ -1119,7 +1167,8 @@ return (False, None, None, None, None, None) -def py2compile(file, checkFlakes = False): + +def py2compile(file, checkFlakes=False): """ Function to compile one Python 2 source file to Python 2 bytecode. @@ -1135,12 +1184,12 @@ """ interpreter = Preferences.getDebugger("PythonInterpreter") if interpreter == "" or not isExecutable(interpreter): - return (True, file, "1", "", - QCoreApplication.translate("Utilities", - "Python2 interpreter not configured."), + return (True, file, "1", "", + QCoreApplication.translate("Utilities", + "Python2 interpreter not configured."), []) - syntaxChecker = os.path.join(getConfig('ericDir'), + syntaxChecker = os.path.join(getConfig('ericDir'), "UtilitiesPython2", "Py2SyntaxChecker.py") args = [syntaxChecker] if checkFlakes: @@ -1155,8 +1204,8 @@ finished = proc.waitForFinished(30000) if finished: output = \ - str(proc.readAllStandardOutput(), - Preferences.getSystem("IOEncoding"), + str(proc.readAllStandardOutput(), + Preferences.getSystem("IOEncoding"), 'replace').splitlines() syntaxerror = output[0] == "ERROR" @@ -1172,20 +1221,21 @@ warnings = [] while index < len(output): if output[index] == "FLAKES_ERROR": - return (True, output[index + 1], output[index + 2], "", + return (True, output[index + 1], output[index + 2], "", output[index + 3], []) else: - warnings.append((output[index + 1], output[index + 2], + warnings.append((output[index + 1], output[index + 2], output[index + 3])) index += 4 return (False, None, None, None, None, None, warnings) - return (True, file, "1", "0", "", + return (True, file, "1", "0", "", QCoreApplication.translate("Utilities", - "Python2 interpreter did not finish within 30s."), + "Python2 interpreter did not finish within 30s."), []) + def getConfigDir(): """ Module function to get the name of the directory storing the config data. @@ -1206,6 +1256,7 @@ hp += "/" + cdn return toNativeSeparators(hp) + def setConfigDir(d): """ Module function to set the name of the directory storing the config data. @@ -1219,14 +1270,15 @@ # functions for environment handling ################################################################################ -def getEnvironmentEntry(key, default = None): + +def getEnvironmentEntry(key, default=None): """ Module function to get an environment entry. @param key key of the requested environment entry (string) @param default value to be returned, if the environment doesn't contain the requested entry (string) - @return the requested entry or the default value, if the entry wasn't + @return the requested entry or the default value, if the entry wasn't found (string or None) """ filter = QRegExp("^{0}[ \t]*=".format(key)) @@ -1241,6 +1293,7 @@ ename, val = entries[0].split("=", 1) return val.strip() + def hasEnvironmentEntry(key): """ Module function to check, if the environment contains an entry. @@ -1259,6 +1312,7 @@ # Qt utility functions below ################################################################################ + def generateQtToolName(toolname): """ Module function to generate the executable name for a Qt tool like designer. @@ -1266,11 +1320,12 @@ @param toolname base name of the tool (string) @return the Qt tool name without extension (string) """ - return "{0}{1}{2}".format(Preferences.getQt("QtToolsPrefix4"), - toolname, + return "{0}{1}{2}".format(Preferences.getQt("QtToolsPrefix4"), + toolname, Preferences.getQt("QtToolsPostfix4") ) + def prepareQtMacBundle(toolname, version, args): """ Module function for starting Qt tools that are Mac OS X bundles. @@ -1299,7 +1354,8 @@ # Other utility functions below ################################################################################ -def generateVersionInfo(linesep = '\n'): + +def generateVersionInfo(linesep='\n'): """ Module function to generate a string with various version infos. @@ -1312,7 +1368,7 @@ except ImportError: sip_version_str = "sip version not available" - info = "Version Numbers:{0} Python {1}{2}".format( + info = "Version Numbers:{0} Python {1}{2}".format( linesep, sys.version.split()[0], linesep) info += " Qt {0}{1} PyQt4 {2}{3}".format( qVersion(), linesep, PYQT_VERSION_STR, linesep) @@ -1330,7 +1386,8 @@ return info -def generatePluginsVersionInfo(linesep = '\n'): + +def generatePluginsVersionInfo(linesep='\n'): """ Module function to generate a string with plugins version infos. @@ -1355,7 +1412,8 @@ return infoStr -def generateDistroInfo(linesep = '\n'): + +def generateDistroInfo(linesep='\n'): """ Module function to generate a string with distribution infos. @@ -1382,6 +1440,7 @@ return infoStr + def checkBlacklistedVersions(): """ Module functions to check for blacklisted versions of the prerequisites. @@ -1438,6 +1497,7 @@ # password handling functions below ################################################################################ + def pwEncode(pw): """ Module function to encode a password. @@ -1450,6 +1510,7 @@ rpw = "".join(random.sample(pop, 32)) + pw + "".join(random.sample(pop, 32)) return marker + base64.b64encode(rpw.encode()).decode() + def pwDecode(epw): """ Module function to decode a password. @@ -1472,6 +1533,7 @@ # win32 compatibility functions below ################################################################################ + def win32_Kill(pid): """ Function to provide an os.kill equivalent for Win32. @@ -1482,6 +1544,7 @@ handle = win32api.OpenProcess(1, 0, pid) return (0 != win32api.TerminateProcess(handle, 0)) + def win32_GetUserName(): """ Function to get the user name under Win32.