From c3fc7f08a0137c560840a0ebe2f2b401a83b3739 Mon Sep 17 00:00:00 2001 From: Victor Milovanov Date: Fri, 19 Feb 2021 12:52:50 -0800 Subject: [PATCH 1/4] allow comparing BorrowedReference to null --- src/runtime/BorrowedReference.cs | 8 ++++++++ src/runtime/importhook.cs | 6 +++--- src/runtime/tricks/NullOnly.cs | 12 ++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/runtime/tricks/NullOnly.cs diff --git a/src/runtime/BorrowedReference.cs b/src/runtime/BorrowedReference.cs index 2f5c347c7..d49f52fe9 100644 --- a/src/runtime/BorrowedReference.cs +++ b/src/runtime/BorrowedReference.cs @@ -28,6 +28,14 @@ public BorrowedReference(IntPtr pointer) => a.pointer == b.pointer; public static bool operator !=(BorrowedReference a, BorrowedReference b) => a.pointer != b.pointer; + public static bool operator ==(BorrowedReference reference, NullOnly @null) + => reference.IsNull; + public static bool operator !=(BorrowedReference reference, NullOnly @null) + => !reference.IsNull; + public static bool operator ==(NullOnly @null, BorrowedReference reference) + => reference.IsNull; + public static bool operator !=(NullOnly @null, BorrowedReference reference) + => !reference.IsNull; public override bool Equals(object obj) { if (obj is IntPtr ptr) diff --git a/src/runtime/importhook.cs b/src/runtime/importhook.cs index 066c765fe..13b45df51 100644 --- a/src/runtime/importhook.cs +++ b/src/runtime/importhook.cs @@ -155,7 +155,7 @@ public static unsafe NewReference GetCLRModule(BorrowedReference fromList = defa // find any items from the from list and get them from the root if they're not // already in the module dictionary - if (fromList != null && fromList != default) + if (fromList != null) { if (Runtime.PyTuple_Check(fromList)) { @@ -224,7 +224,7 @@ public static IntPtr __import__(IntPtr self, IntPtr argsRaw, IntPtr kw) if (num_args >= 4) { fromList = Runtime.PyTuple_GetItem(args, 3); - if (fromList != default && + if (fromList != null && Runtime.PyObject_IsTrue(fromList) == 1) { fromlist = true; @@ -297,7 +297,7 @@ public static IntPtr __import__(IntPtr self, IntPtr argsRaw, IntPtr kw) BorrowedReference modules = Runtime.PyImport_GetModuleDict(); BorrowedReference module = Runtime.PyDict_GetItem(modules, py_mod_name); - if (module != default) + if (module != null) { if (fromlist) { diff --git a/src/runtime/tricks/NullOnly.cs b/src/runtime/tricks/NullOnly.cs new file mode 100644 index 000000000..cc2679a61 --- /dev/null +++ b/src/runtime/tricks/NullOnly.cs @@ -0,0 +1,12 @@ +namespace Python.Runtime +{ + /// + /// An utility class, that can only have one value: null. + /// Useful for overloading operators on structs, + /// that have meaningful concept of null value (e.g. pointers and references). + /// + class NullOnly + { + private NullOnly() { } + } +} From 60bb68c2fab8bfb271dd4f7bab9e15af2a402e9c Mon Sep 17 00:00:00 2001 From: Victor Milovanov Date: Fri, 19 Feb 2021 12:53:04 -0800 Subject: [PATCH 2/4] removed unused Utf8Marshaler --- src/runtime/CustomMarshaler.cs | 45 ---------------------------------- 1 file changed, 45 deletions(-) diff --git a/src/runtime/CustomMarshaler.cs b/src/runtime/CustomMarshaler.cs index 4814e6c0b..3ef5cd662 100644 --- a/src/runtime/CustomMarshaler.cs +++ b/src/runtime/CustomMarshaler.cs @@ -189,49 +189,4 @@ public static ICustomMarshaler GetInstance(string cookie) return Instance; } } - - - /// - /// Custom Marshaler to deal with Managed String to Native - /// conversion on UTF-8. Use on functions that expect UTF-8 encoded - /// strings like `PyUnicode_FromStringAndSize` - /// - /// - /// If instead we used `MarshalAs(UnmanagedType.LPWStr)` the output to - /// `foo` would be `f\x00o\x00o\x00`. - /// - internal class Utf8Marshaler : MarshalerBase - { - private static readonly MarshalerBase Instance = new Utf8Marshaler(); - private static readonly Encoding PyEncoding = Encoding.UTF8; - - public override IntPtr MarshalManagedToNative(object managedObj) - { - var s = managedObj as string; - - if (s == null) - { - return IntPtr.Zero; - } - - byte[] bStr = PyEncoding.GetBytes(s + "\0"); - IntPtr mem = Marshal.AllocHGlobal(bStr.Length); - try - { - Marshal.Copy(bStr, 0, mem, bStr.Length); - } - catch (Exception) - { - Marshal.FreeHGlobal(mem); - throw; - } - - return mem; - } - - public static ICustomMarshaler GetInstance(string cookie) - { - return Instance; - } - } } From 50834ba7b50247ab71f57fcc0dd475027a531003 Mon Sep 17 00:00:00 2001 From: Victor Milovanov Date: Fri, 19 Feb 2021 13:28:27 -0800 Subject: [PATCH 3/4] introduced PyModule (inherits PyScope) changed PyScope to inherit from PyObject --- src/embed_tests/TestFinalizer.cs | 14 +++++- src/embed_tests/TestPythonException.cs | 4 +- src/embed_tests/TestRuntime.cs | 4 +- src/embed_tests/pyimport.cs | 4 +- src/embed_tests/pyinitialize.cs | 3 +- src/runtime/exceptions.cs | 21 ++++----- src/runtime/pymodule.cs | 41 ++++++++++++++++ src/runtime/pyscope.cs | 51 ++++++++++---------- src/runtime/pythonengine.cs | 65 +++++++------------------- src/runtime/pythonexception.cs | 4 +- src/runtime/runtime.cs | 44 +++++++++-------- src/runtime/runtime_state.cs | 9 ++-- src/testing/threadtest.cs | 4 +- 13 files changed, 145 insertions(+), 123 deletions(-) create mode 100644 src/runtime/pymodule.cs diff --git a/src/embed_tests/TestFinalizer.cs b/src/embed_tests/TestFinalizer.cs index 46e2fcdf1..c040e6930 100644 --- a/src/embed_tests/TestFinalizer.cs +++ b/src/embed_tests/TestFinalizer.cs @@ -101,7 +101,17 @@ public void CollectOnShutdown() PythonEngine.Shutdown(); garbage = Finalizer.Instance.GetCollectedObjects(); - Assert.IsEmpty(garbage); + + if (garbage.Count > 0) + { + PythonEngine.Initialize(); + string objects = string.Join("\n", garbage.Select(ob => + { + var obj = new PyObject(new BorrowedReference(ob)); + return $"{obj} [{obj.GetPythonType()}@{obj.Handle}]"; + })); + Assert.Fail("Garbage is not empty:\n" + objects); + } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] // ensure lack of references to obj @@ -173,7 +183,7 @@ public void SimpleTestMemory() bool oldState = Finalizer.Instance.Enable; try { - using (PyObject gcModule = PythonEngine.ImportModule("gc")) + using (PyModule gcModule = PyModule.Import("gc")) using (PyObject pyCollect = gcModule.GetAttr("collect")) { long span1 = CompareWithFinalizerOn(pyCollect, false); diff --git a/src/embed_tests/TestPythonException.cs b/src/embed_tests/TestPythonException.cs index 31addfba1..a74fc3a8b 100644 --- a/src/embed_tests/TestPythonException.cs +++ b/src/embed_tests/TestPythonException.cs @@ -46,7 +46,7 @@ public void TestPythonErrorTypeName() { try { - var module = PythonEngine.ImportModule("really____unknown___module"); + var module = PyModule.Import("really____unknown___module"); Assert.Fail("Unknown module should not be loaded"); } catch (PythonException ex) @@ -95,7 +95,7 @@ public void TestPythonExceptionFormatNoTraceback() { try { - var module = PythonEngine.ImportModule("really____unknown___module"); + var module = PyModule.Import("really____unknown___module"); Assert.Fail("Unknown module should not be loaded"); } catch (PythonException ex) diff --git a/src/embed_tests/TestRuntime.cs b/src/embed_tests/TestRuntime.cs index 59c66cc5e..32369190c 100644 --- a/src/embed_tests/TestRuntime.cs +++ b/src/embed_tests/TestRuntime.cs @@ -96,7 +96,7 @@ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test() // TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check. var threading = Runtime.Runtime.PyImport_ImportModule("threading"); Exceptions.ErrorCheck(threading); - var threadingDict = Runtime.Runtime.PyModule_GetDict(new BorrowedReference(threading)); + var threadingDict = Runtime.Runtime.PyModule_GetDict(threading); Exceptions.ErrorCheck(threadingDict); var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock"); if (lockType.IsNull) @@ -110,6 +110,8 @@ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test() Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance)); Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance)); + threading.Dispose(); + Runtime.Runtime.Py_Finalize(); } } diff --git a/src/embed_tests/pyimport.cs b/src/embed_tests/pyimport.cs index 24f31acff..b34a5d25b 100644 --- a/src/embed_tests/pyimport.cs +++ b/src/embed_tests/pyimport.cs @@ -52,7 +52,7 @@ public void Dispose() [Test] public void TestDottedName() { - PyObject module = PythonEngine.ImportModule("PyImportTest.test.one"); + var module = PyModule.Import("PyImportTest.test.one"); Assert.IsNotNull(module); } @@ -62,7 +62,7 @@ public void TestDottedName() [Test] public void TestSysArgsImportException() { - PyObject module = PythonEngine.ImportModule("PyImportTest.sysargv"); + var module = PyModule.Import("PyImportTest.sysargv"); Assert.IsNotNull(module); } diff --git a/src/embed_tests/pyinitialize.cs b/src/embed_tests/pyinitialize.cs index c774680dd..66a9a3f7c 100644 --- a/src/embed_tests/pyinitialize.cs +++ b/src/embed_tests/pyinitialize.cs @@ -175,7 +175,8 @@ public static void TestRunExitFuncs() { called = true; }; - atexit.InvokeMethod("register", callback.ToPython()); + atexit.InvokeMethod("register", callback.ToPython()).Dispose(); + atexit.Dispose(); Runtime.Runtime.Shutdown(); Assert.True(called); } diff --git a/src/runtime/exceptions.cs b/src/runtime/exceptions.cs index afd0bc14e..da8653853 100644 --- a/src/runtime/exceptions.cs +++ b/src/runtime/exceptions.cs @@ -95,8 +95,8 @@ internal static Exception ToException(IntPtr ob) /// public static class Exceptions { - internal static IntPtr warnings_module; - internal static IntPtr exceptions_module; + internal static PyModule warnings_module; + internal static PyModule exceptions_module; /// /// Initialization performed on startup of the Python runtime. @@ -104,15 +104,12 @@ public static class Exceptions internal static void Initialize() { string exceptionsModuleName = "builtins"; - exceptions_module = Runtime.PyImport_ImportModule(exceptionsModuleName); - - Exceptions.ErrorCheck(exceptions_module); - warnings_module = Runtime.PyImport_ImportModule("warnings"); - Exceptions.ErrorCheck(warnings_module); + exceptions_module = PyModule.Import(exceptionsModuleName); + warnings_module = PyModule.Import("warnings"); Type type = typeof(Exceptions); foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Static)) { - IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module, fi.Name); + IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module.obj, fi.Name); if (op != IntPtr.Zero) { fi.SetValue(type, op); @@ -147,8 +144,8 @@ internal static void Shutdown() Runtime.XDecref(op); fi.SetValue(null, IntPtr.Zero); } - Runtime.Py_CLEAR(ref exceptions_module); - Runtime.Py_CLEAR(ref warnings_module); + exceptions_module.Dispose(); + warnings_module.Dispose(); } /// @@ -348,9 +345,7 @@ public static void warn(string message, IntPtr exception, int stacklevel) Exceptions.RaiseTypeError("Invalid exception"); } - Runtime.XIncref(warnings_module); - IntPtr warn = Runtime.PyObject_GetAttrString(warnings_module, "warn"); - Runtime.XDecref(warnings_module); + IntPtr warn = Runtime.PyObject_GetAttrString(warnings_module.obj, "warn"); Exceptions.ErrorCheck(warn); IntPtr args = Runtime.PyTuple_New(3); diff --git a/src/runtime/pymodule.cs b/src/runtime/pymodule.cs new file mode 100644 index 000000000..800edb686 --- /dev/null +++ b/src/runtime/pymodule.cs @@ -0,0 +1,41 @@ +using System; + +namespace Python.Runtime +{ + public class PyModule : PyScope + { + internal PyModule(ref NewReference reference) : base(ref reference, PyScopeManager.Global) { } + public PyModule(PyObject o) : base(o.Reference, PyScopeManager.Global) { } + + /// + /// Given a module or package name, import the + /// module and return the resulting module object as a . + /// + /// Fully-qualified module or package name + public static PyModule Import(string name) + { + NewReference op = Runtime.PyImport_ImportModule(name); + PythonException.ThrowIfIsNull(op); + return new PyModule(ref op); + } + + /// + /// Reloads the module, and returns the updated object + /// + public PyModule Reload() + { + NewReference op = Runtime.PyImport_ReloadModule(this.Reference); + PythonException.ThrowIfIsNull(op); + return new PyModule(ref op); + } + + public static PyModule FromString(string name, string code) + { + using NewReference c = Runtime.Py_CompileString(code, "none", (int)RunFlagType.File); + PythonException.ThrowIfIsNull(c); + NewReference m = Runtime.PyImport_ExecCodeModule(name, c); + PythonException.ThrowIfIsNull(m); + return new PyModule(ref m); + } + } +} diff --git a/src/runtime/pyscope.cs b/src/runtime/pyscope.cs index 9d68b76fa..4d09004bd 100644 --- a/src/runtime/pyscope.cs +++ b/src/runtime/pyscope.cs @@ -22,15 +22,9 @@ public class PyGILAttribute : Attribute } [PyGIL] - public class PyScope : DynamicObject, IDisposable + public class PyScope : PyObject { - public readonly string Name; - - /// - /// the python Module object the scope associated with. - /// - readonly PyObject obj; - internal BorrowedReference Reference => obj.Reference; + public string Name { get; } /// /// the variable dict of the scope. Borrowed. @@ -49,20 +43,24 @@ public class PyScope : DynamicObject, IDisposable /// public event Action OnDispose; - /// - /// Constructor - /// - /// - /// Create a scope based on a Python Module. - /// - internal PyScope(ref NewReference ptr, PyScopeManager manager) + /// Create a scope based on a Python Module. + internal PyScope(ref NewReference reference, PyScopeManager manager) + : this(reference.DangerousMoveToPointer(), manager) { } + /// Create a scope based on a Python Module. + internal PyScope(BorrowedReference reference, PyScopeManager manager) + : this(reference.DangerousGetAddress(), manager) { - if (!Runtime.PyType_IsSubtype(Runtime.PyObject_TYPE(ptr), Runtime.PyModuleType)) + Runtime.XIncref(reference.DangerousGetAddress()); + } + + /// Create a scope based on a Python Module. + private PyScope(IntPtr ptr, PyScopeManager manager) : base(ptr) + { + if (!Runtime.PyType_IsSubtype(Runtime.PyObject_TYPE(Reference), Runtime.PyModuleType)) { throw new PyScopeException("object is not a module"); } Manager = manager ?? PyScopeManager.Global; - obj = ptr.MoveToPyObject(); //Refcount of the variables not increase variables = Runtime.PyModule_GetDict(Reference).DangerousGetAddress(); PythonException.ThrowIfIsNull(variables); @@ -72,7 +70,8 @@ internal PyScope(ref NewReference ptr, PyScopeManager manager) Runtime.PyEval_GetBuiltins() ); PythonException.ThrowIfIsNotZero(res); - this.Name = this.Get("__name__"); + using var name = this.Get("__name__"); + this.Name = name.As(); } /// @@ -118,7 +117,7 @@ public dynamic Import(string name, string asname = null) } else { - PyObject module = PythonEngine.ImportModule(name); + var module = PyModule.Import(name); Import(module, asname); return module; } @@ -132,7 +131,7 @@ public dynamic Import(string name, string asname = null) /// public void Import(PyScope scope, string asname) { - this.SetPyValue(asname, scope.obj.Handle); + this.SetPyValue(asname, scope.Handle); } /// @@ -169,7 +168,7 @@ public void ImportAll(string name) } else { - PyObject module = PythonEngine.ImportModule(name); + var module = PyModule.Import(name); ImportAll(module); } } @@ -503,16 +502,20 @@ public override bool TrySetMember(SetMemberBinder binder, object value) private void Check() { - if (this.obj.IsDisposed) + if (this.obj == IntPtr.Zero) { throw new PyScopeException($"The scope of name '{Name}' object has been disposed"); } } - public void Dispose() + protected override void Dispose(bool disposing) { + if (this.obj == IntPtr.Zero) + { + return; + } + base.Dispose(disposing); this.OnDispose?.Invoke(this); - this.obj.Dispose(); } } diff --git a/src/runtime/pythonengine.cs b/src/runtime/pythonengine.cs index 35ea3f6d2..b12309733 100644 --- a/src/runtime/pythonengine.cs +++ b/src/runtime/pythonengine.cs @@ -468,62 +468,27 @@ public static void EndAllowThreads(IntPtr ts) Runtime.PyEval_RestoreThread(ts); } + [Obsolete("Use PyModule.Import")] + public static PyObject ImportModule(string name) => PyModule.Import(name); - /// - /// ImportModule Method - /// - /// - /// Given a fully-qualified module or package name, import the - /// module and return the resulting module object as a PyObject - /// or null if an exception is raised. - /// - public static PyObject ImportModule(string name) - { - IntPtr op = Runtime.PyImport_ImportModule(name); - PythonException.ThrowIfIsNull(op); - return new PyObject(op); - } - - - /// - /// ReloadModule Method - /// - /// - /// Given a PyObject representing a previously loaded module, reload - /// the module. - /// + [Obsolete("Use PyModule.Reload")] public static PyObject ReloadModule(PyObject module) - { - IntPtr op = Runtime.PyImport_ReloadModule(module.Handle); - PythonException.ThrowIfIsNull(op); - return new PyObject(op); - } + => module is PyModule pyModule ? pyModule.Reload() : new PyModule(module).Reload(); - - /// - /// ModuleFromString Method - /// - /// - /// Given a string module name and a string containing Python code, - /// execute the code in and return a module of the given name. - /// + [Obsolete("Use PyModule.FromString")] public static PyObject ModuleFromString(string name, string code) - { - IntPtr c = Runtime.Py_CompileString(code, "none", (int)RunFlagType.File); - PythonException.ThrowIfIsNull(c); - IntPtr m = Runtime.PyImport_ExecCodeModule(name, c); - PythonException.ThrowIfIsNull(m); - return new PyObject(m); - } + => PyModule.FromString(name, code); + public static PyObject Compile(string code, string filename = "", RunFlagType mode = RunFlagType.File) { var flag = (int)mode; - IntPtr ptr = Runtime.Py_CompileString(code, filename, flag); + NewReference ptr = Runtime.Py_CompileString(code, filename, flag); PythonException.ThrowIfIsNull(ptr); - return new PyObject(ptr); + return ptr.MoveToPyObject(); } + /// /// Eval Method /// @@ -742,10 +707,12 @@ public static KeywordArguments kw(params object[] kv) return dict; } - public static PyObject Import(string name) - { - return PythonEngine.ImportModule(name); - } + /// + /// Given a module or package name, import the + /// module and return the resulting module object as a . + /// + /// Fully-qualified module or package name + public static PyModule Import(string name) => PyModule.Import(name); public static void SetArgv() { diff --git a/src/runtime/pythonexception.cs b/src/runtime/pythonexception.cs index 7dd4f0811..648888293 100644 --- a/src/runtime/pythonexception.cs +++ b/src/runtime/pythonexception.cs @@ -48,7 +48,7 @@ public PythonException() if (_pyTB != IntPtr.Zero) { - using PyObject tb_module = PythonEngine.ImportModule("traceback"); + using var tb_module = PyModule.Import("traceback"); Runtime.XIncref(_pyTB); using var pyTB = new PyObject(_pyTB); @@ -198,7 +198,7 @@ public string Format() using (PyObject pyType = new PyObject(type)) using (PyObject pyValue = new PyObject(value)) using (PyObject pyTB = new PyObject(tb)) - using (PyObject tb_mod = PythonEngine.ImportModule("traceback")) + using (PyObject tb_mod = PyModule.Import("traceback")) { var buffer = new StringBuilder(); var values = tb_mod.InvokeMethod("format_exception", pyType, pyValue, pyTB); diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index ec7f5e446..173bd294d 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -278,9 +278,8 @@ private static void InitPyMembers() _PyObject_NextNotImplemented = Get_PyObject_NextNotImplemented(); { - IntPtr sys = PyImport_ImportModule("sys"); - PyModuleType = PyObject_Type(sys); - XDecref(sys); + using var sys = PyImport_ImportModule("sys"); + PyModuleType = PyObject_Type(sys.DangerousMoveToPointer()); } } @@ -937,14 +936,14 @@ internal static NewReference PyRun_String(string code, RunFlagType st, BorrowedR /// Return value: New reference. /// This is a simplified interface to Py_CompileStringFlags() below, leaving flags set to NULL. /// - internal static IntPtr Py_CompileString(string str, string file, int start) + internal static NewReference Py_CompileString(string str, string file, int start) { using var strPtr = new StrPtr(str, Encoding.UTF8); using var fileObj = new PyString(file); return Delegates.Py_CompileStringObject(strPtr, fileObj.Reference, start, Utf8String, -1); } - internal static IntPtr PyImport_ExecCodeModule(string name, IntPtr code) + internal static NewReference PyImport_ExecCodeModule(string name, BorrowedReference code) { using var namePtr = new StrPtr(name, Encoding.UTF8); return Delegates.PyImport_ExecCodeModule(namePtr, code); @@ -1027,11 +1026,18 @@ internal static int PyObject_HasAttrString(BorrowedReference pointer, string nam internal static IntPtr PyObject_GetAttrString(IntPtr pointer, string name) { using var namePtr = new StrPtr(name, Encoding.UTF8); - return Delegates.PyObject_GetAttrString(pointer, namePtr); + return Delegates.PyObject_GetAttrString(new BorrowedReference(pointer), namePtr) + .DangerousMoveToPointerOrNull(); } + internal static NewReference PyObject_GetAttrString(BorrowedReference pointer, string name) + { + using var namePtr = new StrPtr(name, Encoding.UTF8); + return Delegates.PyObject_GetAttrString(pointer, namePtr); + } - internal static IntPtr PyObject_GetAttrString(IntPtr pointer, StrPtr name) => Delegates.PyObject_GetAttrString(pointer, name); + internal static NewReference PyObject_GetAttrString(BorrowedReference pointer, StrPtr name) + => Delegates.PyObject_GetAttrString(pointer, name); internal static int PyObject_SetAttrString(IntPtr pointer, string name, IntPtr value) @@ -1917,13 +1923,13 @@ internal static string PyModule_GetFilename(IntPtr module) /// Return value: New reference. /// - internal static IntPtr PyImport_ImportModule(string name) + internal static NewReference PyImport_ImportModule(string name) { using var namePtr = new StrPtr(name, Encoding.UTF8); return Delegates.PyImport_ImportModule(namePtr); } - internal static IntPtr PyImport_ReloadModule(IntPtr module) => Delegates.PyImport_ReloadModule(module); + internal static NewReference PyImport_ReloadModule(BorrowedReference module) => Delegates.PyImport_ReloadModule(module); internal static BorrowedReference PyImport_AddModule(string name) @@ -2294,13 +2300,13 @@ static Delegates() PyRun_SimpleStringFlags = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyRun_SimpleStringFlags), GetUnmanagedDll(_PythonDll)); PyRun_StringFlags = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyRun_StringFlags), GetUnmanagedDll(_PythonDll)); PyEval_EvalCode = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyEval_EvalCode), GetUnmanagedDll(_PythonDll)); - Py_CompileStringObject = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(Py_CompileStringObject), GetUnmanagedDll(_PythonDll)); - PyImport_ExecCodeModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_ExecCodeModule), GetUnmanagedDll(_PythonDll)); + Py_CompileStringObject = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(Py_CompileStringObject), GetUnmanagedDll(_PythonDll)); + PyImport_ExecCodeModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_ExecCodeModule), GetUnmanagedDll(_PythonDll)); PyCFunction_NewEx = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyCFunction_NewEx), GetUnmanagedDll(_PythonDll)); PyCFunction_Call = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyCFunction_Call), GetUnmanagedDll(_PythonDll)); PyMethod_New = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyMethod_New), GetUnmanagedDll(_PythonDll)); PyObject_HasAttrString = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_HasAttrString), GetUnmanagedDll(_PythonDll)); - PyObject_GetAttrString = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_GetAttrString), GetUnmanagedDll(_PythonDll)); + PyObject_GetAttrString = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_GetAttrString), GetUnmanagedDll(_PythonDll)); PyObject_SetAttrString = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_SetAttrString), GetUnmanagedDll(_PythonDll)); PyObject_HasAttr = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_HasAttr), GetUnmanagedDll(_PythonDll)); PyObject_GetAttr = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_GetAttr), GetUnmanagedDll(_PythonDll)); @@ -2458,8 +2464,8 @@ static Delegates() PyModule_GetFilename = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyModule_GetFilename), GetUnmanagedDll(_PythonDll)); PyModule_Create2 = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyModule_Create2), GetUnmanagedDll(_PythonDll)); PyImport_Import = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_Import), GetUnmanagedDll(_PythonDll)); - PyImport_ImportModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_ImportModule), GetUnmanagedDll(_PythonDll)); - PyImport_ReloadModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_ReloadModule), GetUnmanagedDll(_PythonDll)); + PyImport_ImportModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_ImportModule), GetUnmanagedDll(_PythonDll)); + PyImport_ReloadModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_ReloadModule), GetUnmanagedDll(_PythonDll)); PyImport_AddModule = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_AddModule), GetUnmanagedDll(_PythonDll)); PyImport_GetModuleDict = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyImport_GetModuleDict), GetUnmanagedDll(_PythonDll)); PySys_SetArgvEx = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PySys_SetArgvEx), GetUnmanagedDll(_PythonDll)); @@ -2566,13 +2572,13 @@ static Delegates() internal static delegate* unmanaged[Cdecl] PyRun_SimpleStringFlags { get; } internal static delegate* unmanaged[Cdecl] PyRun_StringFlags { get; } internal static delegate* unmanaged[Cdecl] PyEval_EvalCode { get; } - internal static delegate* unmanaged[Cdecl] Py_CompileStringObject { get; } - internal static delegate* unmanaged[Cdecl] PyImport_ExecCodeModule { get; } + internal static delegate* unmanaged[Cdecl] Py_CompileStringObject { get; } + internal static delegate* unmanaged[Cdecl] PyImport_ExecCodeModule { get; } internal static delegate* unmanaged[Cdecl] PyCFunction_NewEx { get; } internal static delegate* unmanaged[Cdecl] PyCFunction_Call { get; } internal static delegate* unmanaged[Cdecl] PyMethod_New { get; } internal static delegate* unmanaged[Cdecl] PyObject_HasAttrString { get; } - internal static delegate* unmanaged[Cdecl] PyObject_GetAttrString { get; } + internal static delegate* unmanaged[Cdecl] PyObject_GetAttrString { get; } internal static delegate* unmanaged[Cdecl] PyObject_SetAttrString { get; } internal static delegate* unmanaged[Cdecl] PyObject_HasAttr { get; } internal static delegate* unmanaged[Cdecl] PyObject_GetAttr { get; } @@ -2723,8 +2729,8 @@ static Delegates() internal static delegate* unmanaged[Cdecl] PyModule_GetFilename { get; } internal static delegate* unmanaged[Cdecl] PyModule_Create2 { get; } internal static delegate* unmanaged[Cdecl] PyImport_Import { get; } - internal static delegate* unmanaged[Cdecl] PyImport_ImportModule { get; } - internal static delegate* unmanaged[Cdecl] PyImport_ReloadModule { get; } + internal static delegate* unmanaged[Cdecl] PyImport_ImportModule { get; } + internal static delegate* unmanaged[Cdecl] PyImport_ReloadModule { get; } internal static delegate* unmanaged[Cdecl] PyImport_AddModule { get; } internal static delegate* unmanaged[Cdecl] PyImport_GetModuleDict { get; } internal static delegate* unmanaged[Cdecl] PySys_SetArgvEx { get; } diff --git a/src/runtime/runtime_state.cs b/src/runtime/runtime_state.cs index 295219675..b541a7c44 100644 --- a/src/runtime/runtime_state.cs +++ b/src/runtime/runtime_state.cs @@ -139,18 +139,15 @@ private static void RestoreObjects(IntPtr dummyGC) public static IEnumerable PyGCGetObjects() { - var gc = PyImport_ImportModule("gc"); - PythonException.ThrowIfIsNull(gc); - var get_objects = PyObject_GetAttrString(gc, "get_objects"); - var objs = PyObject_CallObject(get_objects, IntPtr.Zero); + using var gc = PyModule.Import("gc"); + using var get_objects = gc.GetAttr("get_objects"); + var objs = PyObject_CallObject(get_objects.Handle, IntPtr.Zero); var length = PyList_Size(new BorrowedReference(objs)); for (long i = 0; i < length; i++) { var obj = PyList_GetItem(new BorrowedReference(objs), i); yield return obj.DangerousGetAddress(); } - XDecref(objs); - XDecref(gc); } public static IEnumerable GetModuleNames() diff --git a/src/testing/threadtest.cs b/src/testing/threadtest.cs index 9c76929b2..6664c3643 100644 --- a/src/testing/threadtest.cs +++ b/src/testing/threadtest.cs @@ -34,7 +34,7 @@ public static string CallEchoString(string arg) { if (module == null) { - module = PythonEngine.ModuleFromString("tt", testmod); + module = PyModule.FromString("tt", testmod); } PyObject func = module.GetAttr("echostring"); var parg = new PyString(arg); @@ -58,7 +58,7 @@ public static string CallEchoString2(string arg) { if (module == null) { - module = PythonEngine.ModuleFromString("tt", testmod); + module = PyModule.FromString("tt", testmod); } PyObject func = module.GetAttr("echostring2"); From ac68aab1374b2553e05e6e4cec87753e83c15f41 Mon Sep 17 00:00:00 2001 From: Victor Milovanov Date: Fri, 19 Feb 2021 15:08:59 -0800 Subject: [PATCH 4/4] minor fixes --- src/embed_tests/GlobalTestsSetup.cs | 2 +- src/embed_tests/TestNativeTypeOffset.cs | 2 +- src/runtime/pystring.cs | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/embed_tests/GlobalTestsSetup.cs b/src/embed_tests/GlobalTestsSetup.cs index 458ab6a99..9a832cb0c 100644 --- a/src/embed_tests/GlobalTestsSetup.cs +++ b/src/embed_tests/GlobalTestsSetup.cs @@ -7,7 +7,7 @@ namespace Python.EmbeddingTest // As the SetUpFixture, the OneTimeTearDown of this class is executed after // all tests have run. [SetUpFixture] - public class GlobalTestsSetup + public partial class GlobalTestsSetup { [OneTimeTearDown] public void FinalCleanup() diff --git a/src/embed_tests/TestNativeTypeOffset.cs b/src/embed_tests/TestNativeTypeOffset.cs index 7dd5a765e..8efd16e02 100644 --- a/src/embed_tests/TestNativeTypeOffset.cs +++ b/src/embed_tests/TestNativeTypeOffset.cs @@ -9,7 +9,7 @@ using Python.Runtime; -namespace Python.EmbeddingPythonTest +namespace Python.EmbeddingTest { public class TestNativeTypeOffset { diff --git a/src/runtime/pystring.cs b/src/runtime/pystring.cs index b3d0dc86d..07eabba14 100644 --- a/src/runtime/pystring.cs +++ b/src/runtime/pystring.cs @@ -67,11 +67,8 @@ public PyString(string s) : base(FromString(s)) /// - /// IsStringType Method - /// - /// /// Returns true if the given object is a Python string. - /// + /// public static bool IsStringType(PyObject value) { return Runtime.PyString_Check(value.obj); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy