@@ -2226,9 +2226,10 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
2226
2226
Result := inherited GetAttrO(key);
2227
2227
if GetPythonEngine.PyErr_Occurred = nil then Exit; // We found what we wanted
2228
2228
2229
- if Assigned(DelphiObject) and GetPythonEngine.PyUnicode_Check(Key) then
2230
- KeyName := GetPythonEngine.PyUnicodeAsString(Key)
2231
- else
2229
+ // should not happen
2230
+ if not (Assigned(DelphiObject) and
2231
+ CheckStrAttribute(Key, ' GetAttrO key parameter' , KeyName))
2232
+ then
2232
2233
Exit;
2233
2234
2234
2235
GetPythonEngine.PyErr_Clear;
@@ -2512,11 +2513,15 @@ function TPyDelphiObject.Repr: PPyObject;
2512
2513
2513
2514
function TPyDelphiObject.SetAttrO (key, value : PPyObject): Integer;
2514
2515
(*
2515
- First look whether the attribute has ben wrapped (RegisterGetSet, RegisterMethod).
2516
- This is done by calling the inherited SetAttrO. If this fails then
2516
+ First look whether the attribute exists., e.g. has been wrapped with
2517
+ RegisterGetSet, RegisterMethod, etc.
2518
+ If it does then the inherited generic SetAttrO is called.
2519
+ If the attribute does not exist or the generic SetAttO fails (unlikely) then
2517
2520
- Use Rtti to locate the property in DELPHIXE_OR_HIGHER (EXTENDED_RTTI)
2518
2521
or for other versions
2519
2522
- Look for published properties
2523
+ Finally, if all the above fail then you call the inherited generic SetAttrO
2524
+ which adds a new field in the object dictionary
2520
2525
*)
2521
2526
2522
2527
function HandleEvent (PropInfo: PPropInfo; out ErrMsg: string) : Integer;
@@ -2582,20 +2587,29 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
2582
2587
{ $ENDIF}
2583
2588
KeyName: string;
2584
2589
ErrMsg: string;
2590
+ PyEngine: TPythonEngine;
2591
+ PyObj: PPyobject;
2585
2592
begin
2586
2593
Result := -1 ;
2587
- if Assigned(DelphiObject) and GetPythonEngine.PyUnicode_Check(Key) then
2588
- KeyName := GetPythonEngine.PyUnicodeAsString(Key)
2589
- else begin
2594
+ PyEngine := GetPythonEngine;
2595
+
2596
+ // should not happen
2597
+ if not (Assigned(DelphiObject) and
2598
+ CheckStrAttribute(Key, ' SetAttrO key parameter' , KeyName))
2599
+ then
2590
2600
Exit;
2591
- end ;
2592
2601
2593
- // Only call the inherited method if the attribute exists
2594
- if GetPythonEngine.PyObject_HasAttrString(GetSelf, PAnsiChar(key)) = 1 then
2602
+ // Only call the inherited method at this stage if the attribute exists
2603
+ PyObj := PyEngine.PyObject_GenericGetAttr(GetSelf, key);
2604
+ if Assigned(PyObj) then
2605
+ begin
2606
+ PyEngine.Py_DECREF(PyObj); // not needed
2595
2607
Result := inherited SetAttrO(key, value );
2596
- if Result = 0 then Exit;
2608
+ if Result = 0 then
2609
+ Exit;
2610
+ end ;
2597
2611
2598
- GetPythonEngine .PyErr_Clear;
2612
+ PyEngine .PyErr_Clear;
2599
2613
{ $IFDEF EXTENDED_RTTI}
2600
2614
Context := TRttiContext.Create();
2601
2615
try
@@ -2623,8 +2637,8 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
2623
2637
if Result <> 0 then
2624
2638
Result := inherited SetAttrO(key, value );
2625
2639
if Result <> 0 then
2626
- with GetPythonEngine do
2627
- PyErr_SetObject(PyExc_AttributeError^, PyUnicodeFromString(
2640
+ with PyEngine do
2641
+ PyErr_SetObject(PyEngine. PyExc_AttributeError^, PyUnicodeFromString(
2628
2642
Format(rs_ErrAttrSetr, [KeyName, ErrMsg])));
2629
2643
end ;
2630
2644
0 commit comments