@@ -78,6 +78,9 @@ interface
7878  SysUtils,
7979  SyncObjs,
8080  Variants,
81+ // DAV>>>
82+   System.AnsiStrings, Data.SqlTimSt,
83+ // DAV<<<
8184{ $IFDEF DELPHI2005_OR_HIGHER} 
8285{ $IFNDEF UNICODE} 
8386  WideStrings,
@@ -138,7 +141,12 @@ interface
138141    (DllName: ' python33.dll' ' 3.3' 1013 ; CanUseLatest: True),
139142    (DllName: ' python34.dll' ' 3.4' 1013 ; CanUseLatest: True),
140143    (DllName: ' python35.dll' ' 3.5' 1013 ; CanUseLatest: True),
144+ { $IFDEF DEBUG} 
145+     //  (DllName: 'python36_d.dll'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True) );
141146    (DllName: ' python36.dll' ' 3.6' 1013 ; CanUseLatest: True),
147+ { $ELSE} 
148+     (DllName: ' python36.dll' ' 3.6' 1013 ; CanUseLatest: True),
149+ { $ENDIF} 
142150    (DllName: ' python37.dll' ' 3.7' 1013 ; CanUseLatest: True) );
143151{ $ENDIF} 
144152{ $IFDEF LINUX} 
@@ -193,12 +201,14 @@ interface
193201{ $IFDEF PYTHON36} 
194202  COMPILED_FOR_PYTHON_VERSION_INDEX = 12 ;
195203{ $ENDIF} 
196- { $IFDEF PYTHON36 } 
204+ { $IFDEF PYTHON37 } 
197205  COMPILED_FOR_PYTHON_VERSION_INDEX = 13 ;
198206{ $ENDIF} 
199-   PYT_METHOD_BUFFER_INCREASE = 10 ;
200-   PYT_MEMBER_BUFFER_INCREASE = 10 ;
201-   PYT_GETSET_BUFFER_INCREASE = 10 ;
207+ // DAV>>>   !!! ReallocMethods, ReallocMembers, ReallocGetSets don't work correctly !!! 
208+   PYT_METHOD_BUFFER_INCREASE = 100 ;
209+   PYT_MEMBER_BUFFER_INCREASE = 100 ;
210+   PYT_GETSET_BUFFER_INCREASE = 100 ;
211+ // DAV<<<
202212
203213  METH_VARARGS  = $0001 ;
204214  METH_KEYWORDS = $0002 ;
@@ -1389,7 +1399,7 @@    EPyWindowsError = class (EPyOSError);
13891399
13901400  { $IF not Defined(FPC) and (CompilerVersion >= 23)} 
13911401  [ComponentPlatformsAttribute(pidWin32 or  pidWin64)]
1392-   { $IFEND } 
1402+   { $ENDIF } 
13931403  TPythonInputOutput = class (TComponent)
13941404  protected 
13951405    FMaxLines        : Integer;
@@ -1916,6 +1926,7 @@   TPythonInterface=class(TDynamicDll)
19161926    _PyObject_New:function (obt:PPyTypeObject;ob:PPyObject):PPyObject; cdecl;
19171927    _PyString_Resize:function (var  ob:PPyObject;i:NativeInt):integer; cdecl;
19181928    Py_Finalize                     : procedure; cdecl;
1929+     Py_FinalizeEx                   : function : Integer;
19191930    PyErr_ExceptionMatches          : function ( exc : PPyObject) : Integer; cdecl;
19201931    PyErr_GivenExceptionMatches     : function ( raised_exc, exc : PPyObject) : Integer; cdecl;
19211932    PyEval_EvalCode                 : function ( co : PPyCodeObject; globals, locals : PPyObject) : PPyObject; cdecl;
@@ -2130,7 +2141,7 @@   TPythonTraceback = class
21302141
21312142  { $IF not Defined(FPC) and (CompilerVersion >= 23)} 
21322143  [ComponentPlatformsAttribute(pidWin32 or  pidWin64)]
2133-   { $IFEND } 
2144+   { $ENDIF } 
21342145  TPythonEngine = class (TPythonInterface)
21352146  private 
21362147    FInitScript:                 TStrings;
@@ -2598,7 +2609,7 @@   TErrors = class(TCollection)
25982609
25992610  { $IF not Defined(FPC) and (CompilerVersion >= 23)} 
26002611  [ComponentPlatformsAttribute(pidWin32 or  pidWin64)]
2601-   { $IFEND } 
2612+   { $ENDIF } 
26022613  TPythonModule = class (TMethodsContainer)
26032614    protected 
26042615      FModuleName : AnsiString;
@@ -2633,6 +2644,9 @@   TPythonModule = class(TMethodsContainer)
26332644      procedure  SetVar ( const  varName : AnsiString; value  : PPyObject );
26342645      function   GetVar ( const  varName : AnsiString ) : PPyObject;
26352646      procedure  DeleteVar ( const  varName : AnsiString );
2647+ // DAV>>>
2648+       procedure  ClearVars ;
2649+ // DAV<<<
26362650      procedure  SetVarFromVariant ( const  varName : AnsiString; const  value  : Variant );
26372651      function   GetVarAsVariant ( const  varName: AnsiString ) : Variant;
26382652
@@ -2863,7 +2877,7 @@   TTypeServices = class(TPersistent)
28632877  //  that creates instances of itself.
28642878  { $IF not Defined(FPC) and (CompilerVersion >= 23)} 
28652879  [ComponentPlatformsAttribute(pidWin32 or  pidWin64)]
2866-   { $IFEND } 
2880+   { $ENDIF } 
28672881  TPythonType = class (TGetSetContainer)
28682882    protected 
28692883      FType : PyTypeObject;
@@ -2951,7 +2965,7 @@   TPythonType = class(TGetSetContainer)
29512965
29522966  { $IF not Defined(FPC) and (CompilerVersion >= 23)} 
29532967  [ComponentPlatformsAttribute(pidWin32 or  pidWin64)]
2954-   { $IFEND } 
2968+   { $ENDIF } 
29552969  TPythonDelphiVar = class ( TEngineClient )
29562970    protected 
29572971      FModule    : AnsiString;
@@ -4002,6 +4016,8 @@ procedure TPythonInterface.MapDll;
40024016  else 
40034017    _PyString_Resize          :=Import (' _PyBytes_Resize' 
40044018  Py_Finalize                :=Import (' Py_Finalize' 
4019+   if  IsPython3000 then 
4020+     Py_FinalizeEx            :=Import (' Py_FinalizeEx' 
40054021  if  getProcAddress( FDLLHandle, ' PyCode_Addr2Line' nil  then 
40064022    DLL_PyCode_Addr2Line     := Import (' PyCode_Addr2Line' 
40074023  if  getProcAddress( FDLLHandle, ' PyImport_ExecCodeModule' nil  then 
@@ -4614,13 +4630,16 @@ procedure TPythonEngine.Finalize;
46144630            Finalize;
46154631        end ;
46164632  //  Then finalize Python, if we have to
4617-   if  Initialized and  FAutoFinalize then 
4633+   if  Initialized and  FAutoFinalize then   begin 
46184634    try 
4619-       FFinalizing := True;
4620-       Py_Finalize;
4621-     finally 
4622-       FFinalizing := False;
4623-     end ;
4635+       try 
4636+         FFinalizing := True;
4637+         Py_Finalize;
4638+       finally 
4639+         FFinalizing := False;
4640+       end ;
4641+     except  end ;
4642+   end ;
46244643  //  Detach our clients, when engine is beeing destroyed or one of its clients.
46254644  canDetachClients := csDestroying in  ComponentState;
46264645  if  not  canDetachClients then 
@@ -4899,48 +4918,37 @@ procedure TPythonEngine.Notification( AComponent: TComponent;
48994918procedure  TPythonEngine.CheckRegistry ;
49004919{ $IFDEF MSWINDOWS} 
49014920var 
4902-   key : string;
4903-   Path : string;
4904-   NewPath : string;
4905-   MajorVersion : integer;
4906-   MinorVersion : integer;
4907-   VersionSuffix: string;
4921+   key : String;
4922+   path : String;
49084923{ $ENDIF} 
49094924begin 
49104925{ $IFDEF MSWINDOWS} 
4911-   if  Assigned( FOnPathInitialization ) then 
49124926  try 
4913-     with  TRegistry.Create(KEY_ALL_ACCESS  and  not  KEY_NOTIFY) do 
4927+     with  TRegistry.Create(KEY_READ  and  not  KEY_NOTIFY) do 
49144928      try 
4915-         MajorVersion := StrToInt(RegVersion[1 ]);
4916-         MinorVersion := StrToInt(RegVersion[3 ]);
4917-         VersionSuffix := ' ' 
4918- { $IFDEF CPUX86} 
4919-         if  (MajorVersion > 3 ) or  ((MajorVersion = 3 )  and  (MinorVersion >= 5 )) then 
4920-           VersionSuffix := ' -32' 
4921- { $ENDIF} 
4922-         key := Format(' \Software\Python\PythonCore\%s%s\PythonPath' 
4923- 
4929+         // Access := KEY_READ; // works only with Delphi5 or greater
49244930        RootKey := HKEY_LOCAL_MACHINE;
4931+         key := Format(' \Software\Python\PythonCore\%s\PythonPath' 
49254932        if  not  KeyExists( key ) then 
4926-         begin 
4927-           //  try a current user installation
4928-           RootKey := HKEY_CURRENT_USER;
4929-           if  not  KeyExists( key ) then   Exit;
4930-         end ;
4931-         //  Key found
4932-         OpenKey( key, True );
4933-         try 
4934-           Path := ReadString(' ' 
4935-           NewPath := Path;
4936-           FOnPathInitialization( Self, NewPath );
4937-           if  NewPath <> Path then 
49384933          begin 
4939-             WriteString( ' ' 
4934+             //  try a current user installation
4935+             RootKey := HKEY_CURRENT_USER;
4936+             if  not  KeyExists( key ) then 
4937+             begin 
4938+               if  Assigned( FOnPathInitialization ) then 
4939+                 begin 
4940+                   path := ' ' 
4941+                   FOnPathInitialization( Self, path );
4942+                   if  path <> ' ' then 
4943+                     begin 
4944+                       // Access := KEY_ALL_ACCESS; // works only with Delphi5 or greater
4945+                       OpenKey( key, True );
4946+                       WriteString( ' ' 
4947+                       CloseKey;
4948+                     end ;
4949+                 end ;
4950+             end ;
49404951          end ;
4941-         finally 
4942-           CloseKey;
4943-         end ;
49444952      finally 
49454953        Free;
49464954      end ;
@@ -5731,6 +5739,9 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
57315739  Disp : IDispatch;
57325740  DispID : Integer;
57335741  args : PPyObject;
5742+ // DAV>>>
5743+   l_dtSQLTimeStamp: TSQLTimeStamp;
5744+ // DAV<<<
57345745begin 
57355746  Disp := nil ;
57365747  // Dereference Variant
@@ -5829,22 +5840,51 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
58295840        Result := ReturnNone;
58305841      end 
58315842    else 
5832-       try 
5833-         Disp := DeRefV;
5834-         wStr := ' __asPPyObject__' 
5835-         //  detect if the variant supports this special property
5836-         if  Assigned(Disp) and  (Disp.GetIDsOfNames(GUID_NULL, @wStr, 1 , 0 , @DispID) = S_OK) then 
5837-         begin 
5838-           myInt := DeRefV.__asPPyObject__;  // Returns the address to PPyObject as integer. (See impl. in PythonAtom.pas)
5839-           Result := PPyObject(myInt);
5840-           Py_XIncRef(Result);
5843+ // DAV>>>
5844+       if  VarIsSQLTimeStamp(V) then  begin 
5845+         l_dtSQLTimeStamp := VarToSQLTimeStamp(V);
5846+         dt := SQLTimeStampToDateTime(l_dtSQLTimeStamp);
5847+         DecodeDate( dt, y, m, d );
5848+         DecodeTime( dt, h, mi, sec, ms );
5849+         if  (DatetimeConversionMode = dcmToTuple) then  begin 
5850+           wd := (DayOfWeek( dt ) + 7  - 2 ) mod  7 ; //  In Python, Monday is the first day (=0)
5851+           jd := Round(EncodeDate(y,m,d)-EncodeDate(y,1 ,1 ))+1 ; //  This shoud be the Julian day, the day in a year (0-366)
5852+           dl := -1 ; //  This is daylight save...
5853+           Result := ArrayToPyTuple( [y, m, d, h, mi, sec, wd, jd, dl] );
5854+         end 
5855+         else  if  (DatetimeConversionMode = dcmToDatetime) then  begin 
5856+           if  not  Assigned(FPyDateTime_DateTimeType) then 
5857+             raise EPythonError.Create(' dcmToDatetime DatetimeConversionMode cannot be used with this version of python. Missing module datetime' 
5858+           args := ArrayToPyTuple([y, m, d, h, mi, sec, ms*1000 ]);
5859+           try 
5860+             Result := PyEval_CallObjectWithKeywords(FPyDateTime_DateTimeType, args, nil );
5861+             CheckError(False);
5862+           finally 
5863+             Py_DecRef(args);
5864+           end ;
58415865        end 
5842-         else  // If variant don't implement __asPPyObject__, then we have to return nothing.
5866+         else 
5867+           raise EPythonError.Create(' Invalid DatetimeConversionMode' 
5868+       end 
5869+       else  begin 
5870+ // DAV<<<
5871+         try 
5872+           Disp := DeRefV;
5873+           wStr := ' __asPPyObject__' 
5874+           //  detect if the variant supports this special property
5875+           if  Assigned(Disp) and  (Disp.GetIDsOfNames(GUID_NULL, @wStr, 1 , 0 , @DispID) = S_OK) then 
5876+           begin 
5877+             myInt := DeRefV.__asPPyObject__;  // Returns the address to PPyObject as integer. (See impl. in PythonAtom.pas)
5878+             Result := PPyObject(myInt);
5879+             Py_XIncRef(Result);
5880+           end 
5881+           else  // If variant don't implement __asPPyObject__, then we have to return nothing.
5882+             Result := ReturnNone;
5883+         except 
5884+           //  if something went wrong, just return none!
58435885          Result := ReturnNone;
5844-       except 
5845-         //  if something went wrong, just return none!
5846-         Result := ReturnNone;
5847-       end ; //  of try
5886+         end ; //  of try
5887+       end ;
58485888  end ; //  of case
58495889end ;
58505890
@@ -6029,7 +6069,7 @@ function TPythonEngine.VarRecAsPyObject( v : TVarRec ) : PPyObject;
60296069    vtString:
60306070    begin 
60316071      if  Assigned(v.VString) then 
6032-         Result := PyString_FromString( StrPCopy( buff, v.VString^) )
6072+         Result := PyString_FromString( System.AnsiStrings. StrPCopy( buff, v.VString^) )
60336073      else 
60346074        Result := PyString_FromString( ' ' 
60356075    end ;
@@ -6155,7 +6195,7 @@ function TPythonEngine.ArrayToPyDict( items : array of const) : PPyObject;
61556195      vtAnsiString:
61566196        begin 
61576197          if  Assigned(v.VAnsiString) then 
6158-             Result := StrPas(PAnsiChar(Ansistring(v.VAnsiString)))
6198+             Result := System.AnsiStrings. StrPas(PAnsiChar(Ansistring(v.VAnsiString)))
61596199          else 
61606200            Result := ' ' 
61616201        end ;
@@ -6807,8 +6847,9 @@ function TMethodsContainer.AddMethod( AMethodName  : PAnsiChar;
68076847                                      AMethod  : PyCFunction;
68086848                                      ADocString : PAnsiChar ) : PPyMethodDef;
68096849begin 
6810-   if  FMethodCount = FAllocatedMethodCount then 
6850+   if  FMethodCount = FAllocatedMethodCount then   begin 
68116851    ReallocMethods;
6852+   end ;
68126853  Result := Methods[ MethodCount ];
68136854  Result^.ml_name  := AMethodName;
68146855  Result^.ml_meth  := AMethod;
@@ -7582,6 +7623,19 @@ procedure TPythonModule.DeleteVar( const varName : AnsiString );
75827623    raise EPythonError.CreateFmt( ' Can'' t delete var "%s" in module "%s", because it is not yet initialized' 
75837624end ;
75847625
7626+ // DAV>>>
7627+ procedure  TPythonModule.ClearVars ;
7628+ var 
7629+  dict : PPyObject;
7630+ begin 
7631+  if  Assigned(FEngine) and  Assigned( FModule ) then 
7632+    with  Engine do  begin 
7633+      dict := PyModule_GetDict( Module  );
7634+      PyDict_Clear(dict);
7635+    end ;
7636+ end ;
7637+ // DAV<<<
7638+ 
75857639procedure  TPythonModule.SetVarFromVariant ( const  varName : AnsiString; const  value  : Variant );
75867640var 
75877641  obj : PPyObject;
0 commit comments