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

Commit182faed

Browse files
committed
allow creating new .NET arrays from Python using Array[T](dim1, dim2, ...) syntax
fixes#251
1 parentc81c3c3 commit182faed

File tree

8 files changed

+143
-6
lines changed

8 files changed

+143
-6
lines changed

‎CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
99

1010
###Added
1111

12+
- Ability to instantiate new .NET arrays using`Array[T](dim1, dim2, ...)` syntax
13+
1214
###Changed
1315
- Drop support for Python 2, 3.4, and 3.5
1416
-`clr.AddReference` may now throw errors besides`FileNotFoundException`, that provide more

‎src/runtime/BorrowedReference.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,10 @@ public BorrowedReference(IntPtr pointer)
2222
{
2323
this.pointer=pointer;
2424
}
25+
26+
publicstaticbooloperator==(BorrowedReferencea,BorrowedReferenceb)
27+
=>a.pointer==b.pointer;
28+
publicstaticbooloperator!=(BorrowedReferencea,BorrowedReferenceb)
29+
=>a.pointer!=b.pointer;
2530
}
2631
}

‎src/runtime/NewReference.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ public PyObject MoveToPyObject()
2828
returnresult;
2929
}
3030

31+
/// <summary>Moves ownership of this instance to unmanged pointer</summary>
32+
publicIntPtrDangerousMoveToPointerOrNull()
33+
{
34+
varresult=this.pointer;
35+
this.pointer=IntPtr.Zero;
36+
returnresult;
37+
}
38+
3139
/// <summary>
3240
/// Removes this reference to a Python object, and sets it to <c>null</c>.
3341
/// </summary>

‎src/runtime/arrayobject.cs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,109 @@ internal override bool CanSubclass()
2020
returnfalse;
2121
}
2222

23-
publicstaticIntPtrtp_new(IntPtrtp,IntPtrargs,IntPtrkw)
23+
publicstaticIntPtrtp_new(IntPtrtpRaw,IntPtrargs,IntPtrkw)
2424
{
25+
if(kw!=IntPtr.Zero)
26+
{
27+
returnExceptions.RaiseTypeError("array constructor takes no keyword arguments");
28+
}
29+
30+
vartp=newBorrowedReference(tpRaw);
31+
2532
varself=GetManagedObject(tp)asArrayObject;
26-
if(Runtime.PyTuple_Size(args)!=1)
33+
34+
long[]dimensions=newlong[Runtime.PyTuple_Size(args)];
35+
if(dimensions.Length==0)
2736
{
28-
returnExceptions.RaiseTypeError("arrayexpects 1argument");
37+
returnExceptions.RaiseTypeError("arrayconstructor requires at least one integerargument or an object convertible to array");
2938
}
39+
if(dimensions.Length!=1)
40+
{
41+
returnCreateMultidimensional(self.type.GetElementType(),dimensions,
42+
shapeTuple:newBorrowedReference(args),
43+
pyType:tp)
44+
.DangerousMoveToPointerOrNull();
45+
}
46+
3047
IntPtrop=Runtime.PyTuple_GetItem(args,0);
48+
49+
// create single dimensional array
50+
if(Runtime.PyInt_Check(op))
51+
{
52+
dimensions[0]=Runtime.PyLong_AsLongLong(op);
53+
if(dimensions[0]==-1&&Exceptions.ErrorOccurred())
54+
{
55+
Exceptions.Clear();
56+
}
57+
else
58+
{
59+
returnNewInstance(self.type.GetElementType(),tp,dimensions)
60+
.DangerousMoveToPointerOrNull();
61+
}
62+
}
3163
objectresult;
3264

65+
// this implements casting to Array[T]
3366
if(!Converter.ToManaged(op,self.type,outresult,true))
3467
{
3568
returnIntPtr.Zero;
3669
}
37-
returnCLRObject.GetInstHandle(result,tp);
70+
returnCLRObject.GetInstHandle(result,tp)
71+
.DangerousGetAddress();
72+
}
73+
74+
staticNewReferenceCreateMultidimensional(TypeelementType,long[]dimensions,BorrowedReferenceshapeTuple,BorrowedReferencepyType)
75+
{
76+
for(intdimIndex=0;dimIndex<dimensions.Length;dimIndex++)
77+
{
78+
BorrowedReferencedimObj=Runtime.PyTuple_GetItem(shapeTuple,dimIndex);
79+
PythonException.ThrowIfIsNull(dimObj);
80+
81+
if(!Runtime.PyInt_Check(dimObj))
82+
{
83+
Exceptions.RaiseTypeError("array constructor expects integer dimensions");
84+
returndefault;
85+
}
86+
87+
dimensions[dimIndex]=Runtime.PyLong_AsLongLong(dimObj);
88+
if(dimensions[dimIndex]==-1&&Exceptions.ErrorOccurred())
89+
{
90+
Exceptions.RaiseTypeError("array constructor expects integer dimensions");
91+
returndefault;
92+
}
93+
}
94+
95+
returnNewInstance(elementType,pyType,dimensions);
96+
}
97+
98+
staticNewReferenceNewInstance(TypeelementType,BorrowedReferencearrayPyType,long[]dimensions)
99+
{
100+
objectresult;
101+
try
102+
{
103+
result=Array.CreateInstance(elementType,dimensions);
104+
}
105+
catch(ArgumentExceptionbadArgument)
106+
{
107+
Exceptions.SetError(Exceptions.ValueError,badArgument.Message);
108+
returndefault;
109+
}
110+
catch(OverflowExceptionoverflow)
111+
{
112+
Exceptions.SetError(overflow);
113+
returndefault;
114+
}
115+
catch(NotSupportedExceptionnotSupported)
116+
{
117+
Exceptions.SetError(notSupported);
118+
returndefault;
119+
}
120+
catch(OutOfMemoryExceptionoom)
121+
{
122+
Exceptions.SetError(Exceptions.MemoryError,oom.Message);
123+
returndefault;
124+
}
125+
returnCLRObject.GetInstHandle(result,arrayPyType);
38126
}
39127

