EngineTest.cs :  » Script » IronPython » IronPythonTest » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Script » IronPython 
IronPython » IronPythonTest » EngineTest.cs
/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/

#if !CLR2
using System.Linq.Expressions;
using System.Numerics;
#else
using Microsoft.Scripting.Ast;
using Microsoft.Scripting.Math;
using ComplexMicrosoft.Scripting.Math.Complex64;
#endif

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Policy;
using System.Text;

using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;

using IronPython;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Exceptions;
using IronPython.Runtime.Types;
[assembly: ExtensionType(typeof(IronPythonTest.IFooable), typeof(IronPythonTest.FooableExtensions))]
namespace IronPythonTest{
#if !SILVERLIGHT
    class Common {
        public static string RootDirectory;
        public static string RuntimeDirectory;
        public static string ScriptTestDirectory;
        public static string InputTestDirectory;

        static Common() {
            RuntimeDirectory = Path.GetDirectoryName(typeof(PythonContext).Assembly.Location);
            RootDirectory = Environment.GetEnvironmentVariable("MERLIN_ROOT");
            if (RootDirectory != null) {
                ScriptTestDirectory = Path.Combine(RootDirectory, "Languages\\IronPython\\Tests");
            } else {
                RootDirectory = new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().GetFiles()[0].Name).Directory.FullName;
                ScriptTestDirectory = Path.Combine(RootDirectory, "Src\\Tests");
            }
            InputTestDirectory = Path.Combine(ScriptTestDirectory, "Inputs");
        }
    }
#endif

    public static class TestHelpers {
        public static LanguageContext GetContext(CodeContext context) {
            return context.LanguageContext;
        }

        public static int HashObject(object o) {
            return o.GetHashCode();
        }
    }

    public delegate int IntIntDelegate(int arg);
    public delegate string RefStrDelegate(ref string arg);
    public delegate int RefIntDelegate(ref int arg);
    public delegate T GenericDelegate<T, U, V>(U arg1, V arg2);

    public class ClsPart {
        public int Field;
        int m_property;
        public int Property { get { return m_property; } set { m_property = value; } }
        public event IntIntDelegate Event;
        public int Method(int arg) {
            if (Event != null)
                return Event(arg);
            else
                return -1;
        }

        // Private members
#pragma warning disable 169
        // This field is accessed from the test
        private int privateField;
        private int privateProperty { get { return m_property; } set { m_property = value; } }
        private event IntIntDelegate privateEvent;
        private int privateMethod(int arg) {
            if (privateEvent != null)
                return privateEvent(arg);
            else
                return -1;
        }
        private static int privateStaticMethod() {
            return 100;
        }
#pragma warning restore 169
    }

    internal class InternalClsPart {
#pragma warning disable 649
        // This field is accessed from the test
        internal int Field;
#pragma warning restore 649
        int m_property;
        internal int Property { get { return m_property; } set { m_property = value; } }
        internal event IntIntDelegate Event;
        internal int Method(int arg) {
            if (Event != null)
                return Event(arg);
            else
                return -1;
        }
    }

    public class EngineTest
#if !SILVERLIGHT // remoting not supported in Silverlight
        : MarshalByRefObject
