-
Notifications
You must be signed in to change notification settings - Fork 754
Add pysetargv #347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pysetargv #347
Changes from all commits
eca5ac9
331524f
a0849a9
4f67c5d
3785c40
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,17 +2,39 @@ | |
using System.IO; | ||
using System.Threading; | ||
using System.Reflection; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Python.Runtime | ||
{ | ||
/// <summary> | ||
/// This class provides the public interface of the Python runtime. | ||
/// </summary> | ||
public class PythonEngine | ||
public class PythonEngine : IDisposable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this now IDisposable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because that's easier to use correctly than |
||
{ | ||
private static DelegateManager delegateManager; | ||
private static bool initialized; | ||
|
||
public PythonEngine() | ||
{ | ||
Initialize(); | ||
} | ||
|
||
public PythonEngine(params string[] args) | ||
{ | ||
Initialize(args); | ||
} | ||
|
||
public PythonEngine(IEnumerable<string> args) | ||
{ | ||
Initialize(args); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Shutdown(); | ||
} | ||
|
||
#region Properties | ||
|
||
public static bool IsInitialized | ||
|
@@ -102,6 +124,11 @@ public static int RunSimpleString(string code) | |
|
||
#endregion | ||
|
||
public static void Initialize() | ||
{ | ||
Initialize(Enumerable.Empty<string>()); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i did not click submit review few weeks ago |
||
/// <summary> | ||
/// Initialize Method | ||
/// </summary> | ||
|
@@ -112,7 +139,7 @@ public static int RunSimpleString(string code) | |
/// first call. It is *not* necessary to hold the Python global | ||
/// interpreter lock (GIL) to call this method. | ||
/// </remarks> | ||
public static void Initialize() | ||
public static void Initialize(IEnumerable<string> args) | ||
{ | ||
if (!initialized) | ||
{ | ||
|
@@ -126,6 +153,8 @@ public static void Initialize() | |
initialized = true; | ||
Exceptions.Clear(); | ||
|
||
Py.SetArgv(args); | ||
|
||
// register the atexit callback (this doesn't use Py_AtExit as the C atexit | ||
// callbacks are called after python is fully finalized but the python ones | ||
// are called while the python engine is still running). | ||
|
@@ -187,7 +216,8 @@ public static void Initialize() | |
// when it is imported by the CLR extension module. | ||
//==================================================================== | ||
#if PYTHON3 | ||
public static IntPtr InitExt() { | ||
public static IntPtr InitExt() | ||
{ | ||
#elif PYTHON2 | ||
public static void InitExt() | ||
{ | ||
|
@@ -351,10 +381,7 @@ public static void EndAllowThreads(IntPtr ts) | |
public static PyObject ImportModule(string name) | ||
{ | ||
IntPtr op = Runtime.PyImport_ImportModule(name); | ||
if (op == IntPtr.Zero) | ||
{ | ||
return null; | ||
} | ||
Py.Throw(); | ||
return new PyObject(op); | ||
} | ||
|
||
|
@@ -370,10 +397,7 @@ public static PyObject ImportModule(string name) | |
public static PyObject ReloadModule(PyObject module) | ||
{ | ||
IntPtr op = Runtime.PyImport_ReloadModule(module.Handle); | ||
if (op == IntPtr.Zero) | ||
{ | ||
throw new PythonException(); | ||
} | ||
Py.Throw(); | ||
return new PyObject(op); | ||
} | ||
|
||
|
@@ -389,15 +413,9 @@ public static PyObject ReloadModule(PyObject module) | |
public static PyObject ModuleFromString(string name, string code) | ||
{ | ||
IntPtr c = Runtime.Py_CompileString(code, "none", (IntPtr)257); | ||
if (c == IntPtr.Zero) | ||
{ | ||
throw new PythonException(); | ||
} | ||
Py.Throw(); | ||
IntPtr m = Runtime.PyImport_ExecCodeModule(name, c); | ||
if (m == IntPtr.Zero) | ||
{ | ||
throw new PythonException(); | ||
} | ||
Py.Throw(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not also check for IntPtr.Zero? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because this function either returns null and sets an exception, or it returns a module. |
||
return new PyObject(m); | ||
} | ||
|
||
|
@@ -445,10 +463,7 @@ public static PyObject RunString( | |
code, flag, globals.Value, locals.Value | ||
); | ||
|
||
if (Runtime.PyErr_Occurred() != 0) | ||
{ | ||
throw new PythonException(); | ||
} | ||
Py.Throw(); | ||
|
||
return new PyObject(result); | ||
} | ||
|
@@ -500,7 +515,7 @@ public class KeywordArguments : PyDict | |
public static KeywordArguments kw(params object[] kv) | ||
{ | ||
var dict = new KeywordArguments(); | ||
if (kv.Length%2 != 0) | ||
if (kv.Length % 2 != 0) | ||
throw new ArgumentException("Must have an equal number of keys and values"); | ||
for (int i = 0; i < kv.Length; i += 2) | ||
{ | ||
|
@@ -521,5 +536,50 @@ public static PyObject Import(string name) | |
{ | ||
return PythonEngine.ImportModule(name); | ||
} | ||
|
||
public static void SetArgv() | ||
{ | ||
IEnumerable<string> args; | ||
try | ||
{ | ||
args = Environment.GetCommandLineArgs(); | ||
} | ||
catch (NotSupportedException) | ||
{ | ||
args = Enumerable.Empty<string>(); | ||
} | ||
|
||
SetArgv( | ||
new[] { "" }.Concat( | ||
Environment.GetCommandLineArgs().Skip(1) | ||
) | ||
); | ||
} | ||
|
||
public static void SetArgv(params string[] argv) | ||
{ | ||
SetArgv(argv as IEnumerable<string>); | ||
} | ||
|
||
public static void SetArgv(IEnumerable<string> argv) | ||
{ | ||
using (GIL()) | ||
{ | ||
var arr = argv.ToArray(); | ||
Runtime.PySys_SetArgvEx(arr.Length, arr, 0); | ||
Py.Throw(); | ||
} | ||
} | ||
|
||
internal static void Throw() | ||
{ | ||
using (GIL()) | ||
{ | ||
if (Runtime.PyErr_Occurred() != 0) | ||
{ | ||
throw new PythonException(); | ||
} | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first need to check that it is not null
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? If it is
null
, this will fail with aNullReferenceException
, perfectly fine. This PR is supposed to ensure thatsys.argv
is always initialised.