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

Commitd3c5654

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

File tree

6 files changed

+266
-0
lines changed

6 files changed

+266
-0
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1313
- Python operator method will call C# operator method for supported binary and unary operators ([#1324][p1324]).
1414
- Add GetPythonThreadID and Interrupt methods in PythonEngine
1515
- Ability to implement delegates with`ref` and`out` parameters in Python, by returning the modified parameter values in a tuple. ([#1355][i1355])
16+
-`PyType` - a wrapper for Python type objects, that also permits creating new heap types from`TypeSpec`
1617

1718
###Changed
1819
- Drop support for Python 2, 3.4, and 3.5

‎src/embed_tests/TestPyType.cs

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

‎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+
structNativeTypeSpec: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(innativeSpec,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(inNativeTypeSpecspec,BorrowedReferencebases)=>Delegates.PyType_FromSpecWithBases(inspec,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.
@@ -2509,6 +2511,7 @@ static Delegates()
25092511
PyException_SetCause=(delegate* unmanaged[Cdecl]<IntPtr,IntPtr,void>)GetFunctionByName(nameof(PyException_SetCause),GetUnmanagedDll(_PythonDll));
25102512
PyThreadState_SetAsyncExcLLP64=(delegate* unmanaged[Cdecl]<uint,IntPtr,int>)GetFunctionByName("PyThreadState_SetAsyncExc",GetUnmanagedDll(_PythonDll));
25112513
PyThreadState_SetAsyncExcLP64=(delegate* unmanaged[Cdecl]<ulong,IntPtr,int>)GetFunctionByName("PyThreadState_SetAsyncExc",GetUnmanagedDll(_PythonDll));
2514+
PyType_FromSpecWithBases=(delegate* unmanaged[Cdecl]<inNativeTypeSpec,BorrowedReference,NewReference>)GetFunctionByName(nameof(PyType_FromSpecWithBases),GetUnmanagedDll(PythonDLL));
25122515
}
25132516

25142517
staticglobal::System.IntPtrGetUnmanagedDll(stringlibraryName)
@@ -2786,6 +2789,7 @@ static Delegates()
27862789
internalstaticdelegate* unmanaged[Cdecl]<uint,IntPtr,int>PyThreadState_SetAsyncExcLLP64{get;}
27872790
internalstaticdelegate* unmanaged[Cdecl]<ulong,IntPtr,int>PyThreadState_SetAsyncExcLP64{get;}
27882791
internalstaticdelegate* unmanaged[Cdecl]<BorrowedReference,IntPtr,NewReference>PyObject_GenericGetDict{get;}
2792+
internalstaticdelegate* unmanaged[Cdecl]<inNativeTypeSpec,BorrowedReference,NewReference>PyType_FromSpecWithBases{get;}
27892793
}
27902794
}
27912795

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp