Skip to content
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

Add support for async functions #313

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Reuse event loops and close them all at shutdown.

21ffe16
Select commit
Loading
Failed to load commit list.
Sign in for the full log view
Open

Add support for async functions #313

Reuse event loops and close them all at shutdown.
21ffe16
Select commit
Loading
Failed to load commit list.
GitHub Actions / .NET Test report macos-latest-3.11 failed Nov 29, 2024 in 0s

806 passed, 6 failed and 34 skipped

Tests failed

Report Passed Failed Skipped Time
Conda.Tests-macos-latest-3.11-net8.0.trx 1❌ 4s
Conda.Tests-macos-latest-3.11-net9.0.trx 1❌ 4s
CSnakes.Runtime.Tests-macos-latest-3.11-net8.0.trx 120✔️ 17✖️ 9s
CSnakes.Runtime.Tests-macos-latest-3.11-net9.0.trx 120✔️ 17✖️ 9s
CSnakes.Tests-macos-latest-3.11-net8.0.trx 184✔️ 2❌ 11s
CSnakes.Tests-macos-latest-3.11-net9.0.trx 184✔️ 2❌ 11s
Integration.Tests-macos-latest-3.11-net8.0.trx 97✔️ 17s
Integration.Tests-macos-latest-3.11-net9.0.trx 101✔️ 11s

❌ Conda.Tests-macos-latest-3.11-net8.0.trx

1 tests were completed in 4s with 0 passed, 1 failed and 0 skipped.

Test suite Passed Failed Skipped Time
Conda.Tests.BasicTests 1❌ 2s

❌ Conda.Tests.BasicTests

❌ TestSimpleImport
	CSnakes.Runtime.PythonInvocationException : The Python runtime raised a ModuleNotFoundError exception, see InnerException for details.
	---- CSnakes.Runtime.PythonRuntimeException : No module named 'httpx'

❌ Conda.Tests-macos-latest-3.11-net9.0.trx

1 tests were completed in 4s with 0 passed, 1 failed and 0 skipped.

Test suite Passed Failed Skipped Time
Conda.Tests.BasicTests 1❌ 1s

❌ Conda.Tests.BasicTests

❌ TestSimpleImport
	CSnakes.Runtime.PythonInvocationException : The Python runtime raised a ModuleNotFoundError exception, see InnerException for details.
	---- CSnakes.Runtime.PythonRuntimeException : No module named 'httpx'

✔️ CSnakes.Runtime.Tests-macos-latest-3.11-net8.0.trx

137 tests were completed in 9s with 120 passed, 0 failed and 17 skipped.

Test suite Passed Failed Skipped Time
CSnakes.Runtime.Tests.Converter.BigIntegerConverterTest 1✔️ 48ms
CSnakes.Runtime.Tests.Converter.BoolConverterTest 2✔️ 91ms
CSnakes.Runtime.Tests.Converter.BytesConverterTest 2✔️ 135ms
CSnakes.Runtime.Tests.Converter.DictionaryConverterTest 1✔️ 77ms
CSnakes.Runtime.Tests.Converter.DoubleConverterTest 10✔️ 462ms
CSnakes.Runtime.Tests.Converter.ListConverterTest 1✔️ 65ms
CSnakes.Runtime.Tests.Converter.LongConverterTest 7✔️ 371ms
CSnakes.Runtime.Tests.Converter.TupleConverterTests 5✔️ 343ms
CSnakes.Runtime.Tests.Converter.UnicodeConverterTest 6✔️ 334ms
CSnakes.Runtime.Tests.Locators.NuGetLocatorTests 1✔️ 7✖️ 10ms
CSnakes.Runtime.Tests.Locators.PythonLocatorTests 6✔️ 10✖️ 11ms
CSnakes.Runtime.Tests.Python.ImmortalTests 5✔️ 1s
CSnakes.Runtime.Tests.Python.ImportTests 3✔️ 130ms
CSnakes.Runtime.Tests.Python.PyDictionaryTests 6✔️ 199ms
CSnakes.Runtime.Tests.Python.PyObjectTests 45✔️ 2s
CSnakes.Runtime.Tests.ServiceCollectionTests 19✔️ 131ms

✔️ CSnakes.Runtime.Tests-macos-latest-3.11-net9.0.trx

137 tests were completed in 9s with 120 passed, 0 failed and 17 skipped.

Test suite Passed Failed Skipped Time
CSnakes.Runtime.Tests.Converter.BigIntegerConverterTest 1✔️ 40ms
CSnakes.Runtime.Tests.Converter.BoolConverterTest 2✔️ 95ms
CSnakes.Runtime.Tests.Converter.BytesConverterTest 2✔️ 82ms
CSnakes.Runtime.Tests.Converter.DictionaryConverterTest 1✔️ 46ms
CSnakes.Runtime.Tests.Converter.DoubleConverterTest 10✔️ 902ms
CSnakes.Runtime.Tests.Converter.ListConverterTest 1✔️ 58ms
CSnakes.Runtime.Tests.Converter.LongConverterTest 7✔️ 354ms
CSnakes.Runtime.Tests.Converter.TupleConverterTests 5✔️ 550ms
CSnakes.Runtime.Tests.Converter.UnicodeConverterTest 6✔️ 223ms
CSnakes.Runtime.Tests.Locators.NuGetLocatorTests 1✔️ 7✖️ 10ms
CSnakes.Runtime.Tests.Locators.PythonLocatorTests 6✔️ 10✖️ 24ms
CSnakes.Runtime.Tests.Python.ImmortalTests 5✔️ 494ms
CSnakes.Runtime.Tests.Python.ImportTests 3✔️ 103ms
CSnakes.Runtime.Tests.Python.PyDictionaryTests 6✔️ 349ms
CSnakes.Runtime.Tests.Python.PyObjectTests 45✔️ 3s
CSnakes.Runtime.Tests.ServiceCollectionTests 19✔️ 88ms

❌ CSnakes.Tests-macos-latest-3.11-net8.0.trx

186 tests were completed in 11s with 184 passed, 2 failed and 0 skipped.

Test suite Passed Failed Skipped Time
CSnakes.Tests.CaseHelperTests 10✔️ 2ms
CSnakes.Tests.GeneratedSignatureTests 30✔️ 6s
CSnakes.Tests.PythonConstantTests+FloatTests 1✔️ 0ms
CSnakes.Tests.PythonStaticGeneratorTests 13✔️ 2❌ 889ms
CSnakes.Tests.TokenizerTests 81✔️ 505ms
CSnakes.Tests.TypeReflectionTests 49✔️ 469ms

❌ CSnakes.Tests.PythonStaticGeneratorTests

❌ FormatClassFromMethods(resourceName: "CSnakes.Tests.python.test_coroutines.py")
	Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
	cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt"
	----------------------------
	
	Approval file /Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt
	    does not exist
❌ FormatClassFromMethods(resourceName: "CSnakes.Tests.python.test_generators.py")
	Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
	cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.approved.txt"
	----------------------------
	
	compiledCode
	    should match approved with options: Ignoring line endings
	"// <auto-generated/>
	#nullable enable
	
	using CSnakes.Runtime;
	using CSnakes.Runtime.Python;
	
	using System;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Reflection.Metadata;
	
	using Microsoft.Extensions.Logging;
	
	[assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]
	
	namespace Python.Generated.Tests;
	
	public static class TestClassExtensions
	{
	    private static ITestClass? instance;
	
	    private static ReadOnlySpan<byte> HotReloadHash => "657bc350954200f5d7103a2587de60ae"u8;
	
	    public static ITestClass TestClass(this IPythonEnvironment env)
	    {
	        if (instance is null)
	        {
	            instance = new TestClassInternal(env.Logger);
	        }
	        Debug.Assert(!env.IsDisposed());
	        return instance;
	    }
	
	    public static void UpdateApplication(Type[]? updatedTypes)
	    {
	        instance?.ReloadModule();
	    }
	
	    private class TestClassInternal : ITestClass
	    {
	        private PyObject module;
	        private readonly ILogger<IPythonEnvironment> logger;
	
	        private PyObject __func_example_generator;
	        private PyObject __func_test_normal_generator;
	
	        internal TestClassInternal(ILogger<IPythonEnvironment> logger)
	        {
	            this.logger = logger;
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Importing module {ModuleName}", "test");
	                module = Import.ImportModule("test");
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	            }
	        }
	
	        void IReloadableModuleImport.ReloadModule()
	        {
	            logger.LogDebug("Reloading module {ModuleName}", "test");
	            using (GIL.Acquire())
	            {
	                Import.ReloadModule(ref module);
	                // Dispose old functions
	                this.__func_example_generator.Dispose();
	                this.__func_test_normal_generator.Dispose();
	                // Bind to new functions
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	            }
	        }
	
	        public void Dispose()
	        {
	            logger.LogDebug("Disposing module {ModuleName}", "test");
	            this.__func_example_generator.Dispose();
	            this.__func_test_normal_generator.Dispose();
	            module.Dispose();
	        }
	
	        public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
	                PyObject __underlyingPythonFunc = this.__func_example_generator;
	                using PyObject length_pyObject = PyObject.From(length)!;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
	                return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
	            }
	        }
	
	        public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
	                PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
	                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
	            }
	        }
	    }
	}
	
	/// <summary>
	/// Represents functions of the Python module <c>test</c>.
	/// </summary>
	public interface ITestClass : IReloadableModuleImport
	{
	    /// <summary>
	    /// Invokes the Python function <c>example_generator</c>:
	    /// <code><![CDATA[
	    /// def example_generator(length: int) -> Generator[str, int, bool]: ...
	    /// ]]></code>
	    /// </summary>
	    IGeneratorIterator<string, long, bool> ExampleGenerator(long length);
	
	    /// <summary>
	    /// Invokes the Python function <c>test_normal_generator</c>:
	    /// <code><![CDATA[
	    /// def test_normal_generator() -> Generator[str, None, None]: ...
	    /// ]]></code>
	    /// </summary>
	    IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator();
	}
	"
	    but was
	"// <auto-generated/>
	#nullable enable
	
	using CSnakes.Runtime;
	using CSnakes.Runtime.Python;
	
	using System;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Reflection.Metadata;
	
	using Microsoft.Extensions.Logging;
	
	[assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]
	
	namespace Python.Generated.Tests;
	
	public static class TestClassExtensions
	{
	    private static ITestClass? instance;
	
	    private static ReadOnlySpan<byte> HotReloadHash => "628447fb6935f7e3926b93b678146fc8"u8;
	
	    public static ITestClass TestClass(this IPythonEnvironment env)
	    {
	        if (instance is null)
	        {
	            instance = new TestClassInternal(env.Logger);
	        }
	        Debug.Assert(!env.IsDisposed());
	        return instance;
	    }
	
	    public static void UpdateApplication(Type[]? updatedTypes)
	    {
	        instance?.ReloadModule();
	    }
	
	    private class TestClassInternal : ITestClass
	    {
	        private PyObject module;
	        private readonly ILogger<IPythonEnvironment> logger;
	
	        private PyObject __func_example_generator;
	        private PyObject __func_test_normal_generator;
	        private PyObject __func_test_generator_sequence;
	
	        internal TestClassInternal(ILogger<IPythonEnvironment> logger)
	        {
	            this.logger = logger;
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Importing module {ModuleName}", "test");
	                module = Import.ImportModule("test");
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	                this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
	            }
	        }
	
	        void IReloadableModuleImport.ReloadModule()
	        {
	            logger.LogDebug("Reloading module {ModuleName}", "test");
	            using (GIL.Acquire())
	            {
	                Import.ReloadModule(ref module);
	                // Dispose old functions
	                this.__func_example_generator.Dispose();
	                this.__func_test_normal_generator.Dispose();
	                this.__func_test_generator_sequence.Dispose();
	                // Bind to new functions
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	                this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
	            }
	        }
	
	        public void Dispose()
	        {
	            logger.LogDebug("Disposing module {ModuleName}", "test");
	            this.__func_example_generator.Dispose();
	            this.__func_test_normal_generator.Dispose();
	            this.__func_test_generator_sequence.Dispose();
	            module.Dispose();
	        }
	
	        public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
	                PyObject __underlyingPythonFunc = this.__func_example_generator;
	                using PyObject length_pyObject = PyObject.From(length)!;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
	                return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
	            }
	        }
	
	        public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
	                PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
	                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
	            }
	        }
	
	        public IGeneratorIterator<string, PyObject, PyObject> TestGeneratorSequence()
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "test_generator_sequence");
	                PyObject __underlyingPythonFunc = this.__func_test_generator_sequence;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
	                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
	            }
	        }
	    }
	}
	
	/// <summary>
	/// Represents functions of the Python module <c>test</c>.
	/// </summary>
	public interface ITestClass : IReloadableModuleImport
	{
	    /// <summary>
	    /// Invokes the Python function <c>example_generator</c>:
	    /// <code><![CDATA[
	    /// def example_generator(length: int) -> Generator[str, int, bool]: ...
	    /// ]]></code>
	    /// </summary>
	    IGeneratorIterator<string, long, "
	    difference
	Showing some of the 3577 differences
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  502  503  504  505  506  507  508  509  510  511  512  513  514  515  516  517  518  519  520  521  522  ...  
	Expected Value | ...  5    7    b    c    3    5    0    9    5    4    2    0    0    f    5    d    7    1    0    3    a    ...  
	Actual Value   | ...  2    8    4    4    7    f    b    6    9    3    5    f    7    e    3    9    2    6    b    9    3    ...  
	Expected Code  | ...  53   55   98   99   51   53   48   57   53   52   50   48   48   102  53   100  55   49   48   51   97   ...  
	Actual Code    | ...  50   56   52   52   55   102  98   54   57   51   53   102  55   101  51   57   50   54   98   57   51   ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |         |    |    |                                 
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/                                
	Index          | ...  517  518  519  520  521  522  523  524  525  526  527  528  529  530  531  532  533  534  535  536  537  ...  
	Expected Value | ...  d    7    1    0    3    a    2    5    8    7    d    e    6    0    a    e    "    u    8    ;    \n   ...  
	Actual Value   | ...  9    2    6    b    9    3    b    6    7    8    1    4    6    f    c    8    "    u    8    ;    \n   ...  
	Expected Code  | ...  100  55   49   48   51   97   50   53   56   55   100  101  54   48   97   101  34   117  56   59   10   ...  
	Actual Code    | ...  57   50   54   98   57   51   98   54   55   56   49   52   54   102  99   56   34   117  56   59   10   ...  
	
	Difference     |                                |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |                               \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 ...  
	Expected Value | ...  \s   \s   \s   \s   \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    ...  
	Actual Value   | ...  \s   \s   \s   \s   \s   p    r    i    v    a    t    e    \s   P    y    O    b    j    e    c    t    ...  
	Expected Code  | ...  32   32   32   32   32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  ...  
	Actual Code    | ...  32   32   32   32   32   112  114  105  118  97   116  101  32   80   121  79   98   106  101  99   116  ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 ...  
	Expected Value | ...  t    C    l    a    s    s    I    n    t    e    r    n    a    l    (    I    L    o    g    g    e    ...  
	Actual Value   | ...  e    c    t    \s   _    _    f    u    n    c    _    t    e    s    t    _    g    e    n    e    r    ...  
	Expected Code  | ...  116  67   108  97   115  115  73   110  116  101  114  110  97   108  40   73   76   111  103  103  101  ...  
	Actual Code    | ...  101  99   116  32   95   95   102  117  110  99   95   116  101  115  116  95   103  101  110  101  114  ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 ...  
	Expected Value | ...  r    <    I    P    y    t    h    o    n    E    n    v    i    r    o    n    m    e    n    t    >    ...  
	Actual Value   | ...  a    t    o    r    _    s    e    q    u    e    n    c    e    ;    \n   \n   \s   \s   \s   \s   \s   ...  
	Expected Code  | ...  114  60   73   80   121  116  104  111  110  69   110  118  105  114  111  110  109  101  110  116  62   ...  
	Actual Code    | ...  97   116  111  114  95   115  101  113  117  101  110  99   101  59   10   10   32   32   32   32   32   ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 ...  
	Expected Value | ...  l    o    g    g    e    r    )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   ...  
	Actual Value   | ...  \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    a    s    s    I    ...  
	Expected Code  | ...  108  111  103  103  101  114  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   ...  
	Actual Code    | ...  32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  97   115  115  73   ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 ...  
	Expected Value | ...  \s   \s   \s   \s   \s   \s   \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   ...  
	Actual Value   | ...  n    t    e    r    n    a    l    (    I    L    o    g    g    e    r    <    I    P    y    t    h    ...  
	Expected Code  | ...  32   32   32   32   32   32   32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   ...  
	Actual Code    | ...  110  116  101  114  110  97   108  40   73   76   111  103  103  101  114  60   73   80   121  116  104  ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 ...  
	Expected Value | ...  =    \s   l    o    g    g    e    r    ;    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
	Actual Value   | ...  o    n    E    n    v    i    r    o    n    m    e    n    t    >    \s   l    o    g    g    e    r    ...  
	Expected Code  | ...  61   32   108  111  103  103  101  114  59   10   32   32   32   32   32   32   32   32   32   32   32   ...  
	Actual Code    | ...  111  110  69   110  118  105  114  111  110  109  101  110  116  62   32   108  111  103  103  101  114  ...  
	
	Difference     |       |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 ...  
	Expected Value | ...  \s   u    s    i    n    g    \s   (    G    I    L    .    A    c    q    u    i    r    e    (    )    ...  
	Actual Value   | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
	Expected Code  | ...  32   117  115  105  110  103  32   40   71   73   76   46   65   99   113  117  105  114  101  40   41   ...  
	Actual Code    | ...  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   32   32   32   32   ...  
	
	Difference     |       |    |         |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |        
	               |      \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/       
	Index          | ...  1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 ...  
	Expected Value | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   ...  
	Actual Value   | ...  \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   =    \s   l    o    g    g    ...  
	Expected Code  | ...  41   10   32   32   32   32   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   ...  
	Actual Code    | ...  32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   61   32   108  111  103  103  ...  

❌ CSnakes.Tests-macos-latest-3.11-net9.0.trx

186 tests were completed in 11s with 184 passed, 2 failed and 0 skipped.

Test suite Passed Failed Skipped Time
CSnakes.Tests.CaseHelperTests 10✔️ 2ms
CSnakes.Tests.GeneratedSignatureTests 30✔️ 7s
CSnakes.Tests.PythonConstantTests+FloatTests 1✔️ 1ms
CSnakes.Tests.PythonStaticGeneratorTests 13✔️ 2❌ 1s
CSnakes.Tests.TokenizerTests 81✔️ 379ms
CSnakes.Tests.TypeReflectionTests 49✔️ 31ms

❌ CSnakes.Tests.PythonStaticGeneratorTests

❌ FormatClassFromMethods(resourceName: "CSnakes.Tests.python.test_coroutines.py")
	Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
	cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt"
	----------------------------
	
	Approval file /Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt
	    does not exist
❌ FormatClassFromMethods(resourceName: "CSnakes.Tests.python.test_generators.py")
	Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
	cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.approved.txt"
	----------------------------
	
	compiledCode
	    should match approved with options: Ignoring line endings
	"// <auto-generated/>
	#nullable enable
	
	using CSnakes.Runtime;
	using CSnakes.Runtime.Python;
	
	using System;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Reflection.Metadata;
	
	using Microsoft.Extensions.Logging;
	
	[assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]
	
	namespace Python.Generated.Tests;
	
	public static class TestClassExtensions
	{
	    private static ITestClass? instance;
	
	    private static ReadOnlySpan<byte> HotReloadHash => "657bc350954200f5d7103a2587de60ae"u8;
	
	    public static ITestClass TestClass(this IPythonEnvironment env)
	    {
	        if (instance is null)
	        {
	            instance = new TestClassInternal(env.Logger);
	        }
	        Debug.Assert(!env.IsDisposed());
	        return instance;
	    }
	
	    public static void UpdateApplication(Type[]? updatedTypes)
	    {
	        instance?.ReloadModule();
	    }
	
	    private class TestClassInternal : ITestClass
	    {
	        private PyObject module;
	        private readonly ILogger<IPythonEnvironment> logger;
	
	        private PyObject __func_example_generator;
	        private PyObject __func_test_normal_generator;
	
	        internal TestClassInternal(ILogger<IPythonEnvironment> logger)
	        {
	            this.logger = logger;
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Importing module {ModuleName}", "test");
	                module = Import.ImportModule("test");
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	            }
	        }
	
	        void IReloadableModuleImport.ReloadModule()
	        {
	            logger.LogDebug("Reloading module {ModuleName}", "test");
	            using (GIL.Acquire())
	            {
	                Import.ReloadModule(ref module);
	                // Dispose old functions
	                this.__func_example_generator.Dispose();
	                this.__func_test_normal_generator.Dispose();
	                // Bind to new functions
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	            }
	        }
	
	        public void Dispose()
	        {
	            logger.LogDebug("Disposing module {ModuleName}", "test");
	            this.__func_example_generator.Dispose();
	            this.__func_test_normal_generator.Dispose();
	            module.Dispose();
	        }
	
	        public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
	                PyObject __underlyingPythonFunc = this.__func_example_generator;
	                using PyObject length_pyObject = PyObject.From(length)!;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
	                return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
	            }
	        }
	
	        public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
	                PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
	                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
	            }
	        }
	    }
	}
	
	/// <summary>
	/// Represents functions of the Python module <c>test</c>.
	/// </summary>
	public interface ITestClass : IReloadableModuleImport
	{
	    /// <summary>
	    /// Invokes the Python function <c>example_generator</c>:
	    /// <code><![CDATA[
	    /// def example_generator(length: int) -> Generator[str, int, bool]: ...
	    /// ]]></code>
	    /// </summary>
	    IGeneratorIterator<string, long, bool> ExampleGenerator(long length);
	
	    /// <summary>
	    /// Invokes the Python function <c>test_normal_generator</c>:
	    /// <code><![CDATA[
	    /// def test_normal_generator() -> Generator[str, None, None]: ...
	    /// ]]></code>
	    /// </summary>
	    IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator();
	}
	"
	    but was
	"// <auto-generated/>
	#nullable enable
	
	using CSnakes.Runtime;
	using CSnakes.Runtime.Python;
	
	using System;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Reflection.Metadata;
	
	using Microsoft.Extensions.Logging;
	
	[assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]
	
	namespace Python.Generated.Tests;
	
	public static class TestClassExtensions
	{
	    private static ITestClass? instance;
	
	    private static ReadOnlySpan<byte> HotReloadHash => "628447fb6935f7e3926b93b678146fc8"u8;
	
	    public static ITestClass TestClass(this IPythonEnvironment env)
	    {
	        if (instance is null)
	        {
	            instance = new TestClassInternal(env.Logger);
	        }
	        Debug.Assert(!env.IsDisposed());
	        return instance;
	    }
	
	    public static void UpdateApplication(Type[]? updatedTypes)
	    {
	        instance?.ReloadModule();
	    }
	
	    private class TestClassInternal : ITestClass
	    {
	        private PyObject module;
	        private readonly ILogger<IPythonEnvironment> logger;
	
	        private PyObject __func_example_generator;
	        private PyObject __func_test_normal_generator;
	        private PyObject __func_test_generator_sequence;
	
	        internal TestClassInternal(ILogger<IPythonEnvironment> logger)
	        {
	            this.logger = logger;
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Importing module {ModuleName}", "test");
	                module = Import.ImportModule("test");
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	                this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
	            }
	        }
	
	        void IReloadableModuleImport.ReloadModule()
	        {
	            logger.LogDebug("Reloading module {ModuleName}", "test");
	            using (GIL.Acquire())
	            {
	                Import.ReloadModule(ref module);
	                // Dispose old functions
	                this.__func_example_generator.Dispose();
	                this.__func_test_normal_generator.Dispose();
	                this.__func_test_generator_sequence.Dispose();
	                // Bind to new functions
	                this.__func_example_generator = module.GetAttr("example_generator");
	                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
	                this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
	            }
	        }
	
	        public void Dispose()
	        {
	            logger.LogDebug("Disposing module {ModuleName}", "test");
	            this.__func_example_generator.Dispose();
	            this.__func_test_normal_generator.Dispose();
	            this.__func_test_generator_sequence.Dispose();
	            module.Dispose();
	        }
	
	        public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
	                PyObject __underlyingPythonFunc = this.__func_example_generator;
	                using PyObject length_pyObject = PyObject.From(length)!;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
	                return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
	            }
	        }
	
	        public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
	                PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
	                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
	            }
	        }
	
	        public IGeneratorIterator<string, PyObject, PyObject> TestGeneratorSequence()
	        {
	            using (GIL.Acquire())
	            {
	                logger.LogDebug("Invoking Python function: {FunctionName}", "test_generator_sequence");
	                PyObject __underlyingPythonFunc = this.__func_test_generator_sequence;
	                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
	                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
	            }
	        }
	    }
	}
	
	/// <summary>
	/// Represents functions of the Python module <c>test</c>.
	/// </summary>
	public interface ITestClass : IReloadableModuleImport
	{
	    /// <summary>
	    /// Invokes the Python function <c>example_generator</c>:
	    /// <code><![CDATA[
	    /// def example_generator(length: int) -> Generator[str, int, bool]: ...
	    /// ]]></code>
	    /// </summary>
	    IGeneratorIterator<string, long, "
	    difference
	Showing some of the 3577 differences
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  502  503  504  505  506  507  508  509  510  511  512  513  514  515  516  517  518  519  520  521  522  ...  
	Expected Value | ...  5    7    b    c    3    5    0    9    5    4    2    0    0    f    5    d    7    1    0    3    a    ...  
	Actual Value   | ...  2    8    4    4    7    f    b    6    9    3    5    f    7    e    3    9    2    6    b    9    3    ...  
	Expected Code  | ...  53   55   98   99   51   53   48   57   53   52   50   48   48   102  53   100  55   49   48   51   97   ...  
	Actual Code    | ...  50   56   52   52   55   102  98   54   57   51   53   102  55   101  51   57   50   54   98   57   51   ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |         |    |    |                                 
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/                                
	Index          | ...  517  518  519  520  521  522  523  524  525  526  527  528  529  530  531  532  533  534  535  536  537  ...  
	Expected Value | ...  d    7    1    0    3    a    2    5    8    7    d    e    6    0    a    e    "    u    8    ;    \n   ...  
	Actual Value   | ...  9    2    6    b    9    3    b    6    7    8    1    4    6    f    c    8    "    u    8    ;    \n   ...  
	Expected Code  | ...  100  55   49   48   51   97   50   53   56   55   100  101  54   48   97   101  34   117  56   59   10   ...  
	Actual Code    | ...  57   50   54   98   57   51   98   54   55   56   49   52   54   102  99   56   34   117  56   59   10   ...  
	
	Difference     |                                |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |                               \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 ...  
	Expected Value | ...  \s   \s   \s   \s   \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    ...  
	Actual Value   | ...  \s   \s   \s   \s   \s   p    r    i    v    a    t    e    \s   P    y    O    b    j    e    c    t    ...  
	Expected Code  | ...  32   32   32   32   32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  ...  
	Actual Code    | ...  32   32   32   32   32   112  114  105  118  97   116  101  32   80   121  79   98   106  101  99   116  ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 ...  
	Expected Value | ...  t    C    l    a    s    s    I    n    t    e    r    n    a    l    (    I    L    o    g    g    e    ...  
	Actual Value   | ...  e    c    t    \s   _    _    f    u    n    c    _    t    e    s    t    _    g    e    n    e    r    ...  
	Expected Code  | ...  116  67   108  97   115  115  73   110  116  101  114  110  97   108  40   73   76   111  103  103  101  ...  
	Actual Code    | ...  101  99   116  32   95   95   102  117  110  99   95   116  101  115  116  95   103  101  110  101  114  ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 ...  
	Expected Value | ...  r    <    I    P    y    t    h    o    n    E    n    v    i    r    o    n    m    e    n    t    >    ...  
	Actual Value   | ...  a    t    o    r    _    s    e    q    u    e    n    c    e    ;    \n   \n   \s   \s   \s   \s   \s   ...  
	Expected Code  | ...  114  60   73   80   121  116  104  111  110  69   110  118  105  114  111  110  109  101  110  116  62   ...  
	Actual Code    | ...  97   116  111  114  95   115  101  113  117  101  110  99   101  59   10   10   32   32   32   32   32   ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 ...  
	Expected Value | ...  l    o    g    g    e    r    )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   ...  
	Actual Value   | ...  \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    a    s    s    I    ...  
	Expected Code  | ...  108  111  103  103  101  114  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   ...  
	Actual Code    | ...  32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  97   115  115  73   ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 ...  
	Expected Value | ...  \s   \s   \s   \s   \s   \s   \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   ...  
	Actual Value   | ...  n    t    e    r    n    a    l    (    I    L    o    g    g    e    r    <    I    P    y    t    h    ...  
	Expected Code  | ...  32   32   32   32   32   32   32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   ...  
	Actual Code    | ...  110  116  101  114  110  97   108  40   73   76   111  103  103  101  114  60   73   80   121  116  104  ...  
	
	Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 ...  
	Expected Value | ...  =    \s   l    o    g    g    e    r    ;    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
	Actual Value   | ...  o    n    E    n    v    i    r    o    n    m    e    n    t    >    \s   l    o    g    g    e    r    ...  
	Expected Code  | ...  61   32   108  111  103  103  101  114  59   10   32   32   32   32   32   32   32   32   32   32   32   ...  
	Actual Code    | ...  111  110  69   110  118  105  114  111  110  109  101  110  116  62   32   108  111  103  103  101  114  ...  
	
	Difference     |       |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |    |    |    |    |        
	               |      \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
	Index          | ...  1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 ...  
	Expected Value | ...  \s   u    s    i    n    g    \s   (    G    I    L    .    A    c    q    u    i    r    e    (    )    ...  
	Actual Value   | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
	Expected Code  | ...  32   117  115  105  110  103  32   40   71   73   76   46   65   99   113  117  105  114  101  40   41   ...  
	Actual Code    | ...  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   32   32   32   32   ...  
	
	Difference     |       |    |         |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |        
	               |      \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/       
	Index          | ...  1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 ...  
	Expected Value | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   ...  
	Actual Value   | ...  \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   =    \s   l    o    g    g    ...  
	Expected Code  | ...  41   10   32   32   32   32   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   ...  
	Actual Code    | ...  32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   61   32   108  111  103  103  ...  

✔️ Integration.Tests-macos-latest-3.11-net8.0.trx

97 tests were completed in 17s with 97 passed, 0 failed and 0 skipped.

Test suite Passed Failed Skipped Time
Integration.Tests.ArgsTests 6✔️ 14ms
Integration.Tests.BasicTests 9✔️ 26ms
Integration.Tests.BufferTests 28✔️ 346ms
Integration.Tests.CoroutineTests 3✔️ 240ms
Integration.Tests.DefaultsTests 7✔️ 4ms
Integration.Tests.ExceptionTests 2✔️ 5ms
Integration.Tests.FalseReturns 12✔️ 6ms
Integration.Tests.GeneratorTests 2✔️ 4ms
Integration.Tests.NoneTests 2✔️ 2ms
Integration.Tests.ReloadTests 3✔️ 7ms
Integration.Tests.TestDependency 1✔️ 37ms
Integration.Tests.TestDicts 5✔️ 9ms
Integration.Tests.TupleTests 17✔️ 34ms

✔️ Integration.Tests-macos-latest-3.11-net9.0.trx

101 tests were completed in 11s with 101 passed, 0 failed and 0 skipped.

Test suite Passed Failed Skipped Time
Integration.Tests.ArgsTests 6✔️ 17ms
Integration.Tests.BasicTests 9✔️ 32ms
Integration.Tests.BufferTests 32✔️ 163ms
Integration.Tests.CoroutineTests 3✔️ 894ms
Integration.Tests.DefaultsTests 7✔️ 5ms
Integration.Tests.ExceptionTests 2✔️ 4ms
Integration.Tests.FalseReturns 12✔️ 5ms
Integration.Tests.GeneratorTests 2✔️ 4ms
Integration.Tests.NoneTests 2✔️ 1ms
Integration.Tests.ReloadTests 3✔️ 6ms
Integration.Tests.TestDependency 1✔️ 31ms
Integration.Tests.TestDicts 5✔️ 5ms
Integration.Tests.TupleTests 17✔️ 21ms

Annotations

Check failure on line 19 in src/CSnakes.Runtime/Python/PyObject.cs

See this annotation in the file changed.

@github-actions github-actions / .NET Test report macos-latest-3.11

Conda.Tests.BasicTests ► TestSimpleImport

Failed test found in:
  Conda.Tests-macos-latest-3.11-net8.0.trx
Error:
  CSnakes.Runtime.PythonInvocationException : The Python runtime raised a ModuleNotFoundError exception, see InnerException for details.
  ---- CSnakes.Runtime.PythonRuntimeException : No module named 'httpx'
Raw output
CSnakes.Runtime.PythonInvocationException : The Python runtime raised a ModuleNotFoundError exception, see InnerException for details.
---- CSnakes.Runtime.PythonRuntimeException : No module named 'httpx'
   at CSnakes.Runtime.Python.PyObject..ctor(IntPtr pyObject, Boolean ownsHandle) in /_/src/CSnakes.Runtime/Python/PyObject.cs:line 19
   at CSnakes.Runtime.Python.PyObject.Create(IntPtr ptr) in /_/src/CSnakes.Runtime/Python/PyObject.cs:line 27
   at CSnakes.Runtime.CPython.CPythonAPI.Import(String name) in /_/src/CSnakes.Runtime/CPython/Import.cs:line 18
   at CSnakes.Runtime.Python.Import.ImportModule(String module) in /_/src/CSnakes.Runtime/Python/Import.cs:line 10
   at CSnakes.Runtime.TestSimpleExtensions.TestSimpleInternal..ctor(ILogger`1 logger) in /_/src/Conda.Tests/obj/Debug/net8.0/generated/CSnakes.SourceGeneration/CSnakes.PythonStaticGenerator/TestSimple.py.cs:line 52
   at CSnakes.Runtime.TestSimpleExtensions.TestSimple(IPythonEnvironment env) in /_/src/Conda.Tests/obj/Debug/net8.0/generated/CSnakes.SourceGeneration/CSnakes.PythonStaticGenerator/TestSimple.py.cs:line 28
   at Conda.Tests.BasicTests.TestSimpleImport() in /_/src/Conda.Tests/BasicTests.cs:line 8
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
----- Inner Stack Trace -----
  File "/Users/runner/work/CSnakes/CSnakes/src/Conda.Tests/bin/Debug/net8.0/python/test_simple.py", line 1, in <module>
    import httpx

Check failure on line 19 in src/CSnakes.Runtime/Python/PyObject.cs

See this annotation in the file changed.

@github-actions github-actions / .NET Test report macos-latest-3.11

Conda.Tests.BasicTests ► TestSimpleImport

Failed test found in:
  Conda.Tests-macos-latest-3.11-net9.0.trx
Error:
  CSnakes.Runtime.PythonInvocationException : The Python runtime raised a ModuleNotFoundError exception, see InnerException for details.
  ---- CSnakes.Runtime.PythonRuntimeException : No module named 'httpx'
Raw output
CSnakes.Runtime.PythonInvocationException : The Python runtime raised a ModuleNotFoundError exception, see InnerException for details.
---- CSnakes.Runtime.PythonRuntimeException : No module named 'httpx'
   at CSnakes.Runtime.Python.PyObject..ctor(IntPtr pyObject, Boolean ownsHandle) in /_/src/CSnakes.Runtime/Python/PyObject.cs:line 19
   at CSnakes.Runtime.Python.PyObject.Create(IntPtr ptr) in /_/src/CSnakes.Runtime/Python/PyObject.cs:line 27
   at CSnakes.Runtime.CPython.CPythonAPI.Import(String name) in /_/src/CSnakes.Runtime/CPython/Import.cs:line 18
   at CSnakes.Runtime.Python.Import.ImportModule(String module) in /_/src/CSnakes.Runtime/Python/Import.cs:line 10
   at CSnakes.Runtime.TestSimpleExtensions.TestSimpleInternal..ctor(ILogger`1 logger) in /_/src/Conda.Tests/obj/Debug/net9.0/generated/CSnakes.SourceGeneration/CSnakes.PythonStaticGenerator/TestSimple.py.cs:line 52
   at CSnakes.Runtime.TestSimpleExtensions.TestSimple(IPythonEnvironment env) in /_/src/Conda.Tests/obj/Debug/net9.0/generated/CSnakes.SourceGeneration/CSnakes.PythonStaticGenerator/TestSimple.py.cs:line 28
   at Conda.Tests.BasicTests.TestSimpleImport() in /_/src/Conda.Tests/BasicTests.cs:line 8
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
----- Inner Stack Trace -----
  File "/Users/runner/work/CSnakes/CSnakes/src/Conda.Tests/bin/Debug/net9.0/python/test_simple.py", line 1, in <module>
    import httpx

Check failure on line 42 in src/CSnakes.Tests/PythonStaticGeneratorTests.cs

See this annotation in the file changed.

@github-actions github-actions / .NET Test report macos-latest-3.11

CSnakes.Tests.PythonStaticGeneratorTests ► FormatClassFromMethods(resourceName: "CSnakes.Tests.python.test_coroutines.py")

Failed test found in:
  CSnakes.Tests-macos-latest-3.11-net8.0.trx
  CSnakes.Tests-macos-latest-3.11-net9.0.trx
Error:
  Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
  cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt"
  ----------------------------
  
  Approval file /Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt
      does not exist
Raw output
Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt"
----------------------------

Approval file /Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_coroutines.approved.txt
    does not exist
   at CSnakes.Tests.PythonStaticGeneratorTests.FormatClassFromMethods(String resourceName) in /_/src/CSnakes.Tests/PythonStaticGeneratorTests.cs:line 42
   at InvokeStub_PythonStaticGeneratorTests.FormatClassFromMethods(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

Check failure on line 42 in src/CSnakes.Tests/PythonStaticGeneratorTests.cs

See this annotation in the file changed.

@github-actions github-actions / .NET Test report macos-latest-3.11

CSnakes.Tests.PythonStaticGeneratorTests ► FormatClassFromMethods(resourceName: "CSnakes.Tests.python.test_generators.py")

Failed test found in:
  CSnakes.Tests-macos-latest-3.11-net8.0.trx
  CSnakes.Tests-macos-latest-3.11-net9.0.trx
Error:
  Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
  cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.approved.txt"
  ----------------------------
  
  compiledCode
      should match approved with options: Ignoring line endings
  "// <auto-generated/>
  #nullable enable
  
  using CSnakes.Runtime;
  using CSnakes.Runtime.Python;
  
  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Reflection.Metadata;
  
  using Microsoft.Extensions.Logging;
  
  [assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]
  
  namespace Python.Generated.Tests;
  
  public static class TestClassExtensions
  {
      private static ITestClass? instance;
  
      private static ReadOnlySpan<byte> HotReloadHash => "657bc350954200f5d7103a2587de60ae"u8;
  
      public static ITestClass TestClass(this IPythonEnvironment env)
      {
          if (instance is null)
          {
              instance = new TestClassInternal(env.Logger);
          }
          Debug.Assert(!env.IsDisposed());
          return instance;
      }
  
      public static void UpdateApplication(Type[]? updatedTypes)
      {
          instance?.ReloadModule();
      }
  
      private class TestClassInternal : ITestClass
      {
          private PyObject module;
          private readonly ILogger<IPythonEnvironment> logger;
  
          private PyObject __func_example_generator;
          private PyObject __func_test_normal_generator;
  
          internal TestClassInternal(ILogger<IPythonEnvironment> logger)
          {
              this.logger = logger;
              using (GIL.Acquire())
              {
                  logger.LogDebug("Importing module {ModuleName}", "test");
                  module = Import.ImportModule("test");
                  this.__func_example_generator = module.GetAttr("example_generator");
                  this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
              }
          }
  
          void IReloadableModuleImport.ReloadModule()
          {
              logger.LogDebug("Reloading module {ModuleName}", "test");
              using (GIL.Acquire())
              {
                  Import.ReloadModule(ref module);
                  // Dispose old functions
                  this.__func_example_generator.Dispose();
                  this.__func_test_normal_generator.Dispose();
                  // Bind to new functions
                  this.__func_example_generator = module.GetAttr("example_generator");
                  this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
              }
          }
  
          public void Dispose()
          {
              logger.LogDebug("Disposing module {ModuleName}", "test");
              this.__func_example_generator.Dispose();
              this.__func_test_normal_generator.Dispose();
              module.Dispose();
          }
  
          public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
          {
              using (GIL.Acquire())
              {
                  logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
                  PyObject __underlyingPythonFunc = this.__func_example_generator;
                  using PyObject length_pyObject = PyObject.From(length)!;
                  using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
                  return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
              }
          }
  
          public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
          {
              using (GIL.Acquire())
              {
                  logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
                  PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
                  using PyObject __result_pyObject = __underlyingPythonFunc.Call();
                  return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
              }
          }
      }
  }
  
  /// <summary>
  /// Represents functions of the Python module <c>test</c>.
  /// </summary>
  public interface ITestClass : IReloadableModuleImport
  {
      /// <summary>
      /// Invokes the Python function <c>example_generator</c>:
      /// <code><![CDATA[
      /// def example_generator(length: int) -> Generator[str, int, bool]: ...
      /// ]]></code>
      /// </summary>
      IGeneratorIterator<string, long, bool> ExampleGenerator(long length);
  
      /// <summary>
      /// Invokes the Python function <c>test_normal_generator</c>:
      /// <code><![CDATA[
      /// def test_normal_generator() -> Generator[str, None, None]: ...
      /// ]]></code>
      /// </summary>
      IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator();
  }
  "
      but was
  "// <auto-generated/>
  #nullable enable
  
  using CSnakes.Runtime;
  using CSnakes.Runtime.Python;
  
  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Reflection.Metadata;
  
  using Microsoft.Extensions.Logging;
  
  [assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]
  
  namespace Python.Generated.Tests;
  
  public static class TestClassExtensions
  {
      private static ITestClass? instance;
  
      private static ReadOnlySpan<byte> HotReloadHash => "628447fb6935f7e3926b93b678146fc8"u8;
  
      public static ITestClass TestClass(this IPythonEnvironment env)
      {
          if (instance is null)
          {
              instance = new TestClassInternal(env.Logger);
          }
          Debug.Assert(!env.IsDisposed());
          return instance;
      }
  
      public static void UpdateApplication(Type[]? updatedTypes)
      {
          instance?.ReloadModule();
      }
  
      private class TestClassInternal : ITestClass
      {
          private PyObject module;
          private readonly ILogger<IPythonEnvironment> logger;
  
          private PyObject __func_example_generator;
          private PyObject __func_test_normal_generator;
          private PyObject __func_test_generator_sequence;
  
          internal TestClassInternal(ILogger<IPythonEnvironment> logger)
          {
              this.logger = logger;
              using (GIL.Acquire())
              {
                  logger.LogDebug("Importing module {ModuleName}", "test");
                  module = Import.ImportModule("test");
                  this.__func_example_generator = module.GetAttr("example_generator");
                  this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
                  this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
              }
          }
  
          void IReloadableModuleImport.ReloadModule()
          {
              logger.LogDebug("Reloading module {ModuleName}", "test");
              using (GIL.Acquire())
              {
                  Import.ReloadModule(ref module);
                  // Dispose old functions
                  this.__func_example_generator.Dispose();
                  this.__func_test_normal_generator.Dispose();
                  this.__func_test_generator_sequence.Dispose();
                  // Bind to new functions
                  this.__func_example_generator = module.GetAttr("example_generator");
                  this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
                  this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
              }
          }
  
          public void Dispose()
          {
              logger.LogDebug("Disposing module {ModuleName}", "test");
              this.__func_example_generator.Dispose();
              this.__func_test_normal_generator.Dispose();
              this.__func_test_generator_sequence.Dispose();
              module.Dispose();
          }
  
          public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
          {
              using (GIL.Acquire())
              {
                  logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
                  PyObject __underlyingPythonFunc = this.__func_example_generator;
                  using PyObject length_pyObject = PyObject.From(length)!;
                  using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
                  return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
              }
          }
  
          public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
          {
              using (GIL.Acquire())
              {
                  logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
                  PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
                  using PyObject __result_pyObject = __underlyingPythonFunc.Call();
                  return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
              }
          }
  
          public IGeneratorIterator<string, PyObject, PyObject> TestGeneratorSequence()
          {
              using (GIL.Acquire())
              {
                  logger.LogDebug("Invoking Python function: {FunctionName}", "test_generator_sequence");
                  PyObject __underlyingPythonFunc = this.__func_test_generator_sequence;
                  using PyObject __result_pyObject = __underlyingPythonFunc.Call();
                  return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
              }
          }
      }
  }
  
  /// <summary>
  /// Represents functions of the Python module <c>test</c>.
  /// </summary>
  public interface ITestClass : IReloadableModuleImport
  {
      /// <summary>
      /// Invokes the Python function <c>example_generator</c>:
      /// <code><![CDATA[
      /// def example_generator(length: int) -> Generator[str, int, bool]: ...
      /// ]]></code>
      /// </summary>
      IGeneratorIterator<string, long, "
      difference
  Showing some of the 3577 differences
  Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  502  503  504  505  506  507  508  509  510  511  512  513  514  515  516  517  518  519  520  521  522  ...  
  Expected Value | ...  5    7    b    c    3    5    0    9    5    4    2    0    0    f    5    d    7    1    0    3    a    ...  
  Actual Value   | ...  2    8    4    4    7    f    b    6    9    3    5    f    7    e    3    9    2    6    b    9    3    ...  
  Expected Code  | ...  53   55   98   99   51   53   48   57   53   52   50   48   48   102  53   100  55   49   48   51   97   ...  
  Actual Code    | ...  50   56   52   52   55   102  98   54   57   51   53   102  55   101  51   57   50   54   98   57   51   ...  
  
  Difference     |       |    |    |    |    |    |    |    |    |    |    |    |         |    |    |                                 
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/                                
  Index          | ...  517  518  519  520  521  522  523  524  525  526  527  528  529  530  531  532  533  534  535  536  537  ...  
  Expected Value | ...  d    7    1    0    3    a    2    5    8    7    d    e    6    0    a    e    "    u    8    ;    \n   ...  
  Actual Value   | ...  9    2    6    b    9    3    b    6    7    8    1    4    6    f    c    8    "    u    8    ;    \n   ...  
  Expected Code  | ...  100  55   49   48   51   97   50   53   56   55   100  101  54   48   97   101  34   117  56   59   10   ...  
  Actual Code    | ...  57   50   54   98   57   51   98   54   55   56   49   52   54   102  99   56   34   117  56   59   10   ...  
  
  Difference     |                                |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
                 |                               \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 ...  
  Expected Value | ...  \s   \s   \s   \s   \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    ...  
  Actual Value   | ...  \s   \s   \s   \s   \s   p    r    i    v    a    t    e    \s   P    y    O    b    j    e    c    t    ...  
  Expected Code  | ...  32   32   32   32   32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  ...  
  Actual Code    | ...  32   32   32   32   32   112  114  105  118  97   116  101  32   80   121  79   98   106  101  99   116  ...  
  
  Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 ...  
  Expected Value | ...  t    C    l    a    s    s    I    n    t    e    r    n    a    l    (    I    L    o    g    g    e    ...  
  Actual Value   | ...  e    c    t    \s   _    _    f    u    n    c    _    t    e    s    t    _    g    e    n    e    r    ...  
  Expected Code  | ...  116  67   108  97   115  115  73   110  116  101  114  110  97   108  40   73   76   111  103  103  101  ...  
  Actual Code    | ...  101  99   116  32   95   95   102  117  110  99   95   116  101  115  116  95   103  101  110  101  114  ...  
  
  Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 ...  
  Expected Value | ...  r    <    I    P    y    t    h    o    n    E    n    v    i    r    o    n    m    e    n    t    >    ...  
  Actual Value   | ...  a    t    o    r    _    s    e    q    u    e    n    c    e    ;    \n   \n   \s   \s   \s   \s   \s   ...  
  Expected Code  | ...  114  60   73   80   121  116  104  111  110  69   110  118  105  114  111  110  109  101  110  116  62   ...  
  Actual Code    | ...  97   116  111  114  95   115  101  113  117  101  110  99   101  59   10   10   32   32   32   32   32   ...  
  
  Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 ...  
  Expected Value | ...  l    o    g    g    e    r    )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   ...  
  Actual Value   | ...  \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    a    s    s    I    ...  
  Expected Code  | ...  108  111  103  103  101  114  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   ...  
  Actual Code    | ...  32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  97   115  115  73   ...  
  
  Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 ...  
  Expected Value | ...  \s   \s   \s   \s   \s   \s   \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   ...  
  Actual Value   | ...  n    t    e    r    n    a    l    (    I    L    o    g    g    e    r    <    I    P    y    t    h    ...  
  Expected Code  | ...  32   32   32   32   32   32   32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   ...  
  Actual Code    | ...  110  116  101  114  110  97   108  40   73   76   111  103  103  101  114  60   73   80   121  116  104  ...  
  
  Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 ...  
  Expected Value | ...  =    \s   l    o    g    g    e    r    ;    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
  Actual Value   | ...  o    n    E    n    v    i    r    o    n    m    e    n    t    >    \s   l    o    g    g    e    r    ...  
  Expected Code  | ...  61   32   108  111  103  103  101  114  59   10   32   32   32   32   32   32   32   32   32   32   32   ...  
  Actual Code    | ...  111  110  69   110  118  105  114  111  110  109  101  110  116  62   32   108  111  103  103  101  114  ...  
  
  Difference     |       |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |    |    |    |    |        
                 |      \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
  Index          | ...  1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 ...  
  Expected Value | ...  \s   u    s    i    n    g    \s   (    G    I    L    .    A    c    q    u    i    r    e    (    )    ...  
  Actual Value   | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
  Expected Code  | ...  32   117  115  105  110  103  32   40   71   73   76   46   65   99   113  117  105  114  101  40   41   ...  
  Actual Code    | ...  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   32   32   32   32   ...  
  
  Difference     |       |    |         |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |        
                 |      \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/       
  Index          | ...  1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 ...  
  Expected Value | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   ...  
  Actual Value   | ...  \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   =    \s   l    o    g    g    ...  
  Expected Code  | ...  41   10   32   32   32   32   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   ...  
  Actual Code    | ...  32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   61   32   108  111  103  103  ...  
Raw output
Shouldly.ShouldMatchApprovedException : To approve the changes run this command:
cp "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.received.txt" "/Users/runner/work/CSnakes/CSnakes/src/CSnakes.Tests/PythonStaticGeneratorTests/FormatClassFromMethods.test_generators.approved.txt"
----------------------------

compiledCode
    should match approved with options: Ignoring line endings
"// <auto-generated/>
#nullable enable

using CSnakes.Runtime;
using CSnakes.Runtime.Python;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata;

using Microsoft.Extensions.Logging;

[assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]

namespace Python.Generated.Tests;

public static class TestClassExtensions
{
    private static ITestClass? instance;

    private static ReadOnlySpan<byte> HotReloadHash => "657bc350954200f5d7103a2587de60ae"u8;

    public static ITestClass TestClass(this IPythonEnvironment env)
    {
        if (instance is null)
        {
            instance = new TestClassInternal(env.Logger);
        }
        Debug.Assert(!env.IsDisposed());
        return instance;
    }

    public static void UpdateApplication(Type[]? updatedTypes)
    {
        instance?.ReloadModule();
    }

    private class TestClassInternal : ITestClass
    {
        private PyObject module;
        private readonly ILogger<IPythonEnvironment> logger;

        private PyObject __func_example_generator;
        private PyObject __func_test_normal_generator;

        internal TestClassInternal(ILogger<IPythonEnvironment> logger)
        {
            this.logger = logger;
            using (GIL.Acquire())
            {
                logger.LogDebug("Importing module {ModuleName}", "test");
                module = Import.ImportModule("test");
                this.__func_example_generator = module.GetAttr("example_generator");
                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
            }
        }

        void IReloadableModuleImport.ReloadModule()
        {
            logger.LogDebug("Reloading module {ModuleName}", "test");
            using (GIL.Acquire())
            {
                Import.ReloadModule(ref module);
                // Dispose old functions
                this.__func_example_generator.Dispose();
                this.__func_test_normal_generator.Dispose();
                // Bind to new functions
                this.__func_example_generator = module.GetAttr("example_generator");
                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
            }
        }

        public void Dispose()
        {
            logger.LogDebug("Disposing module {ModuleName}", "test");
            this.__func_example_generator.Dispose();
            this.__func_test_normal_generator.Dispose();
            module.Dispose();
        }

        public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
        {
            using (GIL.Acquire())
            {
                logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
                PyObject __underlyingPythonFunc = this.__func_example_generator;
                using PyObject length_pyObject = PyObject.From(length)!;
                using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
                return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
            }
        }

        public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
        {
            using (GIL.Acquire())
            {
                logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
                PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
            }
        }
    }
}

/// <summary>
/// Represents functions of the Python module <c>test</c>.
/// </summary>
public interface ITestClass : IReloadableModuleImport
{
    /// <summary>
    /// Invokes the Python function <c>example_generator</c>:
    /// <code><![CDATA[
    /// def example_generator(length: int) -> Generator[str, int, bool]: ...
    /// ]]></code>
    /// </summary>
    IGeneratorIterator<string, long, bool> ExampleGenerator(long length);

    /// <summary>
    /// Invokes the Python function <c>test_normal_generator</c>:
    /// <code><![CDATA[
    /// def test_normal_generator() -> Generator[str, None, None]: ...
    /// ]]></code>
    /// </summary>
    IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator();
}
"
    but was
"// <auto-generated/>
#nullable enable

using CSnakes.Runtime;
using CSnakes.Runtime.Python;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata;

using Microsoft.Extensions.Logging;

[assembly: MetadataUpdateHandler(typeof(Python.Generated.Tests.TestClassExtensions))]

namespace Python.Generated.Tests;

public static class TestClassExtensions
{
    private static ITestClass? instance;

    private static ReadOnlySpan<byte> HotReloadHash => "628447fb6935f7e3926b93b678146fc8"u8;

    public static ITestClass TestClass(this IPythonEnvironment env)
    {
        if (instance is null)
        {
            instance = new TestClassInternal(env.Logger);
        }
        Debug.Assert(!env.IsDisposed());
        return instance;
    }

    public static void UpdateApplication(Type[]? updatedTypes)
    {
        instance?.ReloadModule();
    }

    private class TestClassInternal : ITestClass
    {
        private PyObject module;
        private readonly ILogger<IPythonEnvironment> logger;

        private PyObject __func_example_generator;
        private PyObject __func_test_normal_generator;
        private PyObject __func_test_generator_sequence;

        internal TestClassInternal(ILogger<IPythonEnvironment> logger)
        {
            this.logger = logger;
            using (GIL.Acquire())
            {
                logger.LogDebug("Importing module {ModuleName}", "test");
                module = Import.ImportModule("test");
                this.__func_example_generator = module.GetAttr("example_generator");
                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
                this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
            }
        }

        void IReloadableModuleImport.ReloadModule()
        {
            logger.LogDebug("Reloading module {ModuleName}", "test");
            using (GIL.Acquire())
            {
                Import.ReloadModule(ref module);
                // Dispose old functions
                this.__func_example_generator.Dispose();
                this.__func_test_normal_generator.Dispose();
                this.__func_test_generator_sequence.Dispose();
                // Bind to new functions
                this.__func_example_generator = module.GetAttr("example_generator");
                this.__func_test_normal_generator = module.GetAttr("test_normal_generator");
                this.__func_test_generator_sequence = module.GetAttr("test_generator_sequence");
            }
        }

        public void Dispose()
        {
            logger.LogDebug("Disposing module {ModuleName}", "test");
            this.__func_example_generator.Dispose();
            this.__func_test_normal_generator.Dispose();
            this.__func_test_generator_sequence.Dispose();
            module.Dispose();
        }

        public IGeneratorIterator<string, long, bool> ExampleGenerator(long length)
        {
            using (GIL.Acquire())
            {
                logger.LogDebug("Invoking Python function: {FunctionName}", "example_generator");
                PyObject __underlyingPythonFunc = this.__func_example_generator;
                using PyObject length_pyObject = PyObject.From(length)!;
                using PyObject __result_pyObject = __underlyingPythonFunc.Call(length_pyObject);
                return __result_pyObject.As<IGeneratorIterator<string, long, bool>>();
            }
        }

        public IGeneratorIterator<string, PyObject, PyObject> TestNormalGenerator()
        {
            using (GIL.Acquire())
            {
                logger.LogDebug("Invoking Python function: {FunctionName}", "test_normal_generator");
                PyObject __underlyingPythonFunc = this.__func_test_normal_generator;
                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
            }
        }

        public IGeneratorIterator<string, PyObject, PyObject> TestGeneratorSequence()
        {
            using (GIL.Acquire())
            {
                logger.LogDebug("Invoking Python function: {FunctionName}", "test_generator_sequence");
                PyObject __underlyingPythonFunc = this.__func_test_generator_sequence;
                using PyObject __result_pyObject = __underlyingPythonFunc.Call();
                return __result_pyObject.As<IGeneratorIterator<string, PyObject, PyObject>>();
            }
        }
    }
}

/// <summary>
/// Represents functions of the Python module <c>test</c>.
/// </summary>
public interface ITestClass : IReloadableModuleImport
{
    /// <summary>
    /// Invokes the Python function <c>example_generator</c>:
    /// <code><![CDATA[
    /// def example_generator(length: int) -> Generator[str, int, bool]: ...
    /// ]]></code>
    /// </summary>
    IGeneratorIterator<string, long, "
    difference
Showing some of the 3577 differences
Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  502  503  504  505  506  507  508  509  510  511  512  513  514  515  516  517  518  519  520  521  522  ...  
Expected Value | ...  5    7    b    c    3    5    0    9    5    4    2    0    0    f    5    d    7    1    0    3    a    ...  
Actual Value   | ...  2    8    4    4    7    f    b    6    9    3    5    f    7    e    3    9    2    6    b    9    3    ...  
Expected Code  | ...  53   55   98   99   51   53   48   57   53   52   50   48   48   102  53   100  55   49   48   51   97   ...  
Actual Code    | ...  50   56   52   52   55   102  98   54   57   51   53   102  55   101  51   57   50   54   98   57   51   ...  

Difference     |       |    |    |    |    |    |    |    |    |    |    |    |         |    |    |                                 
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/                                
Index          | ...  517  518  519  520  521  522  523  524  525  526  527  528  529  530  531  532  533  534  535  536  537  ...  
Expected Value | ...  d    7    1    0    3    a    2    5    8    7    d    e    6    0    a    e    "    u    8    ;    \n   ...  
Actual Value   | ...  9    2    6    b    9    3    b    6    7    8    1    4    6    f    c    8    "    u    8    ;    \n   ...  
Expected Code  | ...  100  55   49   48   51   97   50   53   56   55   100  101  54   48   97   101  34   117  56   59   10   ...  
Actual Code    | ...  57   50   54   98   57   51   98   54   55   56   49   52   54   102  99   56   34   117  56   59   10   ...  

Difference     |                                |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
               |                               \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 ...  
Expected Value | ...  \s   \s   \s   \s   \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    ...  
Actual Value   | ...  \s   \s   \s   \s   \s   p    r    i    v    a    t    e    \s   P    y    O    b    j    e    c    t    ...  
Expected Code  | ...  32   32   32   32   32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  ...  
Actual Code    | ...  32   32   32   32   32   112  114  105  118  97   116  101  32   80   121  79   98   106  101  99   116  ...  

Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 ...  
Expected Value | ...  t    C    l    a    s    s    I    n    t    e    r    n    a    l    (    I    L    o    g    g    e    ...  
Actual Value   | ...  e    c    t    \s   _    _    f    u    n    c    _    t    e    s    t    _    g    e    n    e    r    ...  
Expected Code  | ...  116  67   108  97   115  115  73   110  116  101  114  110  97   108  40   73   76   111  103  103  101  ...  
Actual Code    | ...  101  99   116  32   95   95   102  117  110  99   95   116  101  115  116  95   103  101  110  101  114  ...  

Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 ...  
Expected Value | ...  r    <    I    P    y    t    h    o    n    E    n    v    i    r    o    n    m    e    n    t    >    ...  
Actual Value   | ...  a    t    o    r    _    s    e    q    u    e    n    c    e    ;    \n   \n   \s   \s   \s   \s   \s   ...  
Expected Code  | ...  114  60   73   80   121  116  104  111  110  69   110  118  105  114  111  110  109  101  110  116  62   ...  
Actual Code    | ...  97   116  111  114  95   115  101  113  117  101  110  99   101  59   10   10   32   32   32   32   32   ...  

Difference     |       |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 ...  
Expected Value | ...  l    o    g    g    e    r    )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   ...  
Actual Value   | ...  \s   \s   i    n    t    e    r    n    a    l    \s   T    e    s    t    C    l    a    s    s    I    ...  
Expected Code  | ...  108  111  103  103  101  114  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   ...  
Actual Code    | ...  32   32   105  110  116  101  114  110  97   108  32   84   101  115  116  67   108  97   115  115  73   ...  

Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 ...  
Expected Value | ...  \s   \s   \s   \s   \s   \s   \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   ...  
Actual Value   | ...  n    t    e    r    n    a    l    (    I    L    o    g    g    e    r    <    I    P    y    t    h    ...  
Expected Code  | ...  32   32   32   32   32   32   32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   ...  
Actual Code    | ...  110  116  101  114  110  97   108  40   73   76   111  103  103  101  114  60   73   80   121  116  104  ...  

Difference     |       |    |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 ...  
Expected Value | ...  =    \s   l    o    g    g    e    r    ;    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
Actual Value   | ...  o    n    E    n    v    i    r    o    n    m    e    n    t    >    \s   l    o    g    g    e    r    ...  
Expected Code  | ...  61   32   108  111  103  103  101  114  59   10   32   32   32   32   32   32   32   32   32   32   32   ...  
Actual Code    | ...  111  110  69   110  118  105  114  111  110  109  101  110  116  62   32   108  111  103  103  101  114  ...  

Difference     |       |    |    |    |    |    |         |    |    |    |    |    |    |    |    |    |    |    |    |    |        
               |      \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       
Index          | ...  1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 ...  
Expected Value | ...  \s   u    s    i    n    g    \s   (    G    I    L    .    A    c    q    u    i    r    e    (    )    ...  
Actual Value   | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   ...  
Expected Code  | ...  32   117  115  105  110  103  32   40   71   73   76   46   65   99   113  117  105  114  101  40   41   ...  
Actual Code    | ...  41   10   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   32   32   32   32   ...  

Difference     |       |    |         |    |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |        
               |      \|/  \|/       \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/  \|/       \|/  \|/  \|/  \|/       
Index          | ...  1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 ...  
Expected Value | ...  )    \n   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   \s   {    \n   \s   \s   \s   \s   \s   ...  
Actual Value   | ...  \s   \s   \s   t    h    i    s    .    l    o    g    g    e    r    \s   =    \s   l    o    g    g    ...  
Expected Code  | ...  41   10   32   32   32   32   32   32   32   32   32   32   32   32   123  10   32   32   32   32   32   ...  
Actual Code    | ...  32   32   32   116  104  105  115  46   108  111  103  103  101  114  32   61   32   108  111  103  103  ...  
   at CSnakes.Tests.PythonStaticGeneratorTests.FormatClassFromMethods(String resourceName) in /_/src/CSnakes.Tests/PythonStaticGeneratorTests.cs:line 42
   at InvokeStub_PythonStaticGeneratorTests.FormatClassFromMethods(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)