Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfa53f2b

Browse files
committed
added new class PyType to wrap Python type objects and enable new type construction from PyType_Spec (TypeSpec class)
1 parent16b4df7 commitfa53f2b

File tree

5 files changed

+267
-0
lines changed

5 files changed

+267
-0
lines changed

‎src/embed_tests/TestPyType.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
usingSystem;
2+
usingSystem.Runtime.InteropServices;
3+
usingSystem.Text;
4+
5+
usingNUnit.Framework;
6+
7+
usingPython.Runtime;
8+
usingPython.Runtime.Native;
9+
10+
namespacePython.EmbeddingTest
11+
{
12+
publicclassTestPyType
13+
{
14+
[OneTimeSetUp]
15+
publicvoidSetUp()
16+
{
17+
PythonEngine.Initialize();
18+
}
19+
20+
[OneTimeTearDown]
21+
publicvoidDispose()
22+
{
23+
PythonEngine.Shutdown();
24+
}
25+
26+
[Test]
27+
publicvoidCanCreateHeapType()
28+
{
29+
conststringname="nÁmæ";
30+
conststringdocStr="dÁcæ";
31+
32+
usingvardoc=newStrPtr(docStr,Encoding.UTF8);
33+
varspec=newTypeSpec(
34+
name:name,
35+
basicSize:ObjectOffset.Size(Runtime.Runtime.PyTypeType),
36+
slots:newTypeSpec.Slot[]{
37+
new(TypeSlotID.tp_doc,doc.RawPointer),
38+
},
39+
TypeFlags.Default|TypeFlags.HeapType
40+
);
41+
42+
usingvartype=newPyType(spec);
43+
Assert.AreEqual(name,type.GetAttr("__name__").As<string>());
44+
Assert.AreEqual(docStr,type.GetAttr("__doc__").As<string>());
45+
}
46+
}
47+
}

‎src/runtime/TypeSpec.cs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#nullable enable
2+
usingSystem;
3+
usingSystem.Collections.Generic;
4+
usingSystem.Linq;
5+
usingSystem.Runtime.InteropServices;
6+
7+
namespacePython.Runtime
8+
{
9+
publicclassTypeSpec
10+
{
11+
publicTypeSpec(stringname,intbasicSize,IEnumerable<Slot>slots,TypeFlagsflags,intitemSize=0)
12+
{
13+
this.Name=name??thrownewArgumentNullException(nameof(name));
14+
this.BasicSize=basicSize;
15+
this.Slots=slots.ToArray();
16+
this.Flags=flags;
17+
this.ItemSize=itemSize;
18+
}
19+
publicstringName{get;}
20+
publicintBasicSize{get;}
21+
publicintItemSize{get;}
22+
publicTypeFlagsFlags{get;}
23+
publicIReadOnlyList<Slot>Slots{get;}
24+
25+
[StructLayout(LayoutKind.Sequential)]
26+
publicstructSlot
27+
{
28+
publicSlot(TypeSlotIDid,IntPtrvalue)
29+
{
30+
ID=id;
31+
Value=value;
32+
}
33+
34+
publicTypeSlotIDID{get;}
35+
publicIntPtrValue{get;}
36+
}
37+
}
38+
39+
publicenumTypeSlotID:int
40+
{
41+
mp_ass_subscript=3,
42+
mp_length=4,
43+
mp_subscript=5,
44+
nb_absolute=6,
45+
nb_add=7,
46+
nb_and=8,
47+
nb_bool=9,
48+
nb_divmod=10,
49+
nb_float=11,
50+
nb_floor_divide=12,
51+
nb_index=13,
52+
nb_inplace_add=14,
53+
nb_inplace_and=15,
54+
nb_inplace_floor_divide=16,
55+
nb_inplace_lshift=17,
56+
nb_inplace_multiply=18,
57+
nb_inplace_or=19,
58+
nb_inplace_power=20,
59+
nb_inplace_remainder=21,
60+
nb_inplace_rshift=22,
61+
nb_inplace_subtract=23,
62+
nb_inplace_true_divide=24,
63+
nb_inplace_xor=25,
64+
nb_int=26,
65+
nb_invert=27,
66+
nb_lshift=28,
67+
nb_multiply=29,
68+
nb_negative=30,
69+
nb_or=31,
70+
nb_positive=32,
71+
nb_power=33,
72+
nb_remainder=34,
73+
nb_rshift=35,
74+
nb_subtract=36,
75+
nb_true_divide=37,
76+
nb_xor=38,
77+
sq_ass_item=39,
78+
sq_concat=40,
79+
sq_contains=41,
80+
sq_inplace_concat=42,
81+
sq_inplace_repeat=43,
82+
sq_item=44,
83+
sq_length=45,
84+
sq_repeat=46,
85+
tp_alloc=47,
86+
tp_base=48,
87+
tp_bases=49,
88+
tp_call=50,
89+
tp_clear=51,
90+
tp_dealloc=52,
91+
tp_del=53,
92+
tp_descr_get=54,
93+
tp_descr_set=55,
94+
tp_doc=56,
95+
tp_getattr=57,
96+
tp_getattro=58,
97+
tp_hash=59,
98+
tp_init=60,
99+
tp_is_gc=61,
100+
tp_iter=62,
101+
tp_iternext=63,
102+
tp_methods=64,
103+
tp_new=65,
104+
tp_repr=66,
105+
tp_richcompare=67,
106+
tp_setattr=68,
107+
tp_setattro=69,
108+
tp_str=70,
109+
tp_traverse=71,
110+
tp_members=72,
111+
tp_getset=73,
112+
tp_free=74,
113+
nb_matrix_multiply=75,
114+
nb_inplace_matrix_multiply=76,
115+
am_await=77,
116+
am_aiter=78,
117+
am_anext=79,
118+
/// <remarks>New in 3.5</remarks>
119+
tp_finalize=80,
120+
}
121+
}

