From 4c42c6c636d97a9e72b012f3ec1338be2f547fbc Mon Sep 17 00:00:00 2001 From: pyscripter Date: Sat, 8 Mar 2025 00:54:27 +0200 Subject: [PATCH 1/6] Fix #495 --- Source/PythonEngine.pas | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/PythonEngine.pas b/Source/PythonEngine.pas index dd43d6eb..ec974172 100644 --- a/Source/PythonEngine.pas +++ b/Source/PythonEngine.pas @@ -1034,7 +1034,7 @@ PyConfig = record {$IFDEF CPU64BITS} ((8, 80, 88, 144, 156, 160, 164, 172, 224, 104, 240, 248, 256, 272), (8, 80, 88, 144, 156, 160, 164, 172, 224, 104, 240, 248, 256, 272), - (8, 80, 104, 152, 168, 172, 176, 184, 232, 240, 256, 272, 280, 296), + (8, 80, 104, 152, 168, 172, 176, 184, 240, 248, 264, 280, 288, 304), (8, 96, 120, 168, 184, 188, 192, 200, 264, 272, 288, 304, 312, 336), (8, 96, 120, 168, 184, 188, 192, 200, 268, 272, 288, 304, 312, 336), (8, 96, 120, 168, 184, 188, 192, 200, 272, 280, 296, 312, 320, 344)); @@ -4730,7 +4730,7 @@ procedure TPythonEngine.DoOpenDll(const aDllName : string); procedure TPythonEngine.Initialize; - procedure ConfgigPEP587(var ErrMsg: string); + procedure ConfigPEP587(var ErrMsg: string); // Initialize according to PEP587 available since python 3.8 procedure AssignPyFlags(var Config: PyConfig); @@ -4855,7 +4855,7 @@ procedure TPythonEngine.Initialize; end; end; - procedure ConfgigPEP741(var ErrMsg: string); + procedure ConfigPEP741(var ErrMsg: string); // Initialize according to PEP587 available since python 3.8 procedure AssignPyFlags(Config: PPyInitConfig); @@ -5039,9 +5039,9 @@ procedure TPythonEngine.Initialize; else begin if (MajorVersion > 3) or (MinorVersion >= 14) then - ConfgigPEP741(ErrMsg) + ConfigPEP741(ErrMsg) else - ConfgigPEP587(ErrMsg); + ConfigPEP587(ErrMsg); if not FInitialized then begin From e0164565660d44ca623cb08eccf2d5aa5ff8fa90 Mon Sep 17 00:00:00 2001 From: pyscripter Date: Wed, 9 Apr 2025 17:28:47 +0300 Subject: [PATCH 2/6] Added PyLong_AsVoidPtr --- Source/PythonEngine.pas | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/PythonEngine.pas b/Source/PythonEngine.pas index ec974172..ff16be8d 100644 --- a/Source/PythonEngine.pas +++ b/Source/PythonEngine.pas @@ -1649,6 +1649,7 @@ TPythonInterface=class(TDynamicDll) PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl; PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl; PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl; + PyLong_AsVoidPtr:function(ob:PPyObject): Pointer; PyLong_FromVoidPtr:function(p: Pointer): PPyObject; cdecl; PyMapping_Check:function (ob:PPyObject):integer; cdecl; PyMapping_GetItemString:function (ob:PPyObject;key:PAnsiChar):PPyObject; cdecl; @@ -3984,6 +3985,7 @@ procedure TPythonInterface.MapDll; PyLong_FromLongLong := Import('PyLong_FromLongLong'); PyLong_FromUnsignedLongLong := Import('PyLong_FromUnsignedLongLong'); PyLong_AsLongLong := Import('PyLong_AsLongLong'); + PyLong_AsVoidPtr := Import('PyLong_AsVoidPtr'); PyLong_FromVoidPtr := Import('PyLong_FromVoidPtr'); PyMapping_Check := Import('PyMapping_Check'); PyMapping_GetItemString := Import('PyMapping_GetItemString'); From 83f6b5ee3e24d35a27c73bb3fbe433a78a391d15 Mon Sep 17 00:00:00 2001 From: pyscripter Date: Thu, 10 Apr 2025 05:23:15 +0300 Subject: [PATCH 3/6] Handle Pointer fields, properties and parameters - stored as python integers. --- Source/PythonEngine.pas | 2 +- Source/WrapDelphi.pas | 32 ++++++++++++++++++++++---------- Tests/WrapDelphiTest.pas | 9 +++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Source/PythonEngine.pas b/Source/PythonEngine.pas index ff16be8d..c15fbf48 100644 --- a/Source/PythonEngine.pas +++ b/Source/PythonEngine.pas @@ -1649,7 +1649,7 @@ TPythonInterface=class(TDynamicDll) PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl; PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl; PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl; - PyLong_AsVoidPtr:function(ob:PPyObject): Pointer; + PyLong_AsVoidPtr:function(ob:PPyObject): Pointer; cdecl; PyLong_FromVoidPtr:function(p: Pointer): PPyObject; cdecl; PyMapping_Check:function (ob:PPyObject):integer; cdecl; PyMapping_GetItemString:function (ob:PPyObject;key:PAnsiChar):PPyObject; cdecl; diff --git a/Source/WrapDelphi.pas b/Source/WrapDelphi.pas index bed385ea..a19bc718 100644 --- a/Source/WrapDelphi.pas +++ b/Source/WrapDelphi.pas @@ -1042,7 +1042,7 @@ implementation rs_ExpectedNil = 'In static methods Self should be nil'; rs_ExpectedInterface = 'Expected a Pascal interface'; rs_ExpectedSequence = 'Expected a python sequence'; - rsExpectedPPyObject = 'Expected a PPyObject'; + rsExpectedPointer = 'Expected a Pointer'; rs_InvalidClass = 'Invalid class'; rs_ErrEventNotReg = 'No Registered EventHandler for events of type "%s'; rs_ErrEventNoSuport = 'Class %s does not support events because it must '+ @@ -2188,12 +2188,16 @@ function ValidateDynArray(PyValue: PPyObject; const RttiType: TRttiType; end; end; -function ValidatePPyObject(PyValue: PPyObject; const RttiType: TRttiType; +function ValidatePointer(PyValue: PPyObject; const RttiType: TRttiType; out ParamValue: TValue; out ErrMsg: string): Boolean; var RefType: TRttiType; + PyEngine: TPythonEngine; + P: Pointer; begin Result := False; + PyEngine := GetPythonEngine; + if (RTTIType is TRttiPointerType) then begin RefType := TRttiPointerType(RTTIType).ReferredType; @@ -2201,10 +2205,21 @@ function ValidatePPyObject(PyValue: PPyObject; const RttiType: TRttiType; begin Result := True; ParamValue := TValue.From(PyValue); + end + else if PyEngine.PyLong_Check(PyValue) then + begin + P := PyEngine.PyLong_AsVoidPtr(PyValue); + if PyEngine.PyErr_Occurred = nil then + begin + Result := True; + ParamValue := TValue.From(P); + end + else + PyEngine.PyErr_Clear; end; end; if not Result then - ErrMsg := rsExpectedPPyObject; + ErrMsg := rsExpectedPointer; end; function PyObjectToTValue(PyArg: PPyObject; ArgType: TRttiType; @@ -2238,7 +2253,7 @@ function PyObjectToTValue(PyArg: PPyObject; ArgType: TRttiType; tkDynArray: Result := ValidateDynArray(PyArg, ArgType, Arg, ErrMsg); tkPointer: - Result := ValidatePPyObject(PyArg, ArgType, Arg, ErrMsg); + Result := ValidatePointer(PyArg, ArgType, Arg, ErrMsg); else Result := SimplePythonToValue(PyArg, ArgType.Handle, Arg, ErrMsg); end; @@ -2277,7 +2292,7 @@ function TValueToPyObject(const Value: TValue; DelphiWrapper: TPyDelphiWrapper; out ErrMsg: string): PPyObject; begin if Value.IsEmpty then - Result := GetPythonEngine.ReturnNone + Result := DelphiWrapper.Engine.ReturnNone else case Value.Kind of tkClass: Result := DelphiWrapper.Wrap(Value.AsObject); @@ -2288,13 +2303,10 @@ function TValueToPyObject(const Value: TValue; tkArray, tkDynArray: Result := DynArrayToPython(Value, DelphiWrapper, ErrMsg); tkPointer: - if Value.IsType then + if Value.TypeInfo = TypeInfo(PPyObject) then Result := Value.AsType else - begin - Result := nil; - ErrMsg := rs_ErrValueToPython; - end; + Result := DelphiWrapper.Engine.PyLong_FromVoidPtr(Value.AsType); else Result := SimpleValueToPython(Value, ErrMsg); end; diff --git a/Tests/WrapDelphiTest.pas b/Tests/WrapDelphiTest.pas index 350b0bb2..d320f53a 100644 --- a/Tests/WrapDelphiTest.pas +++ b/Tests/WrapDelphiTest.pas @@ -55,6 +55,7 @@ TTestRttiAccess = class ObjectField: TObject; RecordField: TTestRecord; InterfaceField: ITestInterface; + PointerField: Pointer; ClassRef: TClass; function GetData: TObject; procedure BuyFruits(AFruits: TFruits); @@ -160,6 +161,8 @@ TTestWrapDelphi = class(TObject) procedure TestVarArgs; [Test] procedure TestPPyObjects; + [Test] + procedure TestPointers; end; implementation @@ -439,6 +442,12 @@ procedure TTestWrapDelphi.TestPPyObjects; Assert.AreEqual(List.GetItem(0), 'abc'); end; +procedure TTestWrapDelphi.TestPointers; +begin + rtti_var.PointerField := $FFFF; + Assert.AreEqual(rtti_var.PointerField, $FFFF); +end; + procedure TTestWrapDelphi.TestRecord; begin Rtti_rec.StringField := 'abcd'; From 92717b84a747285b5cb932f71ec454317329239d Mon Sep 17 00:00:00 2001 From: pyscripter Date: Sun, 13 Apr 2025 02:15:28 +0300 Subject: [PATCH 4/6] Fix #497 --- Source/VarPyth.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/VarPyth.pas b/Source/VarPyth.pas index b16f91b8..52607cf0 100644 --- a/Source/VarPyth.pas +++ b/Source/VarPyth.pas @@ -2154,7 +2154,7 @@ procedure VarPyToStrings(const AValue : Variant; const AStrings: TStrings); V: Variant; begin for V in VarPyIterate(AValue) do - AStrings.Add(V) + AStrings.Add(VarPythonAsString(V)) end; initialization From 179b7a666d3b2d765b0014681e2cc757097e1876 Mon Sep 17 00:00:00 2001 From: pyscripter Date: Thu, 1 May 2025 16:15:52 +0300 Subject: [PATCH 5/6] Made python code compatible with recent versions of numpy and matplotlib. --- Tutorials/Webinar II/VizDemo/MainFormSVG.dfm | 42 +++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm b/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm index cda1daa9..0d78949a 100644 --- a/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm +++ b/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm @@ -10,17 +10,12 @@ object Form1: TForm1 Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] - OldCreateOrder = False OnCreate = FormCreate - PixelsPerInch = 96 TextHeight = 13 object Splitter1: TSplitter Left = 489 Top = 0 Height = 613 - ExplicitLeft = 528 - ExplicitTop = 280 - ExplicitHeight = 100 end object SVGIconImage1: TSVGIconImage Left = 960 @@ -35,8 +30,6 @@ object Form1: TForm1 Width = 543 Height = 613 AutoSize = False - ParentDoubleBuffered = False - DoubleBuffered = True Align = alClient end object PageControl1: TPageControl @@ -46,7 +39,7 @@ object Form1: TForm1 Height = 613 ActivePage = TabSheet1 Align = alLeft - TabOrder = 2 + TabOrder = 0 object TabSheet1: TTabSheet Caption = 'matplotlib' object Panel1: TPanel @@ -63,8 +56,6 @@ object Form1: TForm1 Height = 3 Cursor = crVSplit Align = alBottom - ExplicitTop = 10 - ExplicitWidth = 492 end object SynEdit1: TSynEdit Left = 1 @@ -72,6 +63,7 @@ object Form1: TForm1 Width = 479 Height = 444 Align = alClient + CaseSensitive = True Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -13 @@ -85,6 +77,8 @@ object Form1: TForm1 Gutter.Font.Height = -11 Gutter.Font.Name = 'Consolas' Gutter.Font.Style = [] + Gutter.Font.Quality = fqClearTypeNatural + Gutter.Bands = <> Highlighter = SynPythonSyn1 Lines.Strings = ( 'from delphi_module import svg_image' @@ -102,10 +96,16 @@ object Form1: TForm1 '# stores the date as an np.datetime64 with a day unit ('#39'D'#39') in t' + 'he date column.' - - 'price_data = (cbook.get_sample_data('#39'goog.npz'#39', np_load=True)['#39'p' + - 'rice_data'#39']' - ' .view(np.recarray))' + '# Load Google stock price data from Matplotlib'#39's sample data' + 'data = cbook.get_sample_data('#39'goog.npz'#39')' + '' + '# Handle different return types from get_sample_data' + 'if isinstance(data, np.lib.npyio.NpzFile):' + ' # Already an NpzFile, access price_data directly' + ' price_data = data['#39'price_data'#39'].view(np.recarray)' + 'else:' + ' # Assume data is a path or file-like object, use np.load' + ' price_data = np.load(data)['#39'price_data'#39'].view(np.recarray)' 'price_data = price_data[-250:] # get the most recent 250 tradin' + 'g days' @@ -138,6 +138,7 @@ object Form1: TForm1 'svg_image.SvgText = figdata_svg' '' '#plt.show()') + ScrollbarAnnotations = <> end object Panel2: TPanel Left = 1 @@ -183,8 +184,6 @@ object Form1: TForm1 Height = 3 Cursor = crVSplit Align = alBottom - ExplicitTop = 151 - ExplicitWidth = 433 end object SynEdit2: TSynEdit Left = 1 @@ -192,6 +191,7 @@ object Form1: TForm1 Width = 479 Height = 376 Align = alClient + CaseSensitive = True Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -13 @@ -205,6 +205,8 @@ object Form1: TForm1 Gutter.Font.Height = -11 Gutter.Font.Name = 'Consolas' Gutter.Font.Style = [] + Gutter.Font.Quality = fqClearTypeNatural + Gutter.Bands = <> Highlighter = SynPythonSyn1 Lines.Strings = ( 'from delphi_module import svg_image' @@ -222,6 +224,7 @@ object Form1: TForm1 '' '#plt.show()' '') + ScrollbarAnnotations = <> end object Panel6: TPanel Left = 1 @@ -252,9 +255,6 @@ object Form1: TForm1 end end object SynPythonSyn1: TSynPythonSyn - Options.AutoDetectEnabled = False - Options.AutoDetectLineLimit = 0 - Options.Visible = False Left = 632 Top = 40 end @@ -264,6 +264,10 @@ object Form1: TForm1 Top = 89 end object PythonEngine1: TPythonEngine + DllName = 'python313.dll' + APIVersion = 1013 + RegVersion = '3.13' + UseLastKnownVersion = False IO = PythonGUIInputOutput1 Left = 632 Top = 136 From 8b4a78f5b6d62822db65fae543b61ce99a208007 Mon Sep 17 00:00:00 2001 From: pyscripter Date: Sat, 21 Jun 2025 23:17:48 +0300 Subject: [PATCH 6/6] EPySystemExit was not fully specified. --- Source/PythonEngine.pas | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Source/PythonEngine.pas b/Source/PythonEngine.pas index c15fbf48..422146b0 100644 --- a/Source/PythonEngine.pas +++ b/Source/PythonEngine.pas @@ -5570,9 +5570,7 @@ procedure TPythonEngine.RaiseError; s_type := GetTypeAsString(err_type); s_value := PyObjectAsString(err_value); - if (PyErr_GivenExceptionMatches(err_type, PyExc_SystemExit^) <> 0) then - raise Define( EPySystemExit.Create(''), s_type, s_value ) - else if (PyErr_GivenExceptionMatches(err_type, PyExc_StopIteration^) <> 0) then + if (PyErr_GivenExceptionMatches(err_type, PyExc_StopIteration^) <> 0) then raise Define( EPyStopIteration.Create(''), s_type, s_value ) else if (PyErr_GivenExceptionMatches(err_type, PyExc_KeyboardInterrupt^) <> 0) then raise Define( EPyKeyboardInterrupt.Create(''), s_type, s_value ) @@ -6606,6 +6604,7 @@ procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False); var errtype, errvalue, errtraceback: PPyObject; SErrValue: string; + SystemExit: EPySystemExit; begin // PyErr_Fetch clears the error. The returned python objects are new references PyErr_Fetch(errtype, errvalue, errtraceback); @@ -6614,7 +6613,11 @@ procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False); Py_XDECREF(errtype); Py_XDECREF(errvalue); Py_XDECREF(errtraceback); - raise EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]); + + SystemExit := EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]); + SystemExit.EValue := SErrValue; + SystemExit.EName := 'SystemExit'; + raise SystemExit; end; var pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy