/IronPython_2_0/Src/IronPythonTest/EngineTest.cs

# · C# · 1013 lines · 725 code · 197 blank · 91 comment · 29 complexity · 9a69c6c2bb11f6762f72319e8c2c63b9 MD5 · raw file

  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. 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 Microsoft Public License, 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 Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System; using Microsoft;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Diagnostics;
  19. using System.IO;
  20. using System.Security;
  21. using System.Security.Policy;
  22. using System.Text;
  23. using Microsoft.Scripting;
  24. using Microsoft.Scripting.Hosting;
  25. using Microsoft.Scripting.Runtime;
  26. using IronPython;
  27. using IronPython.Hosting;
  28. using IronPython.Runtime;
  29. using IronPython.Runtime.Exceptions;
  30. namespace IronPythonTest {
  31. #if !SILVERLIGHT
  32. class Common {
  33. public static string RootDirectory;
  34. public static string RuntimeDirectory;
  35. public static string ScriptTestDirectory;
  36. public static string InputTestDirectory;
  37. static Common() {
  38. RuntimeDirectory = Path.GetDirectoryName(typeof(PythonContext).Assembly.Location);
  39. RootDirectory = Environment.GetEnvironmentVariable("MERLIN_ROOT");
  40. if (RootDirectory != null) {
  41. ScriptTestDirectory = Path.Combine(RootDirectory, "Languages\\IronPython\\Tests");
  42. } else {
  43. RootDirectory = new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().GetFiles()[0].Name).Directory.FullName;
  44. ScriptTestDirectory = Path.Combine(RootDirectory, "Src\\Tests");
  45. }
  46. InputTestDirectory = Path.Combine(ScriptTestDirectory, "Inputs");
  47. }
  48. }
  49. #endif
  50. public static class TestHelpers {
  51. public static LanguageContext GetContext(CodeContext context) {
  52. return context.LanguageContext;
  53. }
  54. }
  55. public delegate int IntIntDelegate(int arg);
  56. public delegate string RefStrDelegate(ref string arg);
  57. public delegate int RefIntDelegate(ref int arg);
  58. public delegate T GenericDelegate<T, U, V>(U arg1, V arg2);
  59. public class ClsPart {
  60. public int Field;
  61. int m_property;
  62. public int Property { get { return m_property; } set { m_property = value; } }
  63. public event IntIntDelegate Event;
  64. public int Method(int arg) {
  65. if (Event != null)
  66. return Event(arg);
  67. else
  68. return -1;
  69. }
  70. // Private members
  71. #pragma warning disable 169
  72. // This field is accessed from the test
  73. private int privateField;
  74. private int privateProperty { get { return m_property; } set { m_property = value; } }
  75. private event IntIntDelegate privateEvent;
  76. private int privateMethod(int arg) {
  77. if (privateEvent != null)
  78. return privateEvent(arg);
  79. else
  80. return -1;
  81. }
  82. private static int privateStaticMethod() {
  83. return 100;
  84. }
  85. #pragma warning restore 169
  86. }
  87. internal class InternalClsPart {
  88. #pragma warning disable 649
  89. // This field is accessed from the test
  90. internal int Field;
  91. #pragma warning restore 649
  92. int m_property;
  93. internal int Property { get { return m_property; } set { m_property = value; } }
  94. internal event IntIntDelegate Event;
  95. internal int Method(int arg) {
  96. if (Event != null)
  97. return Event(arg);
  98. else
  99. return -1;
  100. }
  101. }
  102. public class EngineTest
  103. #if !SILVERLIGHT // remoting not supported in Silverlight
  104. : MarshalByRefObject
  105. #endif
  106. {
  107. private readonly ScriptEngine _pe;
  108. private readonly ScriptRuntime _env;
  109. public EngineTest() {
  110. // Load a script with all the utility functions that are required
  111. // pe.ExecuteFile(InputTestDirectory + "\\EngineTests.py");
  112. _env = Python.CreateRuntime();
  113. _env.LoadAssembly(typeof(string).Assembly);
  114. _env.LoadAssembly(typeof(Debug).Assembly);
  115. _pe = _env.GetEngine("py");
  116. }
  117. // Used to test exception thrown in another domain can be shown correctly.
  118. public void Run(string script) {
  119. ScriptScope scope = _env.CreateScope();
  120. _pe.CreateScriptSourceFromString(script, SourceCodeKind.File).Execute(scope);
  121. }
  122. static readonly string clspartName = "clsPart";
  123. /// <summary>
  124. /// Asserts an condition it true
  125. /// </summary>
  126. private static void Assert(bool condition, string msg) {
  127. if (!condition) throw new Exception(String.Format("Assertion failed: {0}", msg));
  128. }
  129. private static void Assert(bool condition) {
  130. if (!condition) throw new Exception("Assertion failed");
  131. }
  132. private static T AssertExceptionThrown<T>(Action f) where T : Exception {
  133. try {
  134. f();
  135. } catch (T ex) {
  136. return ex;
  137. }
  138. Assert(false, "Expecting exception '" + typeof(T) + "'.");
  139. return null;
  140. }
  141. #if !SILVERLIGHT
  142. public void ScenarioHostingHelpers() {
  143. AppDomain remote = AppDomain.CreateDomain("foo");
  144. Dictionary<string, object> options = new Dictionary<string,object>();
  145. // DLR ScriptRuntime options
  146. options["Debug"] = true;
  147. options["PrivateBinding"] = true;
  148. // python options
  149. options["StripDocStrings"] = true;
  150. options["Optimize"] = true;
  151. options["DivisionOptions"] = PythonDivisionOptions.New;
  152. options["RecursionLimit"] = 42;
  153. options["IndentationInconsistencySeverity"] = Severity.Warning;
  154. options["WarningFilters"] = new string[] { "warnonme" };
  155. ScriptEngine engine1 = Python.CreateEngine();
  156. ScriptEngine engine2 = Python.CreateEngine(AppDomain.CurrentDomain);
  157. ScriptEngine engine3 = Python.CreateEngine(remote);
  158. TestEngines(null, new ScriptEngine[] { engine1, engine2, engine3 });
  159. ScriptEngine engine4 = Python.CreateEngine(options);
  160. ScriptEngine engine5 = Python.CreateEngine(AppDomain.CurrentDomain, options);
  161. ScriptEngine engine6 = Python.CreateEngine(remote, options);
  162. TestEngines(options, new ScriptEngine[] { engine4, engine5, engine6 });
  163. ScriptRuntime runtime1 = Python.CreateRuntime();
  164. ScriptRuntime runtime2 = Python.CreateRuntime(AppDomain.CurrentDomain);
  165. ScriptRuntime runtime3 = Python.CreateRuntime(remote);
  166. TestRuntimes(null, new ScriptRuntime[] { runtime1, runtime2, runtime3 });
  167. ScriptRuntime runtime4 = Python.CreateRuntime(options);
  168. ScriptRuntime runtime5 = Python.CreateRuntime(AppDomain.CurrentDomain, options);
  169. ScriptRuntime runtime6 = Python.CreateRuntime(remote, options);
  170. TestRuntimes(options, new ScriptRuntime[] { runtime4, runtime5, runtime6 });
  171. }
  172. private void TestEngines(Dictionary<string, object> options, ScriptEngine[] engines) {
  173. foreach (ScriptEngine engine in engines) {
  174. TestEngine(engine, options);
  175. TestRuntime(engine.Runtime, options);
  176. }
  177. }
  178. private void TestRuntimes(Dictionary<string, object> options, ScriptRuntime[] runtimes) {
  179. foreach (ScriptRuntime runtime in runtimes) {
  180. TestRuntime(runtime, options);
  181. TestEngine(Python.GetEngine(runtime), options);
  182. }
  183. }
  184. private void TestEngine(ScriptEngine scriptEngine, Dictionary<string, object> options) {
  185. // basic smoke tests that the engine is alive and working
  186. AreEqual((int)scriptEngine.CreateScriptSourceFromString("42").Execute(scriptEngine.CreateScope()), 42);
  187. if(options != null) {
  188. PythonOptions po = (PythonOptions)Microsoft.Scripting.Hosting.Providers.HostingHelpers.CallEngine<object, LanguageOptions>(
  189. scriptEngine,
  190. (lc, obj) => lc.Options,
  191. null
  192. );
  193. AreEqual(po.StripDocStrings, true);
  194. AreEqual(po.Optimize, true);
  195. AreEqual(po.DivisionOptions, PythonDivisionOptions.New);
  196. AreEqual(po.RecursionLimit, 42);
  197. AreEqual(po.IndentationInconsistencySeverity, Severity.Warning);
  198. AreEqual(po.WarningFilters[0], "warnonme");
  199. }
  200. AreEqual(Python.GetSysModule(scriptEngine).GetVariable<string>("platform"), "cli");
  201. AreEqual(Python.GetBuiltinModule(scriptEngine).GetVariable<bool>("True"), true);
  202. AreEqual(Python.ImportModule(scriptEngine, "nt").GetVariable<int>("F_OK"), 0);
  203. try {
  204. Python.ImportModule(scriptEngine, "non_existant_module");
  205. Assert(false);
  206. } catch (ImportException) {
  207. }
  208. }
  209. private void TestRuntime(ScriptRuntime runtime, Dictionary<string, object> options) {
  210. // basic smoke tests that the runtime is alive and working
  211. runtime.Globals.SetVariable("hello", 42);
  212. Assert(runtime.GetEngine("py") != null);
  213. if (options != null) {
  214. AreEqual(runtime.Setup.DebugMode, true);
  215. AreEqual(runtime.Setup.PrivateBinding, true);
  216. }
  217. AreEqual(Python.GetSysModule(runtime).GetVariable<string>("platform"), "cli");
  218. AreEqual(Python.GetBuiltinModule(runtime).GetVariable<bool>("True"), true);
  219. AreEqual(Python.ImportModule(runtime, "nt").GetVariable<int>("F_OK"), 0);
  220. try {
  221. Python.ImportModule(runtime, "non_existant_module");
  222. Assert(false);
  223. } catch (ImportException) {
  224. }
  225. }
  226. #endif
  227. // Execute
  228. public void ScenarioExecute() {
  229. ClsPart clsPart = new ClsPart();
  230. ScriptScope scope = _env.CreateScope();
  231. scope.SetVariable(clspartName, clsPart);
  232. // field: assign and get back
  233. _pe.CreateScriptSourceFromString("clsPart.Field = 100", SourceCodeKind.Statements).Execute(scope);
  234. _pe.CreateScriptSourceFromString("if 100 != clsPart.Field: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  235. AreEqual(100, clsPart.Field);
  236. // property: assign and get back
  237. _pe.CreateScriptSourceFromString("clsPart.Property = clsPart.Field", SourceCodeKind.Statements).Execute(scope);
  238. _pe.CreateScriptSourceFromString("if 100 != clsPart.Property: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  239. AreEqual(100, clsPart.Property);
  240. // method: Event not set yet
  241. _pe.CreateScriptSourceFromString("a = clsPart.Method(2)", SourceCodeKind.Statements).Execute(scope);
  242. _pe.CreateScriptSourceFromString("if -1 != a: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  243. // method: add python func as event handler
  244. _pe.CreateScriptSourceFromString("def f(x) : return x * x", SourceCodeKind.Statements).Execute(scope);
  245. _pe.CreateScriptSourceFromString("clsPart.Event += f", SourceCodeKind.Statements).Execute(scope);
  246. _pe.CreateScriptSourceFromString("a = clsPart.Method(2)", SourceCodeKind.Statements).Execute(scope);
  247. _pe.CreateScriptSourceFromString("if 4 != a: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  248. // ===============================================
  249. // reset the same variable with instance of the same type
  250. scope.SetVariable(clspartName, new ClsPart());
  251. _pe.CreateScriptSourceFromString("if 0 != clsPart.Field: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  252. // add cls method as event handler
  253. scope.SetVariable("clsMethod", new IntIntDelegate(Negate));
  254. _pe.CreateScriptSourceFromString("clsPart.Event += clsMethod", SourceCodeKind.Statements).Execute(scope);
  255. _pe.CreateScriptSourceFromString("a = clsPart.Method(2)", SourceCodeKind.Statements).Execute(scope);
  256. _pe.CreateScriptSourceFromString("if -2 != a: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  257. // ===============================================
  258. // reset the same variable with integer
  259. scope.SetVariable(clspartName, 1);
  260. _pe.CreateScriptSourceFromString("if 1 != clsPart: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
  261. AreEqual((int)scope.GetVariable(clspartName), 1);
  262. ScriptSource su = _pe.CreateScriptSourceFromString("");
  263. AssertExceptionThrown<ArgumentNullException>(delegate() {
  264. su.Execute(null);
  265. });
  266. }
  267. public void ScenarioEvaluateInAnonymousEngineModule() {
  268. ScriptScope scope1 = _env.CreateScope();
  269. ScriptScope scope2 = _env.CreateScope();
  270. ScriptScope scope3 = _env.CreateScope();
  271. _pe.CreateScriptSourceFromString("x = 0", SourceCodeKind.Statements).Execute(scope1);
  272. _pe.CreateScriptSourceFromString("x = 1", SourceCodeKind.Statements).Execute(scope2);
  273. scope3.SetVariable("x", 2);
  274. AreEqual(0, _pe.CreateScriptSourceFromString("x").Execute<int>(scope1));
  275. AreEqual(0, (int)scope1.GetVariable("x"));
  276. AreEqual(1, _pe.CreateScriptSourceFromString("x").Execute<int>(scope2));
  277. AreEqual(1, (int)scope2.GetVariable("x"));
  278. AreEqual(2, _pe.CreateScriptSourceFromString("x").Execute<int>(scope3));
  279. AreEqual(2, (int)scope3.GetVariable("x"));
  280. }
  281. public void ScenarioCP712() {
  282. ScriptScope scope1 = _env.CreateScope();
  283. _pe.CreateScriptSourceFromString("max(3, 4)", SourceCodeKind.InteractiveCode).Execute(scope1);
  284. //CompiledCode compiledCode = _pe.CreateScriptSourceFromString("max(3,4)", SourceCodeKind.InteractiveCode).Compile();
  285. //compiledCode.Execute(scope1);
  286. //AreEqual(4, scope1.GetVariable<int>("__builtins__._"));
  287. //TODO - this currently fails.
  288. //AreEqual(4, scope1.GetVariable<int>("_"));
  289. }
  290. public void ScenarioEvaluateInPublishedEngineModule() {
  291. PythonContext pc = DefaultContext.DefaultPythonContext;
  292. PythonModule publishedModule = pc.CreateModule();
  293. PythonModule otherModule = pc.CreateModule();
  294. pc.PublishModule("published_context_test", publishedModule);
  295. pc.CreateSnippet("x = 0", SourceCodeKind.Statements).Execute(otherModule.Scope);
  296. pc.CreateSnippet("x = 1", SourceCodeKind.Statements).Execute(publishedModule.Scope);
  297. object x;
  298. // Ensure that the default EngineModule is not affected
  299. x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
  300. AreEqual(0, (int)x);
  301. // Ensure that the published context has been updated as expected
  302. x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(publishedModule.Scope);
  303. AreEqual(1, (int)x);
  304. // Ensure that the published context is accessible from other contexts using sys.modules
  305. // TODO: do better:
  306. // pe.Import("sys", ScriptDomainManager.CurrentManager.DefaultModule);
  307. pc.CreateSnippet("from published_context_test import x", SourceCodeKind.Statements).Execute(otherModule.Scope);
  308. x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
  309. AreEqual(1, (int)x);
  310. }
  311. class CustomDictionary : IDictionary<string, object> {
  312. // Make "customSymbol" always be accessible. This could have been accomplished just by
  313. // doing SetGlobal. However, this mechanism could be used for other extensibility
  314. // purposes like getting a callback whenever the symbol is read
  315. internal static readonly string customSymbol = "customSymbol";
  316. internal const int customSymbolValue = 100;
  317. Dictionary<string, object> dict = new Dictionary<string, object>();
  318. #region IDictionary<string,object> Members
  319. public void Add(string key, object value) {
  320. if (key.Equals(customSymbol))
  321. throw new UnboundNameException("Cannot assign to customSymbol");
  322. dict.Add(key, value);
  323. }
  324. public bool ContainsKey(string key) {
  325. if (key.Equals(customSymbol))
  326. return true;
  327. return dict.ContainsKey(key);
  328. }
  329. public ICollection<string> Keys {
  330. get { throw new NotImplementedException("The method or operation is not implemented."); }
  331. }
  332. public bool Remove(string key) {
  333. if (key.Equals(customSymbol))
  334. throw new UnboundNameException("Cannot delete customSymbol");
  335. return dict.Remove(key);
  336. }
  337. public bool TryGetValue(string key, out object value) {
  338. if (key.Equals(customSymbol)) {
  339. value = customSymbolValue;
  340. return true;
  341. }
  342. return dict.TryGetValue(key, out value);
  343. }
  344. public ICollection<object> Values {
  345. get { throw new NotImplementedException("The method or operation is not implemented."); }
  346. }
  347. public object this[string key] {
  348. get {
  349. if (key.Equals(customSymbol))
  350. return customSymbolValue;
  351. return dict[key];
  352. }
  353. set {
  354. if (key.Equals(customSymbol))
  355. throw new UnboundNameException("Cannot assign to customSymbol");
  356. dict[key] = value;
  357. }
  358. }
  359. #endregion
  360. #region ICollection<KeyValuePair<string,object>> Members
  361. public void Add(KeyValuePair<string, object> item) {
  362. throw new NotImplementedException("The method or operation is not implemented.");
  363. }
  364. public void Clear() {
  365. throw new NotImplementedException("The method or operation is not implemented.");
  366. }
  367. public bool Contains(KeyValuePair<string, object> item) {
  368. throw new NotImplementedException("The method or operation is not implemented.");
  369. }
  370. public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
  371. throw new NotImplementedException("The method or operation is not implemented.");
  372. }
  373. public int Count {
  374. get { throw new NotImplementedException("The method or operation is not implemented."); }
  375. }
  376. public bool IsReadOnly {
  377. get { throw new NotImplementedException("The method or operation is not implemented."); }
  378. }
  379. public bool Remove(KeyValuePair<string, object> item) {
  380. throw new NotImplementedException("The method or operation is not implemented.");
  381. }
  382. #endregion
  383. #region IEnumerable<KeyValuePair<string,object>> Members
  384. public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
  385. throw new NotImplementedException("The method or operation is not implemented.");
  386. }
  387. #endregion
  388. #region IEnumerable Members
  389. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
  390. throw new NotImplementedException("The method or operation is not implemented.");
  391. }
  392. #endregion
  393. }
  394. public void ScenarioCustomDictionary() {
  395. IAttributesCollection customGlobals = new PythonDictionary(new StringDictionaryStorage(new CustomDictionary()));
  396. ScriptScope customModule = _pe.Runtime.CreateScope(customGlobals);
  397. // Evaluate
  398. AreEqual(_pe.CreateScriptSourceFromString("customSymbol + 1").Execute<int>(customModule), CustomDictionary.customSymbolValue + 1);
  399. // Execute
  400. _pe.CreateScriptSourceFromString("customSymbolPlusOne = customSymbol + 1", SourceCodeKind.Statements).Execute(customModule);
  401. AreEqual(_pe.CreateScriptSourceFromString("customSymbolPlusOne").Execute<int>(customModule), CustomDictionary.customSymbolValue + 1);
  402. AreEqual(_pe.GetVariable<int>(customModule, "customSymbolPlusOne"), CustomDictionary.customSymbolValue + 1);
  403. // Compile
  404. CompiledCode compiledCode = _pe.CreateScriptSourceFromString("customSymbolPlusTwo = customSymbol + 2", SourceCodeKind.Statements).Compile();
  405. compiledCode.Execute(customModule);
  406. AreEqual(_pe.CreateScriptSourceFromString("customSymbolPlusTwo").Execute<int>(customModule), CustomDictionary.customSymbolValue + 2);
  407. AreEqual(_pe.GetVariable<int>(customModule, "customSymbolPlusTwo"), CustomDictionary.customSymbolValue + 2);
  408. // check overriding of Add
  409. try {
  410. _pe.CreateScriptSourceFromString("customSymbol = 1", SourceCodeKind.Statements).Execute(customModule);
  411. throw new Exception("We should not reach here");
  412. } catch (UnboundNameException) { }
  413. try {
  414. _pe.CreateScriptSourceFromString(@"global customSymbol
  415. customSymbol = 1", SourceCodeKind.Statements).Execute(customModule);
  416. throw new Exception("We should not reach here");
  417. } catch (UnboundNameException) { }
  418. // check overriding of Remove
  419. try {
  420. _pe.CreateScriptSourceFromString("del customSymbol", SourceCodeKind.Statements).Execute(customModule);
  421. throw new Exception("We should not reach here");
  422. } catch (UnboundNameException) { }
  423. try {
  424. _pe.CreateScriptSourceFromString(@"global customSymbol
  425. del customSymbol", SourceCodeKind.Statements).Execute(customModule);
  426. throw new Exception("We should not reach here");
  427. } catch (UnboundNameException) { }
  428. // vars()
  429. IDictionary vars = _pe.CreateScriptSourceFromString("vars()").Execute<IDictionary>(customModule);
  430. AreEqual(true, vars.Contains("customSymbol"));
  431. // Miscellaneous APIs
  432. //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("customSymbol + arg", customModule);
  433. //AreEqual(d(1), CustomDictionary.customSymbolValue + 1);
  434. }
  435. // Evaluate
  436. public void ScenarioEvaluate() {
  437. ScriptScope scope = _env.CreateScope();
  438. AreEqual(10, (int)_pe.CreateScriptSourceFromString("4+6").Execute(scope));
  439. AreEqual(10, _pe.CreateScriptSourceFromString("4+6").Execute<int>(scope));
  440. AreEqual("abab", (string)_pe.CreateScriptSourceFromString("'ab' * 2").Execute(scope));
  441. AreEqual("abab", _pe.CreateScriptSourceFromString("'ab' * 2").Execute<string>(scope));
  442. ClsPart clsPart = new ClsPart();
  443. scope.SetVariable(clspartName, clsPart);
  444. AreEqual(clsPart, _pe.CreateScriptSourceFromString("clsPart").Execute(scope) as ClsPart);
  445. AreEqual(clsPart, _pe.CreateScriptSourceFromString("clsPart").Execute<ClsPart>(scope));
  446. _pe.CreateScriptSourceFromString("clsPart.Field = 100", SourceCodeKind.Statements).Execute(scope);
  447. AreEqual(100, (int)_pe.CreateScriptSourceFromString("clsPart.Field").Execute(scope));
  448. AreEqual(100, _pe.CreateScriptSourceFromString("clsPart.Field").Execute<int>(scope));
  449. // Ensure that we can get back a delegate to a Python method
  450. _pe.CreateScriptSourceFromString("def IntIntMethod(a): return a * 100", SourceCodeKind.Statements).Execute(scope);
  451. IntIntDelegate d = _pe.CreateScriptSourceFromString("IntIntMethod").Execute<IntIntDelegate>(scope);
  452. AreEqual(d(2), 2 * 100);
  453. }
  454. public void ScenarioCallableClassToDelegate() {
  455. ScriptSource src = _pe.CreateScriptSourceFromString(@"
  456. class Test(object):
  457. def __call__(self):
  458. return 42
  459. inst = Test()
  460. class TestOC:
  461. def __call__(self):
  462. return 42
  463. instOC = TestOC()
  464. ", SourceCodeKind.Statements);
  465. ScriptScope scope = _pe.CreateScope();
  466. src.Execute(scope);
  467. Func<int> t = scope.GetVariable<Func<int>>("inst");
  468. AreEqual(42, t());
  469. t = scope.GetVariable<Func<int>>("instOC");
  470. AreEqual(42, t());
  471. }
  472. #if !SILVERLIGHT
  473. // ExecuteFile
  474. public void ScenarioExecuteFile() {
  475. ScriptSource tempFile1, tempFile2;
  476. ScriptScope scope = _env.CreateScope();
  477. using (StringWriter sw = new StringWriter()) {
  478. sw.WriteLine("var1 = (10, 'z')");
  479. sw.WriteLine("");
  480. sw.WriteLine("clsPart.Field = 100");
  481. sw.WriteLine("clsPart.Property = clsPart.Field * 5");
  482. sw.WriteLine("clsPart.Event += (lambda x: x*x)");
  483. tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
  484. }
  485. ClsPart clsPart = new ClsPart();
  486. scope.SetVariable(clspartName, clsPart);
  487. tempFile1.Execute(scope);
  488. using (StringWriter sw = new StringWriter()) {
  489. sw.WriteLine("if var1[0] != 10: raise AssertionError('test failed')");
  490. sw.WriteLine("if var1[1] != 'z': raise AssertionError('test failed')");
  491. sw.WriteLine("");
  492. sw.WriteLine("if clsPart.Property != clsPart.Field * 5: raise AssertionError('test failed')");
  493. sw.WriteLine("var2 = clsPart.Method(var1[0])");
  494. sw.WriteLine("if var2 != 10 * 10: raise AssertionError('test failed')");
  495. tempFile2 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
  496. }
  497. tempFile2.Execute(scope);
  498. }
  499. #endif
  500. #if !SILVERLIGHT
  501. // Bug: 542
  502. public void Scenario542() {
  503. ScriptSource tempFile1;
  504. ScriptScope scope = _env.CreateScope();
  505. using (StringWriter sw = new StringWriter()) {
  506. sw.WriteLine("def M1(): return -1");
  507. sw.WriteLine("def M2(): return +1");
  508. sw.WriteLine("class C:");
  509. sw.WriteLine(" def M1(self): return -1");
  510. sw.WriteLine(" def M2(self): return +1");
  511. sw.WriteLine("class C1:");
  512. sw.WriteLine(" def M(): return -1");
  513. sw.WriteLine("class C2:");
  514. sw.WriteLine(" def M(): return +1");
  515. tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
  516. }
  517. tempFile1.Execute(scope);
  518. AreEqual(-1, _pe.CreateScriptSourceFromString("M1()").Execute<int>(scope));
  519. AreEqual(+1, _pe.CreateScriptSourceFromString("M2()").Execute<int>(scope));
  520. AreEqual(-1, (int)_pe.CreateScriptSourceFromString("M1()").Execute(scope));
  521. AreEqual(+1, (int)_pe.CreateScriptSourceFromString("M2()").Execute(scope));
  522. _pe.CreateScriptSourceFromString("if M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  523. _pe.CreateScriptSourceFromString("if M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  524. _pe.CreateScriptSourceFromString("c = C()", SourceCodeKind.SingleStatement).Execute(scope);
  525. AreEqual(-1, _pe.CreateScriptSourceFromString("c.M1()").Execute<int>(scope));
  526. AreEqual(+1, _pe.CreateScriptSourceFromString("c.M2()").Execute<int>(scope));
  527. AreEqual(-1, (int)_pe.CreateScriptSourceFromString("c.M1()").Execute(scope));
  528. AreEqual(+1, (int)_pe.CreateScriptSourceFromString("c.M2()").Execute(scope));
  529. _pe.CreateScriptSourceFromString("if c.M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  530. _pe.CreateScriptSourceFromString("if c.M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
  531. //AreEqual(-1, pe.EvaluateAs<int>("C1.M()"));
  532. //AreEqual(+1, pe.EvaluateAs<int>("C2.M()"));
  533. //AreEqual(-1, (int)pe.Evaluate("C1.M()"));
  534. //AreEqual(+1, (int)pe.Evaluate("C2.M()"));
  535. //pe.Execute(pe.CreateScriptSourceFromString("if C1.M() != -1: raise AssertionError('test failed')");
  536. //pe.Execute(pe.CreateScriptSourceFromString("if C2.M() != +1: raise AssertionError('test failed')");
  537. }
  538. #endif
  539. // Bug: 167
  540. public void Scenario167() {
  541. ScriptScope scope = _env.CreateScope();
  542. _pe.CreateScriptSourceFromString("a=1\r\nb=-1", SourceCodeKind.Statements).Execute(scope);
  543. AreEqual(1, _pe.CreateScriptSourceFromString("a").Execute<int>(scope));
  544. AreEqual(-1, _pe.CreateScriptSourceFromString("b").Execute<int>(scope));
  545. }
  546. #if !SILVERLIGHT
  547. // AddToPath
  548. public void ScenarioAddToPath() { // runs first to avoid path-order issues
  549. //pe.InitializeModules(ipc_path, ipc_path + "\\ipy.exe", pe.VersionString);
  550. string tempFile1 = Path.GetTempFileName();
  551. try {
  552. File.WriteAllText(tempFile1, "from iptest.does_not_exist import *");
  553. ScriptScope scope = _pe.Runtime.CreateScope();
  554. try {
  555. _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
  556. throw new Exception("Scenario7");
  557. } catch (IronPython.Runtime.Exceptions.ImportException) { }
  558. File.WriteAllText(tempFile1, "from iptest.assert_util import *");
  559. _pe.SetSearchPaths(new string[] { Common.ScriptTestDirectory });
  560. _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
  561. _pe.CreateScriptSourceFromString("AreEqual(5, eval('2 + 3'))", SourceCodeKind.Statements).Execute(scope);
  562. } finally {
  563. File.Delete(tempFile1);
  564. }
  565. }
  566. // Options.DebugMode
  567. #endif
  568. #if !SILVERLIGHT
  569. public void ScenarioPartialTrust() {
  570. // basic check of running a host in partial trust
  571. AppDomainSetup info = new AppDomainSetup();
  572. info.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
  573. info.ApplicationName = "Test";
  574. Evidence evidence = new Evidence();
  575. evidence.AddHost(new Zone(SecurityZone.Internet));
  576. AppDomain newDomain = AppDomain.CreateDomain("test", evidence, info);
  577. // create runtime in partial trust...
  578. ScriptRuntime runtime = Python.CreateRuntime(newDomain);
  579. // get the Python engine...
  580. ScriptEngine engine = runtime.GetEngine("py");
  581. // execute some simple code
  582. ScriptScope scope = engine.CreateScope();
  583. ScriptSource source = engine.CreateScriptSourceFromString("2 + 2");
  584. AreEqual(source.Execute<int>(scope), 4);
  585. // import all of the built-in modules & make sure we can reflect on them...
  586. source = engine.CreateScriptSourceFromString(@"
  587. import sys
  588. for mod in sys.builtin_module_names:
  589. x = __import__(mod)
  590. dir(x)
  591. ", SourceCodeKind.Statements);
  592. source.Execute(scope);
  593. // define some classes & use the methods...
  594. source = engine.CreateScriptSourceFromString(@"
  595. class x(object):
  596. def f(self): return 1 + 2
  597. a = x()
  598. a.f()
  599. class y:
  600. def f(self): return 1 + 2
  601. b = y()
  602. b.f()
  603. ", SourceCodeKind.Statements);
  604. source.Execute(scope);
  605. // call a protected method on a derived class...
  606. source = engine.CreateScriptSourceFromString(@"
  607. import clr
  608. class x(object):
  609. def f(self): return 1 + 2
  610. a = x()
  611. b = a.MemberwiseClone()
  612. if id(a) == id(b):
  613. raise Exception
  614. ", SourceCodeKind.Statements);
  615. source.Execute(scope);
  616. AppDomain.Unload(newDomain);
  617. }
  618. public void ScenarioStackFrameLineInfo() {
  619. const string lineNumber = "raise.py:line";
  620. // TODO: clone setup?
  621. var scope = Python.CreateRuntime().CreateScope("py");
  622. var debugSetup = Python.CreateRuntimeSetup(null);
  623. debugSetup.DebugMode = true;
  624. var debugScope = new ScriptRuntime(debugSetup).CreateScope("py");
  625. TestLineInfo(scope, lineNumber);
  626. TestLineInfo(debugScope, lineNumber);
  627. TestLineInfo(scope, lineNumber);
  628. // Ensure that all APIs work
  629. AreEqual(scope.GetVariable<int>("x"), 1);
  630. //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("arg + x");
  631. //AreEqual(d(100), 101);
  632. //d = pe.CreateMethod<IntIntDelegate>("var = arg + x\nreturn var");
  633. //AreEqual(d(100), 101);
  634. }
  635. private void TestLineInfo(ScriptScope/*!*/ scope, string lineNumber) {
  636. try {
  637. scope.Engine.ExecuteFile(Common.InputTestDirectory + "\\raise.py", scope);
  638. throw new Exception("We should not get here");
  639. } catch (StringException e2) {
  640. if (scope.Engine.Runtime.Setup.DebugMode != e2.StackTrace.Contains(lineNumber))
  641. throw new Exception("Debugging is enabled even though Options.DebugMode is not specified");
  642. }
  643. }
  644. #endif
  645. // Compile and Run
  646. public void ScenarioCompileAndRun() {
  647. ClsPart clsPart = new ClsPart();
  648. ScriptScope scope = _env.CreateScope();
  649. scope.SetVariable(clspartName, clsPart);
  650. CompiledCode compiledCode = _pe.CreateScriptSourceFromString("def f(): clsPart.Field += 10", SourceCodeKind.Statements).Compile();
  651. compiledCode.Execute(scope);
  652. compiledCode = _pe.CreateScriptSourceFromString("f()").Compile();
  653. compiledCode.Execute(scope);
  654. AreEqual(10, clsPart.Field);
  655. compiledCode.Execute(scope);
  656. AreEqual(20, clsPart.Field);
  657. }
  658. public void ScenarioStreamRedirect() {
  659. MemoryStream stdout = new MemoryStream();
  660. MemoryStream stdin = new MemoryStream();
  661. MemoryStream stderr = new MemoryStream();
  662. Encoding encoding = Encoding.UTF8;
  663. _pe.Runtime.IO.SetInput(stdin, encoding);
  664. _pe.Runtime.IO.SetOutput(stdout, encoding);
  665. _pe.Runtime.IO.SetErrorOutput(stderr, encoding);
  666. const string str = "This is stdout";
  667. byte[] bytes = encoding.GetBytes(str);
  668. try {
  669. ScriptScope scope = _pe.Runtime.CreateScope();
  670. _pe.CreateScriptSourceFromString("import sys", SourceCodeKind.Statements).Execute(scope);
  671. stdin.Write(bytes, 0, bytes.Length);
  672. stdin.Position = 0;
  673. _pe.CreateScriptSourceFromString("output = sys.__stdin__.readline()", SourceCodeKind.Statements).Execute(scope);
  674. AreEqual(str, _pe.CreateScriptSourceFromString("output").Execute<string>(scope));
  675. _pe.CreateScriptSourceFromString("sys.__stdout__.write(output)", SourceCodeKind.Statements).Execute(scope);
  676. stdout.Flush();
  677. stdout.Position = 0;
  678. // deals with BOM:
  679. using (StreamReader reader = new StreamReader(stdout, true)) {
  680. string s = reader.ReadToEnd();
  681. AreEqual(str, s);
  682. }
  683. _pe.CreateScriptSourceFromString("sys.__stderr__.write(\"This is stderr\")", SourceCodeKind.Statements).Execute(scope);
  684. stderr.Flush();
  685. stderr.Position = 0;
  686. // deals with BOM:
  687. using (StreamReader reader = new StreamReader(stderr, true)) {
  688. string s = reader.ReadToEnd();
  689. AreEqual("This is stderr", s);
  690. }
  691. } finally {
  692. _pe.Runtime.IO.RedirectToConsole();
  693. }
  694. }
  695. public void Scenario12() {
  696. ScriptScope scope = _env.CreateScope();
  697. _pe.CreateScriptSourceFromString(@"
  698. class R(object):
  699. def __init__(self, a, b):
  700. self.a = a
  701. self.b = b
  702. def M(self):
  703. return self.a + self.b
  704. sum = property(M, None, None, None)
  705. r = R(10, 100)
  706. if r.sum != 110:
  707. raise AssertionError('Scenario 12 failed')
  708. ", SourceCodeKind.Statements).Execute(scope);
  709. }
  710. // TODO: rewrite
  711. #if FALSE
  712. public void ScenarioTrueDivision1() {
  713. TestOldDivision(pe, DefaultModule);
  714. ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
  715. TestNewDivision(pe, module);
  716. }
  717. public void ScenarioTrueDivision2() {
  718. TestOldDivision(pe, DefaultModule);
  719. ScriptScope module = pe.CreateModule("__future__", ModuleOptions.PublishModule);
  720. module.SetVariable("division", 1);
  721. pe.Execute(pe.CreateScriptSourceFromString("from __future__ import division", module));
  722. TestNewDivision(pe, module);
  723. }
  724. public void ScenarioTrueDivision3() {
  725. TestOldDivision(pe, DefaultModule);
  726. ScriptScope future = pe.CreateModule("__future__", ModuleOptions.PublishModule);
  727. future.SetVariable("division", 1);
  728. ScriptScope td = pe.CreateModule("truediv", ModuleOptions.None);
  729. ScriptCode cc = ScriptCode.FromCompiledCode((CompiledCode)pe.CompileCode("from __future__ import division"));
  730. cc.Run(td);
  731. TestNewDivision(pe, td); // we've polluted the DefaultModule by executing the code
  732. }
  733. #if !SILVERLIGHT
  734. public void ScenarioTrueDivision4() {
  735. pe.AddToPath(Common.ScriptTestDirectory);
  736. string modName = GetTemporaryModuleName();
  737. string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
  738. System.IO.File.WriteAllText(file, "result = 1/2");
  739. PythonDivisionOptions old = PythonEngine.CurrentEngine.Options.DivisionOptions;
  740. try {
  741. PythonEngine.CurrentEngine.Options.DivisionOptions = PythonDivisionOptions.Old;
  742. ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
  743. pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
  744. int res = pe.EvaluateAs<int>(modName + ".result", module);
  745. AreEqual(res, 0);
  746. } finally {
  747. PythonEngine.CurrentEngine.Options.DivisionOptions = old;
  748. try {
  749. System.IO.File.Delete(file);
  750. } catch { }
  751. }
  752. }
  753. private string GetTemporaryModuleName() {
  754. return "tempmod" + Path.GetRandomFileName().Replace('-', '_').Replace('.', '_');
  755. }
  756. public void ScenarioTrueDivision5() {
  757. pe.AddToPath(Common.ScriptTestDirectory);
  758. string modName = GetTemporaryModuleName();
  759. string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
  760. System.IO.File.WriteAllText(file, "from __future__ import division; result = 1/2");
  761. try {
  762. ScriptScope module = ScriptDomainManager.CurrentManager.CreateModule(modName);
  763. pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
  764. double res = pe.EvaluateAs<double>(modName + ".result", module);
  765. AreEqual(res, 0.5);
  766. AreEqual((bool)((PythonContext)DefaultContext.Default.LanguageContext).TrueDivision, false);
  767. } finally {
  768. try {
  769. System.IO.File.Delete(file);
  770. } catch { }
  771. }
  772. }
  773. public void ScenarioSystemStatePrefix() {
  774. AreEqual(IronPythonTest.Common.RuntimeDirectory, pe.SystemState.prefix);
  775. }
  776. #endif
  777. private static void TestOldDivision(ScriptEngine pe, ScriptScope module) {
  778. pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
  779. AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0);
  780. AreEqual(pe.EvaluateAs<int>("1/2", module), 0);
  781. pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
  782. AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1);
  783. AreEqual(pe.EvaluateAs<int>("eval('3/2')", module), 1);
  784. }
  785. private static void TestNewDivision(ScriptEngine pe, ScriptScope module) {
  786. pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
  787. AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0.5);
  788. AreEqual(pe.EvaluateAs<double>("1/2", module), 0.5);
  789. pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
  790. AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1.5);
  791. AreEqual(pe.EvaluateAs<double>("eval('3/2')", module), 1.5);
  792. }
  793. #endif
  794. // More to come: exception related...
  795. public static int Negate(int arg) { return -1 * arg; }
  796. static void AreEqual<T>(T expected, T actual) {
  797. if (expected == null && actual == null) return;
  798. if (!expected.Equals(actual)) {
  799. Console.WriteLine("Expected: {0} Got: {1} from {2}", expected, actual, new StackTrace(true));
  800. throw new Exception();
  801. }
  802. }
  803. }
  804. }