#endif
    {

        private readonly ScriptEngine _pe;
        private readonly ScriptRuntime _env;

        public EngineTest() {
            // Load a script with all the utility functions that are required
            // pe.ExecuteFile(InputTestDirectory + "\\EngineTests.py");
            _env = Python.CreateRuntime();
            _pe = _env.GetEngine("py");
        }

        // Used to test exception thrown in another domain can be shown correctly.
        public void Run(string script) {
            ScriptScope scope = _env.CreateScope();
            _pe.CreateScriptSourceFromString(script, SourceCodeKind.File).Execute(scope);
        }

        static readonly string clspartName = "clsPart";
        
        /// <summary>
        /// Asserts an condition it true
        /// </summary>
        private static void Assert(bool condition, string msg) {
            if (!condition) throw new Exception(String.Format("Assertion failed: {0}", msg));
        }

        private static void Assert(bool condition) {
            if (!condition) throw new Exception("Assertion failed");
        }

        private static T AssertExceptionThrown<T>(Action f) where T : Exception {
            try {
                f();
            } catch (T ex) {
                return ex;
            }

            Assert(false, "Expecting exception '" + typeof(T) + "'.");
            return null;
        }

#if !SILVERLIGHT
        public void ScenarioHostingHelpers() {
            AppDomain remote = AppDomain.CreateDomain("foo");
            Dictionary<string, object> options = new Dictionary<string,object>();
            // DLR ScriptRuntime options
            options["Debug"] = true;
            options["PrivateBinding"] = true;
            
            // python options
            options["StripDocStrings"] = true;
            options["Optimize"] = true;
            options["DivisionOptions"] = PythonDivisionOptions.New;
            options["RecursionLimit"] = 42;
            options["IndentationInconsistencySeverity"] = Severity.Warning;
            options["WarningFilters"] = new string[] { "warnonme" };

            ScriptEngine engine1 = Python.CreateEngine();
            ScriptEngine engine2 = Python.CreateEngine(AppDomain.CurrentDomain);
            ScriptEngine engine3 = Python.CreateEngine(remote);

            TestEngines(null, new ScriptEngine[] { engine1, engine2, engine3 });

            ScriptEngine engine4 = Python.CreateEngine(options);
            ScriptEngine engine5 = Python.CreateEngine(AppDomain.CurrentDomain, options);
            ScriptEngine engine6 = Python.CreateEngine(remote, options);

            TestEngines(options, new ScriptEngine[] { engine4, engine5, engine6 });

            ScriptRuntime runtime1 = Python.CreateRuntime();
            ScriptRuntime runtime2 = Python.CreateRuntime(AppDomain.CurrentDomain);
            ScriptRuntime runtime3 = Python.CreateRuntime(remote);

            TestRuntimes(null, new ScriptRuntime[] { runtime1, runtime2, runtime3 });

            ScriptRuntime runtime4 = Python.CreateRuntime(options);
            ScriptRuntime runtime5 = Python.CreateRuntime(AppDomain.CurrentDomain, options);
            ScriptRuntime runtime6 = Python.CreateRuntime(remote, options);

            TestRuntimes(options, new ScriptRuntime[] { runtime4, runtime5, runtime6 });
        }

        private void TestEngines(Dictionary<string, object> options, ScriptEngine[] engines) {
            foreach (ScriptEngine engine in engines) {
                TestEngine(engine, options);
                TestRuntime(engine.Runtime, options);
            }
        }

        private void TestRuntimes(Dictionary<string, object> options, ScriptRuntime[] runtimes) {
            foreach (ScriptRuntime runtime in runtimes) {
                TestRuntime(runtime, options);

                TestEngine(Python.GetEngine(runtime), options);
            }
        }

        private void TestEngine(ScriptEngine scriptEngine, Dictionary<string, object> options) {
            // basic smoke tests that the engine is alive and working
            AreEqual((int)(object)scriptEngine.Execute("42"), 42);

            if(options != null) {
                PythonOptions po = (PythonOptions)Microsoft.Scripting.Hosting.Providers.HostingHelpers.CallEngine<object, LanguageOptions>(
                    scriptEngine, 
                    (lc, obj) => lc.Options,
                    null
                );

                AreEqual(po.StripDocStrings, true);
                AreEqual(po.Optimize, true);
                AreEqual(po.DivisionOptions, PythonDivisionOptions.New);
                AreEqual(po.RecursionLimit, 42);
                AreEqual(po.IndentationInconsistencySeverity, Severity.Warning);
                AreEqual(po.WarningFilters[0], "warnonme");
            }

            AreEqual(Python.GetSysModule(scriptEngine).GetVariable<string>("platform"), "cli");
            AreEqual(Python.GetBuiltinModule(scriptEngine).GetVariable<bool>("True"), true);
            AreEqual(Python.ImportModule(scriptEngine, "nt").GetVariable<int>("F_OK"), 0);
            try {
                Python.ImportModule(scriptEngine, "non_existant_module");
                Assert(false);
            } catch (ImportException) {
            }
        }

        private void TestRuntime(ScriptRuntime runtime, Dictionary<string, object> options) {
            // basic smoke tests that the runtime is alive and working
            runtime.Globals.SetVariable("hello", 42);
            Assert(runtime.GetEngine("py") != null);

            if (options != null) {
                AreEqual(runtime.Setup.DebugMode, true);
                AreEqual(runtime.Setup.PrivateBinding, true);
            }

            AreEqual(Python.GetSysModule(runtime).GetVariable<string>("platform"), "cli");
            AreEqual(Python.GetBuiltinModule(runtime).GetVariable<bool>("True"), true);
            AreEqual(Python.ImportModule(runtime, "nt").GetVariable<int>("F_OK"), 0);
            try {
                Python.ImportModule(runtime, "non_existant_module");
                Assert(false);
            } catch (ImportException) {
            }
        }
#endif

#if !SILVERLIGHT        
        public void ScenarioCodePlex20472() {
            try {
                string fileName = System.IO.Directory.GetCurrentDirectory() + "\\encoded_files\\cp20472.py";
                _pe.CreateScriptSourceFromFile(fileName, System.Text.Encoding.GetEncoding(1251));

                //Disabled. The line above should have thrown a syntax exception or an import error,
                //but does not.

                //throw new Exception("ScenarioCodePlex20472");
            }
            catch (IronPython.Runtime.Exceptions.ImportException) { }
        }
#endif

        public class TestCodePlex23562 {
            public bool MethodCalled = false;
            public TestCodePlex23562() {
            }
            public void TestMethod() {
                MethodCalled = true;
            }
        }

        public void ScenarioCodePlex23562()
        {
            string pyCode = @"
test = TestCodePlex23562()
test.TestMethod()
";
            var scope = _pe.CreateScope();
            scope.SetVariable("TestCodePlex23562", typeof(TestCodePlex23562));
            _pe.Execute(pyCode, scope);

            TestCodePlex23562 temp = scope.GetVariable<TestCodePlex23562>("test");
            Assert(temp.MethodCalled);
        }

        public void ScenarioCodePlex18595() {
            string pyCode = @"
str_tuple = ('ab', 'cd')
str_list  = ['abc', 'def', 'xyz']

py_func_called = False
def py_func():
    global py_func_called
    py_func_called = True
";
            var scope = _pe.CreateScope();
            _pe.Execute(pyCode, scope);

            IList<string> str_tuple = scope.GetVariable<IList<string>>("str_tuple");
            AreEqual<int>(str_tuple.Count, 2);
            IList<string> str_list  = scope.GetVariable<IList<string>>("str_list");
            AreEqual<int>(str_list.Count, 3);
            VoidDelegate py_func = scope.GetVariable<VoidDelegate>("py_func");
            py_func();
            AreEqual<bool>(scope.GetVariable<bool>("py_func_called"), true);
        }

        public void ScenarioCodePlex24077()
        {
            string pyCode = @"
class K(object):
    def __init__(self, a, b, c):
        global A, B, C
        A = a
        B = b
        C = c
";
            var scope = _pe.CreateScope();
            _pe.Execute(pyCode, scope);
            object KKlass = scope.GetVariable("K");
            object[] Kparams = new object[] { 1, 3.14, "abc"};
            _pe.Operations.CreateInstance(KKlass, Kparams);
            AreEqual<int>(scope.GetVariable<int>("A"), 1);
        }

        // Execute
        public void ScenarioExecute() {
            ClsPart clsPart = new ClsPart();

            ScriptScope scope = _env.CreateScope();

            scope.SetVariable(clspartName, clsPart);

            // field: assign and get back
            _pe.Execute("clsPart.Field = 100", scope);
            _pe.Execute("if 100 != clsPart.Field: raise AssertionError('test failed')", scope);
            AreEqual(100, clsPart.Field);

            // property: assign and get back
            _pe.Execute("clsPart.Property = clsPart.Field", scope);
            _pe.Execute("if 100 != clsPart.Property: raise AssertionError('test failed')", scope);
            AreEqual(100, clsPart.Property);

            // method: Event not set yet
            _pe.Execute("a = clsPart.Method(2)", scope);
            _pe.Execute("if -1 != a: raise AssertionError('test failed')", scope);

            // method: add python func as event handler
            _pe.Execute("def f(x) : return x * x", scope);
            _pe.Execute("clsPart.Event += f", scope);
            _pe.Execute("a = clsPart.Method(2)", scope);
            _pe.Execute("if 4 != a: raise AssertionError('test failed')", scope);

            // ===============================================

            // reset the same variable with instance of the same type
            scope.SetVariable(clspartName, new ClsPart());
            _pe.Execute("if 0 != clsPart.Field: raise AssertionError('test failed')", scope);

            // add cls method as event handler
            scope.SetVariable("clsMethod", new IntIntDelegate(Negate));
            _pe.Execute("clsPart.Event += clsMethod", scope);
            _pe.Execute("a = clsPart.Method(2)", scope);
            _pe.Execute("if -2 != a: raise AssertionError('test failed')", scope);

            // ===============================================

            // reset the same variable with integer
            scope.SetVariable(clspartName, 1);
            _pe.Execute("if 1 != clsPart: raise AssertionError('test failed')", scope);
            AreEqual((int)(object)scope.GetVariable(clspartName), 1);

            ScriptSource su = _pe.CreateScriptSourceFromString("");
            AssertExceptionThrown<ArgumentNullException>(delegate() {
                su.Execute(null);
            });
        }

        public static void ScenarioTryGetMember() {
            var engine = Python.CreateEngine();
            var str = ClrModule.GetPythonType(typeof(string));
            object result;
            AreEqual(engine.Operations.TryGetMember(str, "Equals", out result), true);
            AreEqual(result.ToString(), "IronPython.Runtime.Types.BuiltinFunction");
        }

        public static void ScenarioInterfaceExtensions() {
            var engine = Python.CreateEngine();
            engine.Runtime.LoadAssembly(typeof(Fooable).Assembly);
            ScriptSource src = engine.CreateScriptSourceFromString("x.Bar()");
            ScriptScope scope = engine.CreateScope();
            scope.SetVariable("x", new Fooable());
            AreEqual((object)src.Execute(scope), "Bar Called");
        }

        class MyInvokeMemberBinder : InvokeMemberBinder {
            public MyInvokeMemberBinder(string name, CallInfo callInfo)
                : base(name, false, callInfo) {
            }

            public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
                return errorSuggestion ?? new DynamicMetaObject(
                    Expression.Constant("FallbackInvokeMember"),
                    target.Restrictions.Merge(BindingRestrictions.Combine(args)).Merge(target.Restrict(target.LimitType).Restrictions)
                );
            }

            public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Dynamic(new MyInvokeBinder(CallInfo), typeof(object), DynamicUtils.GetExpressions(ArrayUtils.Insert(target, args))),
                    target.Restrictions.Merge(BindingRestrictions.Combine(args))
                );
            }
        }

        class MyInvokeBinder : InvokeBinder {
            public MyInvokeBinder(CallInfo callInfo)
                : base(callInfo) {                
            }

            public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object) }),
                        Expression.Constant("FallbackInvoke"),
                        target.Expression
                    ),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );
            }
        }

        class MyGetIndexBinder : GetIndexBinder {
            public MyGetIndexBinder(CallInfo args)
                : base(args) {
            }

            public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object) }),
                        Expression.Constant("FallbackGetIndex"),
                        indexes[0].Expression
                    ),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );
            }
        }

        class MySetIndexBinder : SetIndexBinder {
            public MySetIndexBinder(CallInfo args)
                : base(args) {
            }

            public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object), typeof(object) }),
                        Expression.Constant("FallbackSetIndex"),
                        indexes[0].Expression,
                        value.Expression
                    ),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );
            }
        }

        class MyGetMemberBinder : GetMemberBinder {
            public MyGetMemberBinder(string name)
                : base(name, false) {
            }

            public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Constant("FallbackGetMember"),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );
            }
        }


        class MyInvokeBinder2 : InvokeBinder {
            public MyInvokeBinder2(CallInfo args)
                : base(args) {
            }

            public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
                Expression[] exprs = new Expression[args.Length + 1];
                exprs[0] = Expression.Constant("FallbackInvoke");
                for (int i = 0; i < args.Length; i++) {
                    exprs[i + 1] = args[i].Expression;
                }

                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(String).GetMethod("Concat", new Type[] { typeof(object[]) }),
                        Expression.NewArrayInit(
                            typeof(object),
                            exprs
                        )
                    ),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );
            }
        }

        class MyConvertBinder : ConvertBinder {
            private object _result;
            public MyConvertBinder(Type type) : this(type, "Converted") {
            }
            public MyConvertBinder(Type type, object result)
                : base(type, true) {
                _result = result;
            }

            public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Constant(_result),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );

            }
        }

        class MyUnaryBinder : UnaryOperationBinder {
            public MyUnaryBinder(ExpressionType et)
                : base(et) {
            }

            public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
                return new DynamicMetaObject(
                    Expression.Constant("UnaryFallback"),
                    BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                );
            }
        }

        private void TestTarget(object sender, EventArgs args) {
        }

#if !SILVERLIGHT
        public void ScenarioDocumentation() {
            ScriptScope scope = _pe.CreateScope();
            ScriptSource src = _pe.CreateScriptSourceFromString(@"
import System
import clr

def f0(a, b): pass
def f1(a, *b): pass
def f2(a, **b): pass
def f3(a, *b, **c): pass

class C:
    m0 = f0
    m1 = f1
    m2 = f2
    m3 = f3
    def __init__(self):
        self.foo = 42

class SC(C): pass

inst = C()

class NC(object):
    m0 = f0
    m1 = f1
    m2 = f2
    m3 = f3
    def __init__(self):
        self.foo = 42

class SNC(NC): pass

ncinst = C()

class EmptyNC(object): pass

enc = EmptyNC()

m0 = C.m0
m1 = C.m1
m2 = C.m2
m3 = C.m3

z = zip
i = int

", SourceCodeKind.File);

            var doc = _pe.GetService<DocumentationOperations>();
            src.Execute(scope);
            scope.SetVariable("dlg", new EventHandler(TestTarget));

            object f0 = scope.GetVariable("f0");
            object f1 = scope.GetVariable("f1");
            object f2 = scope.GetVariable("f2");
            object f3 = scope.GetVariable("f3");
            object zip = scope.GetVariable("z");
            object dlg = scope.GetVariable("dlg");
            object m0 = scope.GetVariable("m0");
            object m1 = scope.GetVariable("m1");
            object m2 = scope.GetVariable("m2");
            object m3 = scope.GetVariable("m3");

            var tests = new [] { 
                new { 
                    Obj=f0, 
                    Result = new [] { 
                        new[] {
                            new { ParamName="a", ParamAttrs = ParameterFlags.None }, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.None } 
                        }
                    } 
                },
                new { 
                    Obj=f1, 
                    Result = new [] { 
                        new[] { 
                            new { ParamName="a", ParamAttrs = ParameterFlags.None }, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray } 
                        }
                    } 
                },
                new { 
                    Obj=f2, 
                    Result = new [] { 
                        new[] { 
                            new { ParamName="a", ParamAttrs = ParameterFlags.None }, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.ParamsDict} 
                        }
                    } 
                },
                new { 
                    Obj=f3, 
                    Result = new [] { 
                        new [] { 
                            new { ParamName="a", ParamAttrs = ParameterFlags.None}, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray},
                            new { ParamName="c", ParamAttrs = ParameterFlags.ParamsDict} 
                        } 
                    }
                },
                new {
                    Obj = zip,
                    Result = new [] {
                        new [] {
                            new { ParamName="s0", ParamAttrs = ParameterFlags.None },
                            new { ParamName="s1", ParamAttrs = ParameterFlags.None },
                        },
                        new [] {
                            new { ParamName="seqs", ParamAttrs = ParameterFlags.ParamsArray },
                        }
                    }
                },
                new { 
                    Obj=dlg, 
                    Result = new [] { 
                        new [] { 
                            new { ParamName="sender", ParamAttrs = ParameterFlags.None}, 
                            new { ParamName="e", ParamAttrs = ParameterFlags.None},
                        } 
                    }
                },
                new { 
                    Obj=m0, 
                    Result = new [] { 
                        new[] {
                            new { ParamName="a", ParamAttrs = ParameterFlags.None }, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.None } 
                        }
                    } 
                },
                new { 
                    Obj=m1, 
                    Result = new [] { 
                        new[] { 
                            new { ParamName="a", ParamAttrs = ParameterFlags.None }, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray } 
                        }
                    } 
                },
                new { 
                    Obj=m2, 
                    Result = new [] { 
                        new[] { 
                            new { ParamName="a", ParamAttrs = ParameterFlags.None }, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.ParamsDict} 
                        }
                    } 
                },
                new { 
                    Obj=m3, 
                    Result = new [] { 
                        new [] { 
                            new { ParamName="a", ParamAttrs = ParameterFlags.None}, 
                            new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray},
                            new { ParamName="c", ParamAttrs = ParameterFlags.ParamsDict} 
                        } 
                    }
                },

            };

            foreach (var test in tests) {
                var result = new List<OverloadDoc>(doc.GetOverloads(test.Obj));                
                AreEqual(result.Count, test.Result.Length);

                for (int i = 0; i < result.Count; i++) {
                    var received = result[i]; ;
                    var expected = test.Result[i];
                    AreEqual(received.Parameters.Count, expected.Length);
                    var recvParams = new List<ParameterDoc>(received.Parameters);

                    for (int j = 0; j < expected.Length; j++) {
                        var receivedParam = recvParams[j];
                        var expectedParam = expected[j];

                        AreEqual(receivedParam.Flags, expectedParam.ParamAttrs);
                        AreEqual(receivedParam.Name, expectedParam.ParamName);
                    }
                }
            }

            object inst = scope.GetVariable("inst");
            object ncinst = scope.GetVariable("ncinst");
            object klass = scope.GetVariable("C");
            object newklass = scope.GetVariable("NC");
            object subklass = scope.GetVariable("SC");
            object subnewklass = scope.GetVariable("SNC");
            object System = scope.GetVariable("System");
            object clr = scope.GetVariable("clr");

            foreach (object o in new[] { inst, ncinst }) {
                var members = doc.GetMembers(o);
                ContainsMemberName(members, "m0", MemberKind.Method);
                ContainsMemberName(members, "foo", MemberKind.None);
            }
            
            ContainsMemberName(doc.GetMembers(klass), "m0", MemberKind.Method);
            ContainsMemberName(doc.GetMembers(newklass), "m0", MemberKind.Method);
            ContainsMemberName(doc.GetMembers(subklass), "m0", MemberKind.Method);
            ContainsMemberName(doc.GetMembers(subnewklass), "m0", MemberKind.Method);
            ContainsMemberName(doc.GetMembers(System), "Collections", MemberKind.Namespace);
            ContainsMemberName(doc.GetMembers(clr), "AddReference", MemberKind.Function);

            object intType = scope.GetVariable("i");
            foreach (object o in new object[] { intType, 42 }) {
                var members = doc.GetMembers(o);
                ContainsMemberName(members, "__add__", MemberKind.Method);
                ContainsMemberName(members, "conjugate", MemberKind.Method);
                ContainsMemberName(members, "real", MemberKind.Property);
            }
            
            ContainsMemberName(doc.GetMembers(new List<object>()), "Count", MemberKind.Property);
            ContainsMemberName(doc.GetMembers(DynamicHelpers.GetPythonTypeFromType(typeof(DateTime))), "MaxValue", MemberKind.Field);

            doc.GetMembers(scope.GetVariable("enc"));
        }
