8000 * Drop NativeCodePage dependency · pythonnet/pythonnet@1b466df · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 1b466df

Browse files
c 8000 ommitted
* Drop NativeCodePage dependency
* Use TypeOffset.members(memory of the first PythonMemberDef) as magic slot * Improve accuracy of slot implementation detection * Fix refcnt errors
1 parent 9b4864b commit 1b466df

19 files changed

+1177
-560
lines changed

src/embed_tests/TestDomainReload.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public static void DomainReloadAndGC()
6464
// objects is gone.
6565
Assembly pythonRunner2 = BuildAssembly("test2");
6666
RunAssemblyAndUnload(pythonRunner2, "test2");
67+
68+
PythonEngine.Shutdown();
6769
}
6870

6971
//

src/embed_tests/TestRuntime.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@ public static void PlatformCache()
2727
{
2828
Runtime.Runtime.Initialize();
2929

30-
Assert.That(Runtime.Runtime.Machine, Is.Not.EqualTo(MachineType.Other));
31-
Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.MachineName));
30+
Assert.That(NativeCodePageHelper.Machine, Is.Not.EqualTo(MachineType.Other));
31+
Assert.That(!string.IsNullOrEmpty(NativeCodePageHelper.MachineName));
3232

33-
Assert.That(Runtime.Runtime.OperatingSystem, Is.Not.EqualTo(OperatingSystemType.Other));
34-
Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.OperatingSystemName));
33+
Assert.That(NativeCodePageHelper.OperatingSystem, Is.Not.EqualTo(OperatingSystemType.Other));
34+
Assert.That(!string.IsNullOrEmpty(NativeCodePageHelper.OperatingSystemName));
3535

36-
// Don't shut down the runtime: if the python engine was initialized
37-
// but not shut down by another test, we'd end up in a bad state.
38-
}
36+
Runtime.Runtime.Shutdown();
37+
}
3938

4039
[Test]
4140
public static void Py_IsInitializedValue()

src/embed_tests/TestTypeManager.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using NUnit.Framework;
22
using Python.Runtime;
3+
using Python.Runtime.Platform;
34
using System.Runtime.InteropServices;
45

56
namespace Python.EmbeddingTest
@@ -15,22 +16,21 @@ public static void Init()
1516
[TearDown]
1617
public static void Fini()
1718
{
18-
// Don't shut down the runtime: if the python engine was initialized
19-
// but not shut down by another test, we'd end up in a bad state.
19+
Runtime.Runtime.Shutdown();
2020
}
2121

2222
[Test]
2323
public static void TestNativeCode()
2424
{
25-
Assert.That(() => { var _ = TypeManager.NativeCode.Active; }, Throws.Nothing);
26-
Assert.That(TypeManager.NativeCode.Active.Code.Length, Is.GreaterThan(0));
25+
Assert.That(() => { var _ = NativeCodePageHelper.NativeCode.Active; }, Throws.Nothing);
26+
Assert.That(NativeCodePageHelper.NativeCode.Active.Code.Length, Is.GreaterThan(0));
2727
}
2828

2929
[Test]
3030
public static void TestMemoryMapping()
3131
{
32-
Assert.That(() => { var _ = TypeManager.CreateMemoryMapper(); }, Throws.Nothing);
33-
var mapper = TypeManager.CreateMemoryMapper();
32+
Assert.That(() => { var _ = NativeCodePageHelper.CreateMemoryMapper(); }, Throws.Nothing);
33+
var mapper = NativeCodePageHelper.CreateMemoryMapper();
3434

3535
// Allocate a read-write page.
3636
int len = 12;

src/embed_tests/pyimport.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public void SetUp()
4040
IntPtr str = Runtime.Runtime.PyString_FromString(testPath);
4141
IntPtr path = Runtime.Runtime.PySys_GetObject("path");
4242
Runtime.Runtime.PyList_Append(path, str);
43+
Runtime.Runtime.XDecref(str);
4344
}
4445

4546
[TearDown]

