From b5ae97ff9865766261e57d2dd90b53e837b19ff4 Mon Sep 17 00:00:00 2001 From: Victor Nova Date: Wed, 25 Aug 2021 11:32:17 -0700 Subject: [PATCH 1/2] remove needsResolution hack fixes https://github.com/pythonnet/pythonnet/issues/1523 --- CHANGELOG.md | 2 ++ src/embed_tests/TestOperator.cs | 13 +++++++------ src/runtime/methodbinder.cs | 25 +++++-------------------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 387217c76..bc30155d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ One must now either use enum members (e.g. `MyEnum.Option`), or use enum constru - `PythonException.Restore` no longer clears `PythonException` instance. - Replaced the old `__import__` hook hack with a PEP302-style Meta Path Loader - BREAKING: Names of .NET types (e.g. `str(__class__)`) changed to better support generic types +- BREAKING: overload resolution will no longer prefer basic types. Instead, first matching overload will +be chosen. ### Fixed diff --git a/src/embed_tests/TestOperator.cs b/src/embed_tests/TestOperator.cs index 68a6e8e35..a5713274a 100644 --- a/src/embed_tests/TestOperator.cs +++ b/src/embed_tests/TestOperator.cs @@ -1,7 +1,9 @@ using NUnit.Framework; using Python.Runtime; +using Python.Runtime.Codecs; +using System; using System.Linq; using System.Reflection; @@ -212,21 +214,19 @@ public OperableObject(int num) return (a.Num >= b); } - public static bool operator >=(OperableObject a, PyObject b) + public static bool operator >=(OperableObject a, (int, int) b) { using (Py.GIL()) { - // Assuming b is a tuple, take the first element. - int bNum = b[0].As(); + int bNum = b.Item1; return a.Num >= bNum; } } - public static bool operator <=(OperableObject a, PyObject b) + public static bool operator <=(OperableObject a, (int, int) b) { using (Py.GIL()) { - // Assuming b is a tuple, take the first element. - int bNum = b[0].As(); + int bNum = b.Item1; return a.Num <= bNum; } } @@ -421,6 +421,7 @@ public void ForwardOperatorOverloads() [Test] public void TupleComparisonOperatorOverloads() { + TupleCodec.Register(); string name = string.Format("{0}.{1}", typeof(OperableObject).DeclaringType.Name, typeof(OperableObject).Name); diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index 1b7cc4736..e0600181b 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -433,9 +433,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth pi = pi.Take(1).ToArray(); } int outs; - var margs = TryConvertArguments(pi, paramsArray, args, pynargs, kwargDict, defaultArgList, - needsResolution: _methods.Length > 1, // If there's more than one possible match. - outs: out outs); + var margs = TryConvertArguments(pi, paramsArray, args, pynargs, kwargDict, defaultArgList, outs: out outs); if (margs == null) { var mismatchCause = PythonException.FetchCurrent(); @@ -612,7 +610,6 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray, IntPtr args, int pyArgCount, Dictionary kwargDict, ArrayList defaultArgList, - bool needsResolution, out int outs) { outs = 0; @@ -653,7 +650,7 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray, } bool isOut; - if (!TryConvertArgument(op, parameter.ParameterType, needsResolution, out margs[paramIndex], out isOut)) + if (!TryConvertArgument(op, parameter.ParameterType, out margs[paramIndex], out isOut)) { return null; } @@ -681,16 +678,15 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray, /// /// Pointer to the Python argument object. /// That parameter's managed type. - /// If true, there are multiple overloading methods that need resolution. /// Converted argument. /// Whether the CLR type is passed by reference. /// true on success - static bool TryConvertArgument(IntPtr op, Type parameterType, bool needsResolution, + static bool TryConvertArgument(IntPtr op, Type parameterType, out object arg, out bool isOut) { arg = null; isOut = false; - var clrtype = TryComputeClrArgumentType(parameterType, op, needsResolution: needsResolution); + var clrtype = TryComputeClrArgumentType(parameterType, op); if (clrtype == null) { return false; @@ -710,25 +706,14 @@ static bool TryConvertArgument(IntPtr op, Type parameterType, bool needsResoluti /// /// The parameter's managed type. /// Pointer to the Python argument object. - /// If true, there are multiple overloading methods that need resolution. /// null if conversion is not possible - static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool needsResolution) + static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument) { // this logic below handles cases when multiple overloading methods // are ambiguous, hence comparison between Python and CLR types // is necessary Type clrtype = null; IntPtr pyoptype; - if (needsResolution) - { - // HACK: each overload should be weighted in some way instead - pyoptype = Runtime.PyObject_Type(argument); - if (pyoptype != IntPtr.Zero) - { - clrtype = Converter.GetTypeByAlias(pyoptype); - } - Runtime.XDecref(pyoptype); - } if (clrtype != null) { From 1ee17323fea2b374c7f0099bf7d880be46841dd4 Mon Sep 17 00:00:00 2001 From: Victor Nova Date: Wed, 25 Aug 2021 11:37:53 -0700 Subject: [PATCH 2/2] added int overload resolution test by https://github.com/slide --- src/testing/conversiontest.cs | 13 +++++++++++++ tests/test_conversion.py | 14 +++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/testing/conversiontest.cs b/src/testing/conversiontest.cs index 1f9d64e1b..7a00f139e 100644 --- a/src/testing/conversiontest.cs +++ b/src/testing/conversiontest.cs @@ -78,4 +78,17 @@ public override string ToString() return value; } } + + public class MethodResolutionInt + { + public IEnumerable MethodA(ulong address, int size) + { + return new byte[10]; + } + + public int MethodA(string dummy, ulong address, int size) + { + return 0; + } + } } diff --git a/tests/test_conversion.py b/tests/test_conversion.py index eec2bcde6..3322b836f 100644 --- a/tests/test_conversion.py +++ b/tests/test_conversion.py @@ -4,7 +4,7 @@ import pytest import System -from Python.Test import ConversionTest, UnicodeString +from Python.Test import ConversionTest, MethodResolutionInt, UnicodeString from Python.Runtime import PyObjectConversions from Python.Runtime.Codecs import RawProxyEncoder @@ -681,3 +681,15 @@ def CanEncode(self, clr_type): l = ob.ListField l.Add(42) assert ob.ListField.Count == 1 + +def test_int_param_resolution_required(): + """Test resolution of `int` parameters when resolution is needed""" + + mri = MethodResolutionInt() + data = list(mri.MethodA(0x1000, 10)) + assert len(data) == 10 + assert data[0] == 0 + + data = list(mri.MethodA(0x100000000, 10)) + assert len(data) == 10 + assert data[0] == 0 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy