diff --git a/src/embed_tests/Codecs.cs b/src/embed_tests/Codecs.cs index 6159060b3..f9ea2e14f 100644 --- a/src/embed_tests/Codecs.cs +++ b/src/embed_tests/Codecs.cs @@ -25,15 +25,13 @@ static void TupleConversionsGeneric() TupleCodec.Register(); var tuple = Activator.CreateInstance(typeof(T), 42, "42", new object()); T restored = default; - using (var scope = Py.CreateScope()) - { - void Accept(T value) => restored = value; - using var accept = new Action(Accept).ToPython(); - scope.Set(nameof(tuple), tuple); - scope.Set(nameof(accept), accept); - scope.Exec($"{nameof(accept)}({nameof(tuple)})"); - Assert.That(actual: restored, Is.EqualTo(expected: tuple)); - } + using var scope = Py.CreateScope(); + void Accept(T value) => restored = value; + using var accept = new Action(Accept).ToPython(); + scope.Set(nameof(tuple), tuple); + scope.Set(nameof(accept), accept); + scope.Exec($"{nameof(accept)}({nameof(tuple)})"); + Assert.That(actual: restored, Is.EqualTo(expected: tuple)); } [Test] @@ -46,15 +44,13 @@ static void TupleConversionsObject() TupleCodec.Register(); var tuple = Activator.CreateInstance(typeof(T), 42.0, "42", new object()); T restored = default; - using (var scope = Py.CreateScope()) - { - void Accept(object value) => restored = (T)value; - using var accept = new Action(Accept).ToPython(); - scope.Set(nameof(tuple), tuple); - scope.Set(nameof(accept), accept); - scope.Exec($"{nameof(accept)}({nameof(tuple)})"); - Assert.That(actual: restored, Is.EqualTo(expected: tuple)); - } + using var scope = Py.CreateScope(); + void Accept(object value) => restored = (T)value; + using var accept = new Action(Accept).ToPython(); + scope.Set(nameof(tuple), tuple); + scope.Set(nameof(accept), accept); + scope.Exec($"{nameof(accept)}({nameof(tuple)})"); + Assert.That(actual: restored, Is.EqualTo(expected: tuple)); } [Test] @@ -92,7 +88,7 @@ public void ListDecoderTest() var codec = ListDecoder.Instance; var items = new List() { new PyInt(1), new PyInt(2), new PyInt(3) }; - using var pyList = new PyList(items.ToArray()); + using var pyList = new PyList([.. items]); using var pyListType = pyList.GetPythonType(); Assert.IsTrue(codec.CanDecode(pyListType, typeof(IList))); @@ -119,7 +115,7 @@ public void ListDecoderTest() IList stringList = null; Assert.DoesNotThrow(() => { codec.TryDecode(pyList, out stringList); }); Assert.That(3, Is.EqualTo(stringList.Count)); - Assert.Throws(typeof(InvalidCastException), () => { var x = stringList[0]; }); + Assert.Throws(() => { var x = stringList[0]; }); //can't convert python iterable to list (this will require a copy which isn't lossless) using var foo = GetPythonIterable(); @@ -134,7 +130,7 @@ public void SequenceDecoderTest() var items = new List() { new PyInt(1), new PyInt(2), new PyInt(3) }; //SequenceConverter can only convert to any ICollection - using var pyList = new PyList(items.ToArray()); + using var pyList = new PyList([.. items]); using var listType = pyList.GetPythonType(); //it can convert a PyList, since PyList satisfies the python sequence protocol @@ -162,7 +158,7 @@ public void SequenceDecoderTest() //the IList will report a Count of 3. ICollection stringCollection = null; Assert.DoesNotThrow(() => { codec.TryDecode(pyList, out stringCollection); }); - Assert.That(stringCollection.Count(), Is.EqualTo(3)); + Assert.That(stringCollection.Count, Is.EqualTo(3)); Assert.Throws(() => { string[] array = new string[3]; stringCollection.CopyTo(array, 0); @@ -177,7 +173,7 @@ public void SequenceDecoderTest() Assert.IsFalse(codec.CanDecode(fooType, typeof(ICollection))); //python tuples do satisfy the python sequence protocol - var pyTuple = new PyTuple(items.ToArray()); + var pyTuple = new PyTuple([.. items]); var pyTupleType = pyTuple.GetPythonType(); Assert.IsTrue(codec.CanDecode(pyTupleType, typeof(ICollection))); @@ -215,7 +211,7 @@ public void IterableDecoderTest() var codec = IterableDecoder.Instance; var items = new List() { new PyInt(1), new PyInt(2), new PyInt(3) }; - var pyList = new PyList(items.ToArray()); + var pyList = new PyList([.. items]); var pyListType = pyList.GetPythonType(); Assert.IsFalse(codec.CanDecode(pyListType, typeof(IList))); Assert.IsTrue(codec.CanDecode(pyListType, typeof(System.Collections.IEnumerable))); @@ -249,13 +245,13 @@ public void IterableDecoderTest() IEnumerable stringEnumerable = null; Assert.DoesNotThrow(() => { codec.TryDecode(pyList, out stringEnumerable); }); - Assert.Throws(typeof(InvalidCastException), () => { + Assert.Throws(() => { foreach (string item in stringEnumerable) { var x = item; } }); - Assert.Throws(typeof(InvalidCastException), () => { + Assert.Throws(() => { stringEnumerable.Count(); }); @@ -309,7 +305,7 @@ def CanEncode(self, clr_type): public void ExceptionEncoded() { PyObjectConversions.RegisterEncoder(new ValueErrorCodec()); - void CallMe() => throw new ValueErrorWrapper(TestExceptionMessage); + static void CallMe() => throw new ValueErrorWrapper(TestExceptionMessage); var callMeAction = new Action(CallMe); using var scope = Py.CreateScope(); scope.Exec(@" @@ -385,7 +381,9 @@ public void ExceptionDecodedNoInstance() } } +#pragma warning disable IDE0060 // Remove unused parameter public static void AcceptsDateTime(DateTime v) {} +#pragma warning restore IDE0060 // Remove unused parameter [Test] public void As_Object_AffectedByDecoders() @@ -412,15 +410,14 @@ public bool TryDecode(PyObject pyObj, out T value) } } - class ValueErrorWrapper : Exception + class ValueErrorWrapper(string message) : Exception(message) { - public ValueErrorWrapper(string message) : base(message) { } } class ValueErrorCodec : IPyObjectEncoder, IPyObjectDecoder { public bool CanDecode(PyType objectType, Type targetType) - => this.CanEncode(targetType) + => CanEncode(targetType) && PythonReferenceComparer.Instance.Equals(objectType, PythonEngine.Eval("ValueError")); public bool CanEncode(Type type) => type == typeof(ValueErrorWrapper) @@ -480,16 +477,10 @@ class ObjectToEncoderInstanceEncoder : IPyObjectEncoder /// Decodes object of specified Python type to the predefined value /// /// Type of the - class DecoderReturningPredefinedValue : IPyObjectDecoder + class DecoderReturningPredefinedValue(PyObject objectType, TTarget decodeResult) : IPyObjectDecoder { - public PyObject TheOnlySupportedSourceType { get; } - public TTarget DecodeResult { get; } - - public DecoderReturningPredefinedValue(PyObject objectType, TTarget decodeResult) - { - this.TheOnlySupportedSourceType = objectType; - this.DecodeResult = decodeResult; - } + public PyObject TheOnlySupportedSourceType { get; } = objectType; + public TTarget DecodeResult { get; } = decodeResult; public bool CanDecode(PyType objectType, Type targetType) => PythonReferenceComparer.Instance.Equals(objectType, TheOnlySupportedSourceType) @@ -497,7 +488,7 @@ public bool CanDecode(PyType objectType, Type targetType) public bool TryDecode(PyObject pyObj, out T value) { if (typeof(T) != typeof(TTarget)) - throw new ArgumentException(nameof(T)); + throw new ArgumentException(null, nameof(T)); value = (T)(object)DecodeResult; return true; } diff --git a/src/embed_tests/Dynamic.cs b/src/embed_tests/Dynamic.cs index 9d35bfacc..b5b13f1a7 100644 --- a/src/embed_tests/Dynamic.cs +++ b/src/embed_tests/Dynamic.cs @@ -35,10 +35,10 @@ public void AssignNone() { dynamic sys = Py.Import("sys"); sys.testattr = new StringBuilder(); - Assert.IsNotNull(sys.testattr); + Assert.That(sys.testattr, Is.Not.Null); sys.testattr = null; - Assert.IsNull(sys.testattr); + Assert.That(sys.testattr, Is.Null); } /// @@ -80,7 +80,7 @@ public void PassObjectInPython() Assert.That(sys.testattr3.ToString(), Is.EqualTo("True")); // Compare in .NET - Assert.IsTrue(sys.testattr1.Equals(sys.testattr2)); + Assert.That(sys.testattr1, Is.EqualTo(sys.testattr2)); } /// @@ -103,7 +103,7 @@ public void PassPyObjectInNet() Assert.That(sys.testattr3.ToString(), Is.EqualTo("True")); // Compare in .NET - Assert.IsTrue(sys.testattr1.Equals(sys.testattr2)); + Assert.That(sys.testattr1, Is.EqualTo(sys.testattr2)); } // regression test for https://github.com/pythonnet/pythonnet/issues/1848 @@ -119,13 +119,13 @@ class MyEnum(enum.IntEnum): ERROR = 2 def get_status(): - return MyEnum.OK + return MyEnum.OK " ); dynamic MyEnum = scope.Get("MyEnum"); dynamic status = scope.Get("get_status").Invoke(); - Assert.IsTrue(status == MyEnum.OK); + Assert.That(status, Is.EqualTo(MyEnum.OK)); } // regression test for https://github.com/pythonnet/pythonnet/issues/1680 diff --git a/src/embed_tests/NumPyTests.cs b/src/embed_tests/NumPyTests.cs index 57ff11b2b..4bd7356d7 100644 --- a/src/embed_tests/NumPyTests.cs +++ b/src/embed_tests/NumPyTests.cs @@ -67,12 +67,12 @@ public void VarArg() { dynamic zX = np.array(new[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 8, 9, 0 } }); dynamic grad = np.gradient(zX, 4.0, 5.0); - dynamic grad2 = np.InvokeMethod("gradient", new PyObject[] {zX, new PyFloat(4.0), new PyFloat(5.0)}); + dynamic grad2 = np.InvokeMethod("gradient", new PyObject[] { zX, new PyFloat(4.0), new PyFloat(5.0) }); - Assert.AreEqual(4.125, grad[0].sum().__float__().As(), 0.001); - Assert.AreEqual(-1.2, grad[1].sum().__float__().As(), 0.001); - Assert.AreEqual(4.125, grad2[0].sum().__float__().As(), 0.001); - Assert.AreEqual(-1.2, grad2[1].sum().__float__().As(), 0.001); + Assert.That(grad[0].sum().__float__().As(), Is.EqualTo(4.125).Within(0.001)); + Assert.That(grad[1].sum().__float__().As(), Is.EqualTo(-1.2).Within(0.001)); + Assert.That(grad2[0].sum().__float__().As(), Is.EqualTo(4.125).Within(0.001)); + Assert.That(grad2[1].sum().__float__().As(), Is.EqualTo(-1.2).Within(0.001)); } #pragma warning disable IDE1006 diff --git a/src/embed_tests/Python.EmbeddingTest.csproj b/src/embed_tests/Python.EmbeddingTest.csproj index 15258fc83..8697e7aaf 100644 --- a/src/embed_tests/Python.EmbeddingTest.csproj +++ b/src/embed_tests/Python.EmbeddingTest.csproj @@ -24,7 +24,7 @@ - +