PageRenderTime 61ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/Languages/IronPython/IronPythonTest/EngineTest.cs

http://github.com/IronLanguages/main
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
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Apache License, Version 2.0, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if FEATURE_CORE_DLR
  16. using System.Linq.Expressions;
  17. using System.Numerics;
  18. #else
  19. using Microsoft.Scripting.Ast;
  20. using Microsoft.Scripting.Math;
  21. using Complex = Microsoft.Scripting.Math.Complex64;
  22. #endif
  23. using System;
  24. using System.Collections;
  25. using System.Collections.Generic;
  26. using System.Diagnostics;
  27. using System.Dynamic;
  28. using System.IO;
  29. using System.Reflection;
  30. using System.Runtime.CompilerServices;
  31. using System.Security;
  32. #if FEATURE_REMOTING
  33. using System.Security.Policy;
  34. #endif
  35. using System.Text;
  36. using System.Threading;
  37. #if FEATURE_WPF
  38. using System.Windows.Markup;
  39. #endif
  40. using Microsoft.Scripting;
  41. using Microsoft.Scripting.Generation;
  42. using Microsoft.Scripting.Hosting;
  43. using Microsoft.Scripting.Runtime;
  44. using Microsoft.Scripting.Utils;
  45. using IronPython;
  46. using IronPython.Hosting;
  47. using IronPython.Runtime;
  48. using IronPython.Runtime.Exceptions;
  49. using IronPython.Runtime.Operations;
  50. using IronPython.Runtime.Types;
  51. #if FEATURE_WPF
  52. using DependencyObject = System.Windows.DependencyObject;
  53. #endif
  54. [assembly: ExtensionType(typeof(IronPythonTest.IFooable), typeof(IronPythonTest.FooableExtensions))]
  55. namespace IronPythonTest {
  56. #if !SILVERLIGHT
  57. class Common {
  58. public static string RootDirectory;
  59. public static string RuntimeDirectory;
  60. public static string ScriptTestDirectory;
  61. public static string InputTestDirectory;
  62. static Common() {
  63. RuntimeDirectory = Path.GetDirectoryName(typeof(PythonContext).GetTypeInfo().Assembly.Location);
  64. RootDirectory = Environment.GetEnvironmentVariable("DLR_ROOT");
  65. if (RootDirectory != null) {
  66. ScriptTestDirectory = Path.Combine(Path.Combine(Path.Combine(RootDirectory, "Languages"), "IronPython"), "Tests");
  67. } else {
  68. RootDirectory = new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location).Directory.FullName;
  69. ScriptTestDirectory = Path.Combine(Path.Combine(RootDirectory, "Src"), "Tests");
  70. }
  71. InputTestDirectory = Path.Combine(ScriptTestDirectory, "Inputs");
  72. }
  73. }
  74. #endif
  75. public static class TestHelpers {
  76. public static LanguageContext GetContext(CodeContext context) {
  77. return context.LanguageContext;
  78. }
  79. public static int HashObject(object o) {
  80. return o.GetHashCode();
  81. }
  82. }
  83. public delegate int IntIntDelegate(int arg);
  84. public delegate string RefStrDelegate(ref string arg);
  85. public delegate int RefIntDelegate(ref int arg);
  86. public delegate T GenericDelegate<T, U, V>(U arg1, V arg2);
  87. #if FEATURE_WPF
  88. [ContentProperty("Content")]
  89. public class XamlTestObject : DependencyObject {
  90. public event IntIntDelegate Event;
  91. public int Method(int arg) {
  92. if (Event != null)
  93. return Event(arg);
  94. else
  95. return -1;
  96. }
  97. public object Content {
  98. get;
  99. set;
  100. }
  101. }
  102. [ContentProperty("Content")]
  103. [RuntimeNameProperty("MyName")]
  104. public class InnerXamlTextObject : DependencyObject {
  105. public object Content {
  106. get;
  107. set;
  108. }
  109. public string MyName {
  110. get;
  111. set;
  112. }
  113. }
  114. [ContentProperty("Content")]
  115. [RuntimeNameProperty("Name")]
  116. public class InnerXamlTextObject2 : DependencyObject {
  117. public object Content {
  118. get;
  119. set;
  120. }
  121. public string Name {
  122. get;
  123. set;
  124. }
  125. }
  126. #endif
  127. public class ClsPart {
  128. public int Field;
  129. int m_property;
  130. public int Property { get { return m_property; } set { m_property = value; } }
  131. public event IntIntDelegate Event;
  132. public int Method(int arg) {
  133. if (Event != null)
  134. return Event(arg);
  135. else
  136. return -1;
  137. }
  138. // Private members
  139. #pragma warning disable 169
  140. // This field is accessed from the test
  141. private int privateField;
  142. private int privateProperty { get { return m_property; } set { m_property = value; } }
  143. private event IntIntDelegate privateEvent;
  144. private int privateMethod(int arg) {
  145. if (privateEvent != null)
  146. return privateEvent(arg);
  147. else
  148. return -1;
  149. }
  150. private static int privateStaticMethod() {
  151. return 100;
  152. }
  153. #pragma warning restore 169
  154. }
  155. internal class InternalClsPart {
  156. #pragma warning disable 649
  157. // This field is accessed from the test
  158. internal int Field;
  159. #pragma warning restore 649
  160. int m_property;
  161. internal int Property { get { return m_property; } set { m_property = value; } }
  162. internal event IntIntDelegate Event;
  163. internal int Method(int arg) {
  164. if (Event != null)
  165. return Event(arg);
  166. else
  167. return -1;
  168. }
  169. }
  170. public class EngineTest
  171. #if FEATURE_REMOTING
  172. : MarshalByRefObject
  173. #endif
  174. {
  175. private readonly ScriptEngine _pe;
  176. private readonly ScriptRuntime _env;
  177. public EngineTest() {
  178. // Load a script with all the utility functions that are required
  179. // pe.ExecuteFile(InputTestDirectory + "\\EngineTests.py");
  180. _env = Python.CreateRuntime();
  181. _pe = _env.GetEngine("py");
  182. }
  183. // Used to test exception thrown in another domain can be shown correctly.
  184. public void Run(string script) {
  185. ScriptScope scope = _env.CreateScope();
  186. _pe.CreateScriptSourceFromString(script, SourceCodeKind.File).Execute(scope);
  187. }
  188. static readonly string clspartName = "clsPart";
  189. /// <summary>
  190. /// Asserts an condition it true
  191. /// </summary>
  192. private static void Assert(bool condition, string msg) {
  193. if (!condition) throw new Exception(String.Format("Assertion failed: {0}", msg));
  194. }
  195. private static void Assert(bool condition) {
  196. if (!condition) throw new Exception("Assertion failed");
  197. }
  198. private static T AssertExceptionThrown<T>(Action f) where T : Exception {
  199. try {
  200. f();
  201. } catch (T ex) {
  202. return ex;
  203. }
  204. Assert(false, "Expecting exception '" + typeof(T) + "'.");
  205. return null;
  206. }
  207. #if FEATURE_REMOTING
  208. public void ScenarioHostingHelpers() {
  209. AppDomain remote = AppDomain.CreateDomain("foo");
  210. Dictionary<string, object> options = new Dictionary<string,object>();
  211. // DLR ScriptRuntime options
  212. options["Debug"] = true;
  213. options["PrivateBinding"] = true;
  214. // python options
  215. options["StripDocStrings"] = true;
  216. options["Optimize"] = true;
  217. options["DivisionOptions"] = PythonDivisionOptions.New;
  218. options["RecursionLimit"] = 42;
  219. options["IndentationInconsistencySeverity"] = Severity.Warning;
  220. options["WarningFilters"] = new string[] { "warnonme" };
  221. ScriptEngine engine1 = Python.CreateEngine();
  222. ScriptEngine engine2 = Python.CreateEngine(AppDomain.CurrentDomain);
  223. ScriptEngine engine3 = Python.CreateEngine(remote);
  224. TestEngines(null, new ScriptEngine[] { engine1, engine2, engine3 });
  225. ScriptEngine engine4 = Python.CreateEngine(options);
  226. ScriptEngine engine5 = Python.CreateEngine(AppDomain.CurrentDomain, options);
  227. ScriptEngine engine6 = Python.CreateEngine(remote, options);
  228. TestEngines(options, new ScriptEngine[] { engine4, engine5, engine6 });
  229. ScriptRuntime runtime1 = Python.CreateRuntime();
  230. ScriptRuntime runtime2 = Python.CreateRuntime(AppDomain.CurrentDomain);
  231. ScriptRuntime runtime3 = Python.CreateRuntime(remote);
  232. TestRuntimes(null, new ScriptRuntime[] { runtime1, runtime2, runtime3 });
  233. ScriptRuntime runtime4 = Python.CreateRuntime(options);
  234. ScriptRuntime runtime5 = Python.CreateRuntime(AppDomain.CurrentDomain, options);
  235. ScriptRuntime runtime6 = Python.CreateRuntime(remote, options);
  236. TestRuntimes(options, new ScriptRuntime[] { runtime4, runtime5, runtime6 });
  237. }
  238. private void TestEngines(Dictionary<string, object> options, ScriptEngine[] engines) {
  239. foreach (ScriptEngine engine in engines) {
  240. TestEngine(engine, options);
  241. TestRuntime(engine.Runtime, options);
  242. }
  243. }
  244. private void TestRuntimes(Dictionary<string, object> options, ScriptRuntime[] runtimes) {
  245. foreach (ScriptRuntime runtime in runtimes) {
  246. TestRuntime(runtime, options);
  247. TestEngine(Python.GetEngine(runtime), options);
  248. }
  249. }
  250. private void TestEngine(ScriptEngine scriptEngine, Dictionary<string, object> options) {
  251. // basic smoke tests that the engine is alive and working
  252. AreEqual((int)(object)scriptEngine.Execute("42"), 42);
  253. if(options != null) {
  254. // TODO:
  255. #pragma warning disable 618 // obsolete API
  256. PythonOptions po = (PythonOptions)Microsoft.Scripting.Hosting.Providers.HostingHelpers.CallEngine<object, LanguageOptions>(
  257. scriptEngine,
  258. (lc, obj) => lc.Options,
  259. null
  260. );
  261. #pragma warning restore 618
  262. AreEqual(po.StripDocStrings, true);
  263. AreEqual(po.Optimize, true);
  264. AreEqual(po.DivisionOptions, PythonDivisionOptions.New);
  265. AreEqual(po.RecursionLimit, 42);
  266. AreEqual(po.IndentationInconsistencySeverity, Severity.Warning);
  267. AreEqual(po.WarningFilters[0], "warnonme");
  268. }
  269. AreEqual(Python.GetSysModule(scriptEngine).GetVariable<string>("platform"), "cli");
  270. AreEqual(Python.GetBuiltinModule(scriptEngine).GetVariable<bool>("True"), true);
  271. if(System.Environment.OSVersion.Platform == System.PlatformID.Unix) {
  272. AreEqual(Python.ImportModule(scriptEngine, "posix").GetVariable<int>("F_OK"), 0);
  273. } else {
  274. AreEqual(Python.ImportModule(scriptEngine, "nt").GetVariable<int>("F_OK"), 0);
  275. }
  276. try {
  277. Python.ImportModule(scriptEngine, "non_existant_module");
  278. Assert(false);
  279. } catch (ImportException) {
  280. }
  281. }
  282. private void TestRuntime(ScriptRuntime runtime, Dictionary<string, object> options) {
  283. // basic smoke tests that the runtime is alive and working
  284. runtime.Globals.SetVariable("hello", 42);
  285. Assert(runtime.GetEngine("py") != null);
  286. if (options != null) {
  287. AreEqual(runtime.Setup.DebugMode, true);
  288. AreEqual(runtime.Setup.PrivateBinding, true);
  289. }
  290. AreEqual(Python.GetSysModule(runtime).GetVariable<string>("platform"), "cli");
  291. AreEqual(Python.GetBuiltinModule(runtime).GetVariable<bool>("True"), true);
  292. if(System.Environment.OSVersion.Platform == System.PlatformID.Unix) {
  293. AreEqual(Python.ImportModule(runtime, "posix").GetVariable<int>("F_OK"), 0);
  294. } else {
  295. AreEqual(Python.ImportModule(runtime, "nt").GetVariable<int>("F_OK"), 0);
  296. }
  297. try {
  298. Python.ImportModule(runtime, "non_existant_module");
  299. Assert(false);
  300. } catch (ImportException) {
  301. }
  302. }
  303. #endif
  304. public class ScopeDynamicObject : DynamicObject {
  305. internal readonly Dictionary<string, object> _members = new Dictionary<string, object>();
  306. public override bool TryGetMember(GetMemberBinder binder, out object result) {
  307. return _members.TryGetValue(binder.Name, out result);
  308. }
  309. public override bool TrySetMember(SetMemberBinder binder, object value) {
  310. _members[binder.Name] = value;
  311. return true;
  312. }
  313. public override bool TryDeleteMember(DeleteMemberBinder binder) {
  314. return _members.Remove(binder.Name);
  315. }
  316. }
  317. public class ScopeDynamicObject2 : ScopeDynamicObject {
  318. public readonly object __doc__ = null;
  319. }
  320. public class ScopeDynamicObject3 : ScopeDynamicObject {
  321. public object __doc__ {
  322. get {
  323. return null;
  324. }
  325. }
  326. }
  327. public class ScopeDynamicObject4 : ScopeDynamicObject {
  328. private object _doc;
  329. public object __doc__ {
  330. get {
  331. return _doc;
  332. }
  333. set {
  334. _doc = value;
  335. }
  336. }
  337. }
  338. public class ScopeDynamicObject5 : ScopeDynamicObject {
  339. public object __doc__;
  340. }
  341. public class ScopeDynamicObject6 : ScopeDynamicObject {
  342. public void __doc__() {
  343. }
  344. }
  345. public class ScopeDynamicObject7 : ScopeDynamicObject {
  346. public class __doc__ {
  347. }
  348. }
  349. public class ScopeDynamicObject8 : ScopeDynamicObject {
  350. #pragma warning disable 67
  351. public event EventHandler __doc__;
  352. #pragma warning restore 67
  353. }
  354. public void ScenarioDynamicObjectAsScope() {
  355. var engine = Python.CreateEngine();
  356. // tests where __doc__ gets assigned into the members dictionary
  357. foreach (var myScope in new ScopeDynamicObject[] { new ScopeDynamicObject(), new ScopeDynamicObject2(), new ScopeDynamicObject3(), new ScopeDynamicObject6(), new ScopeDynamicObject7(), new ScopeDynamicObject8() }) {
  358. var scope = engine.CreateScope(myScope);
  359. engine.Execute(@"
  360. x = 42", scope);
  361. var source = engine.CreateScriptSourceFromString("x = 42", SourceCodeKind.File);
  362. source.Compile().Execute(scope);
  363. AreEqual(myScope._members.ContainsKey("__doc__"), true);
  364. AreEqual(myScope._members.ContainsKey("x"), true);
  365. AreEqual(myScope._members.ContainsKey("__file__"), true);
  366. source = engine.CreateScriptSourceFromString("'hello world'", SourceCodeKind.File);
  367. source.Compile().Execute(scope);
  368. AreEqual(myScope._members["__doc__"], "hello world");
  369. }
  370. // tests where __doc__ gets assigned into a field/property
  371. {
  372. ScopeDynamicObject myScope = new ScopeDynamicObject4();
  373. var scope = engine.CreateScope(myScope);
  374. var source = engine.CreateScriptSourceFromString("'hello world'\nx=42\n", SourceCodeKind.File);
  375. source.Compile().Execute(scope);
  376. AreEqual(((ScopeDynamicObject4)myScope).__doc__, "hello world");
  377. myScope = new ScopeDynamicObject5();
  378. scope = engine.CreateScope(myScope);
  379. source.Compile().Execute(scope);
  380. AreEqual(((ScopeDynamicObject5)myScope).__doc__, "hello world");
  381. }
  382. }
  383. #if !SILVERLIGHT
  384. public void ScenarioCodePlex20472() {
  385. try {
  386. string fileName = Path.Combine(Path.Combine(System.IO.Directory.GetCurrentDirectory(), "encoded_files"), "cp20472.py");
  387. _pe.CreateScriptSourceFromFile(fileName, System.Text.Encoding.GetEncoding(1251));
  388. //Disabled. The line above should have thrown a syntax exception or an import error,
  389. //but does not.
  390. //throw new Exception("ScenarioCodePlex20472");
  391. }
  392. catch (IronPython.Runtime.Exceptions.ImportException) { }
  393. }
  394. #endif
  395. public void ScenarioInterpreterNestedVariables() {
  396. #if !NETSTANDARD
  397. ParameterExpression arg = Expression.Parameter(typeof(object), "tmp");
  398. var argBody = Expression.Lambda<Func<object, IRuntimeVariables>>(
  399. Expression.RuntimeVariables(
  400. arg
  401. ),
  402. arg
  403. );
  404. var vars = CompilerHelpers.LightCompile(argBody)(42);
  405. AreEqual(vars[0], 42);
  406. #endif
  407. ParameterExpression tmp = Expression.Parameter(typeof(object), "tmp");
  408. var body = Expression.Lambda<Func<object>>(
  409. Expression.Block(
  410. Expression.Block(
  411. new[] { tmp },
  412. Expression.Assign(tmp, Expression.Constant(42, typeof(object)))
  413. ),
  414. Expression.Block(
  415. new[] { tmp },
  416. tmp
  417. )
  418. )
  419. );
  420. AreEqual(body.Compile()(), null);
  421. AreEqual(CompilerHelpers.LightCompile(body)(), null);
  422. body = Expression.Lambda<Func<object>>(
  423. Expression.Block(
  424. Expression.Block(
  425. new[] { tmp },
  426. Expression.Block(
  427. Expression.Assign(tmp, Expression.Constant(42, typeof(object))),
  428. Expression.Block(
  429. new[] { tmp },
  430. tmp
  431. )
  432. )
  433. )
  434. )
  435. );
  436. AreEqual(CompilerHelpers.LightCompile(body)(), null);
  437. AreEqual(body.Compile()(), null);
  438. }
  439. public void ScenarioLightExceptions() {
  440. LightExceptionTests.RunTests();
  441. }
  442. public class TestCodePlex23562 {
  443. public bool MethodCalled = false;
  444. public TestCodePlex23562() {
  445. }
  446. public void TestMethod() {
  447. MethodCalled = true;
  448. }
  449. }
  450. public void ScenarioCodePlex23562()
  451. {
  452. string pyCode = @"
  453. test = TestCodePlex23562()
  454. test.TestMethod()
  455. ";
  456. var scope = _pe.CreateScope();
  457. scope.SetVariable("TestCodePlex23562", typeof(TestCodePlex23562));
  458. _pe.Execute(pyCode, scope);
  459. TestCodePlex23562 temp = scope.GetVariable<TestCodePlex23562>("test");
  460. Assert(temp.MethodCalled);
  461. }
  462. public void ScenarioCodePlex18595() {
  463. string pyCode = @"
  464. str_tuple = ('ab', 'cd')
  465. str_list = ['abc', 'def', 'xyz']
  466. py_func_called = False
  467. def py_func():
  468. global py_func_called
  469. py_func_called = True
  470. ";
  471. var scope = _pe.CreateScope();
  472. _pe.Execute(pyCode, scope);
  473. IList<string> str_tuple = scope.GetVariable<IList<string>>("str_tuple");
  474. AreEqual<int>(str_tuple.Count, 2);
  475. IList<string> str_list = scope.GetVariable<IList<string>>("str_list");
  476. AreEqual<int>(str_list.Count, 3);
  477. VoidDelegate py_func = scope.GetVariable<VoidDelegate>("py_func");
  478. py_func();
  479. AreEqual<bool>(scope.GetVariable<bool>("py_func_called"), true);
  480. }
  481. public void ScenarioCodePlex24077()
  482. {
  483. string pyCode = @"
  484. class K(object):
  485. def __init__(self, a, b, c):
  486. global A, B, C
  487. A = a
  488. B = b
  489. C = c
  490. ";
  491. var scope = _pe.CreateScope();
  492. _pe.Execute(pyCode, scope);
  493. object KKlass = scope.GetVariable("K");
  494. object[] Kparams = new object[] { 1, 3.14, "abc"};
  495. _pe.Operations.CreateInstance(KKlass, Kparams);
  496. AreEqual<int>(scope.GetVariable<int>("A"), 1);
  497. }
  498. // Execute
  499. public void ScenarioExecute() {
  500. ClsPart clsPart = new ClsPart();
  501. ScriptScope scope = _env.CreateScope();
  502. scope.SetVariable(clspartName, clsPart);
  503. // field: assign and get back
  504. _pe.Execute("clsPart.Field = 100", scope);
  505. _pe.Execute("if 100 != clsPart.Field: raise AssertionError('test failed')", scope);
  506. AreEqual(100, clsPart.Field);
  507. // property: assign and get back
  508. _pe.Execute("clsPart.Property = clsPart.Field", scope);
  509. _pe.Execute("if 100 != clsPart.Property: raise AssertionError('test failed')", scope);
  510. AreEqual(100, clsPart.Property);
  511. // method: Event not set yet
  512. _pe.Execute("a = clsPart.Method(2)", scope);
  513. _pe.Execute("if -1 != a: raise AssertionError('test failed')", scope);
  514. // method: add python func as event handler
  515. _pe.Execute("def f(x) : return x * x", scope);
  516. _pe.Execute("clsPart.Event += f", scope);
  517. _pe.Execute("a = clsPart.Method(2)", scope);
  518. _pe.Execute("if 4 != a: raise AssertionError('test failed')", scope);
  519. // ===============================================
  520. // reset the same variable with instance of the same type
  521. scope.SetVariable(clspartName, new ClsPart());
  522. _pe.Execute("if 0 != clsPart.Field: raise AssertionError('test failed')", scope);
  523. // add cls method as event handler
  524. scope.SetVariable("clsMethod", new IntIntDelegate(Negate));
  525. _pe.Execute("clsPart.Event += clsMethod", scope);
  526. _pe.Execute("a = clsPart.Method(2)", scope);
  527. _pe.Execute("if -2 != a: raise AssertionError('test failed')", scope);
  528. // ===============================================
  529. // reset the same variable with integer
  530. scope.SetVariable(clspartName, 1);
  531. _pe.Execute("if 1 != clsPart: raise AssertionError('test failed')", scope);
  532. AreEqual((int)(object)scope.GetVariable(clspartName), 1);
  533. ScriptSource su = _pe.CreateScriptSourceFromString("");
  534. AssertExceptionThrown<ArgumentNullException>(delegate() {
  535. su.Execute(null);
  536. });
  537. }
  538. public static void ScenarioTryGetMember() {
  539. var engine = Python.CreateEngine();
  540. var str = ClrModule.GetPythonType(typeof(string));
  541. object result;
  542. AreEqual(engine.Operations.TryGetMember(str, "Equals", out result), true);
  543. AreEqual(result.ToString(), "IronPython.Runtime.Types.BuiltinFunction");
  544. }
  545. public static void ScenarioInterfaceExtensions() {
  546. var engine = Python.CreateEngine();
  547. engine.Runtime.LoadAssembly(typeof(Fooable).GetTypeInfo().Assembly);
  548. ScriptSource src = engine.CreateScriptSourceFromString("x.Bar()");
  549. ScriptScope scope = engine.CreateScope();
  550. scope.SetVariable("x", new Fooable());
  551. AreEqual((object)src.Execute(scope), "Bar Called");
  552. }
  553. class MyInvokeMemberBinder : InvokeMemberBinder {
  554. public MyInvokeMemberBinder(string name, CallInfo callInfo)
  555. : base(name, false, callInfo) {
  556. }
  557. public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
  558. return errorSuggestion ?? new DynamicMetaObject(
  559. Expression.Constant("FallbackInvokeMember"),
  560. target.Restrictions.Merge(BindingRestrictions.Combine(args)).Merge(target.Restrict(target.LimitType).Restrictions)
  561. );
  562. }
  563. public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
  564. return new DynamicMetaObject(
  565. DynamicExpression.Dynamic(new MyInvokeBinder(CallInfo), typeof(object), DynamicUtils.GetExpressions(ArrayUtils.Insert(target, args))),
  566. target.Restrictions.Merge(BindingRestrictions.Combine(args))
  567. );
  568. }
  569. }
  570. class MyInvokeBinder : InvokeBinder {
  571. public MyInvokeBinder(CallInfo callInfo)
  572. : base(callInfo) {
  573. }
  574. public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
  575. return new DynamicMetaObject(
  576. Expression.Call(
  577. typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object) }),
  578. Expression.Constant("FallbackInvoke"),
  579. target.Expression
  580. ),
  581. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  582. );
  583. }
  584. }
  585. class MyGetIndexBinder : GetIndexBinder {
  586. public MyGetIndexBinder(CallInfo args)
  587. : base(args) {
  588. }
  589. public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion) {
  590. return new DynamicMetaObject(
  591. Expression.Call(
  592. typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object) }),
  593. Expression.Constant("FallbackGetIndex"),
  594. indexes[0].Expression
  595. ),
  596. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  597. );
  598. }
  599. }
  600. class MySetIndexBinder : SetIndexBinder {
  601. public MySetIndexBinder(CallInfo args)
  602. : base(args) {
  603. }
  604. public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion) {
  605. return new DynamicMetaObject(
  606. Expression.Call(
  607. typeof(String).GetMethod("Concat", new Type[] { typeof(object), typeof(object), typeof(object) }),
  608. Expression.Constant("FallbackSetIndex"),
  609. indexes[0].Expression,
  610. value.Expression
  611. ),
  612. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  613. );
  614. }
  615. }
  616. class MyGetMemberBinder : GetMemberBinder {
  617. public MyGetMemberBinder(string name)
  618. : base(name, false) {
  619. }
  620. public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
  621. return new DynamicMetaObject(
  622. Expression.Constant("FallbackGetMember"),
  623. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  624. );
  625. }
  626. }
  627. class MyInvokeBinder2 : InvokeBinder {
  628. public MyInvokeBinder2(CallInfo args)
  629. : base(args) {
  630. }
  631. public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
  632. Expression[] exprs = new Expression[args.Length + 1];
  633. exprs[0] = Expression.Constant("FallbackInvoke");
  634. for (int i = 0; i < args.Length; i++) {
  635. exprs[i + 1] = args[i].Expression;
  636. }
  637. return new DynamicMetaObject(
  638. Expression.Call(
  639. typeof(String).GetMethod("Concat", new Type[] { typeof(object[]) }),
  640. Expression.NewArrayInit(
  641. typeof(object),
  642. exprs
  643. )
  644. ),
  645. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  646. );
  647. }
  648. }
  649. class MyConvertBinder : ConvertBinder {
  650. private object _result;
  651. public MyConvertBinder(Type type) : this(type, "Converted") {
  652. }
  653. public MyConvertBinder(Type type, object result)
  654. : base(type, true) {
  655. _result = result;
  656. }
  657. public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
  658. return new DynamicMetaObject(
  659. Expression.Constant(_result),
  660. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  661. );
  662. }
  663. }
  664. class MyUnaryBinder : UnaryOperationBinder {
  665. public MyUnaryBinder(ExpressionType et)
  666. : base(et) {
  667. }
  668. public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
  669. return new DynamicMetaObject(
  670. Expression.Constant("UnaryFallback"),
  671. BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
  672. );
  673. }
  674. }
  675. private void TestTarget(object sender, EventArgs args) {
  676. }
  677. #if !SILVERLIGHT
  678. public void ScenarioDocumentation() {
  679. ScriptScope scope = _pe.CreateScope();
  680. ScriptSource src = _pe.CreateScriptSourceFromString(@"
  681. import System
  682. import clr
  683. def f0(a, b): pass
  684. def f1(a, *b): pass
  685. def f2(a, **b): pass
  686. def f3(a, *b, **c): pass
  687. class C:
  688. m0 = f0
  689. m1 = f1
  690. m2 = f2
  691. m3 = f3
  692. def __init__(self):
  693. self.foo = 42
  694. class SC(C): pass
  695. inst = C()
  696. class NC(object):
  697. m0 = f0
  698. m1 = f1
  699. m2 = f2
  700. m3 = f3
  701. def __init__(self):
  702. self.foo = 42
  703. class SNC(NC): pass
  704. ncinst = C()
  705. class EmptyNC(object): pass
  706. enc = EmptyNC()
  707. m0 = C.m0
  708. m1 = C.m1
  709. m2 = C.m2
  710. m3 = C.m3
  711. z = zip
  712. i = int
  713. ", SourceCodeKind.File);
  714. var doc = _pe.GetService<DocumentationOperations>();
  715. src.Execute(scope);
  716. scope.SetVariable("dlg", new EventHandler(TestTarget));
  717. object f0 = scope.GetVariable("f0");
  718. object f1 = scope.GetVariable("f1");
  719. object f2 = scope.GetVariable("f2");
  720. object f3 = scope.GetVariable("f3");
  721. object zip = scope.GetVariable("z");
  722. object dlg = scope.GetVariable("dlg");
  723. object m0 = scope.GetVariable("m0");
  724. object m1 = scope.GetVariable("m1");
  725. object m2 = scope.GetVariable("m2");
  726. object m3 = scope.GetVariable("m3");
  727. var tests = new [] {
  728. new {
  729. Obj=f0,
  730. Result = new [] {
  731. new[] {
  732. new { ParamName="a", ParamAttrs = ParameterFlags.None },
  733. new { ParamName="b", ParamAttrs = ParameterFlags.None }
  734. }
  735. }
  736. },
  737. new {
  738. Obj=f1,
  739. Result = new [] {
  740. new[] {
  741. new { ParamName="a", ParamAttrs = ParameterFlags.None },
  742. new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray }
  743. }
  744. }
  745. },
  746. new {
  747. Obj=f2,
  748. Result = new [] {
  749. new[] {
  750. new { ParamName="a", ParamAttrs = ParameterFlags.None },
  751. new { ParamName="b", ParamAttrs = ParameterFlags.ParamsDict}
  752. }
  753. }
  754. },
  755. new {
  756. Obj=f3,
  757. Result = new [] {
  758. new [] {
  759. new { ParamName="a", ParamAttrs = ParameterFlags.None},
  760. new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray},
  761. new { ParamName="c", ParamAttrs = ParameterFlags.ParamsDict}
  762. }
  763. }
  764. },
  765. new {
  766. Obj = zip,
  767. Result = new [] {
  768. new [] {
  769. new { ParamName="s0", ParamAttrs = ParameterFlags.None },
  770. new { ParamName="s1", ParamAttrs = ParameterFlags.None },
  771. },
  772. new [] {
  773. new { ParamName="seqs", ParamAttrs = ParameterFlags.ParamsArray },
  774. }
  775. }
  776. },
  777. new {
  778. Obj=dlg,
  779. Result = new [] {
  780. new [] {
  781. new { ParamName="sender", ParamAttrs = ParameterFlags.None},
  782. new { ParamName="e", ParamAttrs = ParameterFlags.None},
  783. }
  784. }
  785. },
  786. new {
  787. Obj=m0,
  788. Result = new [] {
  789. new[] {
  790. new { ParamName="a", ParamAttrs = ParameterFlags.None },
  791. new { ParamName="b", ParamAttrs = ParameterFlags.None }
  792. }
  793. }
  794. },
  795. new {
  796. Obj=m1,
  797. Result = new [] {
  798. new[] {
  799. new { ParamName="a", ParamAttrs = ParameterFlags.None },
  800. new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray }
  801. }
  802. }
  803. },
  804. new {
  805. Obj=m2,
  806. Result = new [] {
  807. new[] {
  808. new { ParamName="a", ParamAttrs = ParameterFlags.None },
  809. new { ParamName="b", ParamAttrs = ParameterFlags.ParamsDict}
  810. }
  811. }
  812. },
  813. new {
  814. Obj=m3,
  815. Result = new [] {
  816. new [] {
  817. new { ParamName="a", ParamAttrs = ParameterFlags.None},
  818. new { ParamName="b", ParamAttrs = ParameterFlags.ParamsArray},
  819. new { ParamName="c", ParamAttrs = ParameterFlags.ParamsDict}
  820. }
  821. }
  822. },
  823. };
  824. foreach (var test in tests) {
  825. var result = new List<OverloadDoc>(doc.GetOverloads(test.Obj));
  826. AreEqual(result.Count, test.Result.Length);
  827. for (int i = 0; i < result.Count; i++) {
  828. var received = result[i]; ;
  829. var expected = test.Result[i];
  830. AreEqual(received.Parameters.Count, expected.Length);
  831. var recvParams = new List<ParameterDoc>(received.Parameters);
  832. for (int j = 0; j < expected.Length; j++) {
  833. var receivedParam = recvParams[j];
  834. var expectedParam = expected[j];
  835. AreEqual(receivedParam.Flags, expectedParam.ParamAttrs);
  836. AreEqual(receivedParam.Name, expectedParam.ParamName);
  837. }
  838. }
  839. }
  840. object inst = scope.GetVariable("inst");
  841. object ncinst = scope.GetVariable("ncinst");
  842. object klass = scope.GetVariable("C");
  843. object newklass = scope.GetVariable("NC");
  844. object subklass = scope.GetVariable("SC");
  845. object subnewklass = scope.GetVariable("SNC");
  846. object System = scope.GetVariable("System");
  847. object clr = scope.GetVariable("clr");
  848. foreach (object o in new[] { inst, ncinst }) {
  849. var members = doc.GetMembers(o);
  850. ContainsMemberName(members, "m0", MemberKind.Method);
  851. ContainsMemberName(members, "foo", MemberKind.None);
  852. }
  853. ContainsMemberName(doc.GetMembers(klass), "m0", MemberKind.Method);
  854. ContainsMemberName(doc.GetMembers(newklass), "m0", MemberKind.Method);
  855. ContainsMemberName(doc.GetMembers(subklass), "m0", MemberKind.Method);
  856. ContainsMemberName(doc.GetMembers(subnewklass), "m0", MemberKind.Method);
  857. ContainsMemberName(doc.GetMembers(System), "Collections", MemberKind.Namespace);
  858. ContainsMemberName(doc.GetMembers(clr), "AddReference", MemberKind.Function);
  859. object intType = scope.GetVariable("i");
  860. foreach (object o in new object[] { intType, 42 }) {
  861. var members = doc.GetMembers(o);
  862. ContainsMemberName(members, "__add__", MemberKind.Method);
  863. ContainsMemberName(members, "conjugate", MemberKind.Method);
  864. ContainsMemberName(members, "real", MemberKind.Property);
  865. }
  866. ContainsMemberName(doc.GetMembers(new List<object>()), "Count", MemberKind.Property);
  867. ContainsMemberName(doc.GetMembers(DynamicHelpers.GetPythonTypeFromType(typeof(DateTime))), "MaxValue", MemberKind.Field);
  868. doc.GetMembers(scope.GetVariable("enc"));
  869. }
  870. #endif
  871. private void ContainsMemberName(ICollection<MemberDoc> members, string name, MemberKind kind) {
  872. foreach (var member in members) {
  873. if (member.Name == name) {
  874. AreEqual(member.Kind, kind);
  875. return;
  876. }
  877. }
  878. Assert(false, "didn't find member " + name);
  879. }
  880. public void ScenarioDlrInterop() {
  881. string actionOfT = typeof(Action<>).FullName.Split('`')[0];
  882. ScriptScope scope = _env.CreateScope();
  883. ScriptSource src = _pe.CreateScriptSourceFromString(@"
  884. import clr
  885. if clr.IsNetStandard:
  886. clr.AddReference('System.Collections.NonGeneric')
  887. elif not clr.IsMono:
  888. clr.AddReference('System.Windows.Forms')
  889. from System.Windows.Forms import Control
  890. import System
  891. from System.Collections import ArrayList
  892. somecallable = " + actionOfT + @"[object](lambda : 'Delegate')
  893. if not clr.IsNetStandard and not clr.IsMono:
  894. class control(Control):
  895. pass
  896. class control_setattr(Control):
  897. def __init__(self):
  898. object.__setattr__(self, 'lastset', None)
  899. def __setattr__(self, name, value):
  900. object.__setattr__(self, 'lastset', (name, value))
  901. class control_override_prop(Control):
  902. def __setattr__(self, name, value):
  903. pass
  904. def get_AllowDrop(self):
  905. return 'abc'
  906. def set_AllowDrop(self, value):
  907. super(control_setattr, self).AllowDrop.SetValue(value)
  908. class ns(object):
  909. ClassVal = 'ClassVal'
  910. def __init__(self):
  911. self.InstVal = 'InstVal'
  912. self.InstCallable = somecallable
  913. self.LastSetItem = None
  914. def __add__(self, other):
  915. return 'add' + str(other)
  916. def TestFunc(self):
  917. return 'TestFunc'
  918. def ToString(self):
  919. return 'MyToString'
  920. def NsMethod(self, *args, **kwargs):
  921. return args, kwargs
  922. @staticmethod
  923. def StaticMethod():
  924. return 'Static'
  925. @classmethod
  926. def StaticMethod(cls):
  927. return cls
  928. def __call__(self, *args, **kwargs):
  929. return args, kwargs
  930. def __int__(self): return 42
  931. def __float__(self): return 42.0
  932. def __str__(self): return 'Python'
  933. def __long__(self): return 42L
  934. def __complex__(self): return 42j
  935. def __nonzero__(self): return False
  936. def __getitem__(self, index):
  937. return index
  938. def __setitem__(self, index, value):
  939. self.LastSetItem = (index, value)
  940. SomeDelegate = somecallable
  941. class ns_getattr(object):
  942. ClassVal = 'ClassVal'
  943. def __init__(self):
  944. self.InstVal = 'InstVal'
  945. def TestFunc(self):
  946. return 'TestFunc'
  947. def __getattr__(self, name):
  948. if name == 'SomeDelegate':
  949. return somecallable
  950. elif name == 'something':
  951. return 'getattrsomething'
  952. return name
  953. class ns_getattribute(object):
  954. ClassVal = 'ClassVal'
  955. def __init__(self):
  956. self.InstVal = 'InstVal'
  957. def TestFunc(self):
  958. return 'TestFunc'
  959. def __getattribute__(self, name):
  960. if name == 'SomeDelegate':
  961. return somecallable
  962. return name
  963. class MyArrayList(ArrayList):
  964. ClassVal = 'ClassVal'
  965. def __init__(self):
  966. self.InstVal = 'InstVal'
  967. def TestFunc(self):
  968. return 'TestFunc'
  969. class MyArrayList_getattr(ArrayList):
  970. ClassVal = 'ClassVal'
  971. def __init__(self):
  972. self.InstVal = 'InstVal'
  973. def TestFunc(self):
  974. return 'TestFunc'
  975. def __getattr__(self, name):
  976. return name
  977. class MyArrayList_getattribute(ArrayList):
  978. ClassVal = 'ClassVal'
  979. def __init__(self):
  980. self.InstVal = 'InstVal'
  981. def TestFunc(self):
  982. return 'TestFunc'
  983. def __getattribute__(self, name):
  984. return name
  985. class IterableObject(object):
  986. def __iter__(self):
  987. yield 1
  988. yield 2
  989. yield 3
  990. class IterableObjectOs:
  991. def __iter__(self):
  992. yield 1
  993. yield 2
  994. yield 3
  995. class os:
  996. ClassVal = 'ClassVal'
  997. def __init__(self):
  998. self.InstVal = 'InstVal'
  999. self.InstCallable = somecallable
  1000. self.LastSetItem = None
  1001. def TestFunc(self):
  1002. return 'TestFunc'
  1003. def __call__(self, *args, **kwargs):
  1004. return args, kwargs
  1005. def __int__(self): return 42
  1006. def __float__(self): return 42.0
  1007. def __str__(self): return 'Python'
  1008. def __long__(self): return 42L
  1009. def __nonzero__(self): return False
  1010. def __complex__(self): return 42j
  1011. def __getitem__(self, index):
  1012. return index
  1013. def __setitem__(self, index, value):
  1014. self.LastSetItem = (index, value)
  1015. SomeDelegate = somecallable
  1016. class plain_os:
  1017. pass
  1018. class plain_ns(object): pass
  1019. class os_getattr:
  1020. ClassVal = 'ClassVal'
  1021. def __init__(self):
  1022. self.InstVal = 'InstVal'
  1023. def __getattr__(self, name):
  1024. if name == 'SomeDelegate':
  1025. return somecallable
  1026. return name
  1027. def TestFunc(self):
  1028. return 'TestFunc'
  1029. class ns_nonzero(object):
  1030. def __nonzero__(self):
  1031. return True
  1032. ns_nonzero_inst = ns_nonzero()
  1033. class ns_len1(object):
  1034. def __len__(self): return 1
  1035. ns_len1_inst = ns_len1()
  1036. class ns_len0(object):
  1037. def __len__(self): return 0
  1038. ns_len0_inst = ns_len0()
  1039. def TestFunc():
  1040. return 'TestFunc'
  1041. TestFunc.SubFunc = TestFunc
  1042. def Invokable(*args, **kwargs):
  1043. return args, kwargs
  1044. TestFunc.TestFunc = TestFunc
  1045. TestFunc.InstVal = 'InstVal'
  1046. TestFunc.ClassVal = 'ClassVal' # just here to simplify tests
  1047. if not clr.IsNetStandard and not clr.IsMono:
  1048. controlinst = control()
  1049. nsinst = ns()
  1050. iterable = IterableObject()
  1051. iterableos = IterableObjectOs()
  1052. plainnsinst = plain_ns()
  1053. nsmethod = nsinst.NsMethod
  1054. alinst = MyArrayList()
  1055. osinst = os()
  1056. plainosinst = plain_os()
  1057. os_getattrinst = os_getattr()
  1058. ns_getattrinst = ns_getattr()
  1059. al_getattrinst = MyArrayList_getattr()
  1060. ns_getattributeinst = ns_getattribute()
  1061. al_getattributeinst = MyArrayList_getattribute()
  1062. xrange = xrange
  1063. ", SourceCodeKind.Statements);
  1064. src.Execute(scope);
  1065. // InvokeMember tests
  1066. var allObjects = new object[] { scope.GetVariable("nsinst"), scope.GetVariable("osinst"), scope.GetVariable("alinst"), scope.GetVariable("TestFunc") };
  1067. var getattrObjects = new object[] { scope.GetVariable("ns_getattrinst"), scope.GetVariable("os_getattrinst"), scope.GetVariable("al_getattrinst") };
  1068. var getattributeObjects = new object[] { scope.GetVariable("ns_getattributeinst"), scope.GetVariable("al_getattributeinst") };
  1069. var indexableObjects = new object[] { scope.GetVariable("nsinst"), scope.GetVariable("osinst") };
  1070. var unindexableObjects = new object[] { scope.GetVariable("TestFunc"), scope.GetVariable("ns_getattrinst"), scope.GetVariable("somecallable") }; // scope.GetVariable("plainosinst"),
  1071. var invokableObjects = new object[] { scope.GetVariable("Invokable"), scope.GetVariable("nsinst"), scope.GetVariable("osinst"), scope.GetVariable("nsmethod"), };
  1072. var convertableObjects = new object[] { scope.GetVariable("nsinst"), scope.GetVariable("osinst") };
  1073. var unconvertableObjects = new object[] { scope.GetVariable("plainnsinst"), scope.GetVariable("plainosinst") };
  1074. var iterableObjects = new object[] { scope.GetVariable("iterable"), scope.GetVariable("iterableos") };
  1075. // if it lives on a system type we should do a fallback invoke member
  1076. var site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("Count", new CallInfo(0)));
  1077. AreEqual(site.Target(site, (object)scope.GetVariable("alinst")), "FallbackInvokeMember");
  1078. // invoke a function that's a member on an object
  1079. foreach (object inst in allObjects) {
  1080. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("TestFunc", new CallInfo(0)));
  1081. AreEqual(site.Target(site, inst), "TestFunc");
  1082. }
  1083. // invoke a field / property that's on an object
  1084. foreach (object inst in allObjects) {
  1085. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("InstVal", new CallInfo(0)));
  1086. AreEqual(site.Target(site, inst), "FallbackInvokeInstVal");
  1087. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("ClassVal", new CallInfo(0)));
  1088. AreEqual(site.Target(site, inst), "FallbackInvokeClassVal");
  1089. if (!(inst is PythonFunction)) {
  1090. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("SomeMethodThatNeverExists", new CallInfo(0)));
  1091. AreEqual(site.Target(site, inst), "FallbackInvokeMember");
  1092. }
  1093. }
  1094. // invoke a field / property that's not defined on objects w/ __getattr__
  1095. foreach (object inst in getattrObjects) {
  1096. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0)));
  1097. AreEqual(site.Target(site, inst), "FallbackInvokeDoesNotExist");
  1098. }
  1099. // invoke a field / property that's not defined on objects w/ __getattribute__
  1100. foreach (object inst in getattributeObjects) {
  1101. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0)));
  1102. AreEqual(site.Target(site, inst), "FallbackInvokeDoesNotExist");
  1103. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("Count", new CallInfo(0)));
  1104. AreEqual(site.Target(site, inst), "FallbackInvokeCount");
  1105. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("TestFunc", new CallInfo(0)));
  1106. AreEqual(site.Target(site, inst), "FallbackInvokeTestFunc");
  1107. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("InstVal", new CallInfo(0)));
  1108. AreEqual(site.Target(site, inst), "FallbackInvokeInstVal");
  1109. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("ClassVal", new CallInfo(0)));
  1110. AreEqual(site.Target(site, inst), "FallbackInvokeClassVal");
  1111. }
  1112. foreach (object inst in indexableObjects) {
  1113. var site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyGetIndexBinder(new CallInfo(1)));
  1114. AreEqual(site2.Target(site2, inst, "index"), "index");
  1115. var site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MySetIndexBinder(new CallInfo(1)));
  1116. AreEqual(site3.Target(site3, inst, "index", "value"), "value");
  1117. site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("LastSetItem"));
  1118. IList<object> res = (IList<object>)site.Target(site, inst);
  1119. AreEqual(res.Count, 2);
  1120. AreEqual(res[0], "index");
  1121. AreEqual(res[1], "value");
  1122. }
  1123. foreach (object inst in unindexableObjects) {
  1124. var site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyGetIndexBinder(new CallInfo(1)));
  1125. //Console.WriteLine(inst);
  1126. AreEqual(site2.Target(site2, inst, "index"), "FallbackGetIndexindex");
  1127. var site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MySetIndexBinder(new CallInfo(1)));
  1128. AreEqual(site3.Target(site3, inst, "index", "value"), "FallbackSetIndexindexvalue");
  1129. }
  1130. foreach (object inst in invokableObjects) {
  1131. var site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(1)));
  1132. VerifyFunction(new[] { "foo"}, new string[0], site2.Target(site2, inst, "foo"));
  1133. site2 = CallSite<Func<CallSite, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(1, "bar")));
  1134. VerifyFunction(new[] { "foo" }, new[] { "bar" }, site2.Target(site2, inst, "foo"));
  1135. var site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(2)));
  1136. VerifyFunction(new[] { "foo", "bar" }, new string[0], site3.Target(site3, inst, "foo", "bar"));
  1137. site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(2, "bar")));
  1138. VerifyFunction(new[] { "foo", "bar" }, new[] { "bar" }, site3.Target(site3, inst, "foo", "bar"));
  1139. site3 = CallSite<Func<CallSite, object, object, object, object>>.Create(new MyInvokeBinder2(new CallInfo(2, "foo", "bar")));
  1140. VerifyFunction(new[] { "foo", "bar" }, new[] { "foo", "bar" }, site3.Target(site3, inst, "foo", "bar"));
  1141. }
  1142. foreach (object inst in convertableObjects) {
  1143. // These may be invalid according to the DLR (wrong ret type) but currently work today.
  1144. site = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(string)));
  1145. AreEqual(site.Target(site, inst), "Python");
  1146. var dlgsiteo = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(Func<object, object>), null));
  1147. VerifyFunction(new[] { "foo" }, new string[0], ((Func<object, object>)(dlgsiteo.Target(dlgsiteo, inst)))("foo"));
  1148. var dlgsite2o = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(Func<object, object, object>), null));
  1149. VerifyFunction(new[] { "foo", "bar" }, new string[0], ((Func<object, object, object>)dlgsite2o.Target(dlgsite2o, inst))("foo", "bar"));
  1150. // strongly typed return versions
  1151. var ssite = CallSite<Func<CallSite, object, string>>.Create(new MyConvertBinder(typeof(string)));
  1152. AreEqual(ssite.Target(ssite, inst), "Python");
  1153. var isite = CallSite<Func<CallSite, object, int>>.Create(new MyConvertBinder(typeof(int), 23));
  1154. AreEqual(isite.Target(isite, inst), 42);
  1155. var dsite = CallSite<Func<CallSite, object, double>>.Create(new MyConvertBinder(typeof(double), 23.0));
  1156. AreEqual(dsite.Target(dsite, inst), 42.0);
  1157. var csite = CallSite<Func<CallSite, object, Complex>>.Create(new MyConvertBinder(typeof(Complex), new Complex(0, 23)));
  1158. AreEqual(csite.Target(csite, inst), new Complex(0, 42));
  1159. var bsite = CallSite<Func<CallSite, object, bool>>.Create(new MyConvertBinder(typeof(bool), true));
  1160. AreEqual(bsite.Target(bsite, inst), false);
  1161. var bisite = CallSite<Func<CallSite, object, BigInteger>>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23));
  1162. AreEqual(bisite.Target(bisite, inst), (BigInteger)42);
  1163. var dlgsite = CallSite<Func<CallSite, object, Func<object, object>>>.Create(new MyConvertBinder(typeof(Func<object, object>), null));
  1164. VerifyFunction(new[] { "foo" }, new string[0], dlgsite.Target(dlgsite, inst)("foo"));
  1165. var dlgsite2 = CallSite<Func<CallSite, object, Func<object, object, object>>>.Create(new MyConvertBinder(typeof(Func<object, object, object>), null));
  1166. VerifyFunction(new[] { "foo", "bar" }, new string[0], dlgsite2.Target(dlgsite2, inst)("foo", "bar"));
  1167. }
  1168. foreach (object inst in unconvertableObjects) {
  1169. // These may be invalid according to the DLR (wrong ret type) but currently work today.
  1170. site = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(string)));
  1171. AreEqual(site.Target(site, inst), "Converted");
  1172. #if CLR2
  1173. site = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23));
  1174. AreEqual(site.Target(site, inst), (BigInteger)23);
  1175. #endif
  1176. // strongly typed return versions
  1177. var ssite = CallSite<Func<CallSite, object, string>>.Create(new MyConvertBinder(typeof(string)));
  1178. AreEqual(ssite.Target(ssite, inst), "Converted");
  1179. var isite = CallSite<Func<CallSite, object, int>>.Create(new MyConvertBinder(typeof(int), 23));
  1180. AreEqual(isite.Target(isite, inst), 23);
  1181. var dsite = CallSite<Func<CallSite, object, double>>.Create(new MyConvertBinder(typeof(double), 23.0));
  1182. AreEqual(dsite.Target(dsite, inst), 23.0);
  1183. var csite = CallSite<Func<CallSite, object, Complex>>.Create(new MyConvertBinder(typeof(Complex), new Complex(0, 23.0)));
  1184. AreEqual(csite.Target(csite, inst), new Complex(0, 23.0));
  1185. var bsite = CallSite<Func<CallSite, object, bool>>.Create(new MyConvertBinder(typeof(bool), true));
  1186. AreEqual(bsite.Target(bsite, inst), true);
  1187. var bisite = CallSite<Func<CallSite, object, BigInteger>>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23));
  1188. AreEqual(bisite.Target(bisite, inst), (BigInteger)23);
  1189. }
  1190. // get on .NET member should fallback
  1191. #if !NETSTANDARD
  1192. if(!ClrModule.IsMono) {
  1193. // property
  1194. site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("AllowDrop"));
  1195. AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");
  1196. // method
  1197. site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("BringToFront"));
  1198. AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");
  1199. // protected method
  1200. site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("OnParentChanged"));
  1201. AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");
  1202. // event
  1203. site = CallSite<Func<CallSite, object, object>>.Create(new MyGetMemberBinder("DoubleClick"));
  1204. AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember");
  1205. }
  1206. #endif
  1207. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("something", new CallInfo(0)));
  1208. AreEqual(site.Target(site, (object)scope.GetVariable("ns_getattrinst")), "FallbackInvokegetattrsomething");
  1209. foreach (object inst in iterableObjects) {
  1210. // converting a type which implements __iter__
  1211. var enumsite = CallSite<Func<CallSite, object, IEnumerable>>.Create(new MyConvertBinder(typeof(IEnumerable)));
  1212. IEnumerable ie = enumsite.Target(enumsite, inst);
  1213. IEnumerator ator = ie.GetEnumerator();
  1214. AreEqual(ator.MoveNext(), true);
  1215. AreEqual(ator.Current, 1);
  1216. AreEqual(ator.MoveNext(), true);
  1217. AreEqual(ator.Current, 2);
  1218. AreEqual(ator.MoveNext(), true);
  1219. AreEqual(ator.Current, 3);
  1220. AreEqual(ator.MoveNext(), false);
  1221. var enumobjsite = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(IEnumerable)));
  1222. ie = (IEnumerable)enumobjsite.Target(enumobjsite, inst);
  1223. ator = ie.GetEnumerator();
  1224. AreEqual(ator.MoveNext(), true);
  1225. AreEqual(ator.Current, 1);
  1226. AreEqual(ator.MoveNext(), true);
  1227. AreEqual(ator.Current, 2);
  1228. AreEqual(ator.MoveNext(), true);
  1229. AreEqual(ator.Current, 3);
  1230. AreEqual(ator.MoveNext(), false);
  1231. var enumatorsite = CallSite<Func<CallSite, object, IEnumerator>>.Create(new MyConvertBinder(typeof(IEnumerator)));
  1232. ator = enumatorsite.Target(enumatorsite, inst);
  1233. AreEqual(ator.MoveNext(), true);
  1234. AreEqual(ator.Current, 1);
  1235. AreEqual(ator.MoveNext(), true);
  1236. AreEqual(ator.Current, 2);
  1237. AreEqual(ator.MoveNext(), true);
  1238. AreEqual(ator.Current, 3);
  1239. AreEqual(ator.MoveNext(), false);
  1240. var enumatorobjsite = CallSite<Func<CallSite, object, object>>.Create(new MyConvertBinder(typeof(IEnumerator)));
  1241. ator = (IEnumerator)enumatorobjsite.Target(enumatorobjsite, inst);
  1242. AreEqual(ator.MoveNext(), true);
  1243. AreEqual(ator.Current, 1);
  1244. AreEqual(ator.MoveNext(), true);
  1245. AreEqual(ator.Current, 2);
  1246. AreEqual(ator.MoveNext(), true);
  1247. AreEqual(ator.Current, 3);
  1248. AreEqual(ator.MoveNext(), false);
  1249. // Bug, need to support conversions of new-style classes to IEnumerable<T>,
  1250. // see http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=21253
  1251. if (inst is IronPython.Runtime.Types.OldInstance) {
  1252. var enumofTsite = CallSite<Func<CallSite, object, IEnumerable<object>>>.Create(new MyConvertBinder(typeof(IEnumerable<object>), new object[0]));
  1253. IEnumerable<object> ieofT = enumofTsite.Target(enumofTsite, inst);
  1254. IEnumerator<object> atorofT = ieofT.GetEnumerator();
  1255. AreEqual(atorofT.MoveNext(), true);
  1256. AreEqual(atorofT.Current, 1);
  1257. AreEqual(atorofT.MoveNext(), true);
  1258. AreEqual(atorofT.Current, 2);
  1259. AreEqual(atorofT.MoveNext(), true);
  1260. AreEqual(atorofT.Current, 3);
  1261. AreEqual(atorofT.MoveNext(), false);
  1262. }
  1263. }
  1264. site = CallSite<Func<CallSite, object, object>>.Create(new MyUnaryBinder(ExpressionType.Not));
  1265. AreEqual(site.Target(site, (object)scope.GetVariable("nsinst")), true);
  1266. AreEqual(site.Target(site, (object)scope.GetVariable("ns_nonzero_inst")), false);
  1267. AreEqual(site.Target(site, (object)scope.GetVariable("ns_len0_inst")), true);
  1268. AreEqual(site.Target(site, (object)scope.GetVariable("ns_len1_inst")), false);
  1269. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("ToString", new CallInfo(0)));
  1270. AreEqual(site.Target(site, (object)scope.GetVariable("xrange")), "FallbackInvokeMember");
  1271. // invoke a function defined as a member of a function
  1272. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("SubFunc", new CallInfo(0)));
  1273. AreEqual(site.Target(site, (object)scope.GetVariable("TestFunc")), "TestFunc");
  1274. site = CallSite<Func<CallSite, object, object>>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0)));
  1275. AreEqual(site.Target(site, (object)scope.GetVariable("TestFunc")), "FallbackInvokeMember");
  1276. }
  1277. class MyDynamicObject : DynamicObject {
  1278. public object Last;
  1279. public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) {
  1280. result = binder.Operation;
  1281. return true;
  1282. }
  1283. public override bool TryUnaryOperation(UnaryOperationBinder binder, out object result) {
  1284. result = binder.Operation;
  1285. return true;
  1286. }
  1287. public override bool TryGetMember(GetMemberBinder binder, out object result) {
  1288. result = binder.Name;
  1289. return true;
  1290. }
  1291. public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) {
  1292. result = indexes[0];
  1293. return true;
  1294. }
  1295. public override bool TryDeleteMember(DeleteMemberBinder binder) {
  1296. Last = binder.Name;
  1297. return true;
  1298. }
  1299. public override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes) {
  1300. Last = indexes[0];
  1301. return true;
  1302. }
  1303. public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) {
  1304. Last = indexes[0];
  1305. return true;
  1306. }
  1307. public override bool TrySetMember(SetMemberBinder binder, object value) {
  1308. Last = value;
  1309. return true;
  1310. }
  1311. public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) {
  1312. result = binder.CallInfo;
  1313. return true;
  1314. }
  1315. public override bool TryConvert(ConvertBinder binder, out object result) {
  1316. result = 1000;
  1317. return true;
  1318. }
  1319. }
  1320. public void ScenarioDlrInterop_ConsumeDynamicObject() {
  1321. var scope = _pe.CreateScope();
  1322. var dynObj = new MyDynamicObject();
  1323. scope.SetVariable("x", dynObj);
  1324. _pe.Execute("import clr", scope);
  1325. var tests = new[] {
  1326. new {TestCase = "clr.Convert(x, int)", Result=(object)1000},
  1327. new {TestCase = "x(2,3,4)", Result=(object)new CallInfo(3)},
  1328. new {TestCase = "x(2,3,4, z = 4)", Result=(object)new CallInfo(4, "z")},
  1329. new {TestCase = "not x", Result=(object)ExpressionType.Not},
  1330. new {TestCase = "+x", Result=(object)ExpressionType.UnaryPlus},
  1331. new {TestCase = "-x", Result=(object)ExpressionType.Negate},
  1332. new {TestCase = "~x", Result=(object)ExpressionType.OnesComplement},
  1333. new {TestCase = "x + 42", Result=(object)ExpressionType.Add},
  1334. new {TestCase = "x - 42", Result=(object)ExpressionType.Subtract},
  1335. new {TestCase = "x / 42", Result=(object)ExpressionType.Divide},
  1336. new {TestCase = "x * 42", Result=(object)ExpressionType.Multiply},
  1337. new {TestCase = "x % 42", Result=(object)ExpressionType.Modulo},
  1338. new {TestCase = "x ^ 42", Result=(object)ExpressionType.ExclusiveOr},
  1339. new {TestCase = "x << 42", Result=(object)ExpressionType.LeftShift},
  1340. new {TestCase = "x >> 42", Result=(object)ExpressionType.RightShift},
  1341. new {TestCase = "x | 42", Result=(object)ExpressionType.Or},
  1342. new {TestCase = "x & 42", Result=(object)ExpressionType.And},
  1343. new {TestCase = "x ** 42", Result=(object)ExpressionType.Power},
  1344. new {TestCase = "x > 42", Result=(object)ExpressionType.GreaterThan},
  1345. new {TestCase = "x < 42", Result=(object)ExpressionType.LessThan},
  1346. new {TestCase = "x >= 42", Result=(object)ExpressionType.GreaterThanOrEqual},
  1347. new {TestCase = "x <= 42", Result=(object)ExpressionType.LessThanOrEqual},
  1348. new {TestCase = "x == 42", Result=(object)ExpressionType.Equal},
  1349. new {TestCase = "x != 42", Result=(object)ExpressionType.NotEqual},
  1350. new {TestCase = "x.abc", Result=(object)"abc"},
  1351. new {TestCase = "x.foo", Result=(object)"foo"},
  1352. new {TestCase = "x[0]", Result=(object)0},
  1353. new {TestCase = "x[1]", Result=(object)1},
  1354. };
  1355. foreach(var test in tests) {
  1356. AreEqual(test.Result, (object)_pe.Execute(test.TestCase, scope));
  1357. }
  1358. var tests2 = new[] {
  1359. new {TestCase = "x.foo = 42", Last=(object)42},
  1360. new {TestCase = "x[23] = 5", Last=(object)23},
  1361. new {TestCase = "del x[5]", Last=(object)5},
  1362. new {TestCase = "del x.abc", Last=(object)"abc"},
  1363. };
  1364. foreach (var test in tests2) {
  1365. _pe.Execute(test.TestCase, scope);
  1366. AreEqual(test.Last, dynObj.Last);
  1367. }
  1368. }
  1369. private void VerifyFunction(object[] results, string[] names, object value) {
  1370. IList<object> res = (IList<object>)value;
  1371. AreEqual(res.Count, 2);
  1372. IList<object> positional = (IList<object>)res[0];
  1373. IDictionary<object, object> kwargs = (IDictionary<object, object>)res[1];
  1374. for (int i = 0; i < positional.Count; i++) {
  1375. AreEqual(positional[i], results[i]);
  1376. }
  1377. for (int i = positional.Count; i < results.Length; i++) {
  1378. AreEqual(kwargs[names[i - positional.Count]], results[i]);
  1379. }
  1380. }
  1381. public void ScenarioEvaluateInAnonymousEngineModule() {
  1382. ScriptScope scope1 = _env.CreateScope();
  1383. ScriptScope scope2 = _env.CreateScope();
  1384. ScriptScope scope3 = _env.CreateScope();
  1385. _pe.Execute("x = 0", scope1);
  1386. _pe.Execute("x = 1", scope2);
  1387. scope3.SetVariable("x", 2);
  1388. AreEqual(0, _pe.Execute<int>("x", scope1));
  1389. AreEqual(0, (int)(object)scope1.GetVariable("x"));
  1390. AreEqual(1, _pe.Execute<int>("x", scope2));
  1391. AreEqual(1, (int)(object)scope2.GetVariable("x"));
  1392. AreEqual(2, _pe.Execute<int>("x", scope3));
  1393. AreEqual(2, (int)(object)scope3.GetVariable("x"));
  1394. }
  1395. public void ScenarioObjectOperations() {
  1396. var ops = _pe.Operations;
  1397. AreEqual("(1, 2, 3)", ops.Format(new PythonTuple(new object[] { 1, 2, 3 })));
  1398. var scope = _pe.CreateScope();
  1399. scope.SetVariable("ops", ops);
  1400. AreEqual("[1, 2, 3]", _pe.Execute<string>("ops.Format([1,2,3])", scope));
  1401. ScriptSource src = _pe.CreateScriptSourceFromString("def f(*args): return args", SourceCodeKind.Statements);
  1402. src.Execute(scope);
  1403. object f = (object)scope.GetVariable("f");
  1404. for (int i = 0; i < 20; i++) {
  1405. object[] inp = new object[i];
  1406. for (int j = 0; j < inp.Length; j++) {
  1407. inp[j] = j;
  1408. }
  1409. AreEqual((object)ops.Invoke(f, inp), PythonTuple.MakeTuple(inp));
  1410. }
  1411. ScriptScope mod = _env.CreateScope();
  1412. _pe.CreateScriptSourceFromString(@"
  1413. class foo(object):
  1414. abc = 3
  1415. def __init__(self, x, y):
  1416. self.x = x
  1417. self.y = y
  1418. ", SourceCodeKind.Statements).Execute(mod);
  1419. object klass = mod.GetVariable("foo");
  1420. // create instance of foo, verify members
  1421. object foo = ops.CreateInstance(klass , 123, 444);
  1422. Assert(ops.GetMember<int>(foo, "abc") == 3);
  1423. Assert(ops.GetMember<int>(foo, "x") == 123);
  1424. Assert(ops.GetMember<int>(foo, "y") == 444);
  1425. }
  1426. public void ScenarioCP712() {
  1427. ScriptScope scope1 = _env.CreateScope();
  1428. _pe.CreateScriptSourceFromString("max(3, 4)", SourceCodeKind.InteractiveCode).Execute(scope1);
  1429. //CompiledCode compiledCode = _pe.CreateScriptSourceFromString("max(3,4)", SourceCodeKind.InteractiveCode).Compile();
  1430. //compiledCode.Execute(scope1);
  1431. //AreEqual(4, scope1.GetVariable<int>("__builtins__._"));
  1432. //TODO - this currently fails.
  1433. //AreEqual(4, scope1.GetVariable<int>("_"));
  1434. }
  1435. public void ScenarioCP24784() {
  1436. var code = _pe.CreateScriptSourceFromString("def f():\r\n \r\n print 1", SourceCodeKind.InteractiveCode);
  1437. AreEqual(code.GetCodeProperties(), ScriptCodeParseResult.IncompleteStatement);
  1438. }
  1439. public delegate int CP19724Delegate(double p1);
  1440. public void ScenarioCP19724()
  1441. {
  1442. ScriptScope scope1 = _env.CreateScope();
  1443. ScriptSource src = _pe.CreateScriptSourceFromString(@"
  1444. class KNew(object):
  1445. def __call__(self, p1):
  1446. global X
  1447. X = 42
  1448. return 7
  1449. k = KNew()", SourceCodeKind.Statements);
  1450. src.Execute(scope1);
  1451. CP19724Delegate tDelegate = scope1.GetVariable<CP19724Delegate>("k");
  1452. AreEqual(7, tDelegate(3.14));
  1453. AreEqual(42, scope1.GetVariable<int>("X"));
  1454. }
  1455. public void ScenarioEvaluateInPublishedEngineModule() {
  1456. PythonContext pc = DefaultContext.DefaultPythonContext;
  1457. PythonModule publishedModule = new PythonModule();
  1458. PythonModule otherModule = new PythonModule();
  1459. pc.PublishModule("published_context_test", publishedModule);
  1460. pc.CreateSnippet("x = 0", SourceCodeKind.Statements).Execute(otherModule.Scope);
  1461. pc.CreateSnippet("x = 1", SourceCodeKind.Statements).Execute(publishedModule.Scope);
  1462. object x;
  1463. // Ensure that the default EngineModule is not affected
  1464. x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
  1465. AreEqual(0, (int)x);
  1466. // Ensure that the published context has been updated as expected
  1467. x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(publishedModule.Scope);
  1468. AreEqual(1, (int)x);
  1469. // Ensure that the published context is accessible from other contexts using sys.modules
  1470. // TODO: do better:
  1471. // pe.Import("sys", ScriptDomainManager.CurrentManager.DefaultModule);
  1472. pc.CreateSnippet("from published_context_test import x", SourceCodeKind.Statements).Execute(otherModule.Scope);
  1473. x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
  1474. AreEqual(1, (int)x);
  1475. }
  1476. class CustomDictionary : IDictionary<string, object> {
  1477. // Make "customSymbol" always be accessible. This could have been accomplished just by
  1478. // doing SetGlobal. However, this mechanism could be used for other extensibility
  1479. // purposes like getting a callback whenever the symbol is read
  1480. internal static readonly string customSymbol = "customSymbol";
  1481. internal const int customSymbolValue = 100;
  1482. Dictionary<string, object> dict = new Dictionary<string, object>();
  1483. #region IDictionary<string,object> Members
  1484. public void Add(string key, object value) {
  1485. if (key.Equals(customSymbol))
  1486. throw new UnboundNameException("Cannot assign to customSymbol");
  1487. dict.Add(key, value);
  1488. }
  1489. public bool ContainsKey(string key) {
  1490. if (key.Equals(customSymbol))
  1491. return true;
  1492. return dict.ContainsKey(key);
  1493. }
  1494. public ICollection<string> Keys {
  1495. get { throw new NotImplementedException("The method or operation is not implemented."); }
  1496. }
  1497. public bool Remove(string key) {
  1498. if (key.Equals(customSymbol))
  1499. throw new UnboundNameException("Cannot delete customSymbol");
  1500. return dict.Remove(key);
  1501. }
  1502. public bool TryGetValue(string key, out object value) {
  1503. if (key.Equals(customSymbol)) {
  1504. value = customSymbolValue;
  1505. return true;
  1506. }
  1507. return dict.TryGetValue(key, out value);
  1508. }
  1509. public ICollection<object> Values {
  1510. get { throw new NotImplementedException("The method or operation is not implemented."); }
  1511. }
  1512. public object this[string key] {
  1513. get {
  1514. if (key.Equals(customSymbol))
  1515. return customSymbolValue;
  1516. return dict[key];
  1517. }
  1518. set {
  1519. if (key.Equals(customSymbol))
  1520. throw new UnboundNameException("Cannot assign to customSymbol");
  1521. dict[key] = value;
  1522. }
  1523. }
  1524. #endregion
  1525. #region ICollection<KeyValuePair<string,object>> Members
  1526. public void Add(KeyValuePair<string, object> item) {
  1527. throw new NotImplementedException("The method or operation is not implemented.");
  1528. }
  1529. public void Clear() {
  1530. throw new NotImplementedException("The method or operation is not implemented.");
  1531. }
  1532. public bool Contains(KeyValuePair<string, object> item) {
  1533. throw new NotImplementedException("The method or operation is not implemented.");
  1534. }
  1535. public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
  1536. throw new NotImplementedException("The method or operation is not implemented.");
  1537. }
  1538. public int Count {
  1539. get { throw new NotImplementedException("The method or operation is not implemented."); }
  1540. }
  1541. public bool IsReadOnly {
  1542. get { throw new NotImplementedException("The method or operation is not implemented."); }
  1543. }
  1544. public bool Remove(KeyValuePair<string, object> item) {
  1545. throw new NotImplementedException("The method or operation is not implemented.");
  1546. }
  1547. #endregion
  1548. #region IEnumerable<KeyValuePair<string,object>> Members
  1549. public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
  1550. foreach (var keyValue in dict) {
  1551. yield return keyValue;
  1552. }
  1553. yield return new KeyValuePair<string, object>("customSymbol", customSymbolValue);
  1554. }
  1555. #endregion
  1556. #region IEnumerable Members
  1557. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
  1558. throw new NotImplementedException("The method or operation is not implemented.");
  1559. }
  1560. #endregion
  1561. }
  1562. public void ScenarioCustomDictionary() {
  1563. PythonDictionary customGlobals = new PythonDictionary(new StringDictionaryStorage(new CustomDictionary()));
  1564. ScriptScope customModule = _pe.Runtime.CreateScope(new ObjectDictionaryExpando(customGlobals));
  1565. // Evaluate
  1566. AreEqual(_pe.Execute<int>("customSymbol + 1", customModule), CustomDictionary.customSymbolValue + 1);
  1567. // Execute
  1568. _pe.Execute("customSymbolPlusOne = customSymbol + 1", customModule);
  1569. AreEqual(_pe.Execute<int>("customSymbolPlusOne", customModule), CustomDictionary.customSymbolValue + 1);
  1570. AreEqual(customModule.GetVariable<int>("customSymbolPlusOne"), CustomDictionary.customSymbolValue + 1);
  1571. // Compile
  1572. CompiledCode compiledCode = _pe.CreateScriptSourceFromString("customSymbolPlusTwo = customSymbol + 2").Compile();
  1573. compiledCode.Execute(customModule);
  1574. AreEqual(_pe.Execute<int>("customSymbolPlusTwo", customModule), CustomDictionary.customSymbolValue + 2);
  1575. AreEqual(customModule.GetVariable<int>("customSymbolPlusTwo"), CustomDictionary.customSymbolValue + 2);
  1576. // check overriding of Add
  1577. try {
  1578. _pe.Execute("customSymbol = 1", customModule);
  1579. throw new Exception("We should not reach here");
  1580. } catch (UnboundNameException) { }
  1581. try {
  1582. _pe.Execute(@"global customSymbol
  1583. customSymbol = 1", customModule);
  1584. throw new Exception("We should not reach here");
  1585. } catch (UnboundNameException) { }
  1586. // check overriding of Remove
  1587. try {
  1588. _pe.Execute("del customSymbol", customModule);
  1589. throw new Exception("We should not reach here");
  1590. } catch (UnboundNameException) { }
  1591. try {
  1592. _pe.Execute(@"global customSymbol
  1593. del customSymbol", customModule);
  1594. throw new Exception("We should not reach here");
  1595. } catch (UnboundNameException) { }
  1596. // vars()
  1597. IDictionary vars = _pe.Execute<IDictionary>("vars()", customModule);
  1598. AreEqual(true, vars.Contains("customSymbol"));
  1599. // Miscellaneous APIs
  1600. //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("customSymbol + arg", customModule);
  1601. //AreEqual(d(1), CustomDictionary.customSymbolValue + 1);
  1602. }
  1603. public void ScenarioCallClassInstance() {
  1604. ScriptScope scope = _env.CreateScope();
  1605. _pe.CreateScriptSourceFromString(@"
  1606. class X(object):
  1607. def __call__(self, arg):
  1608. return arg
  1609. a = X()
  1610. class Y:
  1611. def __call__(self, arg):
  1612. return arg
  1613. b = Y()", SourceCodeKind.Statements).Execute(scope);
  1614. var a = scope.GetVariable<Func<object, int>>("a");
  1615. var b = scope.GetVariable<Func<object, int>>("b");
  1616. AreEqual(a(42), 42);
  1617. AreEqual(b(42), 42);
  1618. }
  1619. // Evaluate
  1620. public void ScenarioEvaluate() {
  1621. ScriptScope scope = _env.CreateScope();
  1622. AreEqual(10, _pe.CreateScriptSourceFromString("4+6").Execute<int>(scope));
  1623. AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass").Execute(scope));
  1624. AreEqual(10, _pe.CreateScriptSourceFromString("4+6", SourceCodeKind.AutoDetect).Execute<int>(scope));
  1625. AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.AutoDetect).Execute(scope));
  1626. AreEqual(10, _pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Expression).Execute<int>(scope));
  1627. AssertExceptionThrown<SyntaxErrorException>(() => _pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Expression).Execute(scope));
  1628. AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.File).Execute(scope));
  1629. AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.File).Execute(scope));
  1630. AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.SingleStatement).Execute(scope));
  1631. AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.SingleStatement).Execute(scope));
  1632. AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Statements).Execute(scope));
  1633. AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Statements).Execute(scope));
  1634. AreEqual(10, (int)(object)_pe.Execute("4+6", scope));
  1635. AreEqual(10, _pe.Execute<int>("4+6", scope));
  1636. AreEqual("abab", (string)(object)_pe.Execute("'ab' * 2", scope));
  1637. AreEqual("abab", _pe.Execute<string>("'ab' * 2", scope));
  1638. ClsPart clsPart = new ClsPart();
  1639. scope.SetVariable(clspartName, clsPart);
  1640. AreEqual(clsPart, ((object)_pe.Execute("clsPart", scope)) as ClsPart);
  1641. AreEqual(clsPart, _pe.Execute<ClsPart>("clsPart", scope));
  1642. _pe.Execute("clsPart.Field = 100", scope);
  1643. AreEqual(100, (int)(object)_pe.Execute("clsPart.Field", scope));
  1644. AreEqual(100, _pe.Execute<int>("clsPart.Field", scope));
  1645. // Ensure that we can get back a delegate to a Python method
  1646. _pe.Execute("def IntIntMethod(a): return a * 100", scope);
  1647. IntIntDelegate d = _pe.Execute<IntIntDelegate>("IntIntMethod", scope);
  1648. AreEqual(d(2), 2 * 100);
  1649. }
  1650. public void ScenarioMemberNames() {
  1651. ScriptScope scope = _env.CreateScope();
  1652. _pe.CreateScriptSourceFromString(@"
  1653. class nc(object):
  1654. def __init__(self):
  1655. self.baz = 5
  1656. foo = 3
  1657. def abc(self): pass
  1658. @staticmethod
  1659. def staticfunc(arg1): pass
  1660. @classmethod
  1661. def classmethod(cls): pass
  1662. ncinst = nc()
  1663. def f(): pass
  1664. f.foo = 3
  1665. class oc:
  1666. def __init__(self):
  1667. self.baz = 5
  1668. foo = 3
  1669. def abc(self): pass
  1670. @staticmethod
  1671. def staticfunc(arg1): pass
  1672. @classmethod
  1673. def classmethod(cls): pass
  1674. ocinst = oc()
  1675. ", SourceCodeKind.Statements).Execute(scope);
  1676. ParameterExpression parameter = Expression.Parameter(typeof(object), "");
  1677. DynamicMetaObject nc = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("nc"), parameter);
  1678. DynamicMetaObject ncinst = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("ncinst"), parameter); ;
  1679. DynamicMetaObject f = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("f"), parameter); ;
  1680. DynamicMetaObject oc = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("oc"), parameter); ;
  1681. DynamicMetaObject ocinst = DynamicUtils.ObjectToMetaObject((object)scope.GetVariable("ocinst"), parameter); ;
  1682. List<string> ncnames = new List<string>(nc.GetDynamicMemberNames());
  1683. List<string> ncinstnames = new List<string>(ncinst.GetDynamicMemberNames());
  1684. List<string> fnames = new List<string>(f.GetDynamicMemberNames());
  1685. List<string> ocnames = new List<string>(oc.GetDynamicMemberNames());
  1686. List<string> ocinstnames = new List<string>(ocinst.GetDynamicMemberNames());
  1687. ncnames.Sort();
  1688. ncinstnames.Sort();
  1689. ocnames.Sort();
  1690. ocinstnames.Sort();
  1691. fnames.Sort();
  1692. 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" });
  1693. 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" });
  1694. AreEqualLists(fnames, new[] { "foo" });
  1695. AreEqualLists(ocnames, new[] { "__doc__", "__init__", "__module__", "abc", "classmethod", "foo", "staticfunc" });
  1696. AreEqualLists(ocinstnames, new[] { "__doc__", "__init__", "__module__", "abc", "baz", "classmethod", "foo", "staticfunc" });
  1697. }
  1698. public void ScenarioTokenCategorizer() {
  1699. var categorizer = _pe.GetService<TokenCategorizer>();
  1700. var source = _pe.CreateScriptSourceFromString("sys", SourceCodeKind.Statements);
  1701. categorizer.Initialize(null, source, SourceLocation.MinValue);
  1702. TokenInfo token = categorizer.ReadToken();
  1703. AreEqual(token.Category, TokenCategory.Identifier);
  1704. token = categorizer.ReadToken();
  1705. AreEqual(token.Category, TokenCategory.EndOfStream);
  1706. source = _pe.CreateScriptSourceFromString("\"sys\"", SourceCodeKind.Statements);
  1707. categorizer.Initialize(null, source, SourceLocation.MinValue);
  1708. token = categorizer.ReadToken();
  1709. AreEqual(token.Category, TokenCategory.StringLiteral);
  1710. token = categorizer.ReadToken();
  1711. AreEqual(token.Category, TokenCategory.EndOfStream);
  1712. }
  1713. private void AreEqualLists<T>(IList<T> left, IList<T> right) {
  1714. if (left.Count != right.Count) {
  1715. string res = "lists differ by length: " + left.Count + " vs " + right.Count + Environment.NewLine + ListsToString(left, right);
  1716. Assert(false, res);
  1717. }
  1718. for (int i = 0; i < left.Count; i++) {
  1719. if (!left[i].Equals(right[i])) {
  1720. Assert(false, String.Format("lists differ by value: {0} {1}{2}{3}", left[i], right[i], Environment.NewLine, ListsToString(left, right)));
  1721. }
  1722. }
  1723. }
  1724. private static string ListsToString<T>(IList<T> left, IList<T> right) {
  1725. string res = " ";
  1726. foreach (object o in left) {
  1727. res += "\"" + o + "\", ";
  1728. }
  1729. res += Environment.NewLine + " ";
  1730. foreach (object o in right) {
  1731. res += "\"" + o + "\", ";
  1732. }
  1733. return res;
  1734. }
  1735. public void ScenarioCallableClassToDelegate() {
  1736. ScriptSource src = _pe.CreateScriptSourceFromString(@"
  1737. class Test(object):
  1738. def __call__(self):
  1739. return 42
  1740. inst = Test()
  1741. class TestOC:
  1742. def __call__(self):
  1743. return 42
  1744. instOC = TestOC()
  1745. ", SourceCodeKind.Statements);
  1746. ScriptScope scope = _pe.CreateScope();
  1747. src.Execute(scope);
  1748. Func<int> t = scope.GetVariable<Func<int>>("inst");
  1749. AreEqual(42, t());
  1750. t = scope.GetVariable<Func<int>>("instOC");
  1751. AreEqual(42, t());
  1752. }
  1753. #if !SILVERLIGHT
  1754. // ExecuteFile
  1755. public void ScenarioExecuteFile() {
  1756. ScriptSource tempFile1, tempFile2;
  1757. ScriptScope scope = _env.CreateScope();
  1758. using (StringWriter sw = new StringWriter()) {
  1759. sw.WriteLine("var1 = (10, 'z')");
  1760. sw.WriteLine("");
  1761. sw.WriteLine("clsPart.Field = 100");
  1762. sw.WriteLine("clsPart.Property = clsPart.Field * 5");
  1763. sw.WriteLine("clsPart.Event += (lambda x: x*x)");
  1764. tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
  1765. }
  1766. ClsPart clsPart = new ClsPart();
  1767. scope.SetVariable(clspartName, clsPart);
  1768. tempFile1.Execute(scope);
  1769. using (StringWriter sw = new StringWriter()) {
  1770. sw.WriteLine("if var1[0] != 10: raise AssertionError('test failed')");
  1771. sw.WriteLine("if var1[1] != 'z': raise AssertionError('test failed')");
  1772. sw.WriteLine("");
  1773. sw.WriteLine("if clsPart.Property != clsPart.Field * 5: raise AssertionError('test failed')");
  1774. sw.WriteLine("var2 = clsPart.Method(var1[0])");
  1775. sw.WriteLine("if var2 != 10 * 10: raise AssertionError('test failed')");
  1776. tempFile2 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
  1777. }
  1778. tempFile2.Execute(scope);
  1779. }
  1780. #endif
  1781. #if !SILVERLIGHT
  1782. // Bug: 542
  1783. public void Scenario542() {
  1784. ScriptSource tempFile1;
  1785. ScriptScope scope = _env.CreateScope();
  1786. using (StringWriter sw = new StringWriter()) {
  1787. sw.WriteLine("def M1(): return -1");
  1788. sw.WriteLine("def M2(): return +1");
  1789. sw.WriteLine("class C:");
  1790. sw.WriteLine(" def M1(self): return -1");
  1791. sw.WriteLine(" def M2(self): return +1");
  1792. sw.WriteLine("class C1:");
  1793. sw.WriteLine(" def M(): return -1");
  1794. sw.WriteLine("class C2:");
  1795. sw.WriteLine(" def M(): return +1");
  1796. tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
  1797. }
  1798. tempFile1.Execute(scope);
  1799. AreEqual(-1, _pe.CreateScriptSourceFromString("M1()").Execute<int>(scope));
  1800. AreEqual(+1, _pe.CreateScriptSourceFromString("M2()").Execute<int>(scope));
  1801. AreEqual(-1, (int)(object)_pe.CreateScriptSourceFromString("M1()").Execute(scope));
  1802. AreEqual(+1, (int)(object)_pe.CreateScriptSourceFromString("M2()").Execute(scope));
  1803. _pe.CreateScriptSourceFromString("if M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  1804. _pe.CreateScriptSourceFromString("if M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  1805. _pe.CreateScriptSourceFromString("c = C()", SourceCodeKind.SingleStatement).Execute(scope);
  1806. AreEqual(-1, _pe.CreateScriptSourceFromString("c.M1()").Execute<int>(scope));
  1807. AreEqual(+1, _pe.CreateScriptSourceFromString("c.M2()").Execute<int>(scope));
  1808. AreEqual(-1, (int)(object)_pe.CreateScriptSourceFromString("c.M1()").Execute(scope));
  1809. AreEqual(+1, (int)(object)_pe.CreateScriptSourceFromString("c.M2()").Execute(scope));
  1810. _pe.CreateScriptSourceFromString("if c.M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  1811. _pe.CreateScriptSourceFromString("if c.M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  1812. //AreEqual(-1, pe.EvaluateAs<int>("C1.M()"));
  1813. //AreEqual(+1, pe.EvaluateAs<int>("C2.M()"));
  1814. //AreEqual(-1, (int)pe.Evaluate("C1.M()"));
  1815. //AreEqual(+1, (int)pe.Evaluate("C2.M()"));
  1816. //pe.Execute(pe.CreateScriptSourceFromString("if C1.M() != -1: raise AssertionError('test failed')");
  1817. //pe.Execute(pe.CreateScriptSourceFromString("if C2.M() != +1: raise AssertionError('test failed')");
  1818. }
  1819. #endif
  1820. // Bug: 167
  1821. public void Scenario167() {
  1822. ScriptScope scope = _env.CreateScope();
  1823. _pe.CreateScriptSourceFromString("a=1\r\nb=-1", SourceCodeKind.Statements).Execute(scope);
  1824. AreEqual(1, _pe.CreateScriptSourceFromString("a").Execute<int>(scope));
  1825. AreEqual(-1, _pe.CreateScriptSourceFromString("b").Execute<int>(scope));
  1826. }
  1827. #if !SILVERLIGHT
  1828. // AddToPath
  1829. public void ScenarioAddToPath() { // runs first to avoid path-order issues
  1830. //pe.InitializeModules(ipc_path, ipc_path + "\\ipy.exe", pe.VersionString);
  1831. string tempFile1 = Path.GetTempFileName();
  1832. try {
  1833. File.WriteAllText(tempFile1, "from testpkg1.does_not_exist import *");
  1834. ScriptScope scope = _pe.Runtime.CreateScope();
  1835. try {
  1836. _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
  1837. throw new Exception("Scenario7");
  1838. } catch (IronPython.Runtime.Exceptions.ImportException) { }
  1839. File.WriteAllText(tempFile1, "from testpkg1.mod1 import *");
  1840. _pe.SetSearchPaths(new string[] { Common.ScriptTestDirectory });
  1841. _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
  1842. _pe.CreateScriptSourceFromString("give_back(eval('2 + 3'))", SourceCodeKind.Statements).Execute(scope);
  1843. } finally {
  1844. File.Delete(tempFile1);
  1845. }
  1846. }
  1847. // Options.DebugMode
  1848. #endif
  1849. #if FEATURE_REMOTING
  1850. public void ScenarioPartialTrust() {
  1851. // Mono doesn't implement partial trust
  1852. if(System.Environment.OSVersion.Platform == System.PlatformID.Unix)
  1853. return;
  1854. // basic check of running a host in partial trust
  1855. AppDomainSetup info = new AppDomainSetup();
  1856. info.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
  1857. info.ApplicationName = "Test";
  1858. Evidence evidence = new Evidence();
  1859. // TODO:
  1860. #pragma warning disable 612, 618 // obsolete API
  1861. evidence.AddHost(new Zone(SecurityZone.Internet));
  1862. #pragma warning restore 612, 618
  1863. #if !CLR2
  1864. System.Security.PermissionSet permSet = SecurityManager.GetStandardSandbox(evidence);
  1865. AppDomain newDomain = AppDomain.CreateDomain("test", evidence, info, permSet, null);
  1866. #else
  1867. AppDomain newDomain = AppDomain.CreateDomain("test", evidence, info);
  1868. #endif
  1869. // create runtime in partial trust...
  1870. ScriptRuntime runtime = Python.CreateRuntime(newDomain);
  1871. // get the Python engine...
  1872. ScriptEngine engine = runtime.GetEngine("py");
  1873. // execute some simple code
  1874. ScriptScope scope = engine.CreateScope();
  1875. ScriptSource source = engine.CreateScriptSourceFromString("2 + 2");
  1876. AreEqual(source.Execute<int>(scope), 4);
  1877. // import all of the built-in modules & make sure we can reflect on them...
  1878. source = engine.CreateScriptSourceFromString(@"
  1879. import sys
  1880. for mod in sys.builtin_module_names:
  1881. if mod.startswith('_ctypes'):
  1882. continue
  1883. elif mod.startswith('signal'):
  1884. continue
  1885. elif mod=='mmap':
  1886. print 'http://ironpython.codeplex.com/workitem/27571'
  1887. continue
  1888. x = __import__(mod)
  1889. dir(x)
  1890. ", SourceCodeKind.Statements);
  1891. source.Execute(scope);
  1892. // define some classes & use the methods...
  1893. source = engine.CreateScriptSourceFromString(@"
  1894. class x(object):
  1895. def f(self): return 1 + 2
  1896. a = x()
  1897. a.f()
  1898. class y:
  1899. def f(self): return 1 + 2
  1900. b = y()
  1901. b.f()
  1902. ", SourceCodeKind.Statements);
  1903. source.Execute(scope);
  1904. // call a protected method on a derived class...
  1905. source = engine.CreateScriptSourceFromString(@"
  1906. import clr
  1907. class x(object):
  1908. def f(self): return 1 + 2
  1909. a = x()
  1910. b = a.MemberwiseClone()
  1911. if id(a) == id(b):
  1912. raise Exception
  1913. ", SourceCodeKind.Statements);
  1914. source.Execute(scope);
  1915. AppDomain.Unload(newDomain);
  1916. }
  1917. public void ScenarioStackFrameLineInfo() {
  1918. const string lineNumber = "raise.py:line";
  1919. // TODO: Should this work on Mono?
  1920. if(Environment.OSVersion.Platform == PlatformID.Unix)
  1921. {
  1922. Console.WriteLine("Skipping StackFrameLineInfo test on Mono");
  1923. return;
  1924. }
  1925. // TODO: clone setup?
  1926. var scope = Python.CreateRuntime().CreateScope("py");
  1927. var debugSetup = Python.CreateRuntimeSetup(null);
  1928. debugSetup.DebugMode = true;
  1929. var debugScope = new ScriptRuntime(debugSetup).CreateScope("py");
  1930. TestLineInfo(scope, lineNumber);
  1931. TestLineInfo(debugScope, lineNumber);
  1932. TestLineInfo(scope, lineNumber);
  1933. // Ensure that all APIs work
  1934. AreEqual(scope.GetVariable<int>("x"), 1);
  1935. //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("arg + x");
  1936. //AreEqual(d(100), 101);
  1937. //d = pe.CreateMethod<IntIntDelegate>("var = arg + x\nreturn var");
  1938. //AreEqual(d(100), 101);
  1939. }
  1940. private void TestLineInfo(ScriptScope/*!*/ scope, string lineNumber) {
  1941. try {
  1942. scope.Engine.ExecuteFile(Path.Combine(Common.InputTestDirectory, "raise.py"), scope);
  1943. throw new Exception("We should not get here");
  1944. } catch (StopIterationException e2) {
  1945. if (scope.Engine.Runtime.Setup.DebugMode != e2.StackTrace.Contains(lineNumber))
  1946. throw new Exception("Debugging is enabled even though Options.DebugMode is not specified");
  1947. }
  1948. }
  1949. #endif
  1950. // Compile and Run
  1951. public void ScenarioCompileAndRun() {
  1952. ClsPart clsPart = new ClsPart();
  1953. ScriptScope scope = _env.CreateScope();
  1954. scope.SetVariable(clspartName, clsPart);
  1955. CompiledCode compiledCode = _pe.CreateScriptSourceFromString("def f(): clsPart.Field += 10", SourceCodeKind.Statements).Compile();
  1956. compiledCode.Execute(scope);
  1957. compiledCode = _pe.CreateScriptSourceFromString("f()").Compile();
  1958. compiledCode.Execute(scope);
  1959. AreEqual(10, clsPart.Field);
  1960. compiledCode.Execute(scope);
  1961. AreEqual(20, clsPart.Field);
  1962. }
  1963. public void ScenarioStreamRedirect() {
  1964. MemoryStream stdout = new MemoryStream();
  1965. MemoryStream stdin = new MemoryStream();
  1966. MemoryStream stderr = new MemoryStream();
  1967. Encoding encoding = Encoding.UTF8;
  1968. _pe.Runtime.IO.SetInput(stdin, encoding);
  1969. _pe.Runtime.IO.SetOutput(stdout, encoding);
  1970. _pe.Runtime.IO.SetErrorOutput(stderr, encoding);
  1971. const string str = "This is stdout";
  1972. byte[] bytes = encoding.GetBytes(str);
  1973. try {
  1974. ScriptScope scope = _pe.Runtime.CreateScope();
  1975. _pe.CreateScriptSourceFromString("import sys", SourceCodeKind.Statements).Execute(scope);
  1976. stdin.Write(bytes, 0, bytes.Length);
  1977. stdin.Position = 0;
  1978. _pe.CreateScriptSourceFromString("output = sys.__stdin__.readline()", SourceCodeKind.Statements).Execute(scope);
  1979. AreEqual(str, _pe.CreateScriptSourceFromString("output").Execute<string>(scope));
  1980. _pe.CreateScriptSourceFromString("sys.__stdout__.write(output)", SourceCodeKind.Statements).Execute(scope);
  1981. stdout.Flush();
  1982. stdout.Position = 0;
  1983. // deals with BOM:
  1984. using (StreamReader reader = new StreamReader(stdout, true)) {
  1985. string s = reader.ReadToEnd();
  1986. AreEqual(str, s);
  1987. }
  1988. _pe.CreateScriptSourceFromString("sys.__stderr__.write(\"This is stderr\")", SourceCodeKind.Statements).Execute(scope);
  1989. stderr.Flush();
  1990. stderr.Position = 0;
  1991. // deals with BOM:
  1992. using (StreamReader reader = new StreamReader(stderr, true)) {
  1993. string s = reader.ReadToEnd();
  1994. AreEqual("This is stderr", s);
  1995. }
  1996. } finally {
  1997. _pe.Runtime.IO.RedirectToConsole();
  1998. }
  1999. }
  2000. class DictThreadGlobalState {
  2001. public volatile int DoneCount;
  2002. public bool IsDone;
  2003. public ManualResetEvent Event;
  2004. public ManualResetEvent DoneEvent;
  2005. public PythonDictionary Dict;
  2006. public List<DictThreadTestState> Tests = new List<DictThreadTestState>();
  2007. public List<Thread> Threads = new List<Thread>();
  2008. public Func<PythonDictionary> DictMaker;
  2009. }
  2010. class DictThreadTestState {
  2011. public Action<PythonDictionary> Action;
  2012. public Action<PythonDictionary> Verify;
  2013. public DictThreadGlobalState GlobalState;
  2014. }
  2015. public static void ScenarioDictionaryThreadSafety() {
  2016. const int ThreadCount = 10;
  2017. // add new keys to an empty dictionary concurrently
  2018. RunThreadTest(
  2019. MakeThreadTest(
  2020. ThreadCount,
  2021. AddStringKey,
  2022. VerifyStringKey,
  2023. () => new PythonDictionary()
  2024. )
  2025. );
  2026. // add new keys to a constant dictionary concurrently
  2027. var constantStorage = MakeConstantStringDictionary(ThreadCount);
  2028. RunThreadTest(
  2029. MakeThreadTest(
  2030. ThreadCount,
  2031. AddStringKey,
  2032. VerifyStringKey,
  2033. () => new PythonDictionary(constantStorage)
  2034. )
  2035. );
  2036. // remove keys from a constant dictionary concurrently
  2037. var emptyStorage = MakeConstantStringDictionary(ThreadCount);
  2038. RunThreadTest(
  2039. MakeThreadTest(
  2040. ThreadCount,
  2041. RemoveStringKey,
  2042. VerifyNoKeys,
  2043. () => new PythonDictionary(emptyStorage)
  2044. )
  2045. );
  2046. }
  2047. private static ConstantDictionaryStorage MakeConstantStringDictionary(int ThreadCount) {
  2048. object[] storage = new object[ThreadCount * 2];
  2049. for (int i = 0; i < ThreadCount; i++) {
  2050. storage[i * 2] = StringKey(i);
  2051. storage[i * 2 + 1] = StringKey(i);
  2052. }
  2053. var emptyStorage = new ConstantDictionaryStorage(new CommonDictionaryStorage(storage, true));
  2054. return emptyStorage;
  2055. }
  2056. private static ConstantDictionaryStorage MakeConstantStringDictionary() {
  2057. object[] storage = new object[2];
  2058. storage[0] = storage[1] = "SomeValueWhichIsNeverUsedDuringTheTest";
  2059. var emptyStorage = new ConstantDictionaryStorage(new CommonDictionaryStorage(storage, true));
  2060. return emptyStorage;
  2061. }
  2062. private static void RunThreadTest(DictThreadGlobalState globalState) {
  2063. for (int i = 0; i < globalState.Threads.Count; i++) {
  2064. globalState.Threads[i].Start(globalState.Tests[i]);
  2065. }
  2066. for (int i = 0; i < 10000; i++) {
  2067. globalState.Dict = globalState.DictMaker();
  2068. while (globalState.DoneCount != globalState.Threads.Count) {
  2069. // wait for threads to get back to start point
  2070. }
  2071. globalState.DoneEvent.Reset();
  2072. globalState.Event.Set();
  2073. while (globalState.DoneCount != 0) {
  2074. // wait for threads to get back to finish
  2075. }
  2076. foreach (var test in globalState.Tests) {
  2077. test.Verify(globalState.Dict);
  2078. }
  2079. globalState.Event.Reset();
  2080. globalState.DoneEvent.Set();
  2081. }
  2082. globalState.IsDone = true;
  2083. globalState.Event.Set();
  2084. }
  2085. private static DictThreadGlobalState MakeThreadTest(int threadCount,
  2086. Func<int, Action<PythonDictionary>> actionMaker,
  2087. Func<int, Action<PythonDictionary>> verifyMaker,
  2088. Func<PythonDictionary> dictMaker) {
  2089. DictThreadGlobalState globalState = new DictThreadGlobalState();
  2090. globalState.DictMaker = dictMaker;
  2091. globalState.Event = new ManualResetEvent(false);
  2092. globalState.DoneEvent = new ManualResetEvent(false);
  2093. globalState.Threads = new List<Thread>();
  2094. globalState.Tests = new List<DictThreadTestState>();
  2095. for (int i = 0; i < threadCount; i++) {
  2096. var curTestCase = new DictThreadTestState();
  2097. curTestCase.GlobalState = globalState;
  2098. curTestCase.Action = actionMaker(i);
  2099. curTestCase.Verify = verifyMaker(i);
  2100. globalState.Tests.Add(curTestCase);
  2101. Thread thread = new Thread(new ParameterizedThreadStart((x) => {
  2102. var state = (DictThreadTestState)x;
  2103. #pragma warning disable 0420 // "a reference to a volatile field will not be treated as volatile"
  2104. for (; ; ) {
  2105. Interlocked.Increment(ref state.GlobalState.DoneCount);
  2106. state.GlobalState.Event.WaitOne();
  2107. if (globalState.IsDone) {
  2108. break;
  2109. }
  2110. state.Action(state.GlobalState.Dict);
  2111. Interlocked.Decrement(ref state.GlobalState.DoneCount);
  2112. state.GlobalState.DoneEvent.WaitOne();
  2113. }
  2114. #pragma warning restore 0420
  2115. }));
  2116. thread.IsBackground = true;
  2117. globalState.Threads.Add(thread);
  2118. }
  2119. return globalState;
  2120. }
  2121. private static Action<PythonDictionary> AddStringKey(int value) {
  2122. string key = StringKey(value);
  2123. return (dict) => {
  2124. dict[key] = key;
  2125. };
  2126. }
  2127. private static string StringKey(int value) {
  2128. return new string((char)(65 + value), 1);
  2129. }
  2130. private static Action<PythonDictionary> RemoveStringKey(int value) {
  2131. string key = StringKey(value);
  2132. return (dict) => {
  2133. dict.Remove(key);
  2134. };
  2135. }
  2136. private static Action<PythonDictionary> VerifyStringKey(int value) {
  2137. string key = StringKey(value);
  2138. return (dict) => {
  2139. if (!dict.Contains(key)) {
  2140. Console.WriteLine(PythonOps.Repr(DefaultContext.Default, dict));
  2141. }
  2142. Assert(dict.Contains(key));
  2143. AreEqual((string)dict[key], key);
  2144. };
  2145. }
  2146. private static Action<PythonDictionary> VerifyNoKeys(int value) {
  2147. return (dict) => {
  2148. AreEqual(dict.Count, 0);
  2149. };
  2150. }
  2151. public void Scenario12() {
  2152. ScriptScope scope = _env.CreateScope();
  2153. _pe.CreateScriptSourceFromString(@"
  2154. class R(object):
  2155. def __init__(self, a, b):
  2156. self.a = a
  2157. self.b = b
  2158. def M(self):
  2159. return self.a + self.b
  2160. sum = property(M, None, None, None)
  2161. r = R(10, 100)
  2162. if r.sum != 110:
  2163. raise AssertionError('Scenario 12 failed')
  2164. ", SourceCodeKind.Statements).Execute(scope);
  2165. }
  2166. // TODO: rewrite
  2167. #if FALSE
  2168. public void ScenarioTrueDivision1() {
  2169. TestOldDivision(pe, DefaultModule);
  2170. ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
  2171. TestNewDivision(pe, module);
  2172. }
  2173. public void ScenarioTrueDivision2() {
  2174. TestOldDivision(pe, DefaultModule);
  2175. ScriptScope module = pe.CreateModule("__future__", ModuleOptions.PublishModule);
  2176. module.SetVariable("division", 1);
  2177. pe.Execute(pe.CreateScriptSourceFromString("from __future__ import division", module));
  2178. TestNewDivision(pe, module);
  2179. }
  2180. public void ScenarioTrueDivision3() {
  2181. TestOldDivision(pe, DefaultModule);
  2182. ScriptScope future = pe.CreateModule("__future__", ModuleOptions.PublishModule);
  2183. future.SetVariable("division", 1);
  2184. ScriptScope td = pe.CreateModule("truediv", ModuleOptions.None);
  2185. ScriptCode cc = ScriptCode.FromCompiledCode((CompiledCode)pe.CompileCode("from __future__ import division"));
  2186. cc.Run(td);
  2187. TestNewDivision(pe, td); // we've polluted the DefaultModule by executing the code
  2188. }
  2189. #if !SILVERLIGHT
  2190. public void ScenarioTrueDivision4() {
  2191. pe.AddToPath(Common.ScriptTestDirectory);
  2192. string modName = GetTemporaryModuleName();
  2193. string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
  2194. System.IO.File.WriteAllText(file, "result = 1/2");
  2195. PythonDivisionOptions old = PythonEngine.CurrentEngine.Options.DivisionOptions;
  2196. try {
  2197. PythonEngine.CurrentEngine.Options.DivisionOptions = PythonDivisionOptions.Old;
  2198. ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
  2199. pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
  2200. int res = pe.EvaluateAs<int>(modName + ".result", module);
  2201. AreEqual(res, 0);
  2202. } finally {
  2203. PythonEngine.CurrentEngine.Options.DivisionOptions = old;
  2204. try {
  2205. System.IO.File.Delete(file);
  2206. } catch { }
  2207. }
  2208. }
  2209. private string GetTemporaryModuleName() {
  2210. return "tempmod" + Path.GetRandomFileName().Replace('-', '_').Replace('.', '_');
  2211. }
  2212. public void ScenarioTrueDivision5() {
  2213. pe.AddToPath(Common.ScriptTestDirectory);
  2214. string modName = GetTemporaryModuleName();
  2215. string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
  2216. System.IO.File.WriteAllText(file, "from __future__ import division; result = 1/2");
  2217. try {
  2218. ScriptScope module = ScriptDomainManager.CurrentManager.CreateModule(modName);
  2219. pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
  2220. double res = pe.EvaluateAs<double>(modName + ".result", module);
  2221. AreEqual(res, 0.5);
  2222. AreEqual((bool)((PythonContext)DefaultContext.Default.LanguageContext).TrueDivision, false);
  2223. } finally {
  2224. try {
  2225. System.IO.File.Delete(file);
  2226. } catch { }
  2227. }
  2228. }
  2229. public void ScenarioSystemStatePrefix() {
  2230. AreEqual(IronPythonTest.Common.RuntimeDirectory, pe.SystemState.prefix);
  2231. }
  2232. #endif
  2233. private static void TestOldDivision(ScriptEngine pe, ScriptScope module) {
  2234. pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
  2235. AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0);
  2236. AreEqual(pe.EvaluateAs<int>("1/2", module), 0);
  2237. pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
  2238. AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1);
  2239. AreEqual(pe.EvaluateAs<int>("eval('3/2')", module), 1);
  2240. }
  2241. private static void TestNewDivision(ScriptEngine pe, ScriptScope module) {
  2242. pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
  2243. AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0.5);
  2244. AreEqual(pe.EvaluateAs<double>("1/2", module), 0.5);
  2245. pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
  2246. AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1.5);
  2247. AreEqual(pe.EvaluateAs<double>("eval('3/2')", module), 1.5);
  2248. }
  2249. #endif
  2250. // More to come: exception related...
  2251. public static int Negate(int arg) { return -1 * arg; }
  2252. static void AreEqual<T>(T expected, T actual) {
  2253. if (expected == null && actual == null) return;
  2254. if (!expected.Equals(actual)) {
  2255. Console.WriteLine("Expected: {0} Got: {1} from {2}", expected, actual, new StackTrace((Exception)null, true));
  2256. throw new Exception();
  2257. }
  2258. }
  2259. }
  2260. public interface IFooable {
  2261. }
  2262. public class Fooable : IFooable {
  2263. }
  2264. public static class FooableExtensions {
  2265. public static string Bar(IFooable self) {
  2266. return "Bar Called";
  2267. }
  2268. }
  2269. [PythonHiddenBaseClass]
  2270. public class HiddenBase {
  2271. public void Inaccessible() {
  2272. }
  2273. }
  2274. public class DerivedFromHiddenBase : HiddenBase {
  2275. public int Accessible() {
  2276. return 42;
  2277. }
  2278. }
  2279. public class GenericProperty<T> {
  2280. private T _value;
  2281. public T Value {
  2282. get {
  2283. return this._value;
  2284. }
  2285. set {
  2286. this._value = value;
  2287. }
  2288. }
  2289. }
  2290. }