-
Content Count
983 -
Joined
-
Last visited
-
Days Won
62
Everything posted by pyscripter
-
Not so simple: python - Overriding __setattr__ at runtime - Stack Overflow
-
function TPyPoint.SetAttr(key : PAnsiChar; value : PPyObject) : Integer is called whenever a property is set (e.g. spam.myPoint.x = 10). So you can take an action when the object is modified. However you are not notified when spam.myPoint is assigned a value. To do what you would have to override the __setattr__ on the module, but this is too complicated.
-
See multithreading - Python threading interrupt sleep - Stack Overflow for alternatives to sleep that can be interrupted.
-
from io import StringIO import sys old_stderr = sys.stderr sys.stderr = mystderr = StringIO() # examine mystderr.getvalue()
-
I wrote the code without testing, just to give you the idea. Good that you solved the problem. Also instead of MainModule.builtins._input_prompt you can use BuiltinModule._input_prompt. And the following would do. No need to convert to AnsiString and back. procedure TForm1.PythonInputOutput1ReceiveUniData(Sender: TObject; var Data: string); begin InputQuery( 'Query from Python', BuiltinModule._input_prompt, Data); end;
-
Run a script like this: import builtins def myinput(prompt): builtins._input_prompt = prompt builtins._input(prompt) builtins._input = builtins.input builtins.input = myinput Then the prompt will be stored in builtins._input_prompt
-
Dictionaries are downloaded via Windows Language preferences. You just select the language as in the demo.
-
The KeyboardInterrupt is the correct way to terminate a thread from the main thread. This is because print statement executes without clearing the KeyboardInterrupt exception. You need to trap the KeyboardInterrupt exception either in Python or Delphi code. You can also add to your PythonInputOutput1SendUniData with GetPythonEngine do if PyErr_Occurred <> nil then begin PyErr_Clear; Exit; end;
-
How are you exiting the thread? Are you raising a KeyboardInterrupt as in demo 33? Then why are you surprised that an exception is raised, when the print statement executes. You can modify your script as follows (not tested): while True: try: time.sleep(0.1) print(datetime.now()) except KeyboardInterrupt: break or handle the exception in your Delphi code
-
You are producing output at a high speed from a thread. You need to buffer the output in a way similar to that in python4delphi/Unit1.pas at master · pyscripter/python4delphi (github.com).
-
Yes indeed! P4D makes it quite easy. The TStrings wrapper does that for instance.
-
See Passing a python object to a delphi function parameter - Python4Delphi - Delphi-PRAXiS [en] (delphipraxis.net)
-
Passing a python object to a delphi function parameter
pyscripter replied to iqrf's topic in Python4Delphi
No. You should try to understand the rules behind reference counting. (e.g. Reference Counting in Python (tripod.com)) Note that PyBytes_FromStringAndSize returns a new reference, so there is no need to increment the count. Adjust(Self) is needed when you need to access the Delphi object properties or methods. -
Passing a python object to a delphi function parameter
pyscripter replied to iqrf's topic in Python4Delphi
On the Delphi side you can use PyArg_ParseTuple to get the pointer to the python object. Then you can either: use the python API to call the desired method on the python object or wrap the python object into a custom variant (VarPythonCreate in the VarPyth unit) and call the method in a high-level way. See tutorials and demos on VarPyth for details -
P4D installation error in Delphi 11.3
pyscripter replied to Alexander-R-Bio's topic in Python4Delphi
Try the sources in pyscripter/python4delphi: Free components that wrap up Python into Delphi and Lazarus (FPC) (github.com) and follow the installation instructions. You should report the GetIt issue to the fork Embarcadero/python4delphi: Fork of P4D adding FireMonkey wrapper and Android support (github.com) which is used to create the GetIt package. -
Best Practice Question: Bidirectional EXE-to-EXE communication
pyscripter replied to Alexander Halser's topic in RTL and Delphi Object Pascal
The IPC unit based on named pipes created by Russell Libby in 2003 and updated by @FPiette is worth checking. Blog article: Behind the connection: Inter Process Communication Using Pipes (francois-piette.blogspot.com) Source code: OverByte - Blog Source Code Named pipes in overlapped mode are super efficient and faster than sockets. See Synchronous and Overlapped Pipe I/O - Win32 apps | Microsoft Learn. See also I/O Completion Ports - Win32 apps | Microsoft Learn. I have contributed such a solution to the python library RPyC and it beats the socket based IPC by a large margin. The downside is that it is Windows only. -
In case this of use to anyone: Quite often you find a bug in Delphi RTL and you come up with a fix. Patching involves replacing the RTL procedure with a new patched one. To do that you can use your favorite patching routine or library (I use Detours), but you need the address of the original function/method. a) Patching a non-virtual public method This is quite straight-forward: type TMethodType = procedure ... of object function GetAddress: Pointer; var MethodPtr : TMethodType; begin MethodPtr := TRTLClass(nil).PublicMethod; Result := TMethod(MethodPtr).Code; end; Note the type cast TRTLClass(nil). b) Patching a virtual public method If for example PublicMethod is virtual the above type cast TRTLClass(nil) with result in access violation, since to resolve the virtual method you need to access Self which is nil. You could create a class instance and use that instead of TRTLClass(nil), but apart from not being elegant, in some cases this has side-effects (for example it may require a valid windows handle). The trick is described in this Stackoverflow question. function GetAddress: Pointer; var VMT : NativeInt; MethodPtr: TMethodType; begin VMT := NativeInt(TRTLClass); MethodPtr := TRTLClass(@VMT).PublicMethod; Result := TMethod(MethodPtr).Code; end; This is based on two facts. A class is a pointer to the Virtual Method table (VMT) and an Object structure has as the first field a pointer to the VMT of its class. c) Patching a private virtual method The trick this time involves using a class helper to access the private method of the TRTLClass type TPrivateMethodType = procedure ... of object; TRTLClassHookFix = class helper for TRTLCLass function GetPriveMethodAddr: Pointer; end; function TRTLClassHookFix.GetPriveMethodAddr: Pointer; var VMT : NativeInt; MethodPtr: TPrivateMethodType; begin // Adjust Self to point to the VMT VMT := NativeInt(TRTLCLass); Self := TRTLCLass(@VMT); with Self do MethodPtr := PrivateMethod; Result := TMethod(MethodPtr).Code; end; That's it.
-
Passing more than one argument from Python to Delphi
pyscripter replied to IJCdelpi's topic in Python4Delphi
It should be 'ii:read_AP_register' if you are expecting two integer arguments. -
Maybe this approach is useful.
- 2 replies
-
- pyvista
- datavisualization
-
(and 1 more)
Tagged with:
-
See Embarcadero/PythonEnviroments: Components to simplify the deployment for Python environments for Delphi applications using Python4Delphi. (github.com)
-
Delphi 11.2 unofficial LSP patch
pyscripter replied to Brandon Staggs's topic in Delphi IDE and APIs
Yes. -
Delphi 11.2 unofficial LSP patch
pyscripter replied to Brandon Staggs's topic in Delphi IDE and APIs
FWIW, I have tried the unofficial LSP patches and I could no longer debug programs. So I went back to the original dlls and debugging was available again. -
What did you expect to get? Demo03 shows you how to use TPythonDelphiVar.
-
Use Demo 33 as a guide. As @David Heffernan said running python in threads is not trivial and unlikely to save you time.
-
Getting feedback from the execution. As exceptions or in another kind of management.
pyscripter replied to Juan C.Cilleruelo's topic in Python4Delphi
FPyModule.Name := '__main__'; meeds to be FPyModule.ModuleName := '__main__'; Better to call your module something else (delphimodule or anything else. in the demos 'spam' is used) and import that module.