@@ -588,6 +588,11 @@ TPyDelphiObject = class (TPyInterfacedObject, IFreeNotificationSubscriber)
588588 function SqItem ( idx : NativeInt ) : PPyObject; override;
589589 function SqContains ( obj: PPyObject): integer; override;
590590 function SqAssItem ( idx : NativeInt; obj : PPyObject) : Integer; override;
591+ // Mapping services
592+ { $IFDEF EXTENDED_RTTI}
593+ function MpSubscript (obj: PPyObject) : PPyObject; override;
594+ function MpAssSubscript (obj1, obj2: PPyObject) : Integer; override;
595+ { $ENDIF EXTENDED_RTTI}
591596
592597 class function DelphiObjectClass : TClass; virtual ;
593598 class procedure RegisterMethods ( PythonType : TPythonType ); override;
@@ -3904,8 +3909,6 @@ class procedure TPyDelphiObject.ExposeIndexedProperties(AClass: TClass;
39043909 LClass: TClass;
39053910 LDocStr: string;
39063911begin
3907- // TODO: Identify and handle the default property
3908-
39093912 LRttiCtx := TRttiContext.Create();
39103913 try
39113914 LRttiType := LRttiCtx.GetType(AClass) as TRttiStructuredType;
@@ -3965,12 +3968,94 @@ class procedure TPyDelphiObject.ExposeIndexedProperties(AClass: TClass;
39653968 nil ,
39663969 PAnsiChar(LExposedProperty.DocString),
39673970 nil );
3971+
3972+ // Store the default property in the type
3973+ if LRttiProperty.IsDefault and (APythonType.Tag = 0 ) then
3974+ begin
3975+ APythonType.Tag := NativeInt(LRttiProperty);
3976+ if LRttiProperty.IsWritable then
3977+ APythonType.Services.Mapping := [msSubscript, msAssSubscript]
3978+ else
3979+ APythonType.Services.Mapping := [msSubscript];
3980+ end ;
39683981 end ;
39693982 finally
39703983 LRttiCtx.Free;
39713984 end ;
39723985end ;
39733986
3987+ function TPyDelphiObject.MpSubscript (obj: PPyObject) : PPyObject;
3988+ var
3989+ PyArgs: PPyObject;
3990+ Prop: TRttiIndexedProperty;
3991+ begin
3992+ Assert(PythonType.Tag <> 0 );
3993+ Prop := TRttiIndexedProperty(PythonType.Tag);
3994+
3995+ // obj is a tuple only if we have more than one arguments
3996+ if PyDelphiWrapper.Engine.PyTuple_Check(obj) then
3997+ PyArgs := obj
3998+ else
3999+ PyArgs := PyDelphiWrapper.Engine.MakePyTuple([obj]);
4000+
4001+ Result := RttiCall(DelphiObject, PyDelphiWrapper, Prop.ReadMethod,
4002+ PyArgs, nil );
4003+
4004+ if not PyDelphiWrapper.Engine.PyTuple_Check(obj) then
4005+ PyDelphiWrapper.Engine.Py_DECREF(PyArgs); // release created tuple
4006+ end ;
4007+
4008+ function TPyDelphiObject.MpAssSubscript (obj1, obj2: PPyObject) : Integer;
4009+ var
4010+ Engine: TPythonEngine;
4011+ Prop: TRttiIndexedProperty;
4012+ PyArgs: PPyObject;
4013+ TempPy: PPyObject;
4014+ Count, Index: Integer;
4015+ begin
4016+ Result := -1 ; // Signals failure
4017+
4018+ Assert(PythonType.Tag <> 0 );
4019+ Prop := TRttiIndexedProperty(PythonType.Tag);
4020+
4021+ Engine := PyDelphiWrapper.Engine;
4022+ if not Prop.IsWritable then
4023+ begin
4024+ with Engine do
4025+ PyErr_SetObject(PyExc_TypeError^, PyUnicodeFromString(rs_NotWritable));
4026+ Exit;
4027+ end ;
4028+
4029+ // obj is a tuple only if we have more than one arguments
4030+ if Engine.PyTuple_Check(obj1) then
4031+ begin
4032+ Count := Engine.PyTuple_Size(obj1);
4033+ PyArgs := Engine.PyTuple_New(Count + 1 );
4034+ for Index := 0 to Count - 1 do
4035+ begin
4036+ TempPy := Engine.PyTuple_GetItem(obj1, Index);
4037+ Engine.Py_XINCREF(TempPy);
4038+ Engine.PyTuple_SetItem(PyArgs, Index, TempPy);
4039+ end ;
4040+ Engine.Py_XINCREF(obj2);
4041+ Engine.PyTuple_SetItem(PyArgs, Count, obj2);
4042+ end
4043+ else
4044+ PyArgs := Engine.MakePyTuple([obj1, obj2]);
4045+
4046+ TempPy := RttiCall(DelphiObject, PyDelphiWrapper, Prop.WriteMethod,
4047+ PyArgs, nil );
4048+
4049+ Engine.Py_DECREF(PyArgs); // release created tuple
4050+
4051+ if TempPy <> nil then
4052+ begin
4053+ Engine.Py_DECREF(TempPy); // Should be Py_None
4054+ Result := 0 ; // Signal success
4055+ end ;
4056+ end ;
4057+
4058+
39744059{ $ENDIF EXTENDED_RTTI}
39754060
39764061function TPyDelphiObject.Set_Owned (AValue: PPyObject;
0 commit comments