Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implement coerce logic for net method binding #2590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions src/runtime/MethodBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@
namespace Python.Runtime
{
using MaybeMethodBase = MaybeMethodBase<MethodBase>;

/// <summary>
/// Delegate for custom coercion logic during Python method binding.
/// </summary>
/// <param name="arguments">A dictionary containing the Python arguments passed to the method.</param>
/// <param name="methods">An array of method overloads being considered for binding.</param>
/// <param name="foundBinding">
/// A reference to the method that was successfully bound. This can be modified by the delegate
/// to override the default binding logic. The delegate can set this to null to disable the method call
/// and report an error.
/// </param>
public delegate void MethodBinderCoerceBindDelegate(
Dictionary<string, PyObject> arguments,
MethodBase[] methods,
ref MethodBase? foundBinding);

/// <summary>
/// A MethodBinder encapsulates information about a (possibly overloaded)
/// managed method, and is responsible for selecting the right method given
Expand Down Expand Up @@ -516,7 +532,7 @@ public MismatchedMethod(Exception exception, MethodBase mb)
}
}

return new Binding(mi, target, margs, outs);
return CoerceResult(new Binding(mi, target, margs, outs));
}
else if (matchGenerics && isGeneric)
{
Expand All @@ -528,7 +544,7 @@ public MismatchedMethod(Exception exception, MethodBase mb)
MethodInfo[] overloads = MatchParameters(methods, types);
if (overloads.Length != 0)
{
return Bind(inst, args, kwargDict, overloads, matchGenerics: false);
return CoerceResult(Bind(inst, args, kwargDict, overloads, matchGenerics: false));
}
}
if (mismatchedMethods.Count > 0)
Expand All @@ -537,6 +553,19 @@ public MismatchedMethod(Exception exception, MethodBase mb)
Exceptions.SetError(aggregateException);
}
return null;

Binding? CoerceResult(Binding? binding)
{
if (binding is not null)
{
var foundMethod = binding.info;
MethodBinderEvents.CoerceBind?.Invoke(kwargDict, methods, ref foundMethod);
if (foundMethod is null)
return null;
}

return binding;
}
}

static AggregateException GetAggregateException(IEnumerable<MismatchedMethod> mismatchedMethods)
Expand Down Expand Up @@ -1068,4 +1097,15 @@ static internal class ParameterInfoExtensions
}
}
}

/// <summary>
/// Provides events related to method binding in the MethodBinder class.
/// </summary>
public static class MethodBinderEvents
{
/// <summary>
/// Event triggered to allow custom coercion logic during method binding.
/// </summary>
public static MethodBinderCoerceBindDelegate? CoerceBind;
}
}