Skip to content

Commit ab86012

Browse files
committed
Fix #377
Added ExecFile method.
1 parent c73d8bb commit ab86012

File tree

1 file changed

+87
-44
lines changed

1 file changed

+87
-44
lines changed

Source/PythonEngine.pas

Lines changed: 87 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,25 +1871,26 @@ TPythonEngine = class(TPythonInterface)
18711871
procedure SetPythonHome(const PythonHome: UnicodeString);
18721872
procedure SetProgramName(const ProgramName: UnicodeString);
18731873
function IsType(ob: PPyObject; obt: PPyTypeObject): Boolean;
1874-
function Run_CommandAsString(const command : AnsiString; mode : Integer) : string;
1875-
function Run_CommandAsObject(const command : AnsiString; mode : Integer) : PPyObject;
1876-
function Run_CommandAsObjectWithDict(const command : AnsiString; mode : Integer; locals, globals : PPyObject) : PPyObject;
1874+
function Run_CommandAsString(const command: AnsiString; mode: Integer; const FileName: string = '<string>'): string;
1875+
function Run_CommandAsObject(const command: AnsiString; mode: Integer; const FileName: string = '<string>'): PPyObject;
1876+
function Run_CommandAsObjectWithDict(const command: AnsiString; mode: Integer; locals, globals: PPyObject; const FileName: string = '<string>'): PPyObject;
18771877
function EncodeString (const str: UnicodeString): AnsiString; {$IFDEF FPC}overload;{$ENDIF}
18781878
{$IFDEF FPC}
18791879
overload;
18801880
function EncodeString (const str: AnsiString): AnsiString; overload;
18811881
{$ENDIF}
1882-
function EncodeWindowsFilePath (const str: string): AnsiString;
1883-
procedure ExecString(const command : AnsiString); overload;
1884-
procedure ExecStrings( strings : TStrings ); overload;
1885-
function EvalString(const command : AnsiString) : PPyObject; overload;
1886-
function EvalStringAsStr(const command : AnsiString) : string;
1887-
function EvalStrings( strings : TStrings ) : PPyObject; overload;
1888-
procedure ExecString(const command : AnsiString; locals, globals : PPyObject ); overload;
1889-
procedure ExecStrings( strings : TStrings; locals, globals : PPyObject ); overload;
1890-
function EvalString( const command : AnsiString; locals, globals : PPyObject ) : PPyObject; overload;
1891-
function EvalStrings( strings : TStrings; locals, globals : PPyObject ) : PPyObject; overload;
1892-
function EvalStringsAsStr( strings : TStrings ) : string;
1882+
function EncodeWindowsFilePath(const str: string): AnsiString;
1883+
procedure ExecString(const command: AnsiString; const FileName: string = '<string>'); overload;
1884+
procedure ExecStrings(strings: TStrings; const FileName: string = '<string>'); overload;
1885+
procedure ExecString(const command: AnsiString; locals, globals: PPyObject; const FileName: string = '<string>'); overload;
1886+
procedure ExecFile(const FileName: string; locals: PPyObject = nil; globals: PPyObject = nil); overload;
1887+
procedure ExecStrings(strings: TStrings; locals, globals: PPyObject; const FileName: string = '<string>'); overload;
1888+
function EvalString(const command: AnsiString; const FileName: string = '<string>'): PPyObject; overload;
1889+
function EvalStringAsStr(const command: AnsiString; const FileName: string = '<string>'): string;
1890+
function EvalStrings(strings: TStrings; const FileName: string = '<string>'): PPyObject; overload;
1891+
function EvalString(const command: AnsiString; locals, globals: PPyObject; const FileName: string = '<string>'): PPyObject; overload;
1892+
function EvalStrings(strings: TStrings; locals, globals: PPyObject; const FileName: string = '<string>'): PPyObject; overload;
1893+
function EvalStringsAsStr(strings: TStrings; const FileName: string = '<string>'): string;
18931894
function EvalPyFunction(pyfunc, pyargs:PPyObject): Variant;
18941895
function EvalFunction(pyfunc:PPyObject; const args: array of const): Variant;
18951896
function EvalFunctionNoArgs(pyfunc:PPyObject): Variant;
@@ -4882,40 +4883,55 @@ function TPythonEngine.EvalFunctionNoArgs(pyfunc:PPyObject): Variant;
48824883
end;
48834884
end;
48844885

