iqrf
-
Content Count
43 -
Joined
-
Last visited
Posts posted by iqrf
-
-
Hi,
how to use PyArg_ParseTupleAndKeywords to get the value of a function parameter that is of type Python enum. E.gclass 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.
-
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.
-
Sure this is ok.
I would like in Python
a = TColor.RED
print(type(a)) ### <enum 'TColor'>where TColor defined in Delphi
-
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. -
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)
-
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 -
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.
-
Hi, not using exit() is not the solution for me. Users use exit() when debugging a script.
If to ProcessSystemExit; i add Py_DecRef(errtraceback); so the memory leak problem will disappear. The destructor TTerminalLogSettings will already be called. I have no idea, but how is that possible.
procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False); procedure ProcessSystemExit; var errtype, errvalue, errtraceback: PPyObject; SErrValue: string; begin PyErr_Fetch(errtype, errvalue, errtraceback); Traceback.Refresh(errtraceback); SErrValue := PyObjectAsString(errvalue); Py_DecRef(errtraceback); // workaround PyErr_Clear; raise EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]); end;
- 1
-
On 2/28/2024 at 4:27 PM, pyscripter said:To be able to create columns you need to also to customize the TColumn wrapper:
TColumnWrapper = class(TPyClassWrapper<TColumn>) constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); override; end; constructor TColumnWrapper.CreateWith(APythonType: TPythonType; args, kwds: PPyObject); var W: integer; P: PPyObject; begin Create(APythonType); GetPythonEngine.PyArg_ParseTuple(args, 'iO:CreateColumn', @W, @P); DelphiObject := TColumn.Create; DelphiObject.Width := W; DelphiObject.Visible := GetPythonEngine.PyObject_IsTrue(P) = 1; end;
then register it in Form.Create
PyDelphiWrapper.RegisterDelphiWrapper(TColumnWrapper).Initialize; PyDelphiWrapper.RegisterDelphiWrapper(TPyClassWrapper<TDictionary<string, TColumn>>).Initialize;
Then the following code works:
from spam import myPoint, Column print(myPoint.ColumnA['Note'].Width) print(myPoint.ColumnA['Note'].Visible) new_column = Column(100, False) myPoint.ColumnA.Add('Note1', new_column) print(myPoint.ColumnA['Note1'].Width) print(myPoint.ColumnA['Note1'].Visible)
It is possible to somehow distinguish whether the SetVisible function was called from
new_column.visible = True
or
myPoint.ColumnA['Note1'].Visible = True
procedure TColumn.SetVisible(const Value: Boolean); begin FVisible := Value; ... end;
Thanks for the advice.
-
Hi,
i have this code
TColumn = class(TPersistent) private FHeaderName: String; FVisible: Boolean; FWidth: Integer; FPosition: Integer; procedure SetHeaderName(const Value: String); procedure SetVisible(const Value: Boolean); procedure SetWidth(const Value: Integer); procedure SetPosition(const Value: Integer); public property HeaderName: String read FHeaderName write SetHeaderName; property Visible: Boolean read FVisible write SetVisible; property Width: Integer read FWidth write SetWidth; property Position: Integer read FPosition write SetPosition; end; TColumnWrapper = class(TPyClassWrapper<TColumn>) constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); override; end; TTerminalLogSettings = class(TPersistent) private fColumn: TDictionary<String,TColumn>; function GetAutoScroll: Boolean; function GetSeparatorH: Boolean; function GetSeparatorV: Boolean; function GetViewData: Boolean; procedure SetAutoScroll(const Value: Boolean); procedure SetSeparatorH(const Value: Boolean); procedure SetSeparatorV(const Value: Boolean); procedure SetViewData(const Value: Boolean); public constructor Create; destructor Destroy; override; property AutoScroll: Boolean read GetAutoScroll write SetAutoScroll; property SeparatorH: Boolean read GetSeparatorH write SetSeparatorH; property SeparatorV: Boolean read GetSeparatorV write SetSeparatorV; property ViewData: Boolean read GetViewData write SetViewData; property Column: TDictionary<String, TColumn> read fColumn write fColumn; end;
... FPythonModule_TerminalLog := TPythonModule.Create(nil); FPythonModule_TerminalLog.Name := 'FPythonModule_TerminalLog'; FPythonModule_TerminalLog.Engine := FEngine; FPythonModule_TerminalLog.ModuleName := 'terminal_log'; FPythonModule_TerminalLog.OnInitialization := OnInitialization_TerminalLog; FPythonModule_TerminalLog.OnAfterInitialization := OnAfterInitialization_TerminalLog; ... FPythonVersion.AssignTo(FEngine); FEngine.LoadDll; ... terminalLogSettings := TTerminalLogSettings.Create; pTerminalLogSettings := FPythonWrapper.Wrap(terminalLogSettings, soOwned); FPythonModule_TerminalLog.SetVar( 'settings', pTerminalLogSettings); FEngine.Py_DecRef(pTerminalLogSettings); FPythonWrapper.RegisterDelphiWrapper(TColumnWrapper).Initialize; FPythonWrapper.RegisterDelphiWrapper(TPyClassWrapper<TDictionary<string, TColumn>>).Initialize; ...
if used in this way in the script, then after the script finishes I correctly call the TTerminalLogSettings destructor and free the memory
... iqrfide.terminal_log.settings.autoScroll = True ... settings_object = iqrfide.terminal_log.settings setattr(settings_object, 'autoScroll', True) ...
If the script is interrupted using exit(), the destructor is not called and the memory is not freed. Any explanation?
... iqrfide.terminal_log.settings.autoScroll = True ... settings_object = iqrfide.terminal_log.settings setattr(settings_object, 'autoScroll', True) exit() ...
Putting settings_object = None before exit solves the problem.
-
Is there any way to iterate over TDictionary in Python?
for key in spam.myPoint.ColumnA.Keys: #TypeError: 'Object' object is not iterable print(key) for key, value in spam.myPoint.ColumnA.Items: #TypeError: 'IndexedProperty' object is not iterable print(key, value)
-
Many thanks once again.
Question about TPyPoint. From python it is always called CreateWith, you cannot call Create. Why is that? I solved it like this.
To write p = spam.Point() , I changed ii: to |ii
PyArg_ParseTupleAndKeywords(args, kwds, '|ii:CreatePoint',
@KeyPointerArray[0], @fx, @fy) -
Of course it works. I don't know how to put elements of type TColumn into a dictionary ColumnA in Python.
This doesn't workcol = spam.myPoint.Column() col.Visible = True col.Width = 255 spam.myPoint.ColumnA.["Note1"] = col or spam.myPoint.ColumnA.["Note1"] = spam.myPoint.Column(True, 255)
-
Thank you very, very much. I struggled with it for two days.
Please, how to make the TColumn class visible so it workscol = spam.myPoint.TColumn() col.Visible = True col.Width = 255 spam.myPoint.ColumnA.["Note1"] = col or spam.myPoint.ColumnA.["Note1"] = spam.myPoint.TColumn(True, 255)
or do I have to make TPyColumn = class(TPyDelphiPersistent)?
Thanks -
It doesn't work, the class TPyClassWrapper is not defined anywhere
-
HI,
I modified the example of Demo 32. Added TColumn and fColumn: TDictionary<String,TColumn>; property ColumnA: TDictionary<String,TColumn> read fColumn write fColumn;
{$METHODINFO ON} TColumn = class(TPersistent) private FVisible: Boolean; FWidth: Integer; public property Visible: Boolean read FVisible write FVisible; property Width: Integer read FWidth write FWidth; end; TPoint = class(TPersistent) private fx, fy : Integer; fName : String; fColumn: TDictionary<String,TColumn>; public procedure OffsetBy( dx, dy : integer ); published property x : integer read fx write fx; property y : integer read fy write fy; property Name : string read fName write fName; property ColumnA: TDictionary<String,TColumn> read fColumn write fColumn; end; {$METHODINFO OFF}
procedure TForm1.Button1Click(Sender: TObject); var DelphiPoint : TPoint; p : PPyObject; begin // Here's how you can create/read Python vars from Delphi with // Delphi/Python objects. DelphiPoint := TPoint.Create; DelphiPoint.x := 10; DelphiPoint.y := 20; DelphiPoint.ColumnA := TDictionary<String,TColumn>.Create; var value := TColumn.Create; value.Visible := True; value.Width := 455; DelphiPoint.ColumnA.Add('Note', value); // DelphiPoint will be owned and eventually destroyed by Python p := PyDelphiWrapper.Wrap(DelphiPoint, soOwned); PythonModule1.SetVar( 'myPoint', p ); // Note, that you must not free the delphi point yourself. // Instead use the GetPythonEngine.Py_XDECREF(obj) method, // because the object may be used by another Python object. PythonEngine1.Py_DecRef(p); // Excecute the script PythonEngine1.ExecStrings( memo1.Lines ); end;
if i coll
print(spam.myPoint.ColumnA.Count) print(spam.myPoint.ColumnA.ContainsKey("Note"))
OK
1
Trueprint(spam.myPoint.ColumnA["Note"]) #TypeError: 'Object' object is not subscriptable for key in spam.myPoint.ColumnA: #TypeError: 'Object' object is not iterable print(key)
How to solve this please.
How to make this worka = spam.myPoint.ColumnA.Column() a.Visible = True a.Width = 111 spam.myPoint.ColumnA.Add("Note1", a)
Thanks
-
Hi,
I confirm that both CTRL+F and CTRL+C do not work under Delphi Alexandria + Win11 64b.
Not working is:HtmlHelp(0, Application.HelpFile, HH_DISPLAY_TOC, 0); HtmlHelp(0, Application.HelpFile, HH_DISPLAY_INDEX, DWORD(PWideChar(''))); HtmlHelp(0, Application.HelpFile, HH_DISPLAY_SEARCH, DWORD(@Query)); Application.HelpContext()
Calling HtmlHelpW instead of HtmlHelp works.
A broken Application.HelpContext solved them like this:function TFormMain.ApplicationEvents1Help(Command: Word; Data: NativeInt; var CallHelp: Boolean): Boolean; begin HtmlHelpW(0, PWideChar(Application.HelpFile), HH_HELP_CONTEXT, Data); CallHelp := False; end;
I used HH_HELP_CONTEXT because even when calling the Application.HelpContext the Command parameter contained 1 instead of 15.
Of course, this solution does not work if HelpKeyword is used for components.
A universal solution could be made by possibly recoding these constants.
const { Commands to pass to WinHelp() } {$EXTERNALSYM HELP_CONTEXT} HELP_CONTEXT = 1; { Display topic in ulTopic } {$EXTERNALSYM HELP_QUIT} HELP_QUIT = 2; { Terminate help } {$EXTERNALSYM HELP_INDEX} HELP_INDEX = 3; { Display index } {$EXTERNALSYM HELP_CONTENTS} HELP_CONTENTS = 3; {$EXTERNALSYM HELP_HELPONHELP} HELP_HELPONHELP = 4; { Display help on using help } {$EXTERNALSYM HELP_SETINDEX} HELP_SETINDEX = 5; { Set current Index for multi index help } {$EXTERNALSYM HELP_SETCONTENTS} HELP_SETCONTENTS = 5; {$EXTERNALSYM HELP_CONTEXTPOPUP} HELP_CONTEXTPOPUP = 8; {$EXTERNALSYM HELP_FORCEFILE} HELP_FORCEFILE = 9; {$EXTERNALSYM HELP_KEY} HELP_KEY = 257; { Display topic for keyword in offabData } {$EXTERNALSYM HELP_COMMAND} HELP_COMMAND = 258; {$EXTERNALSYM HELP_PARTIALKEY} HELP_PARTIALKEY = 261; {$EXTERNALSYM HELP_MULTIKEY} HELP_MULTIKEY = 513; {$EXTERNALSYM HELP_SETWINPOS} HELP_SETWINPOS = 515; {$EXTERNALSYM HELP_CONTEXTMENU} HELP_CONTEXTMENU = 10; {$EXTERNALSYM HELP_FINDER} HELP_FINDER = 11; {$EXTERNALSYM HELP_WM_HELP} HELP_WM_HELP = 12; {$EXTERNALSYM HELP_SETPOPUP_POS} HELP_SETPOPUP_POS = 13;
const {$EXTERNALSYM HH_DISPLAY_TOPIC } HH_DISPLAY_TOPIC = 0; {$EXTERNALSYM HH_HELP_FINDER } HH_HELP_FINDER = 0; {$EXTERNALSYM HH_DISPLAY_TOC } HH_DISPLAY_TOC = 1; {$EXTERNALSYM HH_DISPLAY_INDEX } HH_DISPLAY_INDEX = 2; {$EXTERNALSYM HH_DISPLAY_SEARCH } HH_DISPLAY_SEARCH = 3; {$EXTERNALSYM HH_SET_WIN_TYPE } HH_SET_WIN_TYPE = 4; {$EXTERNALSYM HH_GET_WIN_TYPE } HH_GET_WIN_TYPE = 5; {$EXTERNALSYM HH_GET_WIN_HANDLE } HH_GET_WIN_HANDLE = 6; {$EXTERNALSYM HH_ENUM_INFO_TYPE } HH_ENUM_INFO_TYPE = 7; {$EXTERNALSYM HH_SET_INFO_TYPE } HH_SET_INFO_TYPE = 8; {$EXTERNALSYM HH_SYNC } HH_SYNC = 9; {$EXTERNALSYM HH_KEYWORD_LOOKUP } HH_KEYWORD_LOOKUP = $d; {$EXTERNALSYM HH_DISPLAY_TEXT_POPUP } HH_DISPLAY_TEXT_POPUP = $e; {$EXTERNALSYM HH_HELP_CONTEXT } HH_HELP_CONTEXT = $f; {$EXTERNALSYM HH_TP_HELP_CONTEXTMENU } HH_TP_HELP_CONTEXTMENU = $10; {$EXTERNALSYM HH_TP_HELP_WM_HELP } HH_TP_HELP_WM_HELP = $11; {$EXTERNALSYM HH_CLOSE_ALL } HH_CLOSE_ALL = $12; {$EXTERNALSYM HH_ALINK_LOOKUP } HH_ALINK_LOOKUP = $13; {$EXTERNALSYM HH_GET_LAST_ERROR } HH_GET_LAST_ERROR = $14; {$EXTERNALSYM HH_ENUM_CATEGORY } HH_ENUM_CATEGORY = $15; {$EXTERNALSYM HH_ENUM_CATEGORY_IT } HH_ENUM_CATEGORY_IT = $16; {$EXTERNALSYM HH_RESET_IT_FILTER } HH_RESET_IT_FILTER = $17; {$EXTERNALSYM HH_SET_INCLUSIVE_FILTER } HH_SET_INCLUSIVE_FILTER = $18; {$EXTERNALSYM HH_SET_EXCLUSIVE_FILTER } HH_SET_EXCLUSIVE_FILTER = $19; {$EXTERNALSYM HH_INITIALIZE } HH_INITIALIZE = $1c; {$EXTERNALSYM HH_UNINITIALIZE } HH_UNINITIALIZE = $1d; {$EXTERNALSYM HH_SET_QUERYSERVICE } HH_SET_QUERYSERVICE = $1e; {$EXTERNALSYM HH_PRETRANSLATEMESSAGE } HH_PRETRANSLATEMESSAGE = $fd; {$EXTERNALSYM HH_GLOBALPROPERTY } HH_GLOBALPROPERTY = $fc;
- 1
-
I will answer myself. To register a method, you need to use AddMethodWithKeywords instead of AddMethod. It was enough to look at WrapDelphi.pas. I think it would be beneficial if Demo32 included an example of such a method.
14 hours ago, iqrf said:AddMethod('send_and_receive', @TPyDevice.DoSendAndReceive, 'device_manager.device.send_and_recive(data: bytes)');
and still to fix
QuoteKeyPointerArray := [PAnsiChar(KeyArray[0]), PAnsiChar(KeyArray[1]), PAnsiChar(KeyArray[2])];
KeyPointerArray := [PAnsiChar(KeyArray[0]), PAnsiChar(KeyArray[1]), PAnsiChar(KeyArray[2]), nil];
-
Yes, according to Demo32 I implemented it. But it is an example of use in CreateWidth. I am trying to use it in a method.
-
Hi,
I have a TPythonType object TPyDevice = class(TPyObject) and Interface methods in it
function DoSendAndReceive(args: PPyObject): PPyObject; cdecl;function TPyDevice.DoSendAndReceive(args: PPyObject): PPyObject; cdecl; var data: TBytes; pyBytes: PPyObject; timeout: Single; logging: Boolean; begin with GetPythonEngine do begin Adjust(@Self); logging := False; if PyArg_ParseTuple( args, 'S|fp:device.send_and_receive', @pyBytes, @timeout, @logging) <> 0 then begin data := PyBytesAsBytes(pyBytes); var response := False; .... .... if response then begin pyBytes := PyBytes_FromStringAndSize(PAnsiChar(data), Length(data)); Result := pyBytes; end else Result := ReturnNone; end else Result := nil; end; end;
I use it like this
response = device_manager.device.send_and_receive(dat, 0, True) orresponse = device_manager.device.send_and_receive(dat)I would like to call the function like this
device_manager.device.send_and_receive(data=dat, timeout 0, logging=True) ordevice_manager.device.send_and_receive(data=dat, logging=True)I edited it like this
function TPyDevice.DoSendAndReceive(args, kwds: PPyObject): PPyObject; cdecl; var data: TBytes; pyBytes: PPyObject; timeout: Single; logging: Boolean; keyArray: array of AnsiString; keyPointerArray: array of PAnsiChar; begin with GetPythonEngine do begin Adjust(@Self); logging := False; KeyArray := ['data', 'timeout', 'logging']; KeyPointerArray := [PAnsiChar(KeyArray[0]), PAnsiChar(KeyArray[1]), PAnsiChar(KeyArray[2])]; if PyArg_ParseTupleAndKeywords(args, kwds, 'S|fp:device.send_and_receive', @keyPointerArray[0], @pyBytes, @timeout, @logging) <> 0 then begin data := PyBytesAsBytes(pyBytes); var response := False; .... .... if response then begin pyBytes := PyBytes_FromStringAndSize(PAnsiChar(data), Length(data)); Result := pyBytes; end else Result := ReturnNone; end else Result := nil; end; end; TPyDevice = class(TPyObject) ... constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; // Basic services function Repr : PPyObject; override; function Str : PPyObject; override; function GetAttr(Key: PAnsiChar): PPyObject; override; function SetAttr(Key: PAnsiChar; Value: PPyObject): Integer; override; // Methods of TPyDevice ... // Class methods class procedure RegisterMethods(PythonType: TPythonType); override; class procedure RegisterMembers(PythonType: TPythonType); override; class procedure RegisterGetSets(PythonType: TPythonType); override; // Interface methods function DoSendAndReceive(args, kwds: PPyObject): PPyObject; cdecl; ... end; class procedure TPyDevice.RegisterMethods(PythonType: TPythonType); begin inherited; with PythonType do begin AddMethod('send_and_receive', @TPyDevice.DoSendAndReceive, 'device_manager.device.send_and_recive(data: bytes)'); .... end; end; FPythonType_Device := TPythonType.Create(nil); FPythonType_Device.Name := 'FPythonType_Device'; FPythonType_Device.GenerateCreateFunction := False; FPythonType_Device.Engine := FEngine; FPythonType_Device.OnInitialization := OnInitialization_PythonType_Device; FPythonType_Device.TypeName := 'Device'; FPythonType_Device.Prefix := ''; FPythonType_Device.Services.Basic := [bsGetAttr, bsSetAttr, bsRepr, bsStr]; FPythonType_Device.Module := FPythonModule_DeviceManager; pDevice := FPythonType_Device.CreateInstance; FEngine.CheckError; device := TPyDevice(PythonToDelphi(pDevice)); FPythonModule_DeviceManager.SetVar('device', pDevice); FEngine.Py_DecRef(pDevice);
But I get TypeError: send_and_receive() takes no keyword arguments. Execution of the send_and_receive function will not start at all. I looked at the Demo32 example, but there it is used with CreateWith which has parameters args, kwds: PPyObject already PythoEngine.pas
Thank you in advance for your help.
-
It's really not easy, so I'll accept the imperfection and try to solve it sometime in the future. Thanks
-
Couldn't this be done at the Python level using a decorator above the module?
import types class MyModule(types.ModuleType): def __setattr__(self, name, value): print(f"Setting attribute {name} to value {value}") super().__setattr__(name, value) mymodule = MyModule('mymodule') mymodule.my_attribute = 42 print(mymodule.my_attribute)
-
Hi,
Let's take Demo08 as an example where a myPoint object is created in Delphi. I need to detect on the Delphi side if the assignment spam.myPoint = None is made in Python. Cyclic polling using PythonModule1.GetVar('myPoint') is inappropriate for me. I would need something like OnChange in TPythonDelphiVar. I've studied PythonEngine.pas and can't think of anything.
Thank you for your opinion. -
I finally found a way to make a package
import importlib import types import sys # Package name package_name = 'my_package' # List of modules to be part of the package module_names = ['module1', 'module2'] # Create an empty package package = types.ModuleType(package_name) package.__path__ = [] # Import and add individual modules to the package for module_name in module_names: module = importlib.import_module(module_name) setattr(package, module_name, module) # Set __all__ to the list of module names package.__all__ = module_names # Add the package to the list of imported modules sys.modules[package_name] = package
Then it is possible
import my_package from my_package import module1 from my_package import module2 as T print(dir(module1)) print(dir(my_package.module1)) print(dir(T))
Only this import my_package.module1 as T is not possible.
ModuleNotFoundError: No module named 'my_package.sub_module1'
Does anyone know why?
Using Delphi enum in Python
in Python4Delphi
Posted
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();