‎src/runtime/native/NativeTypeSpec.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#nullable enable
2+
usingSystem;
3+
usingSystem.Runtime.InteropServices;
4+
usingSystem.Text;
5+
6+
namespacePython.Runtime.Native
7+
{
8+
[StructLayout(LayoutKind.Sequential)]
9+
classNativeTypeSpec:IDisposable
10+
{
11+
publicreadonlyStrPtrName;
12+
publicreadonlyintBasicSize;
13+
publicreadonlyintItemSize;
14+
publicreadonlyTypeFlagsFlags;
15+
publicIntPtrSlots;
16+
17+
publicNativeTypeSpec(TypeSpecspec)
18+
{
19+
if(specisnull)thrownewArgumentNullException(nameof(spec));
20+
21+
this.Name=newStrPtr(spec.Name,Encoding.UTF8);
22+
this.BasicSize=spec.BasicSize;
23+
this.ItemSize=spec.ItemSize;
24+
this.Flags=spec.Flags;
25+
26+
unsafe
27+
{
28+
intslotsBytes=checked((spec.Slots.Count+1)*Marshal.SizeOf<TypeSpec.Slot>());
29+
varslots=(TypeSpec.Slot*)Marshal.AllocHGlobal(slotsBytes);
30+
for(intslotIndex=0;slotIndex<spec.Slots.Count;slotIndex++)
31+
slots[slotIndex]=spec.Slots[slotIndex];
32+
slots[spec.Slots.Count]=default;
33+
this.Slots=(IntPtr)slots;
34+
}
35+
}
36+
37+
publicvoidDispose()
38+
{
39+
// we have to leak the name
40+
// this.Name.Dispose();
41+
Marshal.FreeHGlobal(this.Slots);
42+
this.Slots=IntPtr.Zero;
43+
}
44+
}
45+
}