40128

‎src/runtime/clrobject.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ static CLRObject GetInstance(object ob)
5151
returnGetInstance(ob,cc.tpHandle);
5252
}
5353

54-
54+
internalstaticNewReferenceGetInstHandle(objectob,BorrowedReferencepyType)
55+
{
56+
CLRObjectco=GetInstance(ob,pyType.DangerousGetAddress());
57+
returnNewReference.DangerousFromPointer(co.pyHandle);
58+
}
5559
internalstaticIntPtrGetInstHandle(objectob,IntPtrpyType)
5660
{
5761
CLRObjectco=GetInstance(ob,pyType);

‎src/runtime/managedtype.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ internal void FreeGCHandle()
7575
}
7676
}
7777

78+
internalstaticManagedTypeGetManagedObject(BorrowedReferenceob)
79+
=>GetManagedObject(ob.DangerousGetAddress());
7880
/// <summary>
7981
/// Given a Python object, return the associated managed object or null.
8082
/// </summary>

‎src/runtime/runtime.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,8 @@ internal static unsafe IntPtr PyObject_TYPE(IntPtr op)
10131013
?newIntPtr((void*)(*((uint*)p+ n)))
10141014
:new IntPtr((void*)(*((ulong*)p+ n)));
10151015
}
1016+
internalstatic unsafe BorrowedReference PyObject_TYPE(BorrowedReferenceop)
1017+
=>new BorrowedReference(PyObject_TYPE(op.DangerousGetAddress()));
10161018

10171019
/// <summary>
10181020
/// Managed version of the standard Python C API PyObject_Type call.
@@ -1202,6 +1204,8 @@ internal static long PyObject_Size(IntPtr pointer)
12021204
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
12031205
internalstaticexternbool PyNumber_Check(IntPtr ob);
12041206

1207+
internalstaticbool PyInt_Check(BorrowedReference ob)
1208+
=> PyObject_TypeCheck(ob,new BorrowedReference(PyIntType));
12051209
internalstaticbool PyInt_Check(IntPtr ob)
12061210
{
12071211
return PyObject_TypeCheck(ob, PyIntType);
@@ -1291,6 +1295,8 @@ internal static object PyLong_AsUnsignedLong(IntPtr value)
12911295
return PyLong_AsUnsignedLong64(value);
12921296
}
12931297

1298+
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
1299+
internalstaticexternlong PyLong_AsLongLong(BorrowedReference value);
12941300
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
12951301
internalstaticexternlong PyLong_AsLongLong(IntPtr value);
12961302

@@ -1829,11 +1835,15 @@ internal static IntPtr PyTuple_New(long size)
18291835
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
18301836
privatestaticextern IntPtr PyTuple_New(IntPtr size);
18311837

1838+
internalstatic BorrowedReference PyTuple_GetItem(BorrowedReference pointer,long index)
1839+
=> PyTuple_GetItem(pointer,new IntPtr(index));
18321840
internalstatic IntPtr PyTuple_GetItem(IntPtr pointer,long index)
18331841
{
18341842
return PyTuple_GetItem(pointer,new IntPtr(index));
18351843
}
18361844

1845+
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
1846+
privatestaticextern BorrowedReference PyTuple_GetItem(BorrowedReference pointer, IntPtr index);
18371847
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
18381848
privatestaticextern IntPtr PyTuple_GetItem(IntPtr pointer, IntPtr index);
18391849

@@ -1950,10 +1960,14 @@ internal static bool PyType_Check(IntPtr ob)
19501960

19511961
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
19521962
internalstaticexternbool PyType_IsSubtype(IntPtr t1, IntPtr t2);
1963+
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
1964+
internalstaticexternbool PyType_IsSubtype(BorrowedReference t1, BorrowedReference t2);
19531965

19541966
internalstaticbool PyObject_TypeCheck(IntPtr ob, IntPtr tp)
1967+
=> PyObject_TypeCheck(new BorrowedReference(ob),new BorrowedReference(tp));
1968+
internalstaticbool PyObject_TypeCheck(BorrowedReference ob, BorrowedReference tp)
19551969
{
1956-
IntPtr t= PyObject_TYPE(ob);
1970+
BorrowedReference t= PyObject_TYPE(ob);
19571971
return(t== tp)|| PyType_IsSubtype(t, tp);
19581972
}
19591973

‎src/tests/test_array.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,20 @@ def test_boxed_value_type_mutation_result():
11741174
assertitems[i].X==i+1
11751175
assertitems[i].Y==i+1
11761176

1177+
deftest_create_array_from_shape():
1178+
fromSystemimportArray
1179+
1180+
value=Array[int](3)
1181+
assertvalue[1]==0
1182+
assertvalue.Length==3
1183+
1184+
value=Array[int](3,4)
1185+
assertvalue[1,1]==0
1186+
assertvalue.GetLength(0)==3
1187+
assertvalue.GetLength(1)==4
1188+
1189+
withpytest.raises(ValueError):
1190+
Array[int](-1)
11771191

11781192
deftest_special_array_creation():
11791193
"""Test using the Array[<type>] syntax for creating arrays."""

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp