@@ -644,6 +644,11 @@ TPyDelphiObject = class (TPyInterfacedObject, IFreeNotificationSubscriber)
644
644
class procedure SetupType ( PythonType : TPythonType ); override;
645
645
// Expose methods, properties and fields via RTTI at definition time
646
646
{ $IFDEF EXPOSE_MEMBERS}
647
+ class function GetExcludedExposeMethods (
648
+ const APythonType: TPythonType): TArray<string>; virtual ;
649
+ class function GetExcludedExposeGettersSetters (
650
+ const APythonType: TPythonType): TArray<string>; virtual ;
651
+
647
652
class procedure ExposeMethods (const AClass: TClass;
648
653
const APythonType: TPythonType; const APyDelphiWrapper: TPyDelphiWrapper;
649
654
const ADeclaredMethodsOnly: boolean = false;
@@ -668,6 +673,9 @@ TPyDelphiObject = class (TPyInterfacedObject, IFreeNotificationSubscriber)
668
673
const AIncludedFieldNames: TArray<string> = [];
669
674
const AExcludedFieldNames: TArray<string> = [];
670
675
const ADefCallback: TExposedFieldDefCallback = nil ); virtual ;
676
+
677
+ class procedure DynamicallyExposeMembers (const APythonType: TPythonType;
678
+ const APyDelphiWrapper: TPyDelphiWrapper);
671
679
{ $ENDIF EXPOSE_MEMBERS}
672
680
// if the class is a container (TStrings, TComponent, TCollection...),
673
681
// then return the class implementing the access to the contained items.
@@ -4101,9 +4109,6 @@ function TPyDelphiObject.SetProps(args, keywords: PPyObject): PPyObject;
4101
4109
class procedure TPyDelphiObject.SetupType (PythonType: TPythonType);
4102
4110
var
4103
4111
_ContainerAccessClass : TContainerAccessClass;
4104
- { $IFDEF EXPOSE_MEMBERS}
4105
- LDocStr: string;
4106
- { $ENDIF EXPOSE_MEMBERS}
4107
4112
begin
4108
4113
inherited ;
4109
4114
PythonType.TypeName := AnsiString(GetTypeName);
@@ -4121,23 +4126,31 @@ class procedure TPyDelphiObject.SetupType(PythonType: TPythonType);
4121
4126
if _ContainerAccessClass.SupportsIndexOf then
4122
4127
PythonType.Services.Sequence := PythonType.Services.Sequence + [ssContains];
4123
4128
end ;
4129
+ end ;
4124
4130
4125
- { $IFDEF EXPOSE_MEMBERS}
4126
- PythonType.TypeFlags := PythonType.TypeFlags + [TPFlag.tpTypeSubclass];
4131
+ { $IFDEF EXPOSE_MEMBERS}
4132
+ class function TPyDelphiObject.GetExcludedExposeMethods (
4133
+ const APythonType: TPythonType): TArray<string>;
4134
+ var
4135
+ I: integer;
4136
+ begin
4137
+ Result := [' CPP_ABI_1' , ' CPP_ABI_2' , ' CPP_ABI_3' ];
4138
+ // Any method manually wrapped must be excluded
4139
+ for I := 0 to APythonType.MethodCount - 1 do
4140
+ Result := Result + [String(APythonType.Methods[I].ml_name)];
4141
+ end ;
4127
4142
4128
- // Try to load the class doc string from doc server
4129
- if TPythonDocServer.Instance.ReadTypeDocStr(DelphiObjectClass.ClassInfo, LDocStr) then
4130
- PythonType.DocString.Text := LDocStr;
4131
-
4132
- ExposeMethods(DelphiObjectClass, PythonType,PythonType.Owner as TPyDelphiWrapper,
4133
- true, [], [' CPP_ABI_1' , ' CPP_ABI_2' , ' CPP_ABI_3' ]);
4134
- ExposeFields(DelphiObjectClass, PythonType, PythonType.Owner as TPyDelphiWrapper, true);
4135
- ExposeProperties(DelphiObjectClass, PythonType, PythonType.Owner as TPyDelphiWrapper, true);
4136
- ExposeIndexedProperties(DelphiObjectClass, PythonType, PythonType.Owner as TPyDelphiWrapper, true);
4137
- { $ENDIF EXPOSE_MEMBERS}
4143
+ class function TPyDelphiObject.GetExcludedExposeGettersSetters (
4144
+ const APythonType: TPythonType): TArray<string>;
4145
+ var
4146
+ I: integer;
4147
+ begin
4148
+ Result := [];
4149
+ // Any field, property or indexed property manually wrapped must be excluded
4150
+ for I := 0 to APythonType.GetSetCount - 1 do
4151
+ Result := Result + [String(APythonType.GetSet[I].name )];
4138
4152
end ;
4139
4153
4140
- { $IFDEF EXPOSE_MEMBERS}
4141
4154
class procedure TPyDelphiObject.ExposeMethods (const AClass: TClass;
4142
4155
const APythonType: TPythonType; const APyDelphiWrapper: TPyDelphiWrapper;
4143
4156
const ADeclaredMethodsOnly: boolean; const AIncludedMethodNames,
@@ -4476,6 +4489,38 @@ class procedure TPyDelphiObject.ExposeFields(const AClass: TClass;
4476
4489
LRttiCtx.Free;
4477
4490
end ;
4478
4491
end ;
4492
+
4493
+ class procedure TPyDelphiObject.DynamicallyExposeMembers (
4494
+ const APythonType: TPythonType; const APyDelphiWrapper: TPyDelphiWrapper);
4495
+ var
4496
+ LDocStr: string;
4497
+ LExcludedMethods: TArray<string>;
4498
+ LExcludedGettersAndSetters: TArray<string>;
4499
+ LDelphiObjectClass: TClass;
4500
+ begin
4501
+ APythonType.TypeFlags := APythonType.TypeFlags + [TPFlag.tpTypeSubclass];
4502
+
4503
+ LDelphiObjectClass := TPyDelphiObjectClass(APythonType.PyObjectClass).DelphiObjectClass;
4504
+
4505
+ // Try to load the class doc string from doc server
4506
+ if TPythonDocServer.Instance.ReadTypeDocStr(LDelphiObjectClass.ClassInfo, LDocStr) then
4507
+ APythonType.DocString.Text := LDocStr;
4508
+
4509
+ // Get excluded methods manually wrapped
4510
+ LExcludedMethods := GetExcludedExposeMethods(APythonType);
4511
+ // Get excluded fields, porperties and indexed properties manually wrapped
4512
+ LExcludedGettersAndSetters := GetExcludedExposeGettersSetters(APythonType);
4513
+
4514
+ ExposeMethods(LDelphiObjectClass, APythonType, APyDelphiWrapper, true,
4515
+ [], LExcludedMethods);
4516
+ ExposeFields(LDelphiObjectClass, APythonType, APyDelphiWrapper, true,
4517
+ [], LExcludedGettersAndSetters);
4518
+ ExposeProperties(LDelphiObjectClass, APythonType, APyDelphiWrapper, true,
4519
+ [], LExcludedGettersAndSetters);
4520
+ ExposeIndexedProperties(LDelphiObjectClass, APythonType, APyDelphiWrapper, true,
4521
+ [], LExcludedGettersAndSetters);
4522
+ end ;
4523
+
4479
4524
{ $ENDIF EXPOSE_MEMBERS}
4480
4525
4481
4526
function TPyDelphiObject.Set_Owned (AValue: PPyObject;
@@ -5352,6 +5397,12 @@ procedure TPyDelphiWrapper.RegisterDelphiWrapper(
5352
5397
RegisteredClass.PythonType.Engine := Engine;
5353
5398
RegisteredClass.PythonType.Module := fModule;
5354
5399
RegisteredClass.PythonType.PyObjectClass := AWrapperClass;
5400
+
5401
+ { $IFDEF EXPOSE_MEMBERS}
5402
+ // Must run after manually wrapped members
5403
+ TPyDelphiObject.DynamicallyExposeMembers(RegisteredClass.PythonType, Self);
5404
+ { $ENDIF EXPOSE_MEMBERS}
5405
+
5355
5406
// Find nearest registered parent class and set it as base
5356
5407
for Index := fClassRegister.Count - 1 downto 0 do
5357
5408
with TRegisteredClass(fClassRegister[Index]) do
0 commit comments