4885-
function TPythonEngine.EvalStringAsStr(const command : AnsiString) : string;
4886+
function TPythonEngine.EvalStringAsStr(const command: AnsiString; const
4887+
FileName: string = '<string>'): string;
48864888
begin
4887-
Result := Run_CommandAsString( command, eval_input );
4889+
Result := Run_CommandAsString(command, eval_input, FileName);
48884890
end;
48894891

4890-
function TPythonEngine.EvalString(const command : AnsiString) : PPyObject;
4892+
function TPythonEngine.EvalString(const command: AnsiString; const FileName:
4893+
string = '<string>'): PPyObject;
48914894
begin
4892-
Result := Run_CommandAsObject( command, eval_input );
4895+
Result := Run_CommandAsObject(command, eval_input, FileName);
48934896
end;
48944897

4895-
procedure TPythonEngine.ExecString(const command : AnsiString);
4898+
procedure TPythonEngine.ExecString(const command: AnsiString; const FileName:
4899+
string = '<string>');
48964900
begin
4897-
Py_XDecRef( Run_CommandAsObject( command, file_input ) );
4901+
Py_XDecRef(Run_CommandAsObject(command, file_input, FileName));
48984902
end;
48994903

4900-
function TPythonEngine.Run_CommandAsString(const command : AnsiString; mode : Integer) : string;
4904+
function TPythonEngine.Run_CommandAsString(const command: AnsiString; mode:
4905+
Integer; const FileName: string = '<string>'): string;
49014906
var
4902-
v : PPyObject;
4907+
PRes : PPyObject;
49034908
begin
49044909
Result := '';
4905-
v := Run_CommandAsObject( command, mode );
4906-
Result := PyObjectAsString( v );
4907-
Py_XDECREF(v);
4910+
PRes := Run_CommandAsObject(command, mode, FileName);
4911+
Result := PyObjectAsString(PRes);
4912+
Py_XDECREF(PRes);
49084913
end;
49094914

4910-
function TPythonEngine.Run_CommandAsObject(const command : AnsiString; mode : Integer) : PPyObject;
4915+
function TPythonEngine.Run_CommandAsObject(const command: AnsiString; mode:
4916+
Integer; const FileName: string = '<string>'): PPyObject;
49114917
begin
4912-
Result := Run_CommandAsObjectWithDict(command, mode, nil, nil);
4918+
Result := Run_CommandAsObjectWithDict(command, mode, nil, nil, FileName);
49134919
end;
49144920

4915-
function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; mode : Integer; locals, globals : PPyObject) : PPyObject;
4921+
function TPythonEngine.Run_CommandAsObjectWithDict(const command: AnsiString;
4922+
mode: Integer; locals, globals: PPyObject; const FileName: string =
4923+
'<string>'): PPyObject;
4924+
{
4925+
This is the core function for executing/evaluating python code
4926+
Parameters:
4927+
- command: utf-8 encoded AnsiString with the code that will be executed or evaluated
4928+
- mode: one of the constants file_input, single_input, eval_input
4929+
- locals, globals: python dictionaries with local/global namespaces. Can be nil.
4930+
- FileName; optional string used when debugging code with external debuggers
4931+
}
49164932
var
49174933
m : PPyObject;
4918-
_locals, _globals : PPyObject;
4934+
_locals, _globals, Code : PPyObject;
49194935
begin
49204936
CheckPython;
49214937
Result := nil;
@@ -4941,7 +4957,11 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; m
49414957
_globals := _locals;
49424958

49434959
try
4944-
Result := PyRun_String(PAnsiChar(CleanString(command)), mode, _globals, _locals);
4960+
Code := Py_CompileString(PAnsiChar(CleanString(command)),
4961+
PAnsiChar(EncodeString(FileName)), mode);
4962+
if Code = nil then
4963+
CheckError(False);
4964+
Result := PyEval_EvalCode(Code, _globals, _locals );
49454965
if Result = nil then
49464966
CheckError(False);
49474967
except
@@ -4952,39 +4972,62 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; m
49524972
end;
49534973
end;
49544974

