hsauro 40 Posted April 7 I'm using the WrapDelphiClasses unit to construct a Delphi class whose methods than can be called from Python. I have it working without problem for simple types and lists. However, I can't work out how to construct and return a numpy array to the python call. I'm generating data within delphi but I'd like to do some analysis from with Python. I looked at Demo35 and it describes the construction of a numpy array but I am not sure what to return from Delphi. I am currently testing it with this small test case: function ThostAPI.getNumpy : Variant; var np: Variant; arr: Variant; begin np := Import('numpy'); arr := np.array(BuiltinModule.range(10)); result := arr; end; But when I call this from python it returns None. What is the right way to return a numpy array from Delphi? I'm currently using Delphi 11.3 and the python4delphi that came with getit,. I think however there is a newer version which could be the issue as I know some buffer code has been added. Share this post Link to post
hsauro 40 Posted April 8 I updated to the latest 2023 version of delphi4python. It required some changes but it works without issue. The ability to automatically wrap either a class or an instanciated object requires hardly any effort on the Delphi side. I still need to figure out how to return a numpy array from Delphi to python, via a python call at the Python end. Share this post Link to post
pyscripter 689 Posted April 8 (edited) 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; Edited April 8 by pyscripter Share this post Link to post
hsauro 40 Posted April 8 Thanks for the reply. I tried a very simple example to try it out with no arguments, a method that just returns a list of NULLs but I'm getting a runtime error (I also used setitem to fill the list in case that was the problem, but same error). This is the method: function ThostAPI.NewList : PPyObject; begin Result := GetPythonEngine.PyList_New(5); end; and here is the runtime error when using this python code from app import host x = host.NewList () TypeError: Call "NewList" returned a value that could not be converted to Python Error: Unsupported conversion from TValue to Python value I couldn't resolve the issue so I started to use the more low level calls (not using the wrapping unit) and I can return lists and numpy arrays to python. But it would be interesting to know what might be the issue with the above code. The class that contains NewList is just: {$METHODINFO ON} ThostAPI = class (TPersistent) function NewList : PPyObject; end; {$METHODINFO OFF} In the FormCreate I just have: initPython; host := THostAPI.Create (); DelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<THostAPI>).Initialize; DelphiWrapper.DefineVar('host', host); Share this post Link to post
hsauro 40 Posted April 8 (edited) I updated the sources yesterday afternoon. I'll take another look at the repo. I see there are some changes from 9 hours ago. I'll update to see if that helps. Edited April 8 by hsauro Share this post Link to post
hsauro 40 Posted April 8 It works! I can return a numpy array and list easily. Thank you! Share this post Link to post