Skip to content

Commit

Permalink
Merge pull request #31 from pyscripter/master
Browse files Browse the repository at this point in the history
Merging head repository last changes
  • Loading branch information
lmbelo authored Jul 27, 2022
2 parents 3af6852 + 556b33e commit 19192ad
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 20 deletions.
13 changes: 8 additions & 5 deletions Source/PythonEngine.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,7 @@ TPythonInterface=class(TDynamicDll)
PyObject_GetAttrString:function (ob:PPyObject;c:PAnsiChar):PPyObject; cdecl;
PyObject_GetItem:function (ob,key:PPyObject):PPyObject; cdecl;
PyObject_DelItem:function (ob,key:PPyObject):PPyObject; cdecl;
PyObject_HasAttr:function (ob, attr_name:PPyObject):integer; cdecl;
PyObject_HasAttrString:function (ob:PPyObject;key:PAnsiChar):integer; cdecl;
PyObject_Hash:function (ob:PPyObject):NativeInt; cdecl;
PyObject_IsTrue:function (ob:PPyObject):integer; cdecl;
Expand Down Expand Up @@ -3711,6 +3712,7 @@ procedure TPythonInterface.MapDll;
PyObject_GetAttrString := Import('PyObject_GetAttrString');
PyObject_GetItem := Import('PyObject_GetItem');
PyObject_DelItem := Import('PyObject_DelItem');
PyObject_HasAttr := Import('PyObject_HasAttr');
PyObject_HasAttrString := Import('PyObject_HasAttrString');
PyObject_Hash := Import('PyObject_Hash');
PyObject_IsTrue := Import('PyObject_IsTrue');
Expand Down Expand Up @@ -7311,11 +7313,12 @@ function TPythonModule.GetVarAsVariant( const varName : AnsiString ) : Variant;
with Engine do
begin
obj := GetVar( varName );
try
Result := PyObjectAsVariant( obj );
finally
Py_XDecRef(obj);
end;
if Assigned(obj) then
try
Result := PyObjectAsVariant( obj );
finally
Py_XDecRef(obj);
end;
end;
end;

Expand Down
44 changes: 29 additions & 15 deletions Source/WrapDelphi.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2226,9 +2226,10 @@ function TPyDelphiObject.GetAttrO(key: PPyObject): PPyObject;
Result := inherited GetAttrO(key);
if GetPythonEngine.PyErr_Occurred = nil then Exit; // We found what we wanted

if Assigned(DelphiObject) and GetPythonEngine.PyUnicode_Check(Key) then
KeyName := GetPythonEngine.PyUnicodeAsString(Key)
else
// should not happen
if not (Assigned(DelphiObject) and
CheckStrAttribute(Key, 'GetAttrO key parameter', KeyName))
then
Exit;

GetPythonEngine.PyErr_Clear;
Expand Down Expand Up @@ -2512,11 +2513,15 @@ function TPyDelphiObject.Repr: PPyObject;

function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
(*
First look whether the attribute has ben wrapped (RegisterGetSet, RegisterMethod).
This is done by calling the inherited SetAttrO. If this fails then
First look whether the attribute exists., e.g. has been wrapped with
RegisterGetSet, RegisterMethod, etc.
If it does then the inherited generic SetAttrO is called.
If the attribute does not exist or the generic SetAttO fails (unlikely) then
- Use Rtti to locate the property in DELPHIXE_OR_HIGHER (EXTENDED_RTTI)
or for other versions
- Look for published properties
Finally, if all the above fail then you call the inherited generic SetAttrO
which adds a new field in the object dictionary
*)

function HandleEvent(PropInfo: PPropInfo; out ErrMsg: string) : Integer;
Expand Down Expand Up @@ -2582,20 +2587,29 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
{$ENDIF}
KeyName: string;
ErrMsg: string;
PyEngine: TPythonEngine;
PyObj: PPyobject;
begin
Result := -1;
if Assigned(DelphiObject) and GetPythonEngine.PyUnicode_Check(Key) then
KeyName := GetPythonEngine.PyUnicodeAsString(Key)
else begin
PyEngine := GetPythonEngine;

// should not happen
if not (Assigned(DelphiObject) and
CheckStrAttribute(Key, 'SetAttrO key parameter', KeyName))
then
Exit;
end;

// Only call the inherited method if the attribute exists
if GetPythonEngine.PyObject_HasAttrString(GetSelf, PAnsiChar(key)) = 1 then
// Only call the inherited method at this stage if the attribute exists
PyObj := PyEngine.PyObject_GenericGetAttr(GetSelf, key);
if Assigned(PyObj) then
begin
PyEngine.Py_DECREF(PyObj); // not needed
Result := inherited SetAttrO(key, value);
if Result = 0 then Exit;
if Result = 0 then
Exit;
end;

GetPythonEngine.PyErr_Clear;
PyEngine.PyErr_Clear;
{$IFDEF EXTENDED_RTTI}
Context := TRttiContext.Create();
try
Expand Down Expand Up @@ -2623,8 +2637,8 @@ function TPyDelphiObject.SetAttrO(key, value: PPyObject): Integer;
if Result <> 0 then
Result := inherited SetAttrO(key, value);
if Result <> 0 then
with GetPythonEngine do
PyErr_SetObject(PyExc_AttributeError^, PyUnicodeFromString(
with PyEngine do
PyErr_SetObject(PyEngine.PyExc_AttributeError^, PyUnicodeFromString(
Format(rs_ErrAttrSetr, [KeyName, ErrMsg])));
end;

Expand Down

0 comments on commit 19192ad

Please sign in to comment.