22using System . IO ;
33using System . Threading ;
44using System . Reflection ;
5+ using System . Collections . Generic ;
6+ using System . Linq ;
57
68namespace Python . Runtime
79{
810 /// <summary>
911 /// This class provides the public interface of the Python runtime.
1012 /// </summary>
11- public class PythonEngine
13+ public class PythonEngine : IDisposable
1214 {
1315 private static DelegateManager delegateManager ;
1416 private static bool initialized ;
1517
18+ public PythonEngine ( )
19+ {
20+ Initialize ( ) ;
21+ }
22+
23+ public PythonEngine ( params string [ ] args )
24+ {
25+ Initialize ( args ) ;
26+ }
27+
28+ public PythonEngine ( IEnumerable < string > args )
29+ {
30+ Initialize ( args ) ;
31+ }
32+
33+ public void Dispose ( )
34+ {
35+ Shutdown ( ) ;
36+ }
37+
1638 #region Properties
1739
1840 public static bool IsInitialized
@@ -102,6 +124,11 @@ public static int RunSimpleString(string code)
102124
103125 #endregion
104126
127+ public static void Initialize ( )
128+ {
129+ Initialize ( Enumerable . Empty < string > ( ) ) ;
130+ }
131+
105132 /// <summary>
106133 /// Initialize Method
107134 /// </summary>
@@ -112,7 +139,7 @@ public static int RunSimpleString(string code)
112139 /// first call. It is *not* necessary to hold the Python global
113140 /// interpreter lock (GIL) to call this method.
114141 /// </remarks>
115- public static void Initialize ( )
142+ public static void Initialize ( IEnumerable < string > args )
116143 {
117144 if ( ! initialized )
118145 {
@@ -126,6 +153,8 @@ public static void Initialize()
126153 initialized = true ;
127154 Exceptions . Clear ( ) ;
128155
156+ Py . SetArgv ( args ) ;
157+
129158 // register the atexit callback (this doesn't use Py_AtExit as the C atexit
130159 // callbacks are called after python is fully finalized but the python ones
131160 // are called while the python engine is still running).
@@ -187,7 +216,8 @@ public static void Initialize()
187216 // when it is imported by the CLR extension module.
188217 //====================================================================
189218#if PYTHON3
190- public static IntPtr InitExt ( ) {
219+ public static IntPtr InitExt ( )
220+ {
191221#elif PYTHON2
192222 public static void InitExt ( )
193223 {
@@ -351,10 +381,7 @@ public static void EndAllowThreads(IntPtr ts)
351381 public static PyObject ImportModule ( string name )
352382 {
353383 IntPtr op = Runtime . PyImport_ImportModule ( name ) ;
354- if ( op == IntPtr . Zero )
355- {
356- return null ;
357- }
384+ Py . Throw ( ) ;
358385 return new PyObject ( op ) ;
359386 }
360387
@@ -370,10 +397,7 @@ public static PyObject ImportModule(string name)
370397 public static PyObject ReloadModule ( PyObject module )
371398 {
372399 IntPtr op = Runtime . PyImport_ReloadModule ( module . Handle ) ;
373- if ( op == IntPtr . Zero )
374- {
375- throw new PythonException ( ) ;
376- }
400+ Py . Throw ( ) ;
377401 return new PyObject ( op ) ;
378402 }
379403
@@ -389,15 +413,9 @@ public static PyObject ReloadModule(PyObject module)
389413 public static PyObject ModuleFromString ( string name , string code )
390414 {
391415 IntPtr c = Runtime . Py_CompileString ( code , "none" , ( IntPtr ) 257 ) ;
392- if ( c == IntPtr . Zero )
393- {
394- throw new PythonException ( ) ;
395- }
416+ Py . Throw ( ) ;
396417 IntPtr m = Runtime . PyImport_ExecCodeModule ( name , c ) ;
397- if ( m == IntPtr . Zero )
398- {
399- throw new PythonException ( ) ;
400- }
418+ Py . Throw ( ) ;
401419 return new PyObject ( m ) ;
402420 }
403421
@@ -445,10 +463,7 @@ public static PyObject RunString(
445463 code , flag , globals . Value , locals . Value
446464 ) ;
447465
448- if ( Runtime . PyErr_Occurred ( ) != 0 )
449- {
450- throw new PythonException ( ) ;
451- }
466+ Py . Throw ( ) ;
452467
453468 return new PyObject ( result ) ;
454469 }
@@ -500,7 +515,7 @@ public class KeywordArguments : PyDict
500515 public static KeywordArguments kw ( params object [ ] kv )
501516 {
502517 var dict = new KeywordArguments ( ) ;
503- if ( kv . Length % 2 != 0 )
518+ if ( kv . Length % 2 != 0 )
504519 throw new ArgumentException ( "Must have an equal number of keys and values" ) ;
505520 for ( int i = 0 ; i < kv . Length ; i += 2 )
506521 {
@@ -521,5 +536,50 @@ public static PyObject Import(string name)
521536 {
522537 return PythonEngine . ImportModule ( name ) ;
523538 }
539+
540+ public static void SetArgv ( )
541+ {
542+ IEnumerable < string > args ;
543+ try
544+ {
545+ args = Environment . GetCommandLineArgs ( ) ;
546+ }
547+ catch ( NotSupportedException )
548+ {
549+ args = Enumerable . Empty < string > ( ) ;
550+ }
551+
552+ SetArgv (
553+ new [ ] { "" } . Concat (
554+ Environment . GetCommandLineArgs ( ) . Skip ( 1 )
555+ )
556+ ) ;
557+ }
558+
559+ public static void SetArgv ( params string [ ] argv )
560+ {
561+ SetArgv ( argv as IEnumerable < string > ) ;
562+ }
563+
564+ public static void SetArgv ( IEnumerable < string > argv )
565+ {
566+ using ( GIL ( ) )
567+ {
568+ var arr = argv . ToArray ( ) ;
569+ Runtime . PySys_SetArgvEx ( arr . Length , arr , 0 ) ;
570+ Py . Throw ( ) ;
571+ }
572+ }
573+
574+ internal static void Throw ( )
575+ {
576+ using ( GIL ( ) )
577+ {
578+ if ( Runtime . PyErr_Occurred ( ) != 0 )
579+ {
580+ throw new PythonException ( ) ;
581+ }
582+ }
583+ }
524584 }
525585}
0 commit comments