Skip to content

Commit 5bcd708

Browse files
authored
Merge pull request #1391 from losttech/cleanup/21-02-19
Remove Utf8Marshaler, set PyScope base class to PyObject, added PyModule
2 parents c4f2ad7 + ac68aab commit 5bcd708

20 files changed

+171
-177
lines changed

src/embed_tests/GlobalTestsSetup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Python.EmbeddingTest
77
// As the SetUpFixture, the OneTimeTearDown of this class is executed after
88
// all tests have run.
99
[SetUpFixture]
10-
public class GlobalTestsSetup
10+
public partial class GlobalTestsSetup
1111
{
1212
[OneTimeTearDown]
1313
public void FinalCleanup()

src/embed_tests/TestFinalizer.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,17 @@ public void CollectOnShutdown()
101101

102102
PythonEngine.Shutdown();
103103
garbage = Finalizer.Instance.GetCollectedObjects();
104-
Assert.IsEmpty(garbage);
104+
105+
if (garbage.Count > 0)
106+
{
107+
PythonEngine.Initialize();
108+
string objects = string.Join("\n", garbage.Select(ob =>
109+
{
110+
var obj = new PyObject(new BorrowedReference(ob));
111+
return $"{obj} [{obj.GetPythonType()}@{obj.Handle}]";
112+
}));
113+
Assert.Fail("Garbage is not empty:\n" + objects);
114+
}
105115
}
106116

107117
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] // ensure lack of references to obj
@@ -173,7 +183,7 @@ public void SimpleTestMemory()
173183
bool oldState = Finalizer.Instance.Enable;
174184
try
175185
{
176-
using (PyObject gcModule = PythonEngine.ImportModule("gc"))
186+
using (PyModule gcModule = PyModule.Import("gc"))
177187
using (PyObject pyCollect = gcModule.GetAttr("collect"))
178188
{
179189
long span1 = CompareWithFinalizerOn(pyCollect, false);

src/embed_tests/TestNativeTypeOffset.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
using Python.Runtime;
1111

12-
namespace Python.EmbeddingPythonTest
12+
namespace Python.EmbeddingTest
1313
{
1414
public class TestNativeTypeOffset
1515
{

src/embed_tests/TestPythonException.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void TestPythonErrorTypeName()
4646
{
4747
try
4848
{
49-
var module = PythonEngine.ImportModule("really____unknown___module");
49+
var module = PyModule.Import("really____unknown___module");
5050
Assert.Fail("Unknown module should not be loaded");
5151
}
5252
catch (PythonException ex)
@@ -95,7 +95,7 @@ public void TestPythonExceptionFormatNoTraceback()
9595
{
9696
try
9797
{
98-
var module = PythonEngine.ImportModule("really____unknown___module");
98+
var module = PyModule.Import("really____unknown___module");
9999
Assert.Fail("Unknown module should not be loaded");
100100
}
101101
catch (PythonException ex)

src/embed_tests/TestRuntime.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test()
9696
// TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check.
9797
var threading = Runtime.Runtime.PyImport_ImportModule("threading");
9898
Exceptions.ErrorCheck(threading);
99-
var threadingDict = Runtime.Runtime.PyModule_GetDict(new BorrowedReference(threading));
99+
var threadingDict = Runtime.Runtime.PyModule_GetDict(threading);
100100
Exceptions.ErrorCheck(threadingDict);
101101
var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock");
102102
if (lockType.IsNull)
@@ -110,6 +110,8 @@ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test()
110110
Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance));
111111
Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance));
112112

113+
threading.Dispose();
114+
113115
Runtime.Runtime.Py_Finalize();
114116
}
115117
}

src/embed_tests/pyimport.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public void Dispose()
5252
[Test]
5353
public void TestDottedName()
5454
{
55-
PyObject module = PythonEngine.ImportModule("PyImportTest.test.one");
55+
var module = PyModule.Import("PyImportTest.test.one");
5656
Assert.IsNotNull(module);
5757
}
5858

@@ -62,7 +62,7 @@ public void TestDottedName()
6262
[Test]
6363
public void TestSysArgsImportException()
6464
{
65-
PyObject module = PythonEngine.ImportModule("PyImportTest.sysargv");
65+
var module = PyModule.Import("PyImportTest.sysargv");
6666
Assert.IsNotNull(module);
6767
}
6868

src/embed_tests/pyinitialize.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ public static void TestRunExitFuncs()
175175
{
176176
called = true;
177177
};
178-
atexit.InvokeMethod("register", callback.ToPython());
178+
atexit.InvokeMethod("register", callback.ToPython()).Dispose();
179+
atexit.Dispose();
179180
Runtime.Runtime.Shutdown();
180181
Assert.True(called);
181182
}

