Jump to content

pyscripter

Members
  • Content Count

    983
  • Joined

  • Last visited

  • Days Won

    62

Everything posted by pyscripter

  1. pyscripter

    How to catch if the object is assigned None

    Not so simple: python - Overriding __setattr__ at runtime - Stack Overflow
  2. pyscripter

    How to catch if the object is assigned None

    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.
  3. pyscripter

    Cancel script execution

    See multithreading - Python threading interrupt sleep - Stack Overflow for alternatives to sleep that can be interrupted.
  4. pyscripter

    TPythonInputOutput separation Python Error

    from io import StringIO import sys old_stderr = sys.stderr sys.stderr = mystderr = StringIO() # examine mystderr.getvalue()
  5. pyscripter

    Get the propt value of input()

    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;
  6. pyscripter

    Get the propt value of input()

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

    Spell Checker implementation?

    Dictionaries are downloaded via Windows Language preferences. You just select the language as in the demo.
  8. pyscripter

    TPythonThread

    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;
  9. pyscripter

    TPythonThread

    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
  10. pyscripter

    TPythonThread

    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).
  11. pyscripter

    Create a property get of 'dict' type

    Yes indeed! P4D makes it quite easy. The TStrings wrapper does that for instance.
  12. pyscripter

    Create a property get of 'dict' type

    See Passing a python object to a delphi function parameter - Python4Delphi - Delphi-PRAXiS [en] (delphipraxis.net)
  13. 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.
  14. 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
  15. pyscripter

    P4D installation error in Delphi 11.3

    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.
  16. 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.
  17. 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.
  18. pyscripter

    Passing more than one argument from Python to Delphi

    It should be 'ii:read_AP_register' if you are expecting two integer arguments.
  19. pyscripter

    Using pyvista in delphi form

    Maybe this approach is useful.
  20. pyscripter

    Documentation on deployment

    See Embarcadero/PythonEnviroments: Components to simplify the deployment for Python environments for Delphi applications using Python4Delphi. (github.com)
  21. pyscripter

    Delphi 11.2 unofficial LSP patch

    Yes.
  22. pyscripter

    Delphi 11.2 unofficial LSP patch

    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.
  23. pyscripter

    I get value=none

    What did you expect to get? Demo03 shows you how to use TPythonDelphiVar.
  24. pyscripter

    How USE Python4Delphi in multithreads

    Use Demo 33 as a guide. As @David Heffernan said running python in threads is not trivial and unlikely to save you time.
  25. 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.
×