Merge pull request #347 from filmor/add-pysetargv · pythonnet/pythonnet@7cab332 · GitHub
Skip to content

Commit 7cab332

Browse files
committed
Merge pull request #347 from filmor/add-pysetargv
Closes #347
2 parents f7f2fc0 + 3785c40 commit 7cab332

3 files changed

Lines changed: 125 additions & 28 deletions

File tree

src/embed_tests/InitializeTest.cs

Lines changed: 24 additions & 2 deletions

src/runtime/pythonengine.cs

Lines changed: 84 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,39 @@
22
using System.IO;
33
using System.Threading;
44
using System.Reflection;
5+
using System.Collections.Generic;
6+
using System.Linq;
57

68
namespace 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
}

src/runtime/runtime.cs

Lines changed: 17 additions & 2 deletions

0 commit comments

Comments
 (0)