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

Commit01d6772

Browse files
gertdreyerlostmsu
authored andcommitted
Bugfix: RecursionError when reverse/righthand operations invoked. e.g. __rsub__, __rmul__
1 parent87fc365 commit01d6772

File tree

5 files changed

+42
-39
lines changed

5 files changed

+42
-39
lines changed

‎src/runtime/ClassManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
546546
ci.members[pyName]=newMethodObject(type,name,forwardMethods).AllocObject();
547547
// Only methods where only the right operand is the declaring type.
548548
if(reverseMethods.Length>0)
549-
ci.members[pyNameReverse]=newMethodObject(type,name,reverseMethods).AllocObject();
549+
ci.members[pyNameReverse]=newMethodObject(type,name,reverseMethods,reverse_args:true).AllocObject();
550550
}
551551
}
552552

‎src/runtime/MethodBinder.cs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,22 @@ internal class MethodBinder
2828

2929
[NonSerialized]
3030
publicboolinit=false;
31+
3132
publicconstboolDefaultAllowThreads=true;
3233
publicboolallow_threads=DefaultAllowThreads;
3334

34-
internalMethodBinder()
35+
publicboolargs_reversed=false;
36+
37+
internalMethodBinder(boolreverse_args=false)
3538
{
3639
list=newList<MaybeMethodBase>();
40+
args_reversed=reverse_args;
3741
}
3842

39-
internalMethodBinder(MethodInfomi)
43+
internalMethodBinder(MethodInfomi,boolreverse_args=false)
4044
{
4145
list=newList<MaybeMethodBase>{newMaybeMethodBase(mi)};
46+
args_reversed=reverse_args;
4247
}
4348

4449
publicintCount
@@ -271,10 +276,11 @@ internal static int ArgPrecedence(Type t)
271276
/// <param name="inst">The Python target of the method invocation.</param>
272277
/// <param name="args">The Python arguments.</param>
273278
/// <param name="kw">The Python keyword arguments.</param>
279+
/// <param name="reverse_args">Reverse arguments of methods. Used for methods such as __radd__, __rsub__, __rmod__ etc</param>
274280
/// <returns>A Binding if successful. Otherwise null.</returns>
275-
internalBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw)
281+
internalBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,boolreverse_args=false)
276282
{
277-
returnBind(inst,args,kw,null,null);
283+
returnBind(inst,args,kw,null,null,reverse_args);
278284
}
279285

280286
/// <summary>
@@ -287,10 +293,11 @@ internal static int ArgPrecedence(Type t)
287293
/// <param name="args">The Python arguments.</param>
288294
/// <param name="kw">The Python keyword arguments.</param>
289295
/// <param name="info">If not null, only bind to that method.</param>
296+
/// <param name="reverse_args">Reverse arguments of methods. Used for methods such as __radd__, __rsub__, __rmod__ etc</param>
290297
/// <returns>A Binding if successful. Otherwise null.</returns>
291-
internalBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info)
298+
internalBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,boolreverse_args=false)
292299
{
293-
returnBind(inst,args,kw,info,null);
300+
returnBind(inst,args,kw,info,null,reverse_args);
294301
}
295302

296303
privatereadonlystructMatchedMethod
@@ -334,8 +341,9 @@ public MismatchedMethod(Exception exception, MethodBase mb)
334341
/// <param name="kw">The Python keyword arguments.</param>
335342
/// <param name="info">If not null, only bind to that method.</param>
336343
/// <param name="methodinfo">If not null, additionally attempt to bind to the generic methods in this array by inferring generic type parameters.</param>
344+
/// <param name="reverse_args">Reverse arguments of methods. Used for methods such as __radd__, __rsub__, __rmod__ etc</param>
337345
/// <returns>A Binding if successful. Otherwise null.</returns>
338-
internalBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,MethodBase[]?methodinfo)
346+
internalBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,MethodBase[]?methodinfo,boolreverse_args=false)
339347
{
340348
// loop to find match, return invoker w/ or w/o error
341349
varkwargDict=newDictionary<string,PyObject>();
@@ -363,10 +371,10 @@ public MismatchedMethod(Exception exception, MethodBase mb)
363371
_methods=GetMethods();
364372
}
365373

366-
returnBind(inst,args,kwargDict,_methods,matchGenerics:true);
374+
returnBind(inst,args,kwargDict,_methods,matchGenerics:true,reverse_args);
367375
}
368376

369-
staticBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,Dictionary<string,PyObject>kwargDict,MethodBase[]methods,boolmatchGenerics)
377+
privatestaticBinding?Bind(BorrowedReferenceinst,BorrowedReferenceargs,Dictionary<string,PyObject>kwargDict,MethodBase[]methods,boolmatchGenerics,boolreversed=false)
370378
{
371379
varpynargs=(int)Runtime.PyTuple_Size(args);
372380
varisGeneric=false;
@@ -386,7 +394,7 @@ public MismatchedMethod(Exception exception, MethodBase mb)
386394
// Binary operator methods will have 2 CLR args but only one Python arg
387395
// (unary operators will have 1 less each), since Python operator methods are bound.
388396
isOperator=isOperator&&pynargs==pi.Length-1;
389-
boolisReverse=isOperator&&OperatorMethod.IsReverse((MethodInfo)mi);// Only cast if isOperator.
397+
boolisReverse=isOperator&&reversed;// Only cast if isOperator.
390398
if(isReverse&&OperatorMethod.IsComparisonOp((MethodInfo)mi))
391399
continue;// Comparison operators in Python have no reverse mode.
392400
if(!MatchesArgumentCount(pynargs,pi,kwargDict,outboolparamsArray,outArrayList?defaultArgList,outintkwargsMatched,outintdefaultsNeeded)&&!isOperator)
@@ -809,14 +817,14 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
809817
returnmatch;
810818
}
811819

812-
internalvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw)
820+
internalvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,boolreverse_args=false)
813821
{
814-
returnInvoke(inst,args,kw,null,null);
822+
returnInvoke(inst,args,kw,null,null,reverse_args);
815823
}
816824

817-
internalvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info)
825+
internalvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,boolreverse_args=false)
818826
{
819-
returnInvoke(inst,args,kw,info,null);
827+
returnInvoke(inst,args,kw,info,null,reverse_args=false);
820828
}
821829

822830
protectedstaticvoidAppendArgumentTypes(StringBuilderto,BorrowedReferenceargs)
@@ -852,7 +860,7 @@ protected static void AppendArgumentTypes(StringBuilder to, BorrowedReference ar
852860
to.Append(')');
853861
}
854862

855-
internalvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,MethodBase[]?methodinfo)
863+
internalvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,MethodBase[]?methodinfo,boolreverse_args=false)
856864
{
857865
// No valid methods, nothing to bind.
858866
if(GetMethods().Length==0)
@@ -865,7 +873,7 @@ internal virtual NewReference Invoke(BorrowedReference inst, BorrowedReference a
865873
returnExceptions.RaiseTypeError(msg.ToString());
866874
}
867875

868-
Binding?binding=Bind(inst,args,kw,info,methodinfo);
876+
Binding?binding=Bind(inst,args,kw,info,methodinfo,reverse_args);
869877
objectresult;
870878
IntPtrts=IntPtr.Zero;
871879

‎src/runtime/Types/MethodBinding.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ public static NewReference tp_call(BorrowedReference ob, BorrowedReference args,
237237
}
238238
}
239239
}
240-
returnself.m.Invoke(targetisnull?BorrowedReference.Null:target,args,kw,self.info.UnsafeValue);
240+
241+
returnself.m.Invoke(targetisnull?BorrowedReference.Null:target,args,kw,self.info.UnsafeValue,self.m.binder.args_reversed);
241242
}
242243
finally
243244
{

‎src/runtime/Types/MethodObject.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ internal class MethodObject : ExtensionType
1919
{
2020
[NonSerialized]
2121
privateMethodBase[]?_info=null;
22+
2223
privatereadonlyList<MaybeMethodInfo>infoList;
2324
internalstringname;
2425
internalreadonlyMethodBinderbinder;
2526
internalboolis_static=false;
26-
2727
internalPyString?doc;
2828
internalMaybeTypetype;
2929

30-
publicMethodObject(MaybeTypetype,stringname,MethodBase[]info,boolallow_threads)
30+
publicMethodObject(MaybeTypetype,stringname,MethodBase[]info,boolallow_threads,boolreverse_args=false)
3131
{
3232
this.type=type;
3333
this.name=name;
3434
this.infoList=newList<MaybeMethodInfo>();
35-
binder=newMethodBinder();
35+
binder=newMethodBinder(reverse_args);
3636
foreach(MethodBaseitemininfo)
3737
{
3838
this.infoList.Add(item);
@@ -45,8 +45,8 @@ public MethodObject(MaybeType type, string name, MethodBase[] info, bool allow_t
4545
binder.allow_threads=allow_threads;
4646
}
4747

48-
publicMethodObject(MaybeTypetype,stringname,MethodBase[]info)
49-
:this(type,name,info,allow_threads:AllowThreads(info))
48+
publicMethodObject(MaybeTypetype,stringname,MethodBase[]info,boolreverse_args=false)
49+
:this(type,name,info,allow_threads:AllowThreads(info),reverse_args)
5050
{
5151
}
5252

@@ -67,14 +67,14 @@ internal MethodBase[] info
6767
}
6868
}
6969

70-
publicvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw)
70+
publicvirtualNewReferenceInvoke(BorrowedReferenceinst,BorrowedReferenceargs,BorrowedReferencekw,boolreverse_args=false)
7171
{
72-
returnInvoke(inst,args,kw,null);
72+
returnInvoke(inst,args,kw,null,reverse_args);
7373
}
7474

75-
publicvirtualNewReferenceInvoke(BorrowedReferencetarget,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info)
75+
publicvirtualNewReferenceInvoke(BorrowedReferencetarget,BorrowedReferenceargs,BorrowedReferencekw,MethodBase?info,boolreverse_args=false)
7676
{
77-
returnbinder.Invoke(target,args,kw,info,this.info);
77+
returnbinder.Invoke(target,args,kw,info,this.info,reverse_args);
7878
}
7979

8080
/// <summary>

‎src/runtime/Types/OperatorMethod.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,14 @@ public static string ReversePyMethodName(string pyName)
177177
}
178178

179179
/// <summary>
180-
/// Check if the methodis performing areverse operation.
180+
/// Check if the methodshould have areversed operation.
181181
/// </summary>
182182
/// <param name="method">The operator method.</param>
183183
/// <returns></returns>
184-
publicstaticboolIsReverse(MethodBasemethod)
184+
publicstaticboolHaveReverse(MethodBasemethod)
185185
{
186-
TypeprimaryType=method.IsOpsHelper()
187-
?method.DeclaringType.GetGenericArguments()[0]
188-
:method.DeclaringType;
189-
TypeleftOperandType=method.GetParameters()[0].ParameterType;
190-
returnleftOperandType!=primaryType;
186+
varpi=method.GetParameters();
187+
returnOpMethodMap.ContainsKey(method.Name)&&pi.Length==2;
191188
}
192189

193190
publicstaticvoidFilterMethods(MethodBase[]methods,outMethodBase[]forwardMethods,outMethodBase[]reverseMethods)
@@ -196,14 +193,11 @@ public static void FilterMethods(MethodBase[] methods, out MethodBase[] forwardM
196193
varreverseMethodsList=newList<MethodBase>();
197194
foreach(varmethodinmethods)
198195
{
199-
if(IsReverse(method))
196+
forwardMethodsList.Add(method);
197+
if(HaveReverse(method))
200198
{
201199
reverseMethodsList.Add(method);
202-
}else
203-
{
204-
forwardMethodsList.Add(method);
205200
}
206-
207201
}
208202
forwardMethods=forwardMethodsList.ToArray();
209203
reverseMethods=reverseMethodsList.ToArray();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp