From 4eee659ecab66d2a90c6dba3c9f235965a944e3c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 18:27:23 +0000 Subject: [PATCH 1/5] Initial plan From 095087ee9f6e737b776862c882f59994b5b525b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 18:42:52 +0000 Subject: [PATCH 2/5] Fix PicklingError in subprocess spawn by moving fixtures to conftest.py Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> --- tests/conftest.py | 25 +++++++++++++++++++++++++ tests/test_common.py | 22 ---------------------- 2 files changed, 25 insertions(+), 22 deletions(-) create mode 100644 tests/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..17ffeee --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,25 @@ +from pathlib import Path +from subprocess import check_call + +import pytest + +NETCORE_VERSION = "net10.0" + + +@pytest.fixture(scope="session") +def example_netstandard(tmp_path_factory: pytest.TempPathFactory) -> Path: + return build_example(tmp_path_factory, "netstandard2.0") + + +@pytest.fixture(scope="session") +def example_netcore(tmp_path_factory: pytest.TempPathFactory) -> Path: + return build_example(tmp_path_factory, NETCORE_VERSION) + + +def build_example(tmp_path_factory: pytest.TempPathFactory, framework: str) -> Path: + out = tmp_path_factory.mktemp(f"example-{framework}") + proj_path = Path(__file__).parent.parent / "example" / "example.csproj" + + _ = check_call(["dotnet", "build", str(proj_path), "-o", str(out), "-f", framework]) + + return out diff --git a/tests/test_common.py b/tests/test_common.py index 4c3e1e4..9d4a829 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -1,31 +1,9 @@ import shutil import sys from pathlib import Path -from subprocess import check_call import pytest -NETCORE_VERSION = "net10.0" - - -@pytest.fixture(scope="session") -def example_netstandard(tmp_path_factory: pytest.TempPathFactory) -> Path: - return build_example(tmp_path_factory, "netstandard2.0") - - -@pytest.fixture(scope="session") -def example_netcore(tmp_path_factory: pytest.TempPathFactory) -> Path: - return build_example(tmp_path_factory, NETCORE_VERSION) - - -def build_example(tmp_path_factory: pytest.TempPathFactory, framework: str) -> Path: - out = tmp_path_factory.mktemp(f"example-{framework}") - proj_path = Path(__file__).parent.parent / "example" / "example.csproj" - - _ = check_call(["dotnet", "build", str(proj_path), "-o", str(out), "-f", framework]) - - return out - def test_mono(example_netstandard: Path): from clr_loader import get_mono From ae47f46e33222b418a7ae5c8dc415de965a5981f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:04:50 +0000 Subject: [PATCH 3/5] Fix silent subprocess failures: assert exitcode and fix test_coreclr_properties kwargs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The real reason CI doesn't fail despite Python 3.13 being tested: run_in_subprocess never checked p.exitcode, so any subprocess crash was silently ignored by the parent test. Adding the assert immediately exposes a pre-existing bug: test_coreclr_properties passed properties=dict(...) as a single kwarg, but _do_test_coreclr_autogenerated_runtimeconfig uses **properties to collect individual kwargs. This double-wrapped the dict, causing AttributeError: 'dict' object has no attribute 'encode' in the subprocess — silently swallowed until now. Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> --- tests/test_common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_common.py b/tests/test_common.py index 9d4a829..fd24c15 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -90,7 +90,7 @@ def test_coreclr_properties(example_netcore: Path): run_in_subprocess( _do_test_coreclr_autogenerated_runtimeconfig, example_netcore, - properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore)), + APP_CONTEXT_BASE_DIRECTORY=str(example_netcore), ) @@ -155,4 +155,5 @@ def run_in_subprocess(func, *args, **kwargs): p = get_context("spawn").Process(target=func, args=args, kwargs=kwargs) p.start() p.join() + assert p.exitcode == 0, f"Subprocess {func.__name__!r} failed with exit code {p.exitcode}" p.close() From c625a777276eee47dc658ffbd25313255610b45f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:37:11 +0000 Subject: [PATCH 4/5] Fix resource leak: wrap p.exitcode assert in try/finally so p.close() always runs Without try/finally, if `assert p.exitcode == 0` raises AssertionError, `p.close()` is never called. This leaves the Process object unclosed and causes `ResourceWarning: process ... not closed` on Python 3.12+. Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> --- tests/test_common.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_common.py b/tests/test_common.py index fd24c15..0da14d3 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -155,5 +155,7 @@ def run_in_subprocess(func, *args, **kwargs): p = get_context("spawn").Process(target=func, args=args, kwargs=kwargs) p.start() p.join() - assert p.exitcode == 0, f"Subprocess {func.__name__!r} failed with exit code {p.exitcode}" - p.close() + try: + assert p.exitcode == 0, f"Subprocess {func.__name__!r} failed with exit code {p.exitcode}" + finally: + p.close() From eaad069596617ee5c287958c19143a0f29ea6cbe Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 19 Mar 2026 11:31:35 +0100 Subject: [PATCH 5/5] Fix format --- tests/test_common.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_common.py b/tests/test_common.py index 0da14d3..263cb16 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -156,6 +156,8 @@ def run_in_subprocess(func, *args, **kwargs): p.start() p.join() try: - assert p.exitcode == 0, f"Subprocess {func.__name__!r} failed with exit code {p.exitcode}" + assert p.exitcode == 0, ( + f"Subprocess {func.__name__!r} failed with exit code {p.exitcode}" + ) finally: p.close()