@@ -2226,9 +2226,10 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
22262226 Result := inherited GetAttrO(key);
22272227 if GetPythonEngine.PyErr_Occurred = nil then Exit; // We found what we wanted
22282228
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
22322233 Exit;
22332234
22342235 GetPythonEngine.PyErr_Clear;
@@ -2512,11 +2513,15 @@ function TPyDelphiObject.Repr: PPyObject;
25122513
25132514function TPyDelphiObject.SetAttrO (key, value : PPyObject): Integer;
25142515(*
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
25172520 - Use Rtti to locate the property in DELPHIXE_OR_HIGHER (EXTENDED_RTTI)
25182521 or for other versions
25192522 - 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
25202525*)
25212526
25222527 function HandleEvent (PropInfo: PPropInfo; out ErrMsg: string) : Integer;
@@ -2582,20 +2587,29 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
25822587 { $ENDIF}
25832588 KeyName: string;
25842589 ErrMsg: string;
2590+ PyEngine: TPythonEngine;
2591+ PyObj: PPyobject;
25852592begin
25862593 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
25902600 Exit;
2591- end ;
25922601
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
25952607 Result := inherited SetAttrO(key, value );
2596- if Result = 0 then Exit;
2608+ if Result = 0 then
2609+ Exit;
2610+ end ;
25972611
2598- GetPythonEngine .PyErr_Clear;
2612+ PyEngine .PyErr_Clear;
25992613 { $IFDEF EXTENDED_RTTI}
26002614 Context := TRttiContext.Create();
26012615 try
@@ -2623,8 +2637,8 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
26232637 if Result <> 0 then
26242638 Result := inherited SetAttrO(key, value );
26252639 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(
26282642 Format(rs_ErrAttrSetr, [KeyName, ErrMsg])));
26292643end ;
26302644
0 commit comments