Juan C.Cilleruelo 12 Posted January 6, 2023 I've seen the EvalScript method and the ExecuteScript method of the TPythonEngine component. I need to get from Delphi, some feedback about any problem executing the Python Script. The type of error, the line, the column where start the problem, etc. Does someone have an example of this? Please, avoid generic responses or responses not related. Thank's all. Share this post Link to post
KoRiF 1 Posted January 11, 2023 On 1/6/2023 at 1:56 PM, Juan C.Cilleruelo said: I've seen the EvalScript method and the ExecuteScript method of the TPythonEngine component. I need to get from Delphi, some feedback about any problem executing the Python Script. The type of error, the line, the column where start the problem, etc. As far as I understand your question, you just need get access to the Python error output, this is usual situation: https://github.com/pyscripter/python4delphi/blob/master/Demos/Demo01/Unit1.dfm#L119 Share this post Link to post
Juan C.Cilleruelo 12 Posted January 12, 2023 13 hours ago, KoRiF said: As far as I understand your question, you just need get access to the Python error output, this is usual situation: https://github.com/pyscripter/python4delphi/blob/master/Demos/Demo01/Unit1.dfm#L119 Thank you!!! That is better than what I'm looking for. I was looking for an example of exception management. Still, this solution is better because it allows the final user to generate error messages inside the Python code that can return to the application. I'm going to investigate this line. The type of scripts I expect that the final user write doesn't need any returned message. Because of this, I can consider any message the final user includes as a warning of an error message. Great. Thanks. Now I need to embed this functionality in an on-the-fly component. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 On 1/11/2023 at 7:30 PM, KoRiF said: As far as I understand your question, you just need get access to the Python error output, this is usual situation: https://github.com/pyscripter/python4delphi/blob/master/Demos/Demo01/Unit1.dfm#L119 Unfortunately, this solution doesn't work well when you don't use visual components. I need to recover the error messages in a TStringList instance and if there are not empty, translate them to the user, probably in a log file. The first thing is to create the TMemo programmatically without a visual parent, but this doesn't work in the current version of VCL. TMemo visual component needs a Parent to allow add strings in his Lines (TStringList) property, raising an exception if you make this without the Parent assigned. https://quality.embarcadero.com/browse/RSP-40383 I will try to solve this without this visual component. Share this post Link to post
Fr0sT.Brutal 900 Posted January 13, 2023 46 minutes ago, Juan C.Cilleruelo said: I need to recover the error messages in a TStringList instance and if there are not empty, translate them to the user, probably in a log file. If there's TPythonGUIInputOutput , I guess there must be TPythonSomethingElseInputOutput Share this post Link to post
Lajos Juhász 293 Posted January 13, 2023 5 minutes ago, Fr0sT.Brutal said: If there's TPythonGUIInputOutput , I guess there must be TPythonSomethingElseInputOutput It's TPythonInputOutput as the property is definied: property IO: TPythonInputOutput read FIO write SetIO; Share this post Link to post
Fr0sT.Brutal 900 Posted January 13, 2023 2 hours ago, Lajos Juhász said: It's TPythonInputOutput as the property is definied: property IO: TPythonInputOutput read FIO write SetIO; so - ? Share this post Link to post
pyscripter 689 Posted January 13, 2023 9 minutes ago, Fr0sT.Brutal said: so - ? You can use TPythonInputOutput event handlers to log python output to file or produce output in a console application. Share this post Link to post
Fr0sT.Brutal 900 Posted January 13, 2023 16 minutes ago, pyscripter said: You can use TPythonInputOutput event handlers to log python output to file or produce output in a console application. That's exactly I was giving a hint at. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 1 hour ago, pyscripter said: You can use TPythonInputOutput event handlers to log python output to file or produce output in a console application. I'm creating TPythonInputOutput on the fly, with visual components. procedure TForm1.FormCreate(Sender: TObject); var p :PPyObject; begin FOutput := TStringList.Create; FPythonIO := TPythonInputOutput.Create(Self); FPythonIO.UnicodeIO := True; FPythonIO.RawOutput := False; FPythonIO.OnSendUniData := OnSendUniData; {$IFDEF VISUAL_COMPONENTS} PyEngine.LoadDll; p := PyEngine.PyLong_FromLong(1); PyModule.SetVar('QUANTITY', p); PyEngine.Py_DecRef(p); PyEngine.IO := FPythonIO; {$ELSE} With the next code in OnSendUniData EventHandler: FOutput.Add(PChar(Data)); And this code in the Button Execute On Click Event Handler: PyEngine.CheckError(); PyEngine.ExecStrings(Memo1.Lines); if FOutput.Count > 0 then begin Memo2.Lines.Assign(FOutput); end; And I always get FOutput.Count = 0. It seems the ExecStrings(Memo1.Lines) don't work well with on the fly created TPythonInputOutput component. I Include the complete code. Demo on Fly.zip Share this post Link to post
pyscripter 689 Posted January 13, 2023 (edited) 10 minutes ago, Juan C.Cilleruelo said: PyEngine.LoadDll; p := PyEngine.PyLong_FromLong(1); PyModule.SetVar('QUANTITY', p); PyEngine.Py_DecRef(p); PyEngine.IO := FPythonIO; Set PyEngine.IO before you call LoadDLL Redirection is setup by TPythonEngine.Initialize, which is called by LoadDLL. Edited January 13, 2023 by pyscripter Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 24 minutes ago, pyscripter said: Set PyEngine.IO before you call LoadDLL Redirection is setup by TPythonEngine.Initialize, which is called by LoadDLL. Ok. The version with Visual components works with this order of lines: ... {$IFDEF VISUAL_COMPONENTS} PyEngine.IO := FPythonIO; PyEngine.LoadDll; p := PyEngine.PyLong_FromLong(1); PyModule.SetVar('QUANTITY', p); PyEngine.Py_DecRef(p); {$ELSE} ... I'm still fighting with the version of non-visual components. If you want try it, I'm going to thank you. Share this post Link to post
pyscripter 689 Posted January 13, 2023 17 minutes ago, Juan C.Cilleruelo said: I'm still fighting with the version of non-visual components. Create and link all non-visual components before you call LoadDLL. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 2 hours ago, pyscripter said: Create and link all non-visual components before you call LoadDLL. This is not the solution to all the problems. This is the more accurate form of doing it. Don't work!!!!! var p :PPyObject; begin FOutput := TStringList.Create; FPythonIO := TPythonInputOutput.Create(Self); FPythonIO.UnicodeIO := True; FPythonIO.RawOutput := False; FPythonIO.OnSendUniData := OnSendUniData; FPyEngine := TPythonEngine.Create(nil); FPyEngine.AutoLoad := False; FPyEngine.DllName := 'python311.dll'; FPyEngine.DllPath := 'C:\Views\senCille\bin\Win64\Python'; FPyEngine.APIVersion := 1013; FPyEngine.RegVersion := '3.11'; FPyEngine.UseLastKnownVersion := False; FPyEngine.OnBeforeLoad := PyEngineBeforeLoad; FPyEngine.InitScript.Add('import sys' ); FPyEngine.InitScript.Add('print ("Python Dll: ", sys.version)'); FPyEngine.InitScript.Add('print (sys.copyright)' ); FPyEngine.InitScript.Add('print' ); FPyEngine.IO := FPythonIO; FPyModule := TPythonModule.Create(nil); FPyModule.Engine := FPyEngine; FPyModule.Name := '__main__'; FPyModule.OnInitialization := PyModuleInitialization; FPyEngine.LoadDll; FPyModule.Initialize; p := FPyEngine.PyLong_FromLong(1); FPyModule.SetVar('QUANTITY', p); FPyEngine.Py_DecRef(p); +++++++ I can't load DLL after PyModule creation or link because I get an error calling Initialize; The script admits the declaration of variables or functions but doesn't recognize either when I run the script. I'm sure it is a problem with the components. I'm investigating it. It probably is creating the variables and the modules in a missing module or something like this. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 This is the form in which I execute the code: FPyEngine.CheckError(); FPyEngine.ExecStrings(Memo1.Lines); And is curious because CheckError() does not report any problem, but ExecStrings says that the functions or variables inserted don't exist. Share this post Link to post
pyscripter 689 Posted January 13, 2023 (edited) 37 minutes ago, Juan C.Cilleruelo said: FPyModule.Initialize; There is no need for that. It has already been initialized. Edited January 13, 2023 by pyscripter Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 I just changed ExecStrings(Memo1.Lines) to EvalStrings(Memo1.Lines) and... Now it says directly, syntax error on the first line, do not know the meaning of "import sys" Share this post Link to post
pyscripter 689 Posted January 13, 2023 38 minutes ago, Juan C.Cilleruelo said: FPyModule.Name := '__main__'; Also do not call the module __main__. This is name is reserved for the main python module. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 2 minutes ago, pyscripter said: There is no need for that. I've removed it. All continue in the same form. Do not know the function ComponentCount nor the variable QUANTITY. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 Just now, pyscripter said: Also do not call the module __main__. This is name is reserved for the main python module. Yes, but that is where I want to declare the functions and the variables. I've seen a lot of examples that do this. I don't want to include my members in another module. Anyway, with the version of the visual component works very well with the __main__ module. Share this post Link to post
pyscripter 689 Posted January 13, 2023 (edited) Call you delphi module say "delphimodule" and in your script: import delphimodule print(delphimodule.QUANTITY); or from delphimodule import QUANTITY print(QUANTITY) Please look at the demos, before asking questions here and do yourself a favour. Do watch the two video tutorials. It is only two hours viewing and will save you masses of time if you plan to do any serious work with P4D. Edited January 13, 2023 by pyscripter Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 Just now, pyscripter said: Call you delphi modue say "delphimodule" and in your script: import delphimodule print(delphimodule.QUANTITY); Please look at the demos, before asking questions here. Why do they work when I use visual components? Why can't I use functions and variables created in the __main__ module? What is the matter? Why do I need to create different scripts if I create the components visually than if I create them on the fly? All of this is absurd, true? I've read all the demos and a lot of demos on the web. Of course. I'm going to try this, but this doesn't solve the fact of the different behavior with visual and no visual form of creating the components. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 9 minutes ago, pyscripter said: Call you delphi modue say "delphimodule" and in your script: import delphimodule print(delphimodule.QUANTITY); Please look at the demos, before asking questions here. Can you please download the included example and try to run it? I beg. Is not a failure of my code. It is a failure of the behavior of the components. If you try it and I'm not in the truth. I will recognize that the components are working well. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 11 minutes ago, pyscripter said: Please look at the demos, before asking questions here and do yourself a favour. Do watch the two video tutorials. It is only two hours viewing and will save you masses of time if you plan to do any serious work with P4D. After visualizing all the video tutorials, seeing the demos, and seeing what kind of support the components have, I'm seriously thinking of abandoning this line of investigation. I see these components are still very, very, very, very green. Share this post Link to post
Juan C.Cilleruelo 12 Posted January 13, 2023 (edited) Really doesn't work. There is only a game to pass the time. The things it do does not have sense. Edited January 13, 2023 by Juan C.Cilleruelo Share this post Link to post