@@ -1026,7 +1026,8 @@ implementation
1026
1026
rs_ErrAttrGet = ' Error in getting property "%s".' #$A' Error: %s' ;
1027
1027
rs_UnknownAttribute = ' Unknown attribute' ;
1028
1028
rs_ErrIterSupport = ' Wrapper %s does not support iterators' ;
1029
- rs_ErrAttrSetr = ' Error in setting property %s' #$A' Error: %s' ;
1029
+ rs_ErrAttrSet = ' Error in setting property %s' #$A' Error: %s' ;
1030
+ rs_ErrObjectDestroyed = ' Trying to access a destroyed pascal object' ;
1030
1031
rs_IncompatibleClasses = ' Incompatible classes' ;
1031
1032
rs_IncompatibleRecords = ' Incompatible record types' ;
1032
1033
rs_IncompatibleInterfaces = ' Incompatible interfaces' ;
@@ -1550,7 +1551,7 @@ function TExposedGetSet.SetterWrapper(AObj, AValue: PPyObject; AContext: Pointer
1550
1551
if Result <> 0 then
1551
1552
with GetPythonEngine do
1552
1553
PyErr_SetObject (PyExc_AttributeError^,
1553
- PyUnicodeFromString(Format(rs_ErrAttrSetr , [FRttiMember.Name , ErrMsg])));
1554
+ PyUnicodeFromString(Format(rs_ErrAttrSet , [FRttiMember.Name , ErrMsg])));
1554
1555
end ;
1555
1556
1556
1557
{ TExposedField }
@@ -1646,7 +1647,7 @@ function TExposedEvent.SetterWrapper(AObj, AValue: PPyObject; AContext: Pointer)
1646
1647
if Result <> 0 then
1647
1648
with GetPythonEngine do
1648
1649
PyErr_SetObject (PyExc_AttributeError^,
1649
- PyUnicodeFromString(Format(rs_ErrAttrSetr , [FRttiMember.Name , ErrMsg])));
1650
+ PyUnicodeFromString(Format(rs_ErrAttrSet , [FRttiMember.Name , ErrMsg])));
1650
1651
end ;
1651
1652
1652
1653
{ TExposedIndexedProperty }
@@ -3434,7 +3435,7 @@ function TPyRttiObject.SetAttrO(key, value: PPyObject): Integer;
3434
3435
if Result <> 0 then
3435
3436
with GetPythonEngine do
3436
3437
PyErr_SetObject(PyExc_AttributeError^, PyUnicodeFromString(
3437
- Format(rs_ErrAttrSetr , [KeyName, ErrMsg])));
3438
+ Format(rs_ErrAttrSet , [KeyName, ErrMsg])));
3438
3439
end ;
3439
3440
3440
3441
function TPyRttiObject.SetProps (args, keywords: PPyObject): PPyObject;
@@ -3543,6 +3544,7 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
3543
3544
var
3544
3545
KeyName: string;
3545
3546
ErrMsg : string;
3547
+ PyEngine: TPythonEngine;
3546
3548
{ $IFNDEF EXTENDED_RTTI}
3547
3549
{ $IFNDEF FPC}
3548
3550
Info: PMethodInfoHeader;
@@ -3554,16 +3556,24 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
3554
3556
RttiType: TRttiStructuredType;
3555
3557
{ $ENDIF}
3556
3558
begin
3557
- Result := inherited GetAttrO(key) ;
3558
- if GetPythonEngine.PyErr_Occurred = nil then Exit; // We found what we wanted
3559
+ Result := nil ;
3560
+ PyEngine := GetPythonEngine;
3559
3561
3560
- // should not happen
3561
- if not (Assigned(DelphiObject) and
3562
- CheckStrAttribute(Key, ' GetAttrO key parameter' , KeyName))
3563
- then
3562
+ // If DelphiObject is nil Exit immediately with an error
3563
+ if not Assigned(DelphiObject) then
3564
+ begin
3565
+ PyEngine.PyErr_SetObject(PyEngine.PyExc_AttributeError^,
3566
+ PyEngine.PyUnicodeFromString(rs_ErrObjectDestroyed));
3564
3567
Exit;
3568
+ end ;
3569
+
3570
+ if not CheckStrAttribute(Key, ' GetAttrO key parameter' , KeyName) then
3571
+ Exit; // should not happen
3572
+
3573
+ Result := inherited GetAttrO(key);
3574
+ if PyEngine.PyErr_Occurred = nil then Exit; // We found what we wanted
3565
3575
3566
- GetPythonEngine .PyErr_Clear;
3576
+ PyEngine .PyErr_Clear;
3567
3577
{ $IFDEF EXTENDED_RTTI}
3568
3578
// Use RTTI
3569
3579
if Assigned(DelphiObject) then begin
@@ -3620,17 +3630,17 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
3620
3630
{ $ELSE FPC}
3621
3631
if GetTypeData(PropInfo^.PropType^)^.BaseType^ = TypeInfo(Boolean) then
3622
3632
{ $ENDIF FPC}
3623
- Result := GetPythonEngine .VariantAsPyObject(Boolean(GetOrdProp(Self.DelphiObject, PropInfo)))
3633
+ Result := PyEngine .VariantAsPyObject(Boolean(GetOrdProp(Self.DelphiObject, PropInfo)))
3624
3634
else
3625
3635
{ $IFDEF FPC}
3626
- Result := GetPythonEngine .PyUnicodeFromString(GetEnumName(PropInfo^.PropType,
3636
+ Result := PyEngine .PyUnicodeFromString(GetEnumName(PropInfo^.PropType,
3627
3637
{ $ELSE FPC}
3628
- Result := GetPythonEngine .PyUnicodeFromString(GetEnumName(PropInfo^.PropType^,
3638
+ Result := PyEngine .PyUnicodeFromString(GetEnumName(PropInfo^.PropType^,
3629
3639
{ $ENDIF FPC}
3630
3640
GetOrdProp(Self.DelphiObject, PropInfo)));
3631
3641
end
3632
3642
end else
3633
- Result := GetPythonEngine .VariantAsPyObject(GetPropValue(DelphiObject, PropInfo));
3643
+ Result := PyEngine .VariantAsPyObject(GetPropValue(DelphiObject, PropInfo));
3634
3644
end ;
3635
3645
except
3636
3646
on E: Exception do begin
@@ -3640,9 +3650,8 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
3640
3650
end ;
3641
3651
{ $ENDIF}
3642
3652
if not Assigned(Result) then
3643
- with GetPythonEngine do
3644
- PyErr_SetObject (PyExc_AttributeError^,
3645
- PyUnicodeFromString(Format(rs_ErrAttrGet,[KeyName, ErrMsg])));
3653
+ PyEngine.PyErr_SetObject (PyEngine.PyExc_AttributeError^,
3654
+ PyEngine.PyUnicodeFromString(Format(rs_ErrAttrGet,[KeyName, ErrMsg])));
3646
3655
end ;
3647
3656
3648
3657
function TPyDelphiObject.GetContainerAccess : TContainerAccess;
@@ -3944,11 +3953,16 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
3944
3953
Result := -1 ;
3945
3954
PyEngine := GetPythonEngine;
3946
3955
3947
- // should not happen
3948
- if not (Assigned(DelphiObject) and
3949
- CheckStrAttribute(Key, ' SetAttrO key parameter' , KeyName))
3950
- then
3956
+ // If DelphiObject is nil Exit immediately with an error
3957
+ if not Assigned(DelphiObject) then
3958
+ begin
3959
+ PyEngine.PyErr_SetObject(PyEngine.PyExc_AttributeError^,
3960
+ PyEngine.PyUnicodeFromString(rs_ErrObjectDestroyed));
3951
3961
Exit;
3962
+ end ;
3963
+
3964
+ if not CheckStrAttribute(Key, ' SetAttrO key parameter' , KeyName) then
3965
+ Exit; // should not happen
3952
3966
3953
3967
// Only call the inherited method at this stage if the attribute exists
3954
3968
PyObj := PyEngine.PyObject_GenericGetAttr(GetSelf, key);
@@ -3989,8 +4003,8 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
3989
4003
Result := inherited SetAttrO(key, value );
3990
4004
if Result <> 0 then
3991
4005
with PyEngine do
3992
- PyErr_SetObject(PyEngine. PyExc_AttributeError^, PyUnicodeFromString(
3993
- Format(rs_ErrAttrSetr , [KeyName, ErrMsg])));
4006
+ PyErr_SetObject(PyExc_AttributeError^, PyUnicodeFromString(
4007
+ Format(rs_ErrAttrSet , [KeyName, ErrMsg])));
3994
4008
end ;
3995
4009
3996
4010
procedure TPyDelphiObject.SetDelphiObject (const Value : TObject);
0 commit comments