Skip to content

Strange iterator behavior with async code #283

Description

@gmkado

I'm getting a weird error when trying to run a modified version of Scenario_ExecuteFile_Push. Here is my code:

public static class Scenarios {
    static async Task Main() {
        await Scenario_ExecuteFile_Push();
    }

    public class MyHostObjectModel {
        public Func<IEnumerable<string>> GetUserCommands = default!;
    }
    
    private static ScriptRuntime CreateScriptRuntime()
    {
        var setup = new ScriptRuntimeSetup();
        setup.LanguageSetups.Add(IronPython.Hosting.Python.CreateLanguageSetup(null));
        var runtime = new ScriptRuntime(setup);
        return runtime;
    }

    public static async Task Scenario_ExecuteFile_Push() {
        var hostOm = new MyHostObjectModel();
        var runtime = CreateScriptRuntime();

        runtime.Globals.SetVariable("App", hostOm);
        runtime.ExecuteFile("register_user_commands.py");
        
        foreach (var str in hostOm.GetUserCommands())
        {
            // await Task.Delay(100);
            Console.WriteLine(str);
        }
    }
}

Here is my register_user_commands.py:

import App

def fun():
  yield 'does'
  yield 'this'
  yield 'work'

App.GetUserCommands = fun

Without the Task.Delay, (aka when run synchronously) this prints to the console:

does
this
work

But with the Task.Delay uncommented I get:

does
this
work
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at System.Collections.Generic.List`1.RemoveAt(Int32 index)
   at Microsoft.Scripting.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at Microsoft.Scripting.Interpreter.LightLambda.Run1[T0,TRet](T0 arg0)
   at IronPython.Runtime.PythonGenerator.GetNext()
   at IronPython.Runtime.PythonGenerator.MoveNextWorker()
   at IronPython.Runtime.PythonGenerator.System.Collections.IEnumerator.MoveNext()
   at IronPython.Runtime.IEnumeratorOfTWrapper`1.MoveNext()
   at dlr_playground.Scenarios.Scenario_ExecuteFile_Push() in [...]Program.cs:line 39
   at dlr_playground.Scenarios.Main() in [...]Program.cs:line 17
   at dlr_playground.Scenarios.<Main>()

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions