--- a/eric6/Utilities/__init__.py Fri Apr 02 11:59:41 2021 +0200 +++ b/eric6/Utilities/__init__.py Sat May 01 14:27:20 2021 +0200 @@ -17,6 +17,7 @@ import ctypes import subprocess # secok import shlex +import contextlib def __showwarning(message, category, filename, lineno, file=None, line=""): @@ -220,7 +221,7 @@ @param text byte text to decode (bytes) @return tuple of decoded text and encoding (string, string) """ - try: + with contextlib.suppress(UnicodeError, LookupError): if text.startswith(BOM_UTF8): # UTF-8 with BOM return str(text[len(BOM_UTF8):], 'utf-8'), 'utf-8-bom' @@ -233,21 +234,17 @@ coding = get_codingBytes(text) if coding: return str(text, coding), coding - except (UnicodeError, LookupError): - pass # Assume UTF-8 - try: + with contextlib.suppress(UnicodeError, LookupError): return str(text, 'utf-8'), 'utf-8-guessed' - except (UnicodeError, LookupError): - pass guess = None if Preferences.getEditor("AdvancedEncodingDetection"): # Try the universal character encoding detector try: - import ThirdParty.CharDet.chardet - guess = ThirdParty.CharDet.chardet.detect(text) + import chardet + guess = chardet.detect(text) if ( guess and guess['confidence'] > 0.95 and @@ -261,20 +258,19 @@ pass # Try default encoding - try: + with contextlib.suppress(UnicodeError, LookupError): codec = Preferences.getEditor("DefaultEncoding") return str(text, codec), '{0}-default'.format(codec) - except (UnicodeError, LookupError): - pass - if Preferences.getEditor("AdvancedEncodingDetection"): - # Use the guessed one even if confifence level is low - if guess and guess['encoding'] is not None: - try: - codec = guess['encoding'].lower() - return str(text, codec), '{0}-guessed'.format(codec) - except (UnicodeError, LookupError): - pass + if ( + Preferences.getEditor("AdvancedEncodingDetection") and + guess and + guess['encoding'] is not None + ): + # Use the guessed one even if confidence level is low + with contextlib.suppress(UnicodeError, LookupError): + codec = guess['encoding'].lower() + return str(text, codec), '{0}-guessed'.format(codec) # Assume UTF-8 loosing information return str(text, "utf-8", "ignore"), 'utf-8-ignore' @@ -291,16 +287,14 @@ with open(filename, "rb") as f: text = f.read() if encoding: - try: + with contextlib.suppress(UnicodeError, LookupError): return str(text, encoding), '{0}-selected'.format(encoding) - except (UnicodeError, LookupError): - pass + # Try default encoding - try: + with contextlib.suppress(UnicodeError, LookupError): codec = Preferences.getEditor("DefaultEncoding") return str(text, codec), '{0}-default'.format(codec) - except (UnicodeError, LookupError): - pass + # Assume UTF-8 loosing information return str(text, "utf-8", "ignore"), 'utf-8-ignore' else: @@ -360,12 +354,10 @@ raise CodingError(coding) else: if forcedEncoding: - try: + with contextlib.suppress(UnicodeError, LookupError): etext, encoding = ( text.encode(forcedEncoding), forcedEncoding) - except (UnicodeError, LookupError): - # Error: Forced encoding is incorrect, ignore it - pass + # if forced encoding is incorrect, ignore it if encoding is None: # Try the original encoding @@ -378,25 +370,19 @@ .replace("-guessed", "") .replace("-ignore", "") ) - try: + with contextlib.suppress(UnicodeError, LookupError): etext, encoding = text.encode(coding), coding - except (UnicodeError, LookupError): - pass if encoding is None: # Try configured default - try: + with contextlib.suppress(UnicodeError, LookupError): codec = Preferences.getEditor("DefaultEncoding") etext, encoding = text.encode(codec), codec - except (UnicodeError, LookupError): - pass if encoding is None: # Try saving as ASCII - try: + with contextlib.suppress(UnicodeError): etext, encoding = text.encode('ascii'), 'ascii' - except UnicodeError: - pass if encoding is None: # Save as UTF-8 without BOM @@ -434,7 +420,7 @@ @return decoded text (string) """ # try UTF with BOM - try: + with contextlib.suppress(UnicodeError, LookupError): if buffer.startswith(BOM_UTF8): # UTF-8 with BOM return str(buffer[len(BOM_UTF8):], encoding='utf-8') @@ -444,19 +430,15 @@ elif buffer.startswith(BOM_UTF32): # UTF-32 with BOM return str(buffer[len(BOM_UTF32):], encoding='utf-32') - except (UnicodeError, LookupError): - pass # try UTF-8 - try: + with contextlib.suppress(UnicodeError): return str(buffer, encoding="utf-8") - except UnicodeError: - pass # try codec detection try: - import ThirdParty.CharDet.chardet - guess = ThirdParty.CharDet.chardet.detect(buffer) + import chardet + guess = chardet.detect(buffer) if guess and guess['encoding'] is not None: codec = guess['encoding'].lower() return str(buffer, encoding=codec) @@ -629,10 +611,7 @@ @return dictionary of string, boolean, complex, float and int """ flags = {} - if isinstance(text, str): - lines = text.rstrip().splitlines() - else: - lines = text + lines = text.rstrip().splitlines() if isinstance(text, str) else text for line in reversed(lines): try: index = line.index("eflag:") @@ -655,11 +634,9 @@ # interpret as int first value = int(value) except ValueError: - try: + with contextlib.suppress(ValueError): # interpret as float next value = float(value) - except ValueError: - pass flags[key] = value else: @@ -823,32 +800,29 @@ return False dirs = path.split(os.pathsep) - for directory in dirs: - if os.access(os.path.join(directory, file), os.X_OK): - return True - - return False + return any(os.access(os.path.join(directory, file), os.X_OK) + for directory in dirs) def startswithPath(path, start): """ Function to check, if a path starts with a given start path. - @param path path to be checked (string) - @param start start path (string) + @param path path to be checked + @type str + @param start start path + @type str @return flag indicating that the path starts with the given start - path (boolean) + path + @rtype bool """ - if start: - if path == start: - return True - elif normcasepath(path).startswith( - normcasepath(start + "/")): - return True - else: - return False - else: - return False + return ( + bool(start) and + ( + path == start or + normcasepath(path).startswith(normcasepath(start + "/")) + ) + ) def relativeUniversalPath(path, start): @@ -908,9 +882,8 @@ return "" cur_path = os.path.join(os.curdir, file) - if os.path.exists(cur_path): - if os.access(cur_path, os.X_OK): - return cur_path + if os.path.exists(cur_path) and os.access(cur_path, os.X_OK): + return cur_path path = os.getenv('PATH') @@ -945,9 +918,8 @@ return [] cur_path = os.path.join(os.curdir, file) - if os.path.exists(cur_path): - if os.access(cur_path, os.X_OK): - paths.append(cur_path) + if os.path.exists(cur_path) and os.access(cur_path, os.X_OK): + paths.append(cur_path) path = os.getenv('PATH') @@ -986,9 +958,8 @@ for filename in filenames: cur_path = os.path.join(os.curdir, filename) - if os.path.exists(cur_path): - if os.access(cur_path, os.X_OK): - return os.path.abspath(cur_path) + if os.path.exists(cur_path) and os.access(cur_path, os.X_OK): + return os.path.abspath(cur_path) path = os.getenv('PATH') @@ -1166,10 +1137,7 @@ @return list of all files and directories in the tree rooted at path. The names are expanded to start with path. """ - if filesonly: - files = [] - else: - files = [path] + files = [] if filesonly else [path] try: entries = os.listdir(path) for entry in entries: @@ -1235,7 +1203,7 @@ for name in dirs[:]: if not os.path.islink(name): - dirs = dirs + getDirs(name, excludeDirs) + dirs += getDirs(name, excludeDirs) return dirs @@ -1297,7 +1265,7 @@ else: # we are on a Linux or macOS platform for mountCommand in ["mount", "/sbin/mount", "/usr/sbin/mount"]: - try: + with contextlib.suppress(FileNotFoundError): mountOutput = ( subprocess.check_output(mountCommand).splitlines() # secok ) @@ -1318,8 +1286,6 @@ break if volumeDirectory: break - except FileNotFoundError: - pass if findAll: return volumeDirectories @@ -1479,9 +1445,8 @@ """ user = getpass.getuser() - if isWindowsPlatform(): - if not user: - return win32_GetUserName() + if isWindowsPlatform() and not user: + return win32_GetUserName() return user @@ -1601,11 +1566,11 @@ line0 = source.splitlines()[0] else: line0 = source[0] - if line0.startswith("#!"): - if "python3" in line0: - pyVer = 3 - elif "python" in line0: - pyVer = 3 + if ( + line0.startswith("#!") and + (("python3" in line0) or ("python" in line0)) + ): + pyVer = 3 if pyVer == 0 and ext in py3Ext: pyVer = 3 @@ -1648,10 +1613,11 @@ found (string or None) """ pattern = "^{0}[ \t]*=".format(key) - if isWindowsPlatform(): - filterRe = re.compile(pattern, re.IGNORECASE) - else: - filterRe = re.compile(pattern) + filterRe = ( + re.compile(pattern, re.IGNORECASE) + if isWindowsPlatform() else + re.compile(pattern) + ) entries = [e for e in QProcess.systemEnvironment() if filterRe.search(e) is not None] @@ -1673,10 +1639,11 @@ @rtype bool """ pattern = "^{0}[ \t]*=".format(key) - if isWindowsPlatform(): - filterRe = re.compile(pattern, re.IGNORECASE) - else: - filterRe = re.compile(pattern) + filterRe = ( + re.compile(pattern, re.IGNORECASE) + if isWindowsPlatform() else + re.compile(pattern) + ) entries = [e for e in QProcess.systemEnvironment() if filterRe.search(e) is not None] @@ -1858,11 +1825,7 @@ proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels) proc.start(interpreter, args) finished = proc.waitForFinished(30000) - if finished: - if proc.exitCode() == 0: - return True - - return False + return finished and proc.exitCode() == 0 ############################################################################### # Other utility functions below @@ -1887,10 +1850,7 @@ except (ImportError, AttributeError): sip_version_str = "sip version not available" - if sys.maxsize > 2**32: - sizeStr = "64-Bit" - else: - sizeStr = "32-Bit" + sizeStr = "64-Bit" if sys.maxsize > 2**32 else "32-Bit" info = ["Version Numbers:"] @@ -1910,13 +1870,11 @@ info.append(" PyQtWebEngine not installed") info.append(" QScintilla {0}".format(QSCINTILLA_VERSION_STR)) info.append(" sip {0}".format(sip_version_str)) - try: + with contextlib.suppress(ImportError): from PyQt5 import QtWebEngineWidgets # __IGNORE_WARNING__ from WebBrowser.Tools import WebBrowserTools chromeVersion = WebBrowserTools.getWebEngineVersions()[0] info.append(" WebEngine {0}".format(chromeVersion)) - except ImportError: - pass info.append(" {0} {1}".format(Program, Version)) info.append("") info.append("Platform: {0}".format(sys.platform)) @@ -1941,7 +1899,7 @@ info = [] app = e5App() if app is not None: - try: + with contextlib.suppress(KeyError): pm = app.getObject("PluginManager") versions = {} for pinfo in pm.getPluginInfos(): @@ -1951,8 +1909,6 @@ for pluginModuleName in sorted(versions.keys()): info.append(" {0} {1}".format( pluginModuleName, versions[pluginModuleName])) - except KeyError: - pass return linesep.join(info) @@ -2022,17 +1978,13 @@ proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels) proc.start(interpreter, args) finished = proc.waitForFinished(30000) - if finished: - if proc.exitCode() == 0: - text = proc.readAllStandardOutput() - sysPathResult = str(text, "utf-8", "replace").strip() - try: - sysPath = json.loads(sysPathResult) - if "" in sysPath: - sysPath.remove("") - except (TypeError, ValueError): - # ignore faulty results and return empty list - pass + if finished and proc.exitCode() == 0: + text = proc.readAllStandardOutput() + sysPathResult = str(text, "utf-8", "replace").strip() + with contextlib.suppress(TypeError, ValueError): + sysPath = json.loads(sysPathResult) + if "" in sysPath: + sysPath.remove("") return sysPath