#endif

        private void ContainsMemberName(ICollection<MemberDoc> members, string name, MemberKind kind) {
            foreach (var member in members) {
                if (member.Name == name) {
                    AreEqual(member.Kind, kind);
                    return;
                }
            }

            Assert(false, "didn't find member " + name);
        }

        public void ScenarioDlrInterop() {
            string actionOfT = typeof(Action<>).FullName.Split('`')[0];

#if !SILVERLIGHT
            ScriptScope scope = _env.CreateScope();
            ScriptSource src = _pe.CreateScriptSourceFromString(@"
from System.Collections import ArrayList
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Control
import System


somecallable = " + actionOfT + @"[object](lambda : 'Delegate')

class control(Control):
    pass

class control_setattr(Control):
    def __init__(self):
        object.__setattr__(self, 'lastset', None)
    
    def __setattr__(self, name, value):
        object.__setattr__(self, 'lastset', (name, value))

class control_override_prop(Control):
    def __setattr__(self, name, value):
        pass

    def get_AllowDrop(self):
        return 'abc'

    def set_AllowDrop(self, value):
        super(control_setattr, self).AllowDrop.SetValue(value)

class ns(object):
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
        self.InstCallable = somecallable
        self.LastSetItem = None

    def __add__(self, other):
        return 'add' + str(other)
        
    def TestFunc(self):
        return 'TestFunc'

    def ToString(self):
        return 'MyToString'

    def NsMethod(self, *args, **kwargs):
        return args, kwargs
    
    @staticmethod
    def StaticMethod():
        return 'Static'

    @classmethod
    def StaticMethod(cls):
        return cls
    
    def __call__(self, *args, **kwargs):
        return args, kwargs
    
    def __int__(self): return 42
    def __float__(self): return 42.0
    def __str__(self): return 'Python'
    def __long__(self): return 42L
    def __complex__(self): return 42j
    def __nonzero__(self): return False

    def __getitem__(self, index):
        return index

    def __setitem__(self, index, value):
        self.LastSetItem = (index, value)
    
    SomeDelegate = somecallable
    
class ns_getattr(object):
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
    
    def TestFunc(self):
        return 'TestFunc'

    def __getattr__(self, name):
        if name == 'SomeDelegate':
            return somecallable
        elif name == 'something':
            return 'getattrsomething'
        return name

class ns_getattribute(object):
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
    
    def TestFunc(self):
        return 'TestFunc'

    def __getattribute__(self, name):
        if name == 'SomeDelegate':
            return somecallable
        return name

class MyArrayList(ArrayList):
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
    
    def TestFunc(self):
        return 'TestFunc'


class MyArrayList_getattr(ArrayList):
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
    
    def TestFunc(self):
        return 'TestFunc'

    def __getattr__(self, name):
        return name

class MyArrayList_getattribute(ArrayList):
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
    
    def TestFunc(self):
        return 'TestFunc'
    
    def __getattribute__(self, name):
        return name

class IterableObject(object):
    def __iter__(self):
        yield 1
        yield 2
        yield 3

class IterableObjectOs:
    def __iter__(self):
        yield 1
        yield 2
        yield 3

class os:
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'
        self.InstCallable = somecallable
        self.LastSetItem = None
    
    def TestFunc(self):
        return 'TestFunc'

    def __call__(self, *args, **kwargs):
        return args, kwargs
    
    def __int__(self): return 42
    def __float__(self): return 42.0
    def __str__(self): return 'Python'
    def __long__(self): return 42L
    def __nonzero__(self): return False
    def __complex__(self): return 42j

    def __getitem__(self, index):
        return index

    def __setitem__(self, index, value):
        self.LastSetItem = (index, value)
    
    SomeDelegate = somecallable

class plain_os:
    pass

class plain_ns(object): pass

class os_getattr:
    ClassVal = 'ClassVal'

    def __init__(self):
        self.InstVal = 'InstVal'

    def __getattr__(self, name):
        if name == 'SomeDelegate':
            return somecallable
        return name
    
    def TestFunc(self):
        return 'TestFunc'

class ns_nonzero(object):
    def __nonzero__(self):
        return True

ns_nonzero_inst = ns_nonzero()

class ns_len1(object):
    def __len__(self): return 1

ns_len1_inst = ns_len1()

class ns_len0(object):
    def __len__(self): return 0

ns_len0_inst = ns_len0()

def TestFunc():
    return 'TestFunc'

TestFunc.SubFunc = TestFunc

def Invokable(*args, **kwargs):
    return args, kwargs

TestFunc.TestFunc = TestFunc
TestFunc.InstVal = 'InstVal'
TestFunc.ClassVal = 'ClassVal'  # just here to simplify tests

controlinst = control()
nsinst = ns()
iterable = IterableObject()
iterableos = IterableObjectOs()
plainnsinst = plain_ns()
nsmethod = nsinst.NsMethod
alinst = MyArrayList()
osinst = os()
plainosinst = plain_os()
os_getattrinst = os_getattr()
ns_getattrinst = ns_getattr()
al_getattrinst = MyArrayList_getattr()

ns_getattributeinst = ns_getattribute()
al_getattributeinst = MyArrayList_getattribute()

xrange = xrange
", SourceCodeKind.Statements);

            src.Execute(scope);

            // InvokeMember tests

            var allObjects = new object[] { scope.GetVariable("nsinst"), scope.GetVariable("osinst"), scope.GetVariable("alinst"), scope.GetVariable("TestFunc") };
            var getattrObjects = new object[] { scope.GetVariable("ns_getattrinst"), scope.GetVariable("os_getattrinst"), scope.GetVariable("al_getattrinst") };
            var getattributeObjects = new object[] { scope.GetVariable("ns_getattributeinst"), scope.GetVariable("al_getattributeinst") };
            var indexableObjects = new object[] { scope.GetVariable("nsinst"), scope.GetVariable("osinst") };
            var unindexableObjects = new object[] { scope.GetVariable("TestFunc"), scope.GetVariable("ns_getattrinst"), scope.GetVariable("somecallable") }; // scope.GetVariable("plainosinst"), 
            var invokableObjects = new object[] { scope.GetVariable("Invokable"), scope.GetVariable("nsinst"), scope.GetVariable("osinst"), scope.GetVariable("nsmethod"), };
            var convertableObjects = new object[] { scope.GetVariable("nsinst"), scope.GetVariable("osinst") };
            var unconvertableObjects = new object[] { scope.GetVariable("plainnsinst"), scope.GetVariable("plainosinst") };
            var iterableObjects = new object[] { scope.GetVariable("iterable"), scope.GetVariable("iterableos") };

            // if it lives on a system type we should do a fallback invoke member
            var site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("Count", new CallInfo(0)));
            AreEqual(site.Target(site, (object)scope.GetVariable("alinst")), "FallbackInvokeMember");

            // invoke a function that's a member on an object
            foreach (object inst in allObjects) {
                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("TestFunc", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "TestFunc");
            }

            // invoke a field / property that's on an object
            foreach (object inst in allObjects) {
                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("InstVal", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeInstVal");

                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("ClassVal", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeClassVal");


                if (!(inst is PythonFunction)) {
                    site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("SomeMethodThatNeverExists", new CallInfo(0)));
                    AreEqual(site.Target(site, inst), "FallbackInvokeMember");
                }
            }

            // invoke a field / property that's not defined on objects w/ __getattr__
            foreach (object inst in getattrObjects) {
                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeDoesNotExist");
            }

            // invoke a field / property that's not defined on objects w/ __getattribute__
            foreach (object inst in getattributeObjects) {
                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeDoesNotExist");

                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("Count", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeCount");

                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("TestFunc", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeTestFunc");

                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("InstVal", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeInstVal");

                site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("ClassVal", new CallInfo(0)));
                AreEqual(site.Target(site, inst), "FallbackInvokeClassVal");
            }

            foreach (object inst in indexableObjects) {
                var site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyGetIndexBinder(new CallInfo(1)));
                AreEqual(site2.Target(site2, inst, "index"), "index");

                var site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MySetIndexBinder(new CallInfo(1)));
                AreEqual(site3.Target(site3, inst, "index", "value"), "value");

                site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("LastSetItem"));
                IList<object> res = (IList<object>)site.Target(site, inst);
                AreEqual(res.Count, 2);
                AreEqual(res[0], "index");
                AreEqual(res[1], "value");
            }

            foreach (object inst in unindexableObjects) {
                var site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyGetIndexBinder(new CallInfo(1)));
                //Console.WriteLine(inst);
                AreEqual(site2.Target(site2, inst, "index"), "FallbackGetIndexindex");

                var site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MySetIndexBinder(new CallInfo(1)));
                AreEqual(site3.Target(site3, inst, "index", "value"), "FallbackSetIndexindexvalue");
            }

            foreach (object inst in invokableObjects) {
                var site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(1)));
                VerifyFunction(new[] { "foo"}, new string[0], site2.Target(site2, inst, "foo"));

                site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(1, "bar")));
                VerifyFunction(new[] { "foo" }, new[] { "bar" }, site2.Target(site2, inst, "foo"));

                var site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(2)));
                VerifyFunction(new[] { "foo", "bar" }, new string[0], site3.Target(site3, inst, "foo", "bar"));

                site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(2, "bar")));
                VerifyFunction(new[] { "foo", "bar" }, new[] { "bar" }, site3.Target(site3, inst, "foo", "bar"));

                site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(2, "foo", "bar")));
                VerifyFunction(new[] { "foo", "bar" }, new[] { "foo", "bar" }, site3.Target(site3, inst, "foo", "bar"));
            }

            foreach (object inst in convertableObjects) {
                // These may be invalid according to the DLR (wrong ret type) but currently work today.
                site = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(string)));
                AreEqual(site.Target(site, inst), "Python");

                var dlgsiteo = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(Func<object, object>), null));
                VerifyFunction(new[] { "foo" }, new string[0], ((Func<object, object>)(dlgsiteo.Target(dlgsiteo, inst)))("foo"));

                var dlgsite2o = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(Func<object, object, object>), null));
                VerifyFunction(new[] { "foo", "bar" }, new string[0], ((Func<object, object, object>)dlgsite2o.Target(dlgsite2o, inst))("foo", "bar"));

                // strongly typed return versions
                var ssite = CallSite<Func<CallSite, object, string>>.Create(new MyConvertBinder(typeof(string)));
                AreEqual(ssite.Target(ssite, inst), "Python");

                var isite = CallSite<Func<CallSite, object, int>>.Create(new MyConvertBinder(typeof(int), 23));
                AreEqual(isite.Target(isite, inst), 42);

                var dsite = CallSite<Func<CallSite, object, double>>.Create(new MyConvertBinder(typeof(double), 23.0));
                AreEqual(dsite.Target(dsite, inst), 42.0);

                var csite = CallSite<Func<CallSite, object, Complex>>.Create(new MyConvertBinder(typeof(Complex), new Complex(0, 23)));
                AreEqual(csite.Target(csite, inst), new Complex(0, 42));

                var bsite = CallSite<Func<CallSite, object, bool>>.Create(new MyConvertBinder(typeof(bool), true));
                AreEqual(bsite.Target(bsite, inst), false);

                var bisite = CallSite<Func<CallSite, object, BigInteger>>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23));
                AreEqual(bisite.Target(bisite, inst), (BigInteger)42);

                var dlgsite = CallSite<Func<CallSite, object, Func<object, object>>>.Create(new MyConvertBinder(typeof(Func<object, object>), null));
                VerifyFunction(new[] { "foo" }, new string[0], dlgsite.Target(dlgsite, inst)("foo"));

                var dlgsite2 = CallSite<Func<CallSite, object, Func<object, object, object>>>.Create(new MyConvertBinder(typeof(Func<object, object, object>), null));
                VerifyFunction(new[] { "foo", "bar" }, new string[0], dlgsite2.Target(dlgsite2, inst)("foo", "bar"));
            }

            foreach (object inst in unconvertableObjects) {
                // These may be invalid according to the DLR (wrong ret type) but currently work today.
                site = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(string)));
                AreEqual(site.Target(site, inst), "Converted");

#if CLR2
                site = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23));
                AreEqual(site.Target(site, inst), (BigInteger)23);
#endif

                // strongly typed return versions
                var ssite = CallSite<Func<CallSite, object, string>>.Create(new MyConvertBinder(typeof(string)));
                AreEqual(ssite.Target(ssite, inst), "Converted");

                var isite = CallSite<Func<CallSite, object, int>>.Create(new MyConvertBinder(typeof(int), 23));
                AreEqual(isite.Target(isite, inst), 23);

                var dsite = CallSite<Func<CallSite, object, double>>.Create(new MyConvertBinder(typeof(double), 23.0));
                AreEqual(dsite.Target(dsite, inst), 23.0);

                var csite = CallSite<Func<CallSite, object, Complex>>.Create(new MyConvertBinder(typeof(Complex), new Complex(0, 23.0)));
                AreEqual(csite.Target(csite, inst), new Complex(0, 23.0));

                var bsite = CallSite<Func<CallSite, object, bool>>.Create(new MyConvertBinder(typeof(bool), true));
                AreEqual(bsite.Target(bsite, inst), true);

                var bisite = CallSite<Func<CallSite, object, BigInteger>>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23));
                AreEqual(bisite.Target(bisite, inst), (BigInteger)23);
            }

            // get on .NET member should fallback

            // property
            site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("AllowDrop"));
            AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");

            // method
            site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("BringToFront"));
            AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");

            // protected method
            site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("OnParentChanged"));
            AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");

            // event
            site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("DoubleClick"));
            AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");


            site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("something", new CallInfo(0)));
            AreEqual(site.Target(site, (object)scope.GetVariable("ns_getattrinst")), "FallbackInvokegetattrsomething");

            foreach (object inst in iterableObjects) {
                // converting a type which implements __iter__
                var enumsite = CallSite<Func<CallSite, object, IEnumerable>>.Create(new MyConvertBinder(typeof(IEnumerable)));
                IEnumerable ie = enumsite.Target(enumsite, inst);
                IEnumerator ator = ie.GetEnumerator();
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 1);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 2);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 3);
                AreEqual(ator.MoveNext(), false);

                var enumobjsite = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(IEnumerable)));
                ie = (IEnumerable)enumobjsite.Target(enumobjsite, inst);
                ator = ie.GetEnumerator();
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 1);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 2);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 3);
                AreEqual(ator.MoveNext(), false);

                var enumatorsite = CallSite<Func<CallSite, object, IEnumerator>>.Create(new MyConvertBinder(typeof(IEnumerator)));
                ator = enumatorsite.Target(enumatorsite, inst);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 1);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 2);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 3);
                AreEqual(ator.MoveNext(), false);

                var enumatorobjsite = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(IEnumerator)));
                ator = (IEnumerator)enumatorobjsite.Target(enumatorobjsite, inst);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 1);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 2);
                AreEqual(ator.MoveNext(), true);
                AreEqual(ator.Current, 3);
                AreEqual(ator.MoveNext(), false);

                // Bug, need to support conversions of new-style classes to IEnumerable<T>,
                // see http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=21253
                if (inst is IronPython.Runtime.Types.OldInstance) {
                    var enumofTsite = CallSite<Func<CallSite, object, IEnumerable<object>>>.Create(new MyConvertBinder(typeof(IEnumerable<object>), new object[0]));
                    IEnumerable<object> ieofT = enumofTsite.Target(enumofTsite, inst);
                    IEnumerator<object> atorofT = ieofT.GetEnumerator();
                    AreEqual(atorofT.MoveNext(), true);
                    AreEqual(atorofT.Current, 1);
                    AreEqual(atorofT.MoveNext(), true);
                    AreEqual(atorofT.Current, 2);
                    AreEqual(atorofT.MoveNext(), true);
                    AreEqual(atorofT.Current, 3);
                    AreEqual(atorofT.MoveNext(), false);
                }
            }

            site = CallSite<Func<CallSite, object, object>>.Create(new MyUnaryBinder(ExpressionType.Not));
            AreEqual(site.Target(site, (object)scope.GetVariable("nsinst")), true);
            AreEqual(site.Target(site, (object)scope.GetVariable("ns_nonzero_inst")), false);
            AreEqual(site.Target(site, (object)scope.GetVariable("ns_len0_inst")), true);
            AreEqual(site.Target(site, (object)scope.GetVariable("ns_len1_inst")), false);

            site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("ToString", new CallInfo(0)));
            AreEqual(site.Target(site, (object)scope.GetVariable("xrange")), "FallbackInvokeMember");

            // invoke a function defined as a member of a function
            site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("SubFunc", new CallInfo(0)));
            AreEqual(site.Target(site, (object)scope.GetVariable("TestFunc")), "TestFunc");

            site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0)));
            AreEqual(site.Target(site, (object)scope.GetVariable("TestFunc")), "FallbackInvokeMember");
