@@ -344,6 +344,20 @@ TPythonVersionProp = record
344
344
PyBUF_READ = $100 ;
345
345
PyBUF_WRITE = $200 ;
346
346
347
+ const
348
+ // constants used in PyModuleDef slots from moduleobject.h
349
+ Py_mod_create = 1 ;
350
+ Py_mod_exec = 2 ;
351
+ Py_mod_multiple_interpreters = 3 ; // Added in version 3.12
352
+ Py_mod_gil = 4 ; // Added in version 3.13
353
+
354
+ Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED: Pointer = Pointer(0 );
355
+ Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED: Pointer = Pointer(1 );
356
+ Py_MOD_PER_INTERPRETER_GIL_SUPPORTED: Pointer = Pointer(2 );
357
+
358
+ Py_MOD_GIL_USED: Pointer = Pointer(0 );
359
+ Py_MOD_GIL_NOT_USED: Pointer = Pointer(1 );
360
+
347
361
// #######################################################
348
362
// ## ##
349
363
// ## Non-Python specific constants ##
@@ -643,6 +657,10 @@ TPythonVersionProp = record
643
657
m_free : inquiry;
644
658
end ;
645
659
660
+ // signature of functions used in slots
661
+ Py_create_module_function = function(spec: PPyObject; def: PPyModuleDef):PPyObject; cdecl;
662
+ Py_exec_module_function = function(module : PPyObject): Integer; cdecl;
663
+
646
664
// pybuffer.h
647
665
648
666
PPy_buffer = ^Py_Buffer;
@@ -1541,6 +1559,9 @@ TPythonInterface=class(TDynamicDll)
1541
1559
PyCallable_Check: function(ob : PPyObject): integer; cdecl;
1542
1560
1543
1561
PyModule_Create2: function(moduledef: PPyModuleDef; Api_Version: Integer):PPyObject; cdecl;
1562
+ PyModuleDef_Init: function(moduledef: PPyModuleDef):PPyObject; cdecl;
1563
+ PyModule_ExecDef: function(module : PPyObject; moduledef: PPyModuleDef):Integer; cdecl;
1564
+ PyModule_FromDefAndSpec2: function(moduledef: PPyModuleDef; spec: PPyObject; Api_Version: Integer):PPyObject; cdecl;
1544
1565
PyErr_BadArgument: function: integer; cdecl;
1545
1566
PyErr_BadInternalCall: procedure; cdecl;
1546
1567
PyErr_CheckSignals: function: integer; cdecl;
@@ -2173,7 +2194,7 @@ TPythonEngine = class(TPythonInterface)
2173
2194
property IO: TPythonInputOutput read FIO write SetIO;
2174
2195
property PyFlags: TPythonFlags read FPyFlags write SetPyFlags default DEFAULT_FLAGS;
2175
2196
property RedirectIO: Boolean read FRedirectIO write FRedirectIO default True;
2176
- property UseWindowsConsole: Boolean read FUseWindowsConsole write FUseWindowsConsole default False;
2197
+ property UseWindowsConsole: Boolean read FUseWindowsConsole write SetUseWindowsConsole default False;
2177
2198
property OnAfterInit: TNotifyEvent read FOnAfterInit write FOnAfterInit;
2178
2199
property OnSysPathInit: TSysPathInitEvent read FOnSysPathInit write FOnSysPathInit;
2179
2200
property OnConfigInit: TConfigInitEvent read FOnConfigInit write FOnConfigInit;
@@ -2534,12 +2555,6 @@ TPythonModule = class(TMethodsContainer)
2534
2555
end ;
2535
2556
2536
2557
2537
- // -------------------------------------------------------
2538
- // -- --
2539
- // --class: TPythonType derived from TGetSetContainer --
2540
- // -- --
2541
- // -------------------------------------------------------
2542
-
2543
2558
{
2544
2559
A B C
2545
2560
+-------------------++------------------------------------------------------+
@@ -2556,15 +2571,15 @@ TPythonModule = class(TMethodsContainer)
2556
2571
by GetSelf
2557
2572
2558
2573
- a Python object must start at A.
2559
- - a Delphi class class must start at B
2574
+ - a Delphi class must start at B
2560
2575
- TPyObject.InstanceSize will return C-B
2561
2576
- Sizeof(TPyObject) will return C-B
2562
2577
- The total memory allocated for a TPyObject instance will be C-A,
2563
2578
even if its InstanceSize is C-B.
2564
- - When turning a Python object pointer into a Delphi instance pointer, PythonToDelphi
2565
- will offset the pointer from A to B.
2566
- - When turning a Delphi instance into a Python object pointer, GetSelf will offset
2567
- Self from B to A.
2579
+ - When turning a Python object pointer into a Delphi instance pointer,
2580
+ PythonToDelphi will offset the pointer from A to B.
2581
+ - When turning a Delphi instance into a Python object pointer, GetSelf
2582
+ will offset Self from B to A.
2568
2583
- Properties ob_refcnt and ob_type will call GetSelf to access their data.
2569
2584
2570
2585
Further Notes:
@@ -2581,7 +2596,6 @@ TPythonModule = class(TMethodsContainer)
2581
2596
FreeInstance.
2582
2597
- This class is heart of the P4D library. Pure magic!!
2583
2598
}
2584
- // The base class of all new Python types
2585
2599
TPyObject = class
2586
2600
private
2587
2601
function Get_ob_refcnt : NativeUInt;
@@ -2751,6 +2765,13 @@ TTypeServices = class(TPersistent)
2751
2765
property Mapping : TMappingServices read FMapping write FMapping;
2752
2766
end ;
2753
2767
2768
+ // -------------------------------------------------------
2769
+ // -- --
2770
+ // --class: TPythonType derived from TGetSetContainer --
2771
+ // -- --
2772
+ // -------------------------------------------------------
2773
+
2774
+ // The base class of all new Python types
2754
2775
// The component that initializes the Python type and
2755
2776
// that creates instances of itself.
2756
2777
{ $IF not Defined(FPC) and (CompilerVersion >= 23)}
@@ -3901,6 +3922,9 @@ procedure TPythonInterface.MapDll;
3901
3922
PyDict_SetItemString := Import (' PyDict_SetItemString' );
3902
3923
PyDictProxy_New := Import (' PyDictProxy_New' );
3903
3924
PyModule_Create2 := Import (' PyModule_Create2' );
3925
+ PyModuleDef_Init := Import (' PyModuleDef_Init' );
3926
+ PyModule_ExecDef := Import (' PyModule_ExecDef' );
3927
+ PyModule_FromDefAndSpec2 := Import (' PyModule_FromDefAndSpec2' );
3904
3928
PyErr_Print := Import (' PyErr_Print' );
3905
3929
PyErr_SetNone := Import (' PyErr_SetNone' );
3906
3930
PyErr_SetObject := Import (' PyErr_SetObject' );
@@ -5072,6 +5096,19 @@ procedure TPythonEngine.Initialize;
5072
5096
if not Initialized then
5073
5097
Initialize;
5074
5098
5099
+
5100
+ { $IFDEF MSWINDOWS}
5101
+ if not FRedirectIO and UseWindowsConsole then
5102
+ PyRun_SimpleString(
5103
+ ' import sys, io' #10 +
5104
+ ' sys.stdout = io.TextIOWrapper(open("CONOUT$", "wb", buffering=0), ' +
5105
+ ' encoding="utf-8", errors="replace", line_buffering=True)' #10 +
5106
+ ' sys.stderr = io.TextIOWrapper(open("CONOUT$", "wb", buffering=0), ' +
5107
+ ' encoding="utf-8", errors="replace", line_buffering=False)' #10 +
5108
+ ' sys.stdin = io.TextIOWrapper(open("CONIN$", "rb", buffering=0), ' +
5109
+ ' encoding="utf-8", errors="replace", line_buffering=True)' #10 );
5110
+ { $ENDIF}
5111
+
5075
5112
if InitScript.Count > 0 then
5076
5113
ExecStrings(InitScript);
5077
5114
if Assigned(FOnAfterInit) then
@@ -5127,10 +5164,12 @@ procedure TPythonEngine.InitWinConsole;
5127
5164
FreeConsole;
5128
5165
AllocConsole;
5129
5166
SetConsoleTitle( ' Python console' );
5167
+ SetConsoleOutputCP(CP_UTF8);
5168
+ SetConsoleCP(CP_UTF8);
5130
5169
{ $ENDIF}
5131
5170
end ;
5132
5171
5133
- procedure TPythonEngine.SetUseWindowsConsole ( const Value : Boolean );
5172
+ procedure TPythonEngine.SetUseWindowsConsole (const Value : Boolean);
5134
5173
begin
5135
5174
FUseWindowsConsole := Value ;
5136
5175
if (csDesigning in ComponentState) then
0 commit comments