@@ -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' 
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' 
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