Jump to content
iqrf

Using Delphi enum in Python

Recommended Posts

Posted (edited)

How to export from delphi to python

type
	TColor = (RED = 5, GREEN = 8, BLUE = 9)

and in the return value of the delphi function called from Python to return a PPyObject of type TColor.
Is it any other way than clumsily like this?

FEngine.PyRun_SimpleString('from enum import Enum' + #13 +
  'Color = Enum(''Color'', {''RED'':5, ''GREEN'':8, ''BLUE'':9})');
...
FEngine.ExecString(UTF8Encode(FScript), UTF8Encode(FCode.Path));
...
//result my function
mainModule, colorEnum, redColor: PPyObject;
....

mainModule := PyImport_AddModule('__main__');
colorEnum := PyObject_GetAttrString(mainModule, 'Color');
redColor := PyObject_GetAttrString(colorEnum, 'RED');
result := redColor;
...
if mymodule.test_func() == Color.RED:
...

Thanks for the ideas.

Edited by iqrf

Share this post


Link to post

There is no need to export anything.   Delphi enum values are converted to python strings and sets to lists of strings.

 

On the opposite direction you can access python enum values from Delphi in the same way you access other objects.  The easiest way is to use VarPyth.

 

var colorEnum := MainModule.Color

var Red := colorEnum.RED

Share this post


Link to post

 

14 minutes ago, pyscripter said:

There is no need to export anything.   Delphi enum values are converted to python strings and sets to lists of strings.

 

I don't understand how I can write in Python a = TColor.RED without exporting to Python?

var colorEnum := MainModule.Color;
var Red := colorEnum.RED;
result := Red;  E2010 Incompatible types: 'PPyObject' and 'Variant'

But that's the variant type, I need to return a PPyObject.
Thanks

Share this post


Link to post

Thanks a lot.
And how do I get the enumerated type TColor into Python?

1 hour ago, iqrf said:

type TColor = (RED = 5, GREEN = 8, BLUE = 9)

 

Share this post


Link to post
Posted (edited)

I have no idea what you are trying to do, but it does not make sense to define the enumeration both in Delphi and in Python.

 

I recommend that you familiarize yourself with:

  •   WrapDelphi - high level access to Delphi from python
  •  VarPyth - high level access to python from Delphi. 

The video tutorials offer a good introduction to both.

 

If you use WrapDelphi to export delphi functions to python then you just use python strings in place of enumeration values.

 

Edited by pyscripter

Share this post


Link to post

I don't want to define an enum in both Delphi and Python.
I just want to use an enum defined in Delphi in Python.
WrapDelphi I use both FPythonWrapper.DefineVar() and FPythonWrapper.Wrap(TDelphi, soOwned) and FPythonWrapper.RegisterDelphiWrapper(TPyClassWrapper<...>).Initialize
But I have no idea how to use the same functionality for an enumeration type.

Share this post


Link to post
Posted (edited)
6 minutes ago, iqrf said:

But I have no idea how to use the same functionality for an enumeration type

As mentioned above you just use python strings in place of enumerated values,

 

eg.  exported delphi method using WrapDelphi

 

procedure Test(Color: TColor)

 

in python

 

Test('RED')

Edited by pyscripter

Share this post


Link to post
Posted (edited)

Sure this is ok.
I would like in Python
a = TColor.RED
print(type(a)) ### <enum 'TColor'>

where TColor defined in Delphi

Edited by iqrf

Share this post


Link to post
8 minutes ago, iqrf said:

I would like in Python

It's not how it works.

Share this post


Link to post
Posted (edited)

OK 😞
So I define an enum in python and use it in delphi, which works.
Now I understand why it is like this:


procedure TButtonsRegistration.DefineVars(APyDelphiWrapper: TPyDelphiWrapper);
begin
  inherited;
  APyDelphiWrapper.DefineVar('bkCustom',      bkCustom);
  APyDelphiWrapper.DefineVar('bkOK',          bkOK);
  APyDelphiWrapper.DefineVar('bkCancel',      bkCancel);
  APyDelphiWrapper.DefineVar('bkHelp',        bkHelp);
  APyDelphiWrapper.DefineVar('bkYes',         bkYes);
  APyDelphiWrapper.DefineVar('bkNo',          bkNo);
  APyDelphiWrapper.DefineVar('bkClose',       bkClose);
  APyDelphiWrapper.DefineVar('bkAbort',       bkAbort);
  APyDelphiWrapper.DefineVar('bkRetry',       bkRetry);
  APyDelphiWrapper.DefineVar('bkIgnore',      bkIgnore);
  APyDelphiWrapper.DefineVar('bkAll',         bkAll);
end;

Thanks for your time.

Edited by iqrf

Share this post


Link to post

Hi,
how to use PyArg_ParseTupleAndKeywords to get the value of a function parameter that is of type Python enum. E.g

class color (enum):
         RED = 5
         GREEN = 8
         BLUE = 9

TestFunction (Color.RED)

var pColor: PPyObject;

if (PyArg_ParseTupleAndKeywords(args, kwargs, '|O', @keyPointerArray[0], @pColor) <> 0) then begin

PyEnum_Check(pColor)
returns False why?

How to get value 5 from pColor?

 

I tried this too
    var a := VarPythonCreate(pColor);
    VarIsEnum(a)
also returns False
in 'a' is the string 'color.RED'
 

Thank you for your help.

Share this post


Link to post
Posted (edited)

PyEnum_Check and VarIsEnum have to do with enumerators and not the enum.Enum class.

 

There are many ways to get the value.  Using VarPyth:

 var a := VarPythonCreate(pColor);

  var val := a.value

Edited by pyscripter

Share this post


Link to post

Thank you, I got to that too
var a := VarPythonCreate(pColor
).value

the second way

var valueObj := PyObject_GetAttrString(pColor, 'value');

if Assigned(valueObj) then begin
   a := PyLong_AsLong(valueObj);
   Py_XDECREF(valueObj);
end
else
   PyErr_Print();  

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×