pyscripter/python4delphi

Error in ExtractPythonObjectFrom when creating Enum?

Vobsoft opened this issue · 1 comments

Hi,
If I edit Demo05

function spam_foo( self, args : PPyObject ) : PPyObject; cdecl;
begin
  with GetPythonEngine do
    begin
      ShowMessage( 'args of foo: '+PyObjectAsString(args) );
     // Result := ReturnNone;
     Result := ExtractPythonObjectFrom(MainModule.color.RED);
    end;
end;
import spam
from enum import Enum
from enum import unique

@unique
class color (Enum):
         RED = 0
         GREEN = 1
         BLUE = 2

print (spam.foo('hello world', 1))
print (spam.foo('hello world', 1))
print (spam.foo('hello world', 1))
print (spam.foo('hello world', 1))  #Error
print (spam.foo('hello world', 1))

Will throw an error when repeatedly calling Foo
Project Demo05.exe raised exception class $C0000005 with message 'access violation at 0x79530e00: read of address 0x79530e00'.
If I add Py_IncRef(result); it's OK

function spam_foo( self, args : PPyObject ) : PPyObject; cdecl;
begin
  with GetPythonEngine do
    begin
      ShowMessage( 'args of foo: '+PyObjectAsString(args) );
     // Result := ReturnNone;
     Result := ExtractPythonObjectFrom(MainModule.color.RED);
     Py_IncRef(result);
    end;
end;

This is also OK

function spam_foo( self, args : PPyObject ) : PPyObject; cdecl;
begin
  with GetPythonEngine do
    begin
      ShowMessage( 'args of foo: '+PyObjectAsString(args) );
     var MainM := PyImport_AddModule('__main__');
     var ColorEnum := PyObject_GetAttrString(MainM, 'color');
     result := PyObject_GetAttrString(ColorEnum, 'RED');
     Py_DecRef(ColorEnum);
      end;
end;

Is this a bug or just my inexperience?
Delphi 11, Python Dll: 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 21:47:43) [MSC v.1937 32 bit (Intel)]

The refcount of result needs to be incremented.

ExtractPythonObjectFrom does not increment the result, so you need to do it as in your second routine.

In your third routine PyObject_GetAttrString returns a new reference so you are also OK.