Jump to content
Juan C.Cilleruelo

Getting feedback from the execution. As exceptions or in another kind of management.

Recommended Posts

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
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
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
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
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
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
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
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
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
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
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 by pyscripter

Share this post


Link to post
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
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
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

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
37 minutes ago, Juan C.Cilleruelo said:

FPyModule.Initialize;

There is no need for that.  It has already been initialized.

Edited by pyscripter

Share this post


Link to post

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
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
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
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

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 by pyscripter

Share this post


Link to post
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
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
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

Really doesn't work. There is only a game to pass the time.

The things it do does not have sense.  

Edited by Juan C.Cilleruelo

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×