src/runtime/BorrowedReference.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ public BorrowedReference(IntPtr pointer)
2828
=> a.pointer == b.pointer;
2929
public static bool operator !=(BorrowedReference a, BorrowedReference b)
3030
=> a.pointer != b.pointer;
31+
public static bool operator ==(BorrowedReference reference, NullOnly @null)
32+
=> reference.IsNull;
33+
public static bool operator !=(BorrowedReference reference, NullOnly @null)
34+
=> !reference.IsNull;
35+
public static bool operator ==(NullOnly @null, BorrowedReference reference)
36+
=> reference.IsNull;
37+
public static bool operator !=(NullOnly @null, BorrowedReference reference)
38+
=> !reference.IsNull;
3139

3240
public override bool Equals(object obj) {
3341
if (obj is IntPtr ptr)

src/runtime/CustomMarshaler.cs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -189,49 +189,4 @@ public static ICustomMarshaler GetInstance(string cookie)
189189
return Instance;
190190
}
191191
}
192-
193-
194-
/// <summary>
195-
/// Custom Marshaler to deal with Managed String to Native
196-
/// conversion on UTF-8. Use on functions that expect UTF-8 encoded
197-
/// strings like `PyUnicode_FromStringAndSize`
198-
/// </summary>
199-
/// <remarks>
200-
/// If instead we used `MarshalAs(UnmanagedType.LPWStr)` the output to
201-
/// `foo` would be `f\x00o\x00o\x00`.
202-
/// </remarks>
203-
internal class Utf8Marshaler : MarshalerBase
204-
{
205-
private static readonly MarshalerBase Instance = new Utf8Marshaler();
206-
private static readonly Encoding PyEncoding = Encoding.UTF8;
207-
208-
public override IntPtr MarshalManagedToNative(object managedObj)
209-
{
210-
var s = managedObj as string;
211-
212-
if (s == null)
213-
{
214-
return IntPtr.Zero;
215-
}
216-
217-
byte[] bStr = PyEncoding.GetBytes(s + "\0");
218-
IntPtr mem = Marshal.AllocHGlobal(bStr.Length);
219-
try
220-
{
221-
Marshal.Copy(bStr, 0, mem, bStr.Length);
222-
}
223-
catch (Exception)
224-
{
225-
Marshal.FreeHGlobal(mem);
226-
throw;
227-
}
228-
229-
return mem;
230-
}
231-
232-
public static ICustomMarshaler GetInstance(string cookie)
233-
{
234-
return Instance;
235-
}
236-
}
237192
}

src/runtime/exceptions.cs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,24 +95,21 @@ internal static Exception ToException(IntPtr ob)
9595
/// </remarks>
9696
public static class Exceptions
9797
{
98-
internal static IntPtr warnings_module;
99-
internal static IntPtr exceptions_module;
98+
internal static PyModule warnings_module;
99+
internal static PyModule exceptions_module;
100100

101101
/// <summary>
102102
/// Initialization performed on startup of the Python runtime.
103103
/// </summary>
104104
internal static void Initialize()
105105
{
106106
string exceptionsModuleName = "builtins";
107-
exceptions_module = Runtime.PyImport_ImportModule(exceptionsModuleName);
108-
109-
Exceptions.ErrorCheck(exceptions_module);
110-
warnings_module = Runtime.PyImport_ImportModule("warnings");
111-
Exceptions.ErrorCheck(warnings_module);
107+
exceptions_module = PyModule.Import(exceptionsModuleName);
108+
warnings_module = PyModule.Import("warnings");
112109
Type type = typeof(Exceptions);
113110
foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Static))
114111
{
115-
IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module, fi.Name);
112+
IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module.obj, fi.Name);
116113
if (op != IntPtr.Zero)
117114
{
118115
fi.SetValue(type, op);
@@ -147,8 +144,8 @@ internal static void Shutdown()
147144
Runtime.XDecref(op);
148145
fi.SetValue(null, IntPtr.Zero);
149146
}
150-
Runtime.Py_CLEAR(ref exceptions_module);
151-
Runtime.Py_CLEAR(ref warnings_module);
147+
exceptions_module.Dispose();
148+
warnings_module.Dispose();
152149
}
153150

154151
/// <summary>
@@ -348,9 +345,7 @@ public static void warn(string message, IntPtr exception, int stacklevel)
348345
Exceptions.RaiseTypeError("Invalid exception");
349346
}
350347

351-
Runtime.XIncref(warnings_module);
352-
IntPtr warn = Runtime.PyObject_GetAttrString(warnings_module, "warn");
353-
Runtime.XDecref(warnings_module);
348+
IntPtr warn = Runtime.PyObject_GetAttrString(warnings_module.obj, "warn");
354349
Exceptions.ErrorCheck(warn);
355350

356351
IntPtr args = Runtime.PyTuple_New(3);

0 commit comments

Comments
 (0)