@@ -1902,7 +1902,8 @@ TPythonEngine = class(TPythonInterface)
19021902 procedure AddClient ( client : TEngineClient );
19031903 procedure RemoveClient ( client : TEngineClient );
19041904 function FindClient ( const aName : string ) : TEngineClient;
1905- function FindPythonType ( const TypeName : AnsiString ) : TPythonType;
1905+ function FindPythonType (const TypeName : AnsiString): TPythonType; overload;
1906+ function FindPythonType (PyType: PPyTypeObject): TPythonType; overload;
19061907 function TypeByName ( const aTypeName : AnsiString ) : PPyTypeObject;
19071908 function ModuleByName ( const aModuleName : AnsiString ) : PPyObject;
19081909 function MethodsByName ( const aMethodsContainer: string ) : PPyMethodDef;
@@ -2362,6 +2363,20 @@ TPythonModule = class(TMethodsContainer)
23622363 - When turning a Delphi instance into a Python object pointer, GetSelf will offset
23632364 Self from B to A.
23642365 - Properties ob_refcnt and ob_type will call GetSelf to access their data.
2366+
2367+ Further Notes:
2368+ - PyObject instances are not created directly, but via their python type
2369+ See TPythonType.CreateInstance and TPythonType.NewSubtypeInst (tp_new
2370+ slot). In the second case TPy_Object.NewInstance is not called and
2371+ the size of the memory is determined by the tp_basicsize slot.
2372+ - Their memory can be allocated either by pascal or python. PythonAlloc
2373+ keeps track of how the PyObject memory was allocated.
2374+ - PyObject instances are not destroyed directly, but by PyObjectDestructor
2375+ when their reference count goes down to zero (tp_dealloc slot)
2376+ - The value of PythonAlloc determines how the memory is freed
2377+ using either PyObject_Free (tp_free slot) or in the overwritten
2378+ FreeInstance.
2379+ - This class is heart of the P4D library. Pure magic!!
23652380}
23662381 // The base class of all new Python types
23672382 TPyObject = class
@@ -2767,7 +2782,6 @@ function PythonOK : Boolean;
27672782function PythonToDelphi ( obj : PPyObject ) : TPyObject;
27682783function IsDelphiObject ( obj : PPyObject ) : Boolean;
27692784procedure PyObjectDestructor ( pSelf : PPyObject); cdecl;
2770- procedure FreeSubtypeInst (ob:PPyObject); cdecl;
27712785procedure Register ;
27722786function PyType_HasFeature (AType : PPyTypeObject; AFlag : Integer) : Boolean;
27732787function SysVersionFromDLLName (const DLLFileName : string): string;
@@ -6139,6 +6153,19 @@ function TPythonEngine.FindPythonType(const TypeName: AnsiString): TPythonType;
61396153 end ;
61406154end ;
61416155
6156+ function TPythonEngine.FindPythonType (PyType: PPyTypeObject): TPythonType;
6157+ var
6158+ I : Integer;
6159+ begin
6160+ Result := nil ;
6161+ for I := 0 to ClientCount - 1 do
6162+ if (Clients[I] is TPythonType) and (TPythonType(Clients[I]).TheTypePtr = PyType) then
6163+ begin
6164+ Result := TPythonType(Clients[I]);
6165+ Break;
6166+ end ;
6167+ end ;
6168+
61426169function TPythonEngine.FindFunction (const ModuleName,FuncName: AnsiString): PPyObject;
61436170var
61446171 module ,func: PPyObject;
@@ -8178,6 +8205,9 @@ function TPythonType.NewSubtypeInst( aType: PPyTypeObject; args, kwds : PPyObje
81788205var
81798206 obj : TPyObject;
81808207begin
8208+ // Allocate memory in the python heap for both the pascal and the python
8209+ // PyObject (see tp_basicsize in SetPyObjectClass)
8210+ // nitems = 0 because PyType_GenericAlloc adds +1
81818211 Result := aType^.tp_alloc(aType, 0 );
81828212 if Assigned(Result) then
81838213 begin
@@ -8191,21 +8221,11 @@ function TPythonType.NewSubtypeInst( aType: PPyTypeObject; args, kwds : PPyObje
81918221 begin
81928222 Engine.Py_DECREF(Result);
81938223 Result := nil ;
8224+ obj.Free;
81948225 end ;
81958226 end ;
81968227end ;
81978228
8198- function TPythonType_AllocSubtypeInst ( pSelf: PPyTypeObject; nitems : NativeInt) : PPyObject; cdecl;
8199- begin
8200- Result := GetPythonEngine.PyType_GenericAlloc(pSelf, nitems);
8201- end ;
8202-
8203- procedure FreeSubtypeInst (ob:PPyObject);
8204- begin
8205- GetPythonEngine.PyObject_Free(ob);
8206- end ;
8207-
8208-
82098229// Number services
82108230
82118231function TPythonType_NbAdd ( pSelf, obj : PPyObject) : PPyObject; cdecl;
@@ -8484,9 +8504,9 @@ procedure TPythonType.InitServices;
84848504 if tpfBaseType in TypeFlags then
84858505 begin
84868506 tp_init := TPythonType_InitSubtype;
8487- tp_alloc := TPythonType_AllocSubtypeInst ;
8507+ tp_alloc := FEngine.PyType_GenericAlloc ;
84888508 tp_new := GetCallBack( Self, @TPythonType.NewSubtypeInst, 3 , DEFAULT_CALLBACK_TYPE);
8489- tp_free := FreeSubtypeInst ;
8509+ tp_free := FEngine.PyObject_Free ;
84908510 tp_methods := MethodsData;
84918511 tp_members := MembersData;
84928512 tp_getset := GetSetData;
0 commit comments