Jump to content

pyscripter

Members
  • Content Count

    1067
  • Joined

  • Last visited

  • Days Won

    70

Everything posted by pyscripter

  1. pyscripter

    Python4Delphi in a thread

    Dealing with python threads and the Global Interpreter Lock (GIL) is quite tricky. You need to either: Understand and use correctly the python API Initialization, Finalization, and Threads — Python 3.12.3 documentation or Use the high-level encapsulation provided by P4D, following the instructions in https://github.com/pyscripter/python4delphi/wiki/PythonThreads religiously. Otherwise, things can very easily go wrong.
  2. pyscripter

    Python4Delphi in a thread

    Have you followed the instructions?
  3. pyscripter

    Python4Delphi in a thread

    Please do not insert such long pieces of code in your script. You could have added the project as an attachment. Please read the relevant info PythonThreads · pyscripter/python4delphi Wiki (github.com)
  4. pyscripter

    Gutter width in Delphi 12/12.1

    It is almost a show stopper for laptop screens. I wonder why it has not attracted more votes and the attention of Embarcadero.
  5. pyscripter

    Gutter width in Delphi 12/12.1

    Not sure. It looks worse in a high DPI monitor.
  6. pyscripter

    New ChatLLM application.

    The latter.
  7. You don't need to modify WrapDelphi. Just use the latest version. function TValueToPyObject(const Value: TValue; DelphiWrapper: TPyDelphiWrapper; out ErrMsg: string): PPyObject; begin if Value.IsEmpty then Result := GetPythonEngine.ReturnNone else case Value.Kind of tkClass: Result := DelphiWrapper.Wrap(Value.AsObject); tkClassRef: Result := DelphiWrapper.WrapClass(Value.AsClass); tkInterface: Result := DelphiWrapper.WrapInterface(Value); tkRecord{$IFDEF MANAGED_RECORD},tkMRecord{$ENDIF}: Result := DelphiWrapper.WrapRecord(Value); tkArray, tkDynArray: Result := DynArrayToPython(Value, DelphiWrapper, ErrMsg); tkPointer: if Value.IsType<PPyObject> then Result := Value.AsType<PPyObject> else begin Result := nil; ErrMsg := rs_ErrValueToPython; end; else Result := SimpleValueToPython(Value, ErrMsg); end; end;
  8. pyscripter

    LockBox 3 via GetIt broken since April 2024 Update

    Indeed, but Github repo owners can safeguard against that by adding a .gitattributes file.
  9. pyscripter

    LockBox 3 via GetIt broken since April 2024 Update

    This is a common problem with Delphi github repos: https://github.com/JAM-Software/Virtual-TreeView/issues/1151#issuecomment-1332032004 Virtual-TreeView/.gitattributes at master · JAM-Software/Virtual-TreeView (github.com)
  10. In an older post I showed how to patch a virtual/non virtual, public/private method. A recently came across an Vcl bug that requires patching a non-virtual constructor. Does anyone know how to do that?
  11. pyscripter

    How to patch a constructor?

    @Stefan Glienke Thanks. Would you happen know whether you can patch message methods? The only thing I could find is an old article Hallvard's Blog: Hack#15: Overriding message and dynamic methods at run-time (hallvards.blogspot.com).
  12. There have been a lot of questions in this forum about running python code in threads using Python4Delphi. I have created a comprehensive guide in this Wiki topic.
  13. Your taps Variant has not assigned a value. You are missing: taps := MainModule.taps;
  14. pyscripter

    convert native object instance to wrapped instance

    See TPyDelphiWrapper.Wrap(AObj: TObject; AOwnership: TObjectOwnership): PPyObject; Also you do need need your TPyEventFromScript. This is the old and hard way. You can use instead (e.g. in your FormCreate): PyDelphiWrapper1.RegisterDelphiWrapper(TPyClassWrapper<TEventFromScript>).Initialize; Since you are using interfaces there is also: function TPyDelphiWrapper.WrapInterface(const IValue: TValue): PPyObject;
  15. pyscripter

    Running python code in Delphi threads

    @maomao2028 Works fine here without memory leaks. See attached project. Note the use of DelayWrites := True in the PythonGUIInputOutput and the calls to TPythonThread.Py_End_Allow_Threads and TPythonThread.Py_Begin_Allow_Threads. Demo01.zip
  16. pyscripter

    Adding docs strings to wrapped functions

    Forgot to say that unfortunately you cannot just set the __doc__ property of Wrapped classes and methods. It has to be done at the time of wrapping. A trivial implementation of IDocServer would be: uses TypInfo; type TMyDocServer = class(TInterfacedObject, IDocServer) private function ReadTypeDocStr(ATypeInfo: PTypeInfo; out ADocStr: string): Boolean; function ReadMemberDocStr(AMember: TRttiMember; out ADocStr: string): Boolean; procedure Initialize; procedure Finalize; function Initialized: Boolean; end;{ TMyDocServer } procedure TMyDocServer.Finalize; begin end; procedure TMyDocServer.Initialize; begin end; function TMyDocServer.Initialized: Boolean; begin Result := True; end; function TMyDocServer.ReadMemberDocStr(AMember: TRttiMember; out ADocStr: string): Boolean; begin Result := False; if AMember.Name = 'getVersion' then begin Result := True; ADocStr := 'getVersion'; end; end; function TMyDocServer.ReadTypeDocStr(ATypeInfo: PTypeInfo; out ADocStr: string): Boolean; begin Result := False; if ATypeInfo = TypeInfo(ThostAPI ) then begin Result := True; ADocStr := 'ThostAPI doc'; end; end; and then PyDocServer := TMyDocServer.Create; DelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<THostAPI>).Initialize;
  17. pyscripter

    Adding docs strings to wrapped functions

    WrapDelphi defines the following: IDocServer = interface ['{4AF0D319-47E9-4F0A-9C71-97B8CBB559FF}'] function ReadTypeDocStr(ATypeInfo: PTypeInfo; out ADocStr: string): Boolean; function ReadMemberDocStr(AMember: TRttiMember; out ADocStr: string): Boolean; procedure Initialize; procedure Finalize; function Initialized: Boolean; end; var PyDocServer: IDocServer = nil; You need to implement the interface and assign the implemented interface to PyDocServer. PythonDocs.pas provides an implementation based on xml files, which is used by delphivcl and delphifmx. But if, what you are after is to provide docstrings to a few methods, it would be easier to create your own implementation.
  18. System.AnsiStrings.AnsiCompareStr under POSIX converts the ansistrings to UnicodeStrings and then compares. FPC has a function UTF8CompareStr, which sounds promising, but it also converts the ansi strings to UTF-16 and then compares them. Unfortunately it appears that there is no good way to directly compare utf8 strings without converting them. I hope I am wrong.
  19. Unfortunately (see CompareStringA function (winnls.h) - Win32 apps | Microsoft Learn😞 It also appears that System.AnsiStrings.AnsiCompareStr ignores the code page of the ansi strings.
  20. pyscripter

    [help] how to convert delphi TBytes to python Bytes

    Look at PyBytes_AsString, or PyBytes_AsStringAndSize functions. For example if obj is a bytes PPyObject. the following converts it to an AnsiString. AnsiString(PyBytes_AsString(obj)) Also PyObjectAsVariant(obj) converts it to a variant. In the opposite direction to create a bytes object in Delphi use PyBytes_FromStringAndSize
  21. Have you updated to the latest sources?
  22. pyscripter

    C Libraries to Delphi

    This may be worth a look: neslib/Chet: C Header Translator for Delphi (github.com). From @Erik@Grijjy
  23. WrapDelphi was designed to expose Delphi classes, records and interfaces to python. So it did not handle PPyObject parameters or return values. You could handle that by using the low-level approach (adding an Event to TPythonModule). However, I have now added to WrapDelphi support for exposing functions with parameters and/or results of type PPyObject. See WrapDelphiTest.pas in the latest version of the pyscripter/python4delphi: Free components that wrap up Python into Delphi and Lazarus (FPC) (github.com) repo. Example: Exposed Method: function TTestRttiAccess.PlaceInNewList(PyObj: PPyObject): PPyObject; begin with GetPythonEngine do begin Result := PyList_New(1); Py_XIncRef(PyObj); PyList_SetItem(Result, 0, PyObj); end; end; Usage in python from delphi import rtti_var list = rtti_var.PlaceInNewList('abc') The corresponding test in WrapDelphiTest: procedure TTestWrapDelphi.TestPPyObjects; var List: Variant; begin List := rtti_var.PlaceInNewList('abc'); Assert.IsTrue(VarIsPythonList(List)); Assert.AreEqual<string>(List.GetItem(0), 'abc'); end;
  24. Does anybody know whether the workaround mentioned by @Uwe Raabe in Parnassus Bookmarks issue - again. - Delphi IDE and APIs - Delphi-PRAXiS [en] (delphipraxis.net) is still needed in Delphi 12.1?
  25. Under Tools, Options, Language, Delphi, Library, I see a new platform in the drop-down list "Selected platform" called "Windows 64 bits (Modern)". This is in addition to "Windows 64 bits". There was no mention of it in today's seminar. Anyone knows what it is and how to use it?
×