Skip to content

Merging head repository last changes #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 1 addition & 1 deletion Source/WrapDelphiWindows.pas
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class function TWindowsRegistration.SetProcessDpiAwareness_Wrapper(PySelf,
{$ENDIF DELPHI11_OR_HIGHER}

initialization
RegisteredUnits.Add( TWindowsRegistration.Create );
RegisteredUnits.Add(TWindowsRegistration.Create);

{$IFDEF MSWINDOWS}
{$IFDEF DELPHI11_OR_HIGHER}
Expand Down
4 changes: 2 additions & 2 deletions Source/vcl/WrapVclForms.pas
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ function TPyDelphiCustomForm.LoadProps_Wrapper(args: PPyObject): PPyObject;
Exit(GetPythonEngine().ReturnFalse);
except
on E: Exception do
GetPythonEngine().PyErr_SetString(PyExc_RuntimeError^,
PAnsiChar(AnsiString(E.Message)));
with GetPythonEngine() do
PyErr_SetString(PyExc_RuntimeError^, PAnsiChar(AnsiString(E.Message)));
end;
Result := nil;
end;
Expand Down