‎src/runtime/pytype.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#nullable enable
2+
usingSystem;
3+
usingSystem.Runtime.InteropServices;
4+
5+
usingPython.Runtime.Native;
6+
7+
namespacePython.Runtime
8+
{
9+
publicclassPyType:PyObject
10+
{
11+
/// <summary>Creates heap type object from the <paramref name="spec"/>.</summary>
12+
publicPyType(TypeSpecspec,PyTuple?bases=null):base(FromSpec(spec,bases)){}
13+
/// <summary>Wraps an existing type object.</summary>
14+
publicPyType(PyObjecto):base(FromObject(o)){}
15+
16+
/// <summary>Checks if specified object is a Python type.</summary>
17+
publicstaticboolIsType(PyObjectvalue)
18+
{
19+
if(valueisnull)thrownewArgumentNullException(nameof(value));
20+
21+
returnRuntime.PyType_Check(value.obj);
22+
}
23+
24+
privatestaticBorrowedReferenceFromObject(PyObjecto)
25+
{
26+
if(oisnull)thrownewArgumentNullException(nameof(o));
27+
if(!IsType(o))thrownewArgumentException("object is not a type");
28+
29+
returno.Reference;
30+
}
31+
32+
privatestaticIntPtrFromSpec(TypeSpecspec,PyTuple?bases=null)
33+
{
34+
if(specisnull)thrownewArgumentNullException(nameof(spec));
35+
36+
if((spec.Flags&TypeFlags.HeapType)==0)
37+
thrownewNotSupportedException("Only heap types are supported");
38+
39+
varnativeSpec=newNativeTypeSpec(spec);
40+
varbasesRef=basesisnull?default:bases.Reference;
41+
varresult=Runtime.PyType_FromSpecWithBases(nativeSpec,basesRef);
42+
43+
PythonException.ThrowIfIsNull(result);
44+
45+
nativeSpec.Dispose();
46+
47+
returnresult.DangerousMoveToPointer();
48+
}
49+
}
50+
}

‎src/runtime/runtime.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,8 @@ internal static IntPtr PyType_GenericAlloc(IntPtr type, long n)
20062006

20072007

20082008
privatestaticIntPtrPyType_GenericAlloc(IntPtrtype,IntPtrn)=>Delegates.PyType_GenericAlloc(type,n);
2009+
2010+
internalstaticNewReferencePyType_FromSpecWithBases(NativeTypeSpecspec,BorrowedReferencebases)=>Delegates.PyType_FromSpecWithBases(spec,bases);
20092011

20102012
/// <summary>
20112013
/// Finalize a type object. This should be called on all type objects to finish their initialization. This function is responsible for adding inherited slots from a type’s base class. Return 0 on success, or return -1 and sets an exception on error.
@@ -2510,6 +2512,7 @@ static Delegates()
25102512
PyException_SetCause=(delegate* unmanaged[Cdecl]<IntPtr,IntPtr,void>)GetFunctionByName(nameof(PyException_SetCause),GetUnmanagedDll(_PythonDll));
25112513
PyThreadState_SetAsyncExcLLP64=(delegate* unmanaged[Cdecl]<uint,IntPtr,int>)GetFunctionByName("PyThreadState_SetAsyncExc",GetUnmanagedDll(_PythonDll));
25122514
PyThreadState_SetAsyncExcLP64=(delegate* unmanaged[Cdecl]<ulong,IntPtr,int>)GetFunctionByName("PyThreadState_SetAsyncExc",GetUnmanagedDll(_PythonDll));
2515+
PyType_FromSpecWithBases=(delegate* unmanaged[Cdecl]<NativeTypeSpec,BorrowedReference,NewReference>)GetFunctionByName(nameof(PyType_FromSpecWithBases),GetUnmanagedDll(PythonDLL));
25132516
}
25142517

25152518
staticglobal::System.IntPtrGetUnmanagedDll(stringlibraryName)
@@ -2775,6 +2778,7 @@ static Delegates()
27752778
internalstaticdelegate* unmanaged[Cdecl]<IntPtr,IntPtr,void>PyException_SetCause{get;}
27762779
internalstaticdelegate* unmanaged[Cdecl]<uint,IntPtr,int>PyThreadState_SetAsyncExcLLP64{get;}
27772780
internalstaticdelegate* unmanaged[Cdecl]<ulong,IntPtr,int>PyThreadState_SetAsyncExcLP64{get;}
2781+
internalstaticdelegate* unmanaged[Cdecl]<NativeTypeSpec,BorrowedReference,NewReference>PyType_FromSpecWithBases{get;}
27782782
}
27792783
}
27802784

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp