class TestPython(object): def __init__(self, ID=None): self.Test = QProcess() self.ID = ID #a and b to test if i get a output or command error self.a = True self.Settings = QtCore.QSettings('Tyrant.cfg', QtCore.QSettings.IniFormat) def TestVersion(self): print('Test python version') self.Test.readyReadStandardError.connect(self.getOutput) self.Test.readyReadStandardOutput.connect(self.getOutput) if self.ID is not None: self.Test.error.connect(self.Error) #if i have a custom pythonpath, i'll use it here Res = Resources() Python = Res.getPref('Python') #test if is a pythonpath, if not open a default if len(Python) < 5: Python = 'python' self.Test.start(Python, ['-V']) self.Test.waitForFinished() self.Test.terminate() if (self.a is False) & (self.ID is None): #test a diferent command to run python 2.7 a = self.TestVersion2() print a return a elif self.a: #say to program that python is working print('Python version found') self.Settings.setValue('Python/PythonPath', str(Python)) self.Settings.sync() return True elif ((self.ID is not None) & (self.a is False)): return False def Error(self): self.a = False def TestVersion2(self): print('Testing python version 2') self.Test.readyReadStandardError.connect(self.getOutput) Python = 'python2.7' self.Test.start(Python, ['-V']) self.Test.waitForStarted() self.Test.waitForFinished() self.Test.terminate() if (self.a is False): #say thar python is not working return False else: self.Settings.setValue('Python/PythonPath', str(Python)) self.Settings.sync() return True def getOutput(self): Out = str(self.Test.readAllStandardError()) print(Out) if Out > 'Python 2.8': self.a = False return self.a = True
class CfdConsoleProcess: """ Class to run a console process asynchronously, printing output and errors to the FreeCAD console and allowing clean termination in Linux and Windows """ def __init__(self, finishedHook=None, stdoutHook=None, stderrHook=None): self.process = QProcess() self.finishedHook = finishedHook self.stdoutHook = stdoutHook self.stderrHook = stderrHook self.process.finished.connect(self.finished) self.process.readyReadStandardOutput.connect(self.readStdout) self.process.readyReadStandardError.connect(self.readStderr) self.print_next_error_lines = 0 self.print_next_error_file = False def __del__(self): self.terminate() def start(self, cmd, env_vars=None, working_dir=None): """ Start process and return immediately """ self.print_next_error_lines = 0 self.print_next_error_file = False env = QtCore.QProcessEnvironment.systemEnvironment() if env_vars: for key in env_vars: env.insert(key, env_vars[key]) self.process.setProcessEnvironment(env) if working_dir: self.process.setWorkingDirectory(working_dir) if platform.system() == "Windows": # Run through a wrapper process to allow clean termination cmd = [ os.path.join(FreeCAD.getHomePath(), "bin", "python.exe"), '-u', # Prevent python from buffering stdout os.path.join(os.path.dirname(__file__), "WindowsRunWrapper.py") ] + cmd print("Raw command: ", cmd) self.process.start(cmd[0], cmd[1:]) def terminate(self): if platform.system() == "Windows": # terminate() doesn't operate and kill() doesn't allow cleanup and leaves mpi processes running # Instead, instruct wrapper program to kill child process and itself cleanly with ctrl-break signal self.process.write(b"terminate\n") self.process.waitForBytesWritten() # 'flush' else: self.process.terminate() self.process.waitForFinished() def finished(self, exit_code): if self.finishedHook: self.finishedHook(exit_code) def readStdout(self): # Ensure only complete lines are passed on text = "" while self.process.canReadLine(): byteArr = self.process.readLine() text += QTextStream(byteArr).readAll() if text: print(text, end='') # Avoid displaying on FreeCAD status bar if self.stdoutHook: self.stdoutHook(text) # Must be at the end as it can cause re-entrance if FreeCAD.GuiUp: FreeCAD.Gui.updateGui() def readStderr(self): # Ensure only complete lines are passed on # Print any error output to console self.process.setReadChannel(QProcess.StandardError) text = "" while self.process.canReadLine(): byteArr = self.process.readLine() text += QTextStream(byteArr).readAll() if text: if self.stderrHook: self.stderrHook(text) FreeCAD.Console.PrintError(text) # Must be at the end as it can cause re-entrance if FreeCAD.GuiUp: FreeCAD.Gui.updateGui() self.process.setReadChannel(QProcess.StandardOutput) def state(self): return self.process.state() def waitForStarted(self): return self.process.waitForStarted() def waitForFinished(self): # For some reason waitForFinished doesn't always return - so we resort to a failsafe timeout: while True: ret = self.process.waitForFinished(1000) if self.process.error() != self.process.Timedout: self.readStdout() self.readStderr() return ret if self.process.state() == self.process.NotRunning: self.readStdout() self.readStderr() return True def exitCode(self): return self.process.exitCode() def processErrorOutput(self, err): """ Process standard error text output from OpenFOAM :param err: Standard error output, single or multiple lines :return: A message to be printed on console, or None """ ret = "" errlines = err.split('\n') for errline in errlines: if len(errline) > 0: # Ignore blanks if self.print_next_error_lines > 0: ret += errline + "\n" self.print_next_error_lines -= 1 if self.print_next_error_file and "file:" in errline: ret += errline + "\n" self.print_next_error_file = False words = errline.split(' ', 1) # Split off first field for parallel FATAL = "--> FOAM FATAL ERROR" FATALIO = "--> FOAM FATAL IO ERROR" if errline.startswith(FATAL) or (len(words) > 1 and words[1].startswith(FATAL)): self.print_next_error_lines = 1 ret += "OpenFOAM fatal error:\n" elif errline.startswith(FATALIO) or ( len(words) > 1 and words[1].startswith(FATALIO)): self.print_next_error_lines = 1 self.print_next_error_file = True ret += "OpenFOAM IO error:\n" if len(ret) > 0: return ret else: return None
def parse_asn1(*files, **options): """ Call the ASN.1 parser on a number of files, and return the module containing the AST This function uses QProcess to launch the ASN.1 compiler because the subprocess module from Python has issues on the Windows platform """ global AST ast_version = options.get("ast_version", ASN1.UniqueEnumeratedNames) rename_policy = options.get("rename_policy", ASN1.NoRename) flags = options.get("flags", [ASN1.AstOnly]) assert isinstance(ast_version, ASN1) assert isinstance(rename_policy, ASN1) assert isinstance(flags, list) # if os.name == 'posix' and hasattr(sys, 'frozen'): # Frozen Linux binaries are expected to use the frozen ASN.1 compiler # No: there are issues with freezing the .NET applications - discard # asn1exe = 'asn1scc' # else: # asn1exe = 'asn1.exe' path_to_asn1scc = spawn.find_executable("asn1.exe") if not path_to_asn1scc: raise TypeError("ASN.1 Compiler not found in path") if os.name == "posix": path_to_mono = spawn.find_executable("mono") if not path_to_mono: raise TypeErorr('"mono" not found in path. Please install it.') binary = path_to_mono arg0 = path_to_asn1scc else: binary = path_to_asn1scc arg0 = "" asn1scc_root = os.path.abspath(os.path.dirname(path_to_asn1scc)) # Create a temporary directory to store dataview.py and import it tempdir = tempfile.mkdtemp() sys.path.append(tempdir) if os.name == "nt": # On windows, remove the drive letter, workaround to ASN1SCC bug tempdir = tempdir[2:] asn1scc_root = asn1scc_root[2:] filename = str(uuid.uuid4()).replace("-", "_") filepath = tempdir + os.sep + filename + ".py" stg = asn1scc_root + os.sep + "python.stg" args = [ arg0, "-customStgAstVerion", str(ast_version.value), "-customStg", stg + "::" + filepath, "-renamePolicy", str(rename_policy.value), ] + list(*files) asn1scc = QProcess() LOG.debug(os.getcwd()) LOG.debug(binary + " " + " ".join(args)) asn1scc.start(binary, args) if not asn1scc.waitForStarted(): raise TypeError("Could not start ASN.1 Compiler") if not asn1scc.waitForFinished(): raise TypeError("Execution of ASN.1 Compiler timed out") exitcode = asn1scc.exitCode() result = asn1scc.readAllStandardError() if exitcode != 0: raise TypeError("ASN.1 Compiler Error (exit code = {}) - {}".format(exitcode, str(result))) else: if filename in AST.viewkeys(): # Re-import module if it was already loaded ast = AST[filename] reload(ast) else: ast = importlib.import_module(filename) AST[filename] = ast return ast