4955-
procedure TPythonEngine.ExecStrings( strings : TStrings );
4975+
procedure TPythonEngine.ExecStrings(strings: TStrings; const FileName: string =
4976+
'<string>');
4977+
begin
4978+
Py_XDecRef(Run_CommandAsObject(EncodeString(strings.Text), file_input, FileName));
4979+
end;
4980+
4981+
function TPythonEngine.EvalStrings(strings: TStrings; const FileName: string =
4982+
'<string>'): PPyObject;
49564983
begin
4957-
Py_XDecRef( Run_CommandAsObject( EncodeString(strings.Text) , file_input ) );
4984+
Result := Run_CommandAsObject(EncodeString(strings.Text) , eval_input, FileName);
49584985
end;
49594986

4960-
function TPythonEngine.EvalStrings( strings : TStrings ) : PPyObject;
4987+
procedure TPythonEngine.ExecFile(const FileName: string; locals,
4988+
globals: PPyObject);
4989+
var
4990+
SL: TStringList;
49614991
begin
4962-
Result := Run_CommandAsObject( EncodeString(strings.Text) , eval_input );
4992+
SL := TStringList.Create;
4993+
try
4994+
SL.LoadFromFile(FileName);
4995+
ExecStrings(SL, locals, globals, FileName);
4996+
finally
4997+
SL.Free;
4998+
end;
49634999
end;
49645000

4965-
procedure TPythonEngine.ExecString(const command : AnsiString; locals, globals : PPyObject );
5001+
procedure TPythonEngine.ExecString(const command: AnsiString; locals, globals:
5002+
PPyObject; const FileName: string = '<string>');
49665003
begin
4967-
Py_XDecRef( Run_CommandAsObjectWithDict( command, file_input, locals, globals ) );
5004+
Py_XDecRef(Run_CommandAsObjectWithDict(command, file_input, locals, globals, FileName));
49685005
end;
49695006

4970-
procedure TPythonEngine.ExecStrings( strings : TStrings; locals, globals : PPyObject );
5007+
procedure TPythonEngine.ExecStrings(strings: TStrings; locals, globals:
5008+
PPyObject; const FileName: string = '<string>');
49715009
begin
4972-
Py_XDecRef( Run_CommandAsObjectWithDict( EncodeString(strings.Text), file_input, locals, globals ) );
5010+
Py_XDecRef( Run_CommandAsObjectWithDict(EncodeString(strings.Text),
5011+
file_input, locals, globals, FileName));
49735012
end;
49745013

4975-
function TPythonEngine.EvalString( const command : AnsiString; locals, globals : PPyObject ) : PPyObject;
5014+
function TPythonEngine.EvalString(const command: AnsiString; locals, globals:
5015+
PPyObject; const FileName: string = '<string>'): PPyObject;
49765016
begin
4977-
Result := Run_CommandAsObjectWithDict( command, eval_input, locals, globals );
5017+
Result := Run_CommandAsObjectWithDict(command, eval_input, locals, globals, FileName);
49785018
end;
49795019

4980-
function TPythonEngine.EvalStrings( strings : TStrings; locals, globals : PPyObject ) : PPyObject;
5020+
function TPythonEngine.EvalStrings(strings: TStrings; locals, globals:
5021+
PPyObject; const FileName: string = '<string>'): PPyObject;
49815022
begin
4982-
Result := Run_CommandAsObjectWithDict( EncodeString(strings.Text), eval_input, locals, globals );
5023+
Result := Run_CommandAsObjectWithDict(EncodeString(strings.Text),
5024+
eval_input, locals, globals, FileName);
49835025
end;
49845026

4985-
function TPythonEngine.EvalStringsAsStr( strings : TStrings ) : string;
5027+
function TPythonEngine.EvalStringsAsStr(strings: TStrings; const FileName:
5028+
string = '<string>'): string;
49865029
begin
4987-
Result := Run_CommandAsString( EncodeString(strings.Text), eval_input );
5030+
Result := Run_CommandAsString(EncodeString(strings.Text), eval_input, FileName);
49885031
end;
49895032

49905033
function TPythonEngine.CheckEvalSyntax( const str : AnsiString ) : Boolean;

0 commit comments

Comments
 (0)