Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
34 changes: 34 additions & 0 deletions src/embed_tests/TestPyObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,40 @@ public void InheritedMethodsAutoacquireGIL()
{
PythonEngine.Exec("from System import String\nString.Format('{0},{1}', 1, 2)");
}

[Test]
public void FailedTryAsDoesNotLeavePythonErrorSet()
{
using var _ = Py.GIL();

using var locals = new PyDict();
PythonEngine.Exec("def a_function(a, b): return a * b", null, locals);
using var pyObject = locals.GetItem("a_function");

Assert.IsFalse(pyObject.TryAs<int>(out var _));
Assert.IsFalse(Exceptions.ErrorOccurred());

Assert.IsFalse(pyObject.TryAsManagedObject(typeof(decimal), out var _));
Assert.IsFalse(Exceptions.ErrorOccurred());

// The thread state must be clean for subsequent unrelated Python calls
Assert.DoesNotThrow(() => PyModule.FromString("TryAsLeakCheck", "x = 1").Dispose());
}

[Test]
public void FailedAsManagedObjectRaisesWithConversionErrorAsCause()
{
using var _ = Py.GIL();

using var locals = new PyDict();
PythonEngine.Exec("def a_function(a, b): return a * b", null, locals);
using var pyObject = locals.GetItem("a_function");

var exception = Assert.Throws<InvalidCastException>(() => pyObject.AsManagedObject(typeof(int)));
Assert.IsNotNull(exception.InnerException);
StringAssert.Contains("int()", exception.InnerException.Message);
Assert.IsFalse(Exceptions.ErrorOccurred());
}
}

public class PyObjectTestMethods
Expand Down
4 changes: 2 additions & 2 deletions src/perf_tests/Python.PerformanceTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.*" />
<PackageReference Include="quantconnect.pythonnet" Version="2.0.62" GeneratePathProperty="true">
<PackageReference Include="quantconnect.pythonnet" Version="2.0.63" GeneratePathProperty="true">
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
</ItemGroup>
Expand All @@ -25,7 +25,7 @@
</Target>

<Target Name="CopyBaseline" AfterTargets="Build">
<Copy SourceFiles="$(NuGetPackageRoot)quantconnect.pythonnet\2.0.62\lib\net10.0\Python.Runtime.dll" DestinationFolder="$(OutDir)baseline" />
<Copy SourceFiles="$(NuGetPackageRoot)quantconnect.pythonnet\2.0.63\lib\net10.0\Python.Runtime.dll" DestinationFolder="$(OutDir)baseline" />
</Target>

<Target Name="CopyNewBuild" AfterTargets="Build">
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
[assembly: InternalsVisibleTo("Python.EmbeddingTest, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")]
[assembly: InternalsVisibleTo("Python.Test, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")]

[assembly: AssemblyVersion("2.0.62")]
[assembly: AssemblyFileVersion("2.0.62")]
[assembly: AssemblyVersion("2.0.63")]
[assembly: AssemblyFileVersion("2.0.63")]
2 changes: 1 addition & 1 deletion src/runtime/Python.Runtime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<RootNamespace>Python.Runtime</RootNamespace>
<AssemblyName>Python.Runtime</AssemblyName>
<PackageId>QuantConnect.pythonnet</PackageId>
<Version>2.0.62</Version>
<Version>2.0.63</Version>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/pythonnet/pythonnet</RepositoryUrl>
Expand Down
12 changes: 10 additions & 2 deletions src/runtime/PythonTypes/PyObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static PyObject FromManagedObject(object ob)
/// </remarks>
public object? AsManagedObject(Type t)
{
if (!TryAsManagedObject(t, out var result))
if (!Converter.ToManaged(obj, t, out var result, setError: true))
{
throw new InvalidCastException("cannot convert object to target type",
PythonException.FetchCurrentOrNull(out _));
Expand All @@ -188,7 +188,15 @@ public static PyObject FromManagedObject(object ob)
/// </summary>
public bool TryAsManagedObject(Type t, out object? result)
{
return Converter.ToManaged(obj, t, out result, true);
if (Converter.ToManaged(obj, t, out result, setError: false))
{
return true;
}
// A failed Try-conversion must not leave a Python error pending on the
// thread: the caller only sees the boolean, so a stale error indicator
// would surface from an unrelated later call on this thread.
Exceptions.Clear();
return false;
}

/// <summary>
Expand Down
Loading