src/embed_tests/pyinitialize.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static void LoadDefaultArgs()
2626
using (new PythonEngine())
2727
using (var argv = new PyList(Runtime.Runtime.PySys_GetObject("argv")))
2828
{
29+
Runtime.Runtime.XIncref(argv.Handle);
2930
Assert.AreNotEqual(0, argv.Length());
3031
}
3132
}
@@ -37,6 +38,7 @@ public static void LoadSpecificArgs()
3738
using (new PythonEngine(args))
3839
using (var argv = new PyList(Runtime.Runtime.PySys_GetObject("argv")))
3940
{
41+
Runtime.Runtime.XIncref(argv.Handle);
4042
Assert.AreEqual(args[0], argv[0].ToString());
4143
Assert.AreEqual(args[1], argv[1].ToString());
4244
}

src/runtime/Python.Runtime.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
<Compile Include="Util.cs" />
144144
<Compile Include="platform\Types.cs" />
145145
<Compile Include="platform\LibraryLoader.cs" />
146+
<Compile Include="platform\NativeCodePage.cs" />
146147
<Compile Include="slots\mp_length.cs" />
147148
</ItemGroup>
148149
<ItemGroup Condition=" '$(PythonInteropFile)' != '' ">

src/runtime/classderived.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ internal static IntPtr ToPython(IPythonDerivedType obj)
9999
// collected while Python still has a reference to it.
100100
if (Runtime.Refcount(self.pyHandle) == 1)
101101
{
102+
103+
#if PYTHON_WITH_PYDEBUG
104+
Runtime._Py_NewReference(self.pyHandle);
105+
#endif
102106
GCHandle gc = GCHandle.Alloc(self, GCHandleType.Normal);
103107
Marshal.WriteIntPtr(self.pyHandle, ObjectOffset.magic(self.tpHandle), (IntPtr)gc);
104108
self.gcHandle.Free();

src/runtime/interop.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,37 @@ public ModulePropertyAttribute()
6969
}
7070
}
7171

72+
internal static partial class TypeOffset
73+
{
74+
static class Helper
75+
{
76+
public static int magic;
77+
public static readonly Dictionary<string, int> NameMapping = new Dictionary<string, int>();
78+
}
79+
80+
static TypeOffset()
81+
{
82+
Type type = typeof(TypeOffset);
83+
FieldInfo[] fields = type.GetFields();
84+
int size = IntPtr.Size;
85+
for (int i = 0; i < fields.Length; i++)
86+
{
87+
int offset = i * size;
88+
FieldInfo fi = fields[i];
89+
fi.SetValue(null, offset);
90+
Helper.NameMapping[fi.Name] = offset;
91+
}
92+
// XXX: Use the members after PyHeapTypeObject as magic slot
93+
Helper.magic = members;
94+
}
95+
96+
public static int magic() => Helper.magic;
97+
98+
public static int GetSlotOffset(string name)
99+
{
100+
return Helper.NameMapping[name];
101+
}
102+
}
72103

73104
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
74105
internal class ObjectOffset
@@ -556,4 +587,5 @@ struct PyMethodDef
556587
public int ml_flags;
557588
public IntPtr ml_doc;
558589
}
590+
559591
}

src/runtime/interop27.cs

Lines changed: 94 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
12
// Auto-generated by geninterop.py.
2-
// DO NOT MODIFIY BY HAND.
3+
// DO NOT MODIFY BY HAND.
34

45

56
#if PYTHON27
@@ -12,25 +13,10 @@
1213

1314
namespace Python.Runtime
1415
{
15-
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
16-
internal class TypeOffset
17-
{
18-
static TypeOffset()
19-
{
20-
Type type = typeof(TypeOffset);
21-
FieldInfo[] fi = type.GetFields();
22-
int size = IntPtr.Size;
23-
for (int i = 0; i < fi.Length; i++)
24-
{
25-
fi[i].SetValue(null, i * size);
26-
}
27-
}
28-
29-
public static int magic()
30-
{
31-
return ob_size;
32-
}
3316

17+
[StructLayout(LayoutKind.Sequential)]
18+
internal static partial class TypeOffset
19+
{
3420
// Auto-generated from PyHeapTypeObject in Python.h
3521
public static int ob_refcnt = 0;
3622
public static int ob_type = 0;
@@ -145,6 +131,94 @@ public static int magic()
145131
/* here are optional user slots, followed by the members. */
146132
public static int members = 0;
147133
}
148-
}
149134

135+
[StructLayout(LayoutKind.Sequential)]
136+
internal struct PyNumberMethods
137+
{
138+
public IntPtr nb_add;
139+
public IntPtr nb_subtract;
140+
public IntPtr nb_multiply;
141+
public IntPtr nb_divide;
142+
public IntPtr nb_remainder;
143+
public IntPtr nb_divmod;
144+
public IntPtr nb_power;
145+
public IntPtr nb_negative;
146+
public IntPtr nb_positive;
147+
public IntPtr nb_absolute;
148+
public IntPtr nb_nonzero;
149+
public IntPtr nb_invert;
150+
public IntPtr nb_lshift;
151+
public IntPtr nb_rshift;
152+
public IntPtr nb_and;
153+
public IntPtr nb_xor;
154+
public IntPtr nb_or;
155+
public IntPtr nb_coerce;
156+
public IntPtr nb_int;
157+
public IntPtr nb_long;
158+
public IntPtr nb_float;
159+
public IntPtr nb_oct;
160+
public IntPtr nb_hex;
161+
public IntPtr nb_inplace_add;
162+
public IntPtr nb_inplace_subtract;
163+
public IntPtr nb_inplace_multiply;
164+
public IntPtr nb_inplace_divide;
165+
public IntPtr nb_inplace_remainder;
166+
public IntPtr nb_inplace_power;
167+
public IntPtr nb_inplace_lshift;
168+
public IntPtr nb_inplace_rshift;
169+
public IntPtr nb_inplace_and;
170+
public IntPtr nb_inplace_xor;
171+
public IntPtr nb_inplace_or;
172+
public IntPtr nb_floor_divide;
173+
public IntPtr nb_true_divide;
174+
public IntPtr nb_inplace_floor_divide;
175+
public IntPtr nb_inplace_true_divide;
176+
public IntPtr nb_index;
177+
}
178+
179+
[StructLayout(LayoutKind.Sequential)]
180+
internal struct PySequenceMethods
181+
{
182+
public IntPtr sq_length;
183+
public IntPtr sq_concat;
184+
public IntPtr sq_repeat;
185+
public IntPtr sq_item;
186+
public IntPtr sq_slice;
187+
public IntPtr sq_ass_item;
188+
public IntPtr sq_ass_slice;
189+
public IntPtr sq_contains;
190+
public IntPtr sq_inplace_concat;
191+
public IntPtr sq_inplace_repeat;
192+
}
193+
194+
[StructLayout(LayoutKind.Sequential)]
195+
internal struct PyMappingMethods
196+
{
197+
public IntPtr mp_length;
198+
public IntPtr mp_subscript;
199+
public IntPtr mp_ass_subscript;
200+
}
201+
202+
[StructLayout(LayoutKind.Sequential)]
203+
internal struct PyBufferProcs
204+
{
205+
public IntPtr bf_getreadbuffer;
206+
public IntPtr bf_getwritebuffer;
207+
public IntPtr bf_getsegcount;
208+
public IntPtr bf_getcharbuffer;
209+
public IntPtr bf_getbuffer;
210+
public IntPtr bf_releasebuffer;
211+
}
212+
213+
internal static partial class SlotTypes
214+
{
215+
public static readonly Type[] Types = {
216+
typeof(PyNumberMethods),
217+
typeof(PySequenceMethods),
218+
typeof(PyMappingMethods),
219+
typeof(PyBufferProcs),
220+
};
221+
}
222+
223+
}
150224
#endif

0 commit comments

Comments
 (0)
0