#endif
        }

        class MyDynamicObject : DynamicObject {
            public object Last;

            public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) {
                result = binder.Operation;
                return true;
            }

            public override bool TryUnaryOperation(UnaryOperationBinder binder, out object result) {
                result = binder.Operation;
                return true;
            }

            public override bool TryGetMember(GetMemberBinder binder, out object result) {
                result = binder.Name;
                return true;
            }

            public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) {
                result = indexes[0];
                return true;
            }

            public override bool TryDeleteMember(DeleteMemberBinder binder) {
                Last = binder.Name;
                return true;
            }

            public override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes) {
                Last = indexes[0];
                return true;
            }

            public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) {
                Last = indexes[0];
                return true;
            }

            public override bool TrySetMember(SetMemberBinder binder, object value) {
                Last = value;
                return true;
            }

            public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) {
                result = binder.CallInfo;
                return true;
            }

            public override bool TryConvert(ConvertBinder binder, out object result) {
                result = 1000;
                return true;
            }
        }

        public void ScenarioDlrInterop_ConsumeDynamicObject() {
            var scope = _pe.CreateScope();
            var dynObj = new MyDynamicObject();
            scope.SetVariable("x", dynObj);
            _pe.Execute("import clr", scope);
            var tests = new[] { 
                new {TestCase = "clr.Convert(x, int)", Result=(object)1000},

                new {TestCase = "x(2,3,4)", Result=(object)new CallInfo(3)},
                new {TestCase = "x(2,3,4, z = 4)", Result=(object)new CallInfo(4, "z")},

                new {TestCase = "not x", Result=(object)ExpressionType.Not},
                new {TestCase = "+x", Result=(object)ExpressionType.UnaryPlus},
                new {TestCase = "-x", Result=(object)ExpressionType.Negate},
                new {TestCase = "~x", Result=(object)ExpressionType.OnesComplement},

                new {TestCase = "x + 42", Result=(object)ExpressionType.Add},
                new {TestCase = "x - 42", Result=(object)ExpressionType.Subtract},
                new {TestCase = "x / 42", Result=(object)ExpressionType.Divide},
                new {TestCase = "x * 42", Result=(object)ExpressionType.Multiply},
                new {TestCase = "x % 42", Result=(object)ExpressionType.Modulo},
                new {TestCase = "x ^ 42", Result=(object)ExpressionType.ExclusiveOr},
                new {TestCase = "x << 42", Result=(object)ExpressionType.LeftShift},
                new {TestCase = "x >> 42", Result=(object)ExpressionType.RightShift},
                new {TestCase = "x | 42", Result=(object)ExpressionType.Or},
                new {TestCase = "x & 42", Result=(object)ExpressionType.And},
                new {TestCase = "x ** 42", Result=(object)ExpressionType.Power},

                new {TestCase = "x > 42", Result=(object)ExpressionType.GreaterThan},
                new {TestCase = "x < 42", Result=(object)ExpressionType.LessThan},
                new {TestCase = "x >= 42", Result=(object)ExpressionType.GreaterThanOrEqual},
                new {TestCase = "x <= 42", Result=(object)ExpressionType.LessThanOrEqual},
                new {TestCase = "x == 42", Result=(object)ExpressionType.Equal},
                new {TestCase = "x != 42", Result=(object)ExpressionType.NotEqual},

                new {TestCase = "x.abc", Result=(object)"abc"},
                new {TestCase = "x.foo", Result=(object)"foo"},

                new {TestCase = "x[0]", Result=(object)0},
                new {TestCase = "x[1]", Result=(object)1},

            };
            foreach(var test in tests) {
                AreEqual(test.Result, (object)_pe.Execute(test.TestCase, scope));
            }

            var tests2 = new[] {
                new {TestCase = "x.foo = 42", Last=(object)42},
                new {TestCase = "x[23] = 5", Last=(object)23},
                new {TestCase = "del x[5]", Last=(object)5},
                new {TestCase = "del x.abc", Last=(object)"abc"},
            };

            foreach (var test in tests2) {
                _pe.Execute(test.TestCase, scope);
                AreEqual(test.Last, dynObj.Last);
            }
        }

        private void VerifyFunction(object[] results, string[] names, object value) {
            IList<object> res = (IList<object>)value;
            AreEqual(res.Count, 2);
            IList<object> positional = (IList<object>)res[0];
            IDictionary<object, object> kwargs = (IDictionary<object, object>)res[1];

            for (int i = 0; i < positional.Count; i++) {
                AreEqual(positional[i], results[i]);
            }

            for (int i = positional.Count; i < results.Length; i++) {
                AreEqual(kwargs[names[i - positional.Count]], results[i]);
            }

        }

        public void ScenarioEvaluateInAnonymousEngineModule() {
            ScriptScope scope1 = _env.CreateScope();
            ScriptScope scope2 = _env.CreateScope();
            ScriptScope scope3 = _env.CreateScope();

            _pe.Execute("x = 0", scope1);
            _pe.Execute("x = 1", scope2);

            scope3.SetVariable("x", 2);

            AreEqual(0, _pe.Execute<int>("x", scope1));
            AreEqual(0, (int)(object)scope1.GetVariable("x"));

            AreEqual(1, _pe.Execute<int>("x", scope2));
            AreEqual(1, (int)(object)scope2.GetVariable("x"));

            AreEqual(2, _pe.Execute<int>("x", scope3));
            AreEqual(2, (int)(object)scope3.GetVariable("x"));
        }

        public void ScenarioObjectOperations() {
            var ops = _pe.Operations;
            AreEqual("(1, 2, 3)", ops.Format(new PythonTuple(new object[] { 1, 2, 3 })));

            var scope = _pe.CreateScope();
            scope.SetVariable("ops", ops);
            AreEqual("[1, 2, 3]", _pe.Execute<string>("ops.Format([1,2,3])", scope));

            ScriptSource src = _pe.CreateScriptSourceFromString("def f(*args): return args", SourceCodeKind.Statements);
            src.Execute(scope);
            object f = (object)scope.GetVariable("f");

            for (int i = 0; i < 20; i++) {
                object[] inp = new object[i];
                for (int j = 0; j < inp.Length; j++) {
                    inp[j] = j;
                }

                AreEqual((object)ops.Invoke(f, inp), PythonTuple.MakeTuple(inp));
            }

            ScriptScope mod = _env.CreateScope();

            _pe.CreateScriptSourceFromString(@"
class foo(object):
    abc = 3
    def __init__(self, x, y):
        self.x = x
        self.y = y
", SourceCodeKind.Statements).Execute(mod);

            object klass = mod.GetVariable("foo");

            // create instance of foo, verify members

            object foo = ops.CreateInstance(klass , 123, 444);

            Assert(ops.GetMember<int>(foo, "abc") == 3);
            Assert(ops.GetMember<int>(foo, "x") == 123);
            Assert(ops.GetMember<int>(foo, "y") == 444);
        }

        public void ScenarioCP712() {
            ScriptScope scope1 = _env.CreateScope();
            _pe.CreateScriptSourceFromString("max(3, 4)", SourceCodeKind.InteractiveCode).Execute(scope1);
            //CompiledCode compiledCode = _pe.CreateScriptSourceFromString("max(3,4)", SourceCodeKind.InteractiveCode).Compile();
            //compiledCode.Execute(scope1);
            //AreEqual(4, scope1.GetVariable<int>("__builtins__._"));
            //TODO - this currently fails.
            //AreEqual(4, scope1.GetVariable<int>("_"));
        }

        public void ScenarioCP24784() {
            var code = _pe.CreateScriptSourceFromString("def f():\r\n \r\n print 1", SourceCodeKind.InteractiveCode);

            AreEqual(code.GetCodeProperties(), ScriptCodeParseResult.IncompleteStatement);
        }

        public delegate int CP19724Delegate(double p1);
        public void ScenarioCP19724()
        {
            ScriptScope scope1 = _env.CreateScope();
            ScriptSource src = _pe.CreateScriptSourceFromString(@"
class KNew(object):
    def __call__(self, p1):
        global X
        X = 42
        return 7

k = KNew()", SourceCodeKind.Statements);
            src.Execute(scope1);

            CP19724Delegate tDelegate = scope1.GetVariable<CP19724Delegate>("k");
            AreEqual(7, tDelegate(3.14));
            AreEqual(42, scope1.GetVariable<int>("X"));
        }



        public void ScenarioEvaluateInPublishedEngineModule() {
            PythonContext pc = DefaultContext.DefaultPythonContext;

            PythonModule publishedModule = new PythonModule();
            PythonModule otherModule = new PythonModule();
            pc.PublishModule("published_context_test", publishedModule);

            pc.CreateSnippet("x = 0", SourceCodeKind.Statements).Execute(otherModule.Scope);
            pc.CreateSnippet("x = 1", SourceCodeKind.Statements).Execute(publishedModule.Scope);

            object x;

            // Ensure that the default EngineModule is not affected
            x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
            AreEqual(0, (int)x);
            // Ensure that the published context has been updated as expected
            x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(publishedModule.Scope);
            AreEqual(1, (int)x);

            // Ensure that the published context is accessible from other contexts using sys.modules
            // TODO: do better:
            // pe.Import("sys", ScriptDomainManager.CurrentManager.DefaultModule);
            pc.CreateSnippet("from published_context_test import x", SourceCodeKind.Statements).Execute(otherModule.Scope);
            x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
            AreEqual(1, (int)x);
        }

        class CustomDictionary : IDictionary<string, object> {
            // Make "customSymbol" always be accessible. This could have been accomplished just by
            // doing SetGlobal. However, this mechanism could be used for other extensibility
            // purposes like getting a callback whenever the symbol is read
            internal static readonly string customSymbol = "customSymbol";
            internal const int customSymbolValue = 100;

            Dictionary<string, object> dict = new Dictionary<string, object>();

            #region IDictionary<string,object> Members

            public void Add(string key, object value) {
                if (key.Equals(customSymbol))
                    throw new UnboundNameException("Cannot assign to customSymbol");
                dict.Add(key, value);
            }

            public bool ContainsKey(string key) {
                if (key.Equals(customSymbol))
                    return true;
                return dict.ContainsKey(key);
            }

            public ICollection<string> Keys {
                get { throw new NotImplementedException("The method or operation is not implemented."); }
            }

            public bool Remove(string key) {
                if (key.Equals(customSymbol))
                    throw new UnboundNameException("Cannot delete customSymbol");
                return dict.Remove(key);
            }

            public bool TryGetValue(string key, out object value) {
                if (key.Equals(customSymbol)) {
                    value = customSymbolValue;
                    return true;
                }

                return dict.TryGetValue(key, out value);
            }

            public ICollection<object> Values {
                get { throw new NotImplementedException("The method or operation is not implemented."); }
            }

            public object this[string key] {
                get {
                    if (key.Equals(customSymbol))
                        return customSymbolValue;
                    return dict[key];
                }
                set {
                    if (key.Equals(customSymbol))
                        throw new UnboundNameException("Cannot assign to customSymbol");
                    dict[key] = value;
                }
            }

            #endregion

            #region ICollection<KeyValuePair<string,object>> Members

            public void Add(KeyValuePair<string, object> item) {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            public void Clear() {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            public bool Contains(KeyValuePair<string, object> item) {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            public int Count {
                get { throw new NotImplementedException("The method or operation is not implemented."); }
            }

            public bool IsReadOnly {
                get { throw new NotImplementedException("The method or operation is not implemented."); }
            }

            public bool Remove(KeyValuePair<string, object> item) {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            #endregion

            #region IEnumerable<KeyValuePair<string,object>> Members

            public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            #endregion

            #region IEnumerable Members

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
                throw new NotImplementedException("The method or operation is not implemented.");
            }

            #endregion
        }

        public void ScenarioCustomDictionary() {
            PythonDictionary customGlobals = new PythonDictionary(new StringDictionaryStorage(new CustomDictionary()));
            
            ScriptScope customModule = _pe.Runtime.CreateScope(customGlobals);            

            // Evaluate
            AreEqual(_pe.Execute<int>("customSymbol + 1", customModule), CustomDictionary.customSymbolValue + 1);

            // Execute
            _pe.Execute("customSymbolPlusOne = customSymbol + 1", customModule);
            AreEqual(_pe.Execute<int>("customSymbolPlusOne", customModule), CustomDictionary.customSymbolValue + 1);
            AreEqual(_pe.GetVariable<int>(customModule, "customSymbolPlusOne"), CustomDictionary.customSymbolValue + 1);

            // Compile
            CompiledCode compiledCode = _pe.CreateScriptSourceFromString("customSymbolPlusTwo = customSymbol + 2").Compile();

            compiledCode.Execute(customModule);
            AreEqual(_pe.Execute<int>("customSymbolPlusTwo", customModule), CustomDictionary.customSymbolValue + 2);
            AreEqual(_pe.GetVariable<int>(customModule, "customSymbolPlusTwo"), CustomDictionary.customSymbolValue + 2);

            // check overriding of Add
            try {
                _pe.Execute("customSymbol = 1", customModule);
                throw new Exception("We should not reach here");
            } catch (UnboundNameException) { }

            try {
                _pe.Execute(@"global customSymbol
customSymbol = 1", customModule);
                throw new Exception("We should not reach here");
            } catch (UnboundNameException) { }

            // check overriding of Remove
            try {
                _pe.Execute("del customSymbol", customModule);
                throw new Exception("We should not reach here");
            } catch (UnboundNameException) { }

            try {
                _pe.Execute(@"global customSymbol
del customSymbol", customModule);
                throw new Exception("We should not reach here");
            } catch (UnboundNameException) { }

            // vars()
            IDictionary vars = _pe.Execute<IDictionary>("vars()", customModule);
            AreEqual(true, vars.Contains("customSymbol"));

            // Miscellaneous APIs
            //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("customSymbol + arg", customModule);
            //AreEqual(d(1), CustomDictionary.customSymbolValue + 1);
        }

        public void ScenarioCallClassInstance() {
            ScriptScope scope = _env.CreateScope();
            _pe.CreateScriptSourceFromString(@"
class X(object):
    def __call__(self, arg):
        return arg

a = X()

class Y:
    def __call__(self, arg):
        return arg

b = Y()", SourceCodeKind.Statements).Execute(scope);
            var a = scope.GetVariable<Func<object, int>>("a");
            var b = scope.GetVariable<Func<object, int>>("b");
            AreEqual(a(42), 42);
            AreEqual(b(42), 42);
        }

        // Evaluate
        public void ScenarioEvaluate() {
            ScriptScope scope = _env.CreateScope();

            AreEqual(10, _pe.CreateScriptSourceFromString("4+6").Execute<int>(scope));
            AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass").Execute(scope));

            AreEqual(10, _pe.CreateScriptSourceFromString("4+6", SourceCodeKind.AutoDetect).Execute<int>(scope));
            AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.AutoDetect).Execute(scope));

            AreEqual(10, _pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Expression).Execute<int>(scope));
            AssertExceptionThrown<SyntaxErrorException>(() => _pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Expression).Execute(scope));
            
            AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.File).Execute(scope));
            AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.File).Execute(scope));

            AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.SingleStatement).Execute(scope));
            AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.SingleStatement).Execute(scope));

            AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Statements).Execute(scope));
            AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Statements).Execute(scope));

            AreEqual(10, (int)(object)_pe.Execute("4+6", scope));
            AreEqual(10, _pe.Execute<int>("4+6", scope));

            AreEqual("abab", (string)(object)_pe.Execute("'ab' * 2", scope));
            AreEqual("abab", _pe.Execute<string>("'ab' * 2", scope));

            ClsPart clsPart = new ClsPart();
            scope.SetVariable(clspartName, clsPart);
            AreEqual(clsPart, ((object)_pe.Execute("clsPart", scope)) as ClsPart);
            AreEqual(clsPart, _pe.Execute<ClsPart>("clsPart", scope));

            _pe.Execute("clsPart.Field = 100", scope);
            AreEqual(100, (int)(object)_pe.Execute("clsPart.Field", scope));
            AreEqual(100, _pe.Execute<int>("clsPart.Field", scope));

            // Ensure that we can get back a delegate to a Python method
            _pe.Execute("def IntIntMethod(a): return a * 100", scope);
            IntIntDelegate d = _pe.Execute<IntIntDelegate>("IntIntMethod", scope);
            AreEqual(d(2), 2 * 100);
        }

        public void ScenarioMemberNames() {
            ScriptScope scope = _env.CreateScope();

            _pe.CreateScriptSourceFromString(@"
class nc(object):
    def __init__(self):
        self.baz = 5    
    foo = 3
    def abc(self): pass
    @staticmethod
    def staticfunc(arg1): pass
    @classmethod
    def classmethod(cls): pass

ncinst = nc()

def f(): pass

f.foo = 3

class oc:
    def __init__(self):
        self.baz = 5   
    foo = 3
    def abc(self): pass
    @staticmethod
    def staticfunc(arg1): pass
    @classmethod
    def classmethod(cls): pass

ocinst = oc()
", SourceCodeKind.Statements).Execute(scope);

            ParameterExpression parameter = Expression.Parameter(typeof(object), "");

            DynamicMetaObject nc = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("nc"), parameter);
            DynamicMetaObject ncinst = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("ncinst"), parameter); ;
            DynamicMetaObject f = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("f"), parameter); ;
            DynamicMetaObject oc = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("oc"), parameter); ;
            DynamicMetaObject ocinst = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("ocinst"), parameter); ;

            List<string> ncnames = new List<string>(nc.GetDynamicMemberNames());
            List<string> ncinstnames = new List<string>(ncinst.GetDynamicMemberNames());
            List<string> fnames = new List<string>(f.GetDynamicMemberNames());
            List<string> ocnames = new List<string>(oc.GetDynamicMemberNames());
            List<string> ocinstnames = new List<string>(ocinst.GetDynamicMemberNames());

            ncnames.Sort();
            ncinstnames.Sort();
            ocnames.Sort();
            ocinstnames.Sort();
            fnames.Sort();

            AreEqualLists(ncnames, new[] { "__class__", "__delattr__", "__dict__", "__doc__", "__format__", "__getattribute__", "__hash__", "__init__", "__module__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "abc", "classmethod", "foo", "staticfunc" });
            AreEqualLists(ncinstnames, new[] { "__class__", "__delattr__", "__dict__", "__doc__", "__format__", "__getattribute__", "__hash__", "__init__", "__module__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "abc", "baz", "classmethod", "foo", "staticfunc" });

            AreEqualLists(fnames, new[] { "foo" });

            AreEqualLists(ocnames, new[] { "__doc__", "__init__", "__module__", "abc", "classmethod", "foo", "staticfunc" });
            AreEqualLists(ocinstnames, new[] { "__doc__", "__init__", "__module__", "abc", "baz", "classmethod", "foo", "staticfunc" });

        }

        public void ScenarioTokenCategorizer() {
            var categorizer = _pe.GetService<TokenCategorizer>();
            var source = _pe.CreateScriptSourceFromString("sys", SourceCodeKind.Statements);
            categorizer.Initialize(null, source, SourceLocation.MinValue);
            
            TokenInfo token = categorizer.ReadToken();
            AreEqual(token.Category, TokenCategory.Identifier);
            
            token = categorizer.ReadToken();
            AreEqual(token.Category, TokenCategory.EndOfStream);

            source = _pe.CreateScriptSourceFromString("\"sys\"", SourceCodeKind.Statements);
            categorizer.Initialize(null, source, SourceLocation.MinValue);

            token = categorizer.ReadToken();
            AreEqual(token.Category, TokenCategory.StringLiteral);

            token = categorizer.ReadToken();
            AreEqual(token.Category, TokenCategory.EndOfStream);
        }

        private void AreEqualLists<T>(IList<T> left, IList<T> right) {
            if (left.Count != right.Count) {
                string res = "lists differ by length: " + left.Count + " vs " + right.Count + Environment.NewLine + ListsToString(left, right);
                Assert(false, res);
            }

            for (int i = 0; i < left.Count; i++) {
                if (!left[i].Equals(right[i])) {
                    Assert(false, String.Format("lists differ by value: {0} {1}{2}{3}", left[i], right[i], Environment.NewLine, ListsToString(left, right)));
                }
            }
        }

        private static string ListsToString<T>(IList<T> left, IList<T> right) {
            string res = "    ";

            foreach (object o in left) {
                res += "\"" + o + "\", ";
            }

            res += Environment.NewLine + "    ";
            foreach (object o in right) {
                res += "\"" + o + "\", ";
            }
            return res;
        }

        public void ScenarioCallableClassToDelegate() {
            ScriptSource src = _pe.CreateScriptSourceFromString(@"
class Test(object):
    def __call__(self):
        return 42

inst = Test()

class TestOC:
    def __call__(self):
        return 42

instOC = TestOC()
", SourceCodeKind.Statements);
            ScriptScope scope = _pe.CreateScope();
            src.Execute(scope);

            Func<int> t = scope.GetVariable<Func<int>>("inst");
            AreEqual(42, t());

            t = scope.GetVariable<Func<int>>("instOC");
            AreEqual(42, t());
        }

#if !SILVERLIGHT
        // ExecuteFile
        public void ScenarioExecuteFile() {
            ScriptSource tempFile1, tempFile2;

            ScriptScope scope = _env.CreateScope();

            using (StringWriter sw = new StringWriter()) {
                sw.WriteLine("var1 = (10, 'z')");
                sw.WriteLine("");
                sw.WriteLine("clsPart.Field = 100");
                sw.WriteLine("clsPart.Property = clsPart.Field * 5");
                sw.WriteLine("clsPart.Event += (lambda x: x*x)");

                tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
            }

            ClsPart clsPart = new ClsPart();
            scope.SetVariable(clspartName, clsPart);
            tempFile1.Execute(scope);

            using (StringWriter sw = new StringWriter()) {
                sw.WriteLine("if var1[0] != 10: raise AssertionError('test failed')");
                sw.WriteLine("if var1[1] != 'z': raise AssertionError('test failed')");
                sw.WriteLine("");
                sw.WriteLine("if clsPart.Property != clsPart.Field * 5: raise AssertionError('test failed')");
                sw.WriteLine("var2 = clsPart.Method(var1[0])");
                sw.WriteLine("if var2 != 10 * 10: raise AssertionError('test failed')");

                tempFile2 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
            }

            tempFile2.Execute(scope); 
        }
#endif

#if !SILVERLIGHT
        // Bug: 542
        public void Scenario542() {
            ScriptSource tempFile1;

            ScriptScope scope = _env.CreateScope();

            using (StringWriter sw = new StringWriter()) {
                sw.WriteLine("def M1(): return -1");
                sw.WriteLine("def M2(): return +1");

                sw.WriteLine("class C:");
                sw.WriteLine("    def M1(self): return -1");
                sw.WriteLine("    def M2(self): return +1");

                sw.WriteLine("class C1:");
                sw.WriteLine("    def M(): return -1");
                sw.WriteLine("class C2:");
                sw.WriteLine("    def M(): return +1");

                tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
            }

            tempFile1.Execute(scope);

            AreEqual(-1, _pe.CreateScriptSourceFromString("M1()").Execute<int>(scope));
            AreEqual(+1, _pe.CreateScriptSourceFromString("M2()").Execute<int>(scope));

            AreEqual(-1, (int)(object)_pe.CreateScriptSourceFromString("M1()").Execute(scope));
            AreEqual(+1, (int)(object)_pe.CreateScriptSourceFromString("M2()").Execute(scope));

            _pe.CreateScriptSourceFromString("if M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
            _pe.CreateScriptSourceFromString("if M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);


            _pe.CreateScriptSourceFromString("c = C()", SourceCodeKind.SingleStatement).Execute(scope);
            AreEqual(-1, _pe.CreateScriptSourceFromString("c.M1()").Execute<int>(scope));
            AreEqual(+1, _pe.CreateScriptSourceFromString("c.M2()").Execute<int>(scope));

            AreEqual(-1, (int)(object)_pe.CreateScriptSourceFromString("c.M1()").Execute(scope));
            AreEqual(+1, (int)(object)_pe.CreateScriptSourceFromString("c.M2()").Execute(scope));

            _pe.CreateScriptSourceFromString("if c.M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
            _pe.CreateScriptSourceFromString("if c.M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);


            //AreEqual(-1, pe.EvaluateAs<int>("C1.M()"));
            //AreEqual(+1, pe.EvaluateAs<int>("C2.M()"));

            //AreEqual(-1, (int)pe.Evaluate("C1.M()"));
            //AreEqual(+1, (int)pe.Evaluate("C2.M()"));

            //pe.Execute(pe.CreateScriptSourceFromString("if C1.M() != -1: raise AssertionError('test failed')");
            //pe.Execute(pe.CreateScriptSourceFromString("if C2.M() != +1: raise AssertionError('test failed')");
        }
#endif

        // Bug: 167 
        public void Scenario167() {
            ScriptScope scope = _env.CreateScope();
            _pe.CreateScriptSourceFromString("a=1\r\nb=-1", SourceCodeKind.Statements).Execute(scope);
            AreEqual(1, _pe.CreateScriptSourceFromString("a").Execute<int>(scope));
            AreEqual(-1, _pe.CreateScriptSourceFromString("b").Execute<int>(scope));
        }
#if !SILVERLIGHT
        // AddToPath

        public void ScenarioAddToPath() { // runs first to avoid path-order issues            
            //pe.InitializeModules(ipc_path, ipc_path + "\\ipy.exe", pe.VersionString);
            string tempFile1 = Path.GetTempFileName();

            try {
                File.WriteAllText(tempFile1, "from testpkg1.does_not_exist import *");
                ScriptScope scope = _pe.Runtime.CreateScope();

                try {
                    _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
                    throw new Exception("Scenario7");
                } catch (IronPython.Runtime.Exceptions.ImportException) { }

                File.WriteAllText(tempFile1, "from testpkg1.mod1 import *");
                _pe.SetSearchPaths(new string[] { Common.ScriptTestDirectory });

                _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
                _pe.CreateScriptSourceFromString("give_back(eval('2 + 3'))", SourceCodeKind.Statements).Execute(scope);
            } finally {
                File.Delete(tempFile1);
            }
        }

        // Options.DebugMode
#endif

#if !SILVERLIGHT
        public void ScenarioPartialTrust() {
            // basic check of running a host in partial trust
            
            AppDomainSetup info = new AppDomainSetup();
            info.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            info.ApplicationName = "Test";
            
            Evidence evidence = new Evidence();
            evidence.AddHost(new Zone(SecurityZone.Internet));

#if !CLR2
            System.Security.PermissionSet permSet = SecurityManager.GetStandardSandbox(evidence);
            AppDomain newDomain = AppDomain.CreateDomain("test", evidence, info, permSet, null);
#else
            AppDomain newDomain = AppDomain.CreateDomain("test", evidence, info);
#endif
            
            // create runtime in partial trust...
            ScriptRuntime runtime = Python.CreateRuntime(newDomain);

            // get the Python engine...
            ScriptEngine engine = runtime.GetEngine("py");

            // execute some simple code
            ScriptScope scope = engine.CreateScope();
            ScriptSource source = engine.CreateScriptSourceFromString("2 + 2");
            AreEqual(source.Execute<int>(scope), 4);

            // import all of the built-in modules & make sure we can reflect on them...
            source = engine.CreateScriptSourceFromString(@"
import sys
for mod in sys.builtin_module_names:
    if mod.startswith('_ctypes'):
        continue
    x = __import__(mod)
    dir(x)
", SourceCodeKind.Statements);

            source.Execute(scope);

            // define some classes & use the methods...
            source = engine.CreateScriptSourceFromString(@"
class x(object):
    def f(self): return 1 + 2

a = x()
a.f()


class y: 
    def f(self): return 1 + 2

b = y()
b.f()
", SourceCodeKind.Statements);


            source.Execute(scope);

            // call a protected method on a derived class...
            source = engine.CreateScriptSourceFromString(@"
import clr
class x(object):
    def f(self): return 1 + 2

a = x()
b = a.MemberwiseClone()

if id(a) == id(b):
    raise Exception
", SourceCodeKind.Statements);


            source.Execute(scope);

            AppDomain.Unload(newDomain);
        }

        public void ScenarioStackFrameLineInfo() {
            const string lineNumber = "raise.py:line";

            // TODO: clone setup?
            var scope = Python.CreateRuntime().CreateScope("py");
            var debugSetup = Python.CreateRuntimeSetup(null);
            debugSetup.DebugMode = true;
            var debugScope = new ScriptRuntime(debugSetup).CreateScope("py");

            TestLineInfo(scope, lineNumber);
            TestLineInfo(debugScope, lineNumber);
            TestLineInfo(scope, lineNumber);

            // Ensure that all APIs work
            AreEqual(scope.GetVariable<int>("x"), 1);

            //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("arg + x");
            //AreEqual(d(100), 101);
            //d = pe.CreateMethod<IntIntDelegate>("var = arg + x\nreturn var");
            //AreEqual(d(100), 101);
        }

        private void TestLineInfo(ScriptScope/*!*/ scope, string lineNumber) {
            try {
                scope.Engine.ExecuteFile(Common.InputTestDirectory + "\\raise.py", scope);
                throw new Exception("We should not get here");
            } catch (StopIterationException e2) {
                if (scope.Engine.Runtime.Setup.DebugMode != e2.StackTrace.Contains(lineNumber))
                    throw new Exception("Debugging is enabled even though Options.DebugMode is not specified");
            }
        }

#endif

        // Compile and Run
        public void ScenarioCompileAndRun() {
            ClsPart clsPart = new ClsPart();

            ScriptScope scope = _env.CreateScope();

            scope.SetVariable(clspartName, clsPart);
            CompiledCode compiledCode = _pe.CreateScriptSourceFromString("def f(): clsPart.Field += 10", SourceCodeKind.Statements).Compile();
            compiledCode.Execute(scope);

            compiledCode = _pe.CreateScriptSourceFromString("f()").Compile();
            compiledCode.Execute(scope);
            AreEqual(10, clsPart.Field);
            compiledCode.Execute(scope);
            AreEqual(20, clsPart.Field);
        }

        public void ScenarioStreamRedirect() {
            MemoryStream stdout = new MemoryStream();
            MemoryStream stdin = new MemoryStream();
            MemoryStream stderr = new MemoryStream();
            Encoding encoding = Encoding.UTF8;

            _pe.Runtime.IO.SetInput(stdin, encoding);
            _pe.Runtime.IO.SetOutput(stdout, encoding);
            _pe.Runtime.IO.SetErrorOutput(stderr, encoding);
 
            const string str = "This is stdout";
            byte[] bytes = encoding.GetBytes(str);

            try {
                ScriptScope scope = _pe.Runtime.CreateScope();
                _pe.CreateScriptSourceFromString("import sys", SourceCodeKind.Statements).Execute(scope);

                stdin.Write(bytes, 0, bytes.Length);
                stdin.Position = 0;
                _pe.CreateScriptSourceFromString("output = sys.__stdin__.readline()", SourceCodeKind.Statements).Execute(scope);
                AreEqual(str, _pe.CreateScriptSourceFromString("output").Execute<string>(scope));

                _pe.CreateScriptSourceFromString("sys.__stdout__.write(output)", SourceCodeKind.Statements).Execute(scope);
                stdout.Flush();
                stdout.Position = 0;

                // deals with BOM:
                using (StreamReader reader = new StreamReader(stdout, true)) {
                    string s = reader.ReadToEnd();
                    AreEqual(str, s);
                }

                _pe.CreateScriptSourceFromString("sys.__stderr__.write(\"This is stderr\")", SourceCodeKind.Statements).Execute(scope);

                stderr.Flush();
                stderr.Position = 0;
                
                // deals with BOM:
                using (StreamReader reader = new StreamReader(stderr, true)) {
                    string s = reader.ReadToEnd();
                    AreEqual("This is stderr", s);
                }
            } finally {
                _pe.Runtime.IO.RedirectToConsole();
            }
        }

        public void Scenario12() {
            ScriptScope scope = _env.CreateScope();

            _pe.CreateScriptSourceFromString(@"
class R(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
   
    def M(self):
        return self.a + self.b

    sum = property(M, None, None, None)

r = R(10, 100)
if r.sum != 110:
    raise AssertionError('Scenario 12 failed')
", SourceCodeKind.Statements).Execute(scope);
        }

// TODO: rewrite 
#if FALSE
        public void ScenarioTrueDivision1() {
            TestOldDivision(pe, DefaultModule);
            ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
            TestNewDivision(pe, module);
        }

        public void ScenarioTrueDivision2() {
            TestOldDivision(pe, DefaultModule);
            ScriptScope module = pe.CreateModule("__future__", ModuleOptions.PublishModule);
            module.SetVariable("division", 1);
            pe.Execute(pe.CreateScriptSourceFromString("from __future__ import division", module));
            TestNewDivision(pe, module);
        }

        public void ScenarioTrueDivision3() {
            TestOldDivision(pe, DefaultModule);
            ScriptScope future = pe.CreateModule("__future__", ModuleOptions.PublishModule);
            future.SetVariable("division", 1);
            ScriptScope td = pe.CreateModule("truediv", ModuleOptions.None);
            ScriptCode cc = ScriptCode.FromCompiledCode((CompiledCode)pe.CompileCode("from __future__ import division"));
            cc.Run(td);
            TestNewDivision(pe, td);  // we've polluted the DefaultModule by executing the code
        }
#if !SILVERLIGHT
        public void ScenarioTrueDivision4() {
            pe.AddToPath(Common.ScriptTestDirectory);

            string modName = GetTemporaryModuleName();
            string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
            System.IO.File.WriteAllText(file, "result = 1/2");

            PythonDivisionOptions old = PythonEngine.CurrentEngine.Options.DivisionOptions;

            try {
                PythonEngine.CurrentEngine.Options.DivisionOptions = PythonDivisionOptions.Old;
                ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
                pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
                int res = pe.EvaluateAs<int>(modName + ".result", module);
                AreEqual(res, 0);
            } finally {
                PythonEngine.CurrentEngine.Options.DivisionOptions = old;
                try {
                    System.IO.File.Delete(file);
                } catch { }
            }
        }

        private string GetTemporaryModuleName() {
            return "tempmod" + Path.GetRandomFileName().Replace('-', '_').Replace('.', '_');
        }

        public void ScenarioTrueDivision5() {
            pe.AddToPath(Common.ScriptTestDirectory);

            string modName = GetTemporaryModuleName();
            string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
            System.IO.File.WriteAllText(file, "from __future__ import division; result = 1/2");

            try {
                ScriptScope module = ScriptDomainManager.CurrentManager.CreateModule(modName);
                pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
                double res = pe.EvaluateAs<double>(modName + ".result", module);
                AreEqual(res, 0.5);
                AreEqual((bool)((PythonContext)DefaultContext.Default.LanguageContext).TrueDivision, false);
            } finally {
                try {
                    System.IO.File.Delete(file);
                } catch { }
            }
        }
        public void ScenarioSystemStatePrefix() {
            AreEqual(IronPythonTest.Common.RuntimeDirectory, pe.SystemState.prefix);
        }
#endif

        private static void TestOldDivision(ScriptEngine pe, ScriptScope module) {
            pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
            AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0);
            AreEqual(pe.EvaluateAs<int>("1/2", module), 0);
            pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
            AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1);
            AreEqual(pe.EvaluateAs<int>("eval('3/2')", module), 1);
        }

        private static void TestNewDivision(ScriptEngine pe, ScriptScope module) {
            pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
            AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0.5);
            AreEqual(pe.EvaluateAs<double>("1/2", module), 0.5);
            pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
            AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1.5);
            AreEqual(pe.EvaluateAs<double>("eval('3/2')", module), 1.5);
        }
#endif
        // More to come: exception related...

        public static int Negate(int arg) { return -1 * arg; }

        static void AreEqual<T>(T expected, T actual) {
            if (expected == null && actual == null) return;

            if (!expected.Equals(actual)) {
                Console.WriteLine("Expected: {0} Got: {1} from {2}", expected, actual, new StackTrace(true));
                throw new Exception();
            }
        }
    }


    public interface IFooable {
    }

    public class Fooable : IFooable {

    }

    public static class FooableExtensions {
        public static string Bar(IFooable self) {
            return "Bar Called";
        }
    }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.