/Languages/IronPython/IronPythonTest/EngineTest.cs
C# | 2853 lines | 2268 code | 459 blank | 126 comment | 71 complexity | 114284ad390082b02472e0d5a624e52f MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
Large files files are truncated, but you can click here to view the full file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Apache License, Version 2.0, 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 Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
- #if FEATURE_CORE_DLR
- using System.Linq.Expressions;
- using System.Numerics;
- #else
- using Microsoft.Scripting.Ast;
- using Microsoft.Scripting.Math;
- using Complex = Microsoft.Scripting.Math.Complex64;
- #endif
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Dynamic;
- using System.IO;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Security;
- #if FEATURE_REMOTING
- using System.Security.Policy;
- #endif
- using System.Text;
- using System.Threading;
- #if FEATURE_WPF
- using System.Windows.Markup;
- #endif
- using Microsoft.Scripting;
- using Microsoft.Scripting.Generation;
- 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.Operations;
- using IronPython.Runtime.Types;
- #if FEATURE_WPF
- using DependencyObject = System.Windows.DependencyObject;
- #endif
- [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).GetTypeInfo().Assembly.Location);
- RootDirectory = Environment.GetEnvironmentVariable("DLR_ROOT");
- if (RootDirectory != null) {
- ScriptTestDirectory = Path.Combine(Path.Combine(Path.Combine(RootDirectory, "Languages"), "IronPython"), "Tests");
- } else {
- RootDirectory = new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location).Directory.FullName;
- ScriptTestDirectory = Path.Combine(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);
- #if FEATURE_WPF
- [ContentProperty("Content")]
- public class XamlTestObject : DependencyObject {
- public event IntIntDelegate Event;
- public int Method(int arg) {
- if (Event != null)
- return Event(arg);
- else
- return -1;
- }
- public object Content {
- get;
- set;
- }
- }
- [ContentProperty("Content")]
- [RuntimeNameProperty("MyName")]
- public class InnerXamlTextObject : DependencyObject {
- public object Content {
- get;
- set;
- }
- public string MyName {
- get;
- set;
- }
- }
- [ContentProperty("Content")]
- [RuntimeNameProperty("Name")]
- public class InnerXamlTextObject2 : DependencyObject {
- public object Content {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- }
- #endif
- 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 FEATURE_REMOTING
- : 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 FEATURE_REMOTING
- 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) {
- // TODO:
- #pragma warning disable 618 // obsolete API
- PythonOptions po = (PythonOptions)Microsoft.Scripting.Hosting.Providers.HostingHelpers.CallEngine<object, LanguageOptions>(
- scriptEngine,
- (lc, obj) => lc.Options,
- null
- );
- #pragma warning restore 618
- 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);
- if(System.Environment.OSVersion.Platform == System.PlatformID.Unix) {
- AreEqual(Python.ImportModule(scriptEngine, "posix").GetVariable<int>("F_OK"), 0);
- } else {
- 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);
- if(System.Environment.OSVersion.Platform == System.PlatformID.Unix) {
- AreEqual(Python.ImportModule(runtime, "posix").GetVariable<int>("F_OK"), 0);
- } else {
- AreEqual(Python.ImportModule(runtime, "nt").GetVariable<int>("F_OK"), 0);
- }
- try {
- Python.ImportModule(runtime, "non_existant_module");
- Assert(false);
- } catch (ImportException) {
- }
- }
- #endif
- public class ScopeDynamicObject : DynamicObject {
- internal readonly Dictionary<string, object> _members = new Dictionary<string, object>();
-
- public override bool TryGetMember(GetMemberBinder binder, out object result) {
- return _members.TryGetValue(binder.Name, out result);
- }
- public override bool TrySetMember(SetMemberBinder binder, object value) {
- _members[binder.Name] = value;
- return true;
- }
- public override bool TryDeleteMember(DeleteMemberBinder binder) {
- return _members.Remove(binder.Name);
- }
- }
- public class ScopeDynamicObject2 : ScopeDynamicObject {
- public readonly object __doc__ = null;
- }
- public class ScopeDynamicObject3 : ScopeDynamicObject {
- public object __doc__ {
- get {
- return null;
- }
- }
- }
- public class ScopeDynamicObject4 : ScopeDynamicObject {
- private object _doc;
- public object __doc__ {
- get {
- return _doc;
- }
- set {
- _doc = value;
- }
- }
- }
- public class ScopeDynamicObject5 : ScopeDynamicObject {
- public object __doc__;
- }
- public class ScopeDynamicObject6 : ScopeDynamicObject {
- public void __doc__() {
- }
- }
- public class ScopeDynamicObject7 : ScopeDynamicObject {
- public class __doc__ {
- }
- }
- public class ScopeDynamicObject8 : ScopeDynamicObject {
- #pragma warning disable 67
- public event EventHandler __doc__;
- #pragma warning restore 67
- }
-
- public void ScenarioDynamicObjectAsScope() {
- var engine = Python.CreateEngine();
- // tests where __doc__ gets assigned into the members dictionary
- foreach (var myScope in new ScopeDynamicObject[] { new ScopeDynamicObject(), new ScopeDynamicObject2(), new ScopeDynamicObject3(), new ScopeDynamicObject6(), new ScopeDynamicObject7(), new ScopeDynamicObject8() }) {
- var scope = engine.CreateScope(myScope);
- engine.Execute(@"
- x = 42", scope);
- var source = engine.CreateScriptSourceFromString("x = 42", SourceCodeKind.File);
- source.Compile().Execute(scope);
- AreEqual(myScope._members.ContainsKey("__doc__"), true);
- AreEqual(myScope._members.ContainsKey("x"), true);
- AreEqual(myScope._members.ContainsKey("__file__"), true);
- source = engine.CreateScriptSourceFromString("'hello world'", SourceCodeKind.File);
- source.Compile().Execute(scope);
- AreEqual(myScope._members["__doc__"], "hello world");
- }
- // tests where __doc__ gets assigned into a field/property
- {
- ScopeDynamicObject myScope = new ScopeDynamicObject4();
- var scope = engine.CreateScope(myScope);
- var source = engine.CreateScriptSourceFromString("'hello world'\nx=42\n", SourceCodeKind.File);
- source.Compile().Execute(scope);
- AreEqual(((ScopeDynamicObject4)myScope).__doc__, "hello world");
- myScope = new ScopeDynamicObject5();
- scope = engine.CreateScope(myScope);
- source.Compile().Execute(scope);
- AreEqual(((ScopeDynamicObject5)myScope).__doc__, "hello world");
- }
- }
- #if !SILVERLIGHT
- public void ScenarioCodePlex20472() {
- try {
- string fileName = Path.Combine(Path.Combine(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 void ScenarioInterpreterNestedVariables() {
- #if !NETSTANDARD
- ParameterExpression arg = Expression.Parameter(typeof(object), "tmp");
- var argBody = Expression.Lambda<Func<object, IRuntimeVariables>>(
- Expression.RuntimeVariables(
- arg
- ),
- arg
- );
- var vars = CompilerHelpers.LightCompile(argBody)(42);
- AreEqual(vars[0], 42);
- #endif
- ParameterExpression tmp = Expression.Parameter(typeof(object), "tmp");
- var body = Expression.Lambda<Func<object>>(
- Expression.Block(
- Expression.Block(
- new[] { tmp },
- Expression.Assign(tmp, Expression.Constant(42, typeof(object)))
- ),
- Expression.Block(
- new[] { tmp },
- tmp
- )
- )
- );
- AreEqual(body.Compile()(), null);
- AreEqual(CompilerHelpers.LightCompile(body)(), null);
- body = Expression.Lambda<Func<object>>(
- Expression.Block(
- Expression.Block(
- new[] { tmp },
- Expression.Block(
- Expression.Assign(tmp, Expression.Constant(42, typeof(object))),
- Expression.Block(
- new[] { tmp },
- tmp
- )
- )
- )
- )
- );
- AreEqual(CompilerHelpers.LightCompile(body)(), null);
- AreEqual(body.Compile()(), null);
- }
- public void ScenarioLightExceptions() {
- LightExceptionTests.RunTests();
- }
- 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).GetTypeInfo().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(
- DynamicExpression.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];
- ScriptScope scope = _env.CreateScope();
- ScriptSource src = _pe.CreateScriptSourceFromString(@"
- import clr
- if clr.IsNetStandard:
- clr.AddReference('System.Collections.NonGeneric')
- elif not clr.IsMono:
- clr.AddReference('System.Windows.Forms')
- from System.Windows.Forms import Control
- import System
- from System.Collections import ArrayList
- somecallable = " + actionOfT + @"[object](lambda : 'Delegate')
- if not clr.IsNetStandard and not clr.IsMono:
- 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
- if not clr.IsNetStandard and not clr.IsMono:
- 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 sit…
Large files files are truncated, but you can click here to view the full file