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

Commit659ad56

Browse files
committed
Address review by@lostmsu; Add forward operator test.
1 parent6df5a1f commit659ad56

File tree

5 files changed

+56
-71
lines changed

5 files changed

+56
-71
lines changed

‎src/embed_tests/TestPyMethod.csrenamed to‎src/embed_tests/TestOperator.cs

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespacePython.EmbeddingTest
99
{
10-
publicclassTestPyMethod
10+
publicclassTestOperator
1111
{
1212
[OneTimeSetUp]
1313
publicvoidSetUp()
@@ -28,38 +28,6 @@ public class SampleClass
2828
publicintFoo(inta,intb=10)=>a+b;
2929
}
3030

31-
[Test]
32-
publicvoidTestVoidCall()
33-
{
34-
stringname=string.Format("{0}.{1}",
35-
typeof(SampleClass).DeclaringType.Name,
36-
typeof(SampleClass).Name);
37-
stringmodule=MethodBase.GetCurrentMethod().DeclaringType.Namespace;
38-
PythonEngine.Exec($@"
39-
from{module} import *
40-
SampleClass ={name}
41-
obj = SampleClass()
42-
assert obj.VoidCall() == 10
43-
");
44-
}
45-
46-
[Test]
47-
publicvoidTestDefaultParameter()
48-
{
49-
stringname=string.Format("{0}.{1}",
50-
typeof(SampleClass).DeclaringType.Name,
51-
typeof(SampleClass).Name);
52-
stringmodule=MethodBase.GetCurrentMethod().DeclaringType.Namespace;
53-
54-
PythonEngine.Exec($@"
55-
from{module} import *
56-
SampleClass ={name}
57-
obj = SampleClass()
58-
assert obj.Foo(10) == 20
59-
assert obj.Foo(10, 1) == 11
60-
");
61-
}
62-
6331
publicclassOperableObject
6432
{
6533
publicintNum{get;set;}
@@ -73,6 +41,10 @@ public OperableObject(int num)
7341
{
7442
returnnewOperableObject(a.Num+b.Num);
7543
}
44+
publicstaticOperableObjectoperator+(OperableObjecta,intb)
45+
{
46+
returnnewOperableObject(a.Num+b);
47+
}
7648

7749
publicstaticOperableObjectoperator-(OperableObjecta,OperableObjectb)
7850
{
@@ -151,7 +123,25 @@ public void OperatorOverloads()
151123
");
152124
}
153125
[Test]
154-
publicvoidBitOperatorOverloads()
126+
publicvoidForwardOperatorOverloads()
127+
{
128+
stringname=string.Format("{0}.{1}",
129+
typeof(OperableObject).DeclaringType.Name,
130+
typeof(OperableObject).Name);
131+
stringmodule=MethodBase.GetCurrentMethod().DeclaringType.Namespace;
132+
133+
PythonEngine.Exec($@"
134+
from{module} import *
135+
cls ={name}
136+
a = cls(2)
137+
b = cls(10)
138+
139+
c = a + b.Num
140+
assert c.Num == a.Num + b.Num
141+
");
142+
}
143+
[Test]
144+
publicvoidShiftOperatorOverloads()
155145
{
156146
stringname=string.Format("{0}.{1}",
157147
typeof(OperableObject).DeclaringType.Name,

‎src/runtime/classderived.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,7 @@ internal ClassDerivedObject(Type tp) : base(tp)
6666
publicnewstaticvoidtp_dealloc(IntPtrob)
6767
{
6868
varself=(CLRObject)GetManagedObject(ob);
69-
// Amos's fix https://github.com/pythonnet/pythonnet/pull/1260#issuecomment-726719595
70-
if(self.tpHandle==IntPtr.Zero)
71-
{
72-
ClassBase.tp_dealloc(ob);
73-
return;
74-
}
69+
7570
// don't let the python GC destroy this object
7671
Runtime.PyObject_GC_UnTrack(self.pyHandle);
7772

‎src/runtime/classmanager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ private static ClassInfo GetClassInfo(Type type)
470470

471471
ob=newMethodObject(type,name,mlist);
472472
ci.members[name]=ob;
473-
if(OperatorMethod.IsOperatorMethod(name))
473+
if(OperatorMethod.IsOperatorMethod(mlist[0]))
474474
{
475475
ci.members[OperatorMethod.GetPyMethodName(name)]=ob;
476476
}

‎src/runtime/methodbinder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
354354
needsResolution:_methods.Length>1,// If there's more than one possible match.
355355
isOperator:isOperator,
356356
outs:outouts);
357+
if(margs==null)
358+
{
359+
continue;
360+
}
357361
if(isOperator)
358362
{
359363
if(inst!=IntPtr.Zero)
@@ -367,10 +371,6 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
367371
}
368372
}
369373

370-
if(margs==null)
371-
{
372-
continue;
373-
}
374374

375375
varmatchedMethod=newMatchedMethod(kwargsMatched,defaultsNeeded,margs,outs,mi);
376376
argMatchedMethods.Add(matchedMethod);

‎src/runtime/operatormethod.cs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,35 @@ internal static class OperatorMethod
1212
// Maps the compiled method name in .NET CIL (e.g. op_Addition) to
1313
// the equivalent Python operator (e.g. __add__) as well as the offset
1414
// that identifies that operator's slot (e.g. nb_add) in heap space.
15-
publicstaticDictionary<string,Tuple<string,int>>OpMethodMap{get;privateset;}
16-
15+
publicstaticDictionary<string,SlotDefinition>OpMethodMap{get;privateset;}
16+
publicreadonlystructSlotDefinition
17+
{
18+
publicSlotDefinition(stringmethodName,inttypeOffset)
19+
{
20+
MethodName=methodName;
21+
TypeOffset=typeOffset;
22+
}
23+
publicstringMethodName{get;}
24+
publicintTypeOffset{get;}
25+
}
1726
privatestaticPyObject_opType;
1827

1928
staticOperatorMethod()
2029
{
2130
// TODO: Rich compare, inplace operator support
22-
OpMethodMap=newDictionary<string,Tuple<string,int>>
31+
OpMethodMap=newDictionary<string,SlotDefinition>
2332
{
24-
["op_Addition"]=Tuple.Create("__add__",TypeOffset.nb_add),
25-
["op_Subtraction"]=Tuple.Create("__sub__",TypeOffset.nb_subtract),
26-
["op_Multiply"]=Tuple.Create("__mul__",TypeOffset.nb_multiply),
27-
#ifPYTHON2
28-
["op_Division"]=Tuple.Create("__div__",TypeOffset.nb_divide),
29-
#else
30-
["op_Division"]=Tuple.Create("__truediv__",TypeOffset.nb_true_divide),
31-
#endif
32-
["op_BitwiseAnd"]=Tuple.Create("__and__",TypeOffset.nb_and),
33-
["op_BitwiseOr"]=Tuple.Create("__or__",TypeOffset.nb_or),
34-
["op_ExclusiveOr"]=Tuple.Create("__xor__",TypeOffset.nb_xor),
35-
["op_LeftShift"]=Tuple.Create("__lshift__",TypeOffset.nb_lshift),
36-
["op_RightShift"]=Tuple.Create("__rshift__",TypeOffset.nb_rshift),
37-
["op_Modulus"]=Tuple.Create("__mod__",TypeOffset.nb_remainder),
38-
["op_OneComplement"]=Tuple.Create("__invert__",TypeOffset.nb_invert)
33+
["op_Addition"]=newSlotDefinition("__add__",TypeOffset.nb_add),
34+
["op_Subtraction"]=newSlotDefinition("__sub__",TypeOffset.nb_subtract),
35+
["op_Multiply"]=newSlotDefinition("__mul__",TypeOffset.nb_multiply),
36+
["op_Division"]=newSlotDefinition("__truediv__",TypeOffset.nb_true_divide),
37+
["op_BitwiseAnd"]=newSlotDefinition("__and__",TypeOffset.nb_and),
38+
["op_BitwiseOr"]=newSlotDefinition("__or__",TypeOffset.nb_or),
39+
["op_ExclusiveOr"]=newSlotDefinition("__xor__",TypeOffset.nb_xor),
40+
["op_LeftShift"]=newSlotDefinition("__lshift__",TypeOffset.nb_lshift),
41+
["op_RightShift"]=newSlotDefinition("__rshift__",TypeOffset.nb_rshift),
42+
["op_Modulus"]=newSlotDefinition("__mod__",TypeOffset.nb_remainder),
43+
["op_OneComplement"]=newSlotDefinition("__invert__",TypeOffset.nb_invert)
3944
};
4045
}
4146

@@ -53,11 +58,6 @@ public static void Shutdown()
5358
}
5459
}
5560

56-
publicstaticboolIsOperatorMethod(stringmethodName)
57-
{
58-
returnOpMethodMap.ContainsKey(methodName);
59-
}
60-
6161
publicstaticboolIsOperatorMethod(MethodBasemethod)
6262
{
6363
if(!method.IsSpecialName)
@@ -82,7 +82,7 @@ public static void FixupSlots(IntPtr pyType, Type clrType)
8282
{
8383
continue;
8484
}
85-
intoffset=OpMethodMap[method.Name].Item2;
85+
intoffset=OpMethodMap[method.Name].TypeOffset;
8686
// Copy the default implementation of e.g. the nb_add slot,
8787
// which simply calls __add__ on the type.
8888
IntPtrfunc=Marshal.ReadIntPtr(_opType.Handle,offset);
@@ -97,7 +97,7 @@ public static void FixupSlots(IntPtr pyType, Type clrType)
9797

9898
publicstaticstringGetPyMethodName(stringclrName)
9999
{
100-
returnOpMethodMap[clrName].Item1;
100+
returnOpMethodMap[clrName].MethodName;
101101
}
102102

103103
privatestaticstringGenerateDummyCode()
@@ -106,7 +106,7 @@ private static string GenerateDummyCode()
106106
sb.AppendLine("class OperatorMethod(object):");
107107
foreach(variteminOpMethodMap.Values)
108108
{
109-
stringdef=string.Format(" def {0}(self, other): pass",item.Item1);
109+
stringdef=string.Format(" def {0}(self, other): pass",item.MethodName);
110110
sb.AppendLine(def);
111111
}
112112
returnsb.ToString();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp