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

/IronPython_2_0/Src/IronPython/Runtime/Builtin.cs

#
C# | 1900 lines | 1517 code | 312 blank | 71 comment | 421 complexity | d5d1d1dda4e2fa8ea4864a9870255b0a MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0

Large files files are truncated, but you can click here to view the full 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.Runtime.InteropServices;
  20. using Microsoft.Scripting.Actions;
  21. using System.Text;
  22. using IronPython.Compiler;
  23. using IronPython.Runtime;
  24. using IronPython.Runtime.Binding;
  25. using IronPython.Runtime.Exceptions;
  26. using IronPython.Runtime.Operations;
  27. using IronPython.Runtime.Types;
  28. using Microsoft.Scripting;
  29. using Microsoft.Scripting.Math;
  30. using Microsoft.Scripting.Runtime;
  31. using Microsoft.Scripting.Utils;
  32. using SpecialName = System.Runtime.CompilerServices.SpecialNameAttribute;
  33. using Microsoft.Scripting.Generation;
  34. [assembly: PythonModule("__builtin__", typeof(Builtin))]
  35. namespace IronPython.Runtime {
  36. [Documentation("")] // Documentation suppresses XML Doc on startup.
  37. public static partial class Builtin {
  38. public static object True {
  39. get {
  40. return RuntimeHelpers.True;
  41. }
  42. }
  43. public static object False {
  44. get {
  45. return RuntimeHelpers.False;
  46. }
  47. }
  48. // This will always stay null
  49. public static readonly object None;
  50. public static IronPython.Runtime.Types.Ellipsis Ellipsis {
  51. get {
  52. return IronPython.Runtime.Types.Ellipsis.Value;
  53. }
  54. }
  55. public static NotImplementedType NotImplemented {
  56. get {
  57. return NotImplementedType.Value;
  58. }
  59. }
  60. public static object exit {
  61. get {
  62. return "Use Ctrl-Z plus Return to exit";
  63. }
  64. }
  65. public static object quit {
  66. get {
  67. return "Use Ctrl-Z plus Return to exit";
  68. }
  69. }
  70. [Documentation("__import__(name) -> module\n\nImport a module.")]
  71. public static object __import__(CodeContext/*!*/ context, string name) {
  72. return __import__(context, name, null, null, null);
  73. }
  74. [Documentation("__import__(name, globals) -> module\n\nImport a module.")]
  75. public static object __import__(CodeContext/*!*/ context, string name, object globals) {
  76. return __import__(context, name, globals, null, null);
  77. }
  78. [Documentation("__import__(name, globals, locals) -> module\n\nImport a module.")]
  79. public static object __import__(CodeContext/*!*/ context, string name, object globals, object locals) {
  80. return __import__(context, name, globals, locals, null);
  81. }
  82. [Documentation("__import__(name, globals, locals, fromlist) -> module\n\nImport a module.")]
  83. public static object __import__(CodeContext/*!*/ context, string name, object globals, object locals, object fromlist) {
  84. return __import__(context, name, globals, locals, fromlist, -1);
  85. }
  86. [Documentation("__import__(name, globals, locals, fromlist) -> module\n\nImport a module.")]
  87. public static object __import__(CodeContext/*!*/ context, string name, object globals, object locals, object fromlist, int level) {
  88. //!!! remove suppress in GlobalSuppressions.cs when CodePlex 2704 is fixed.
  89. ISequence from = fromlist as ISequence;
  90. PythonContext pc = PythonContext.GetContext(context);
  91. object ret = Importer.ImportModule(context, globals, name, from != null && from.__len__() > 0, level);
  92. if (ret == null) {
  93. throw PythonOps.ImportError("No module named {0}", name);
  94. }
  95. Scope mod = ret as Scope;
  96. if (mod != null && from != null) {
  97. string strAttrName;
  98. for (int i = 0; i < from.__len__(); i++) {
  99. object attrName = from[i];
  100. if (pc.TryConvertToString(attrName, out strAttrName) &&
  101. !String.IsNullOrEmpty(strAttrName) &&
  102. strAttrName != "*") {
  103. try {
  104. Importer.ImportFrom(context, mod, strAttrName);
  105. } catch (ImportException) {
  106. continue;
  107. }
  108. }
  109. }
  110. }
  111. return ret;
  112. }
  113. [Documentation("abs(number) -> number\n\nReturn the absolute value of the argument.")]
  114. public static object abs(CodeContext/*!*/ context, object o) {
  115. if (o is int) return Int32Ops.Abs((int)o);
  116. if (o is long) return Int64Ops.Abs((long)o);
  117. if (o is double) return DoubleOps.Abs((double)o);
  118. if (o is bool) return (((bool)o) ? 1 : 0);
  119. if (o is string) throw PythonOps.TypeError("bad operand type for abs()");
  120. BigInteger bi = o as BigInteger;
  121. if (!Object.ReferenceEquals(bi, null)) return BigIntegerOps.__abs__(bi);
  122. if (o is Complex64) return ComplexOps.Abs((Complex64)o);
  123. object value;
  124. if (PythonTypeOps.TryInvokeUnaryOperator(context, o, Symbols.AbsoluteValue, out value)) {
  125. return value;
  126. }
  127. throw PythonOps.TypeError("bad operand type for abs()");
  128. }
  129. public static bool all(object x) {
  130. IEnumerator i = PythonOps.GetEnumerator(x);
  131. while (i.MoveNext()) {
  132. if (!PythonOps.IsTrue(i.Current)) return false;
  133. }
  134. return true;
  135. }
  136. public static bool any(object x) {
  137. IEnumerator i = PythonOps.GetEnumerator(x);
  138. while (i.MoveNext()) {
  139. if (PythonOps.IsTrue(i.Current)) return true;
  140. }
  141. return false;
  142. }
  143. [Documentation("apply(object[, args[, kwargs]]) -> value\n\nDeprecated.\nInstead, use:\n function(*args, **keywords).")]
  144. public static object apply(CodeContext/*!*/ context, object func) {
  145. return PythonOps.CallWithContext(context, func);
  146. }
  147. public static object apply(CodeContext/*!*/ context, object func, object args) {
  148. return PythonOps.CallWithArgsTupleAndContext(context, func, ArrayUtils.EmptyObjects, args);
  149. }
  150. public static object apply(CodeContext/*!*/ context, object func, object args, object kws) {
  151. return PythonOps.CallWithArgsTupleAndKeywordDictAndContext(context, func, ArrayUtils.EmptyObjects, ArrayUtils.EmptyStrings, args, kws);
  152. }
  153. public static PythonType basestring {
  154. get {
  155. return DynamicHelpers.GetPythonTypeFromType(typeof(string));
  156. }
  157. }
  158. public static PythonType @bool {
  159. get {
  160. return DynamicHelpers.GetPythonTypeFromType(typeof(bool));
  161. }
  162. }
  163. public static PythonType buffer {
  164. get {
  165. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonBuffer));
  166. }
  167. }
  168. [Documentation("callable(object) -> bool\n\nReturn whether the object is callable (i.e., some kind of function).")]
  169. public static bool callable(CodeContext/*!*/ context, object o) {
  170. return PythonOps.IsCallable(context, o);
  171. }
  172. [Documentation("chr(i) -> character\n\nReturn a string of one character with ordinal i; 0 <= i< 256.")]
  173. public static string chr(int value) {
  174. if (value < 0 || value > 0xFF) {
  175. throw PythonOps.ValueError("{0} is not in required range", value);
  176. }
  177. return RuntimeHelpers.CharToString((char)value);
  178. }
  179. internal static object TryCoerce(CodeContext/*!*/ context, object x, object y) {
  180. PythonTypeSlot pts;
  181. PythonType xType = DynamicHelpers.GetPythonType(x);
  182. if (xType.TryResolveSlot(context, Symbols.Coerce, out pts)) {
  183. object callable;
  184. if (pts.TryGetBoundValue(context, x, xType, out callable)) {
  185. return PythonCalls.Call(context, callable, y);
  186. }
  187. }
  188. return NotImplementedType.Value;
  189. }
  190. [Documentation("coerce(x, y) -> (x1, y1)\n\nReturn a tuple consisting of the two numeric arguments converted to\na common type. If coercion is not possible, raise TypeError.")]
  191. public static object coerce(CodeContext/*!*/ context, object x, object y) {
  192. object converted;
  193. if (x == null && y == null) {
  194. return PythonTuple.MakeTuple(null, null);
  195. }
  196. converted = TryCoerce(context, x, y);
  197. if (converted != null && converted != NotImplementedType.Value) {
  198. return converted;
  199. }
  200. converted = TryCoerce(context, y, x);
  201. if (converted != null && converted != NotImplementedType.Value) {
  202. PythonTuple pt = converted as PythonTuple;
  203. if (pt != null && pt.Count == 2) {
  204. return PythonTuple.MakeTuple(pt[1], pt[0]);
  205. }
  206. }
  207. throw PythonOps.TypeError("coercion failed");
  208. }
  209. [Documentation("compile a unit of source code.\n\nThe source can be compiled either as exec, eval, or single.\nexec compiles the code as if it were a file\neval compiles the code as if were an expression\nsingle compiles a single statement\n\n")]
  210. public static object compile(CodeContext/*!*/ context, string source, string filename, string kind, object flags, object dontInherit) {
  211. if (source.IndexOf('\0') != -1) {
  212. throw PythonOps.TypeError("compile() expected string without null bytes");
  213. }
  214. bool inheritContext = GetCompilerInheritance(dontInherit);
  215. CompileFlags cflags = GetCompilerFlags(flags);
  216. PythonCompilerOptions opts = GetDefaultCompilerOptions(context, inheritContext, cflags);
  217. if ((cflags & CompileFlags.CO_DONT_IMPLY_DEDENT) != 0) {
  218. opts.DontImplyDedent = true;
  219. }
  220. opts.Module |= ModuleOptions.ExecOrEvalCode;
  221. SourceUnit sourceUnit;
  222. string unitPath = String.IsNullOrEmpty(filename) ? null : filename;
  223. switch (kind) {
  224. case "exec": sourceUnit = context.LanguageContext.CreateSnippet(source, unitPath, SourceCodeKind.Statements); break;
  225. case "eval": sourceUnit = context.LanguageContext.CreateSnippet(source, unitPath, SourceCodeKind.Expression); break;
  226. case "single": sourceUnit = context.LanguageContext.CreateSnippet(source, unitPath, SourceCodeKind.InteractiveCode); break;
  227. default:
  228. throw PythonOps.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'");
  229. }
  230. ScriptCode compiledCode = sourceUnit.Compile(opts, ThrowingErrorSink.Default);
  231. compiledCode.EnsureCompiled();
  232. FunctionCode res = new FunctionCode(compiledCode, cflags);
  233. res.SetFilename(filename);
  234. return res;
  235. }
  236. [Documentation("compile a unit of source code.\n\nThe source can be compiled either as exec, eval, or single.\nexec compiles the code as if it were a file\neval compiles the code as if were an expression\nsingle compiles a single statement\n\n")]
  237. public static object compile(CodeContext/*!*/ context, string source, string filename, string kind, object flags) {
  238. return compile(context, source, filename, kind, flags, null);
  239. }
  240. [Documentation("compile a unit of source code.\n\nThe source can be compiled either as exec, eval, or single.\nexec compiles the code as if it were a file\neval compiles the code as if were an expression\nsingle compiles a single statement\n\n")]
  241. public static object compile(CodeContext/*!*/ context, string source, string filename, string kind) {
  242. return compile(context, source, filename, kind, null, null);
  243. }
  244. public static PythonType classmethod {
  245. get {
  246. return DynamicHelpers.GetPythonTypeFromType(typeof(classmethod));
  247. }
  248. }
  249. public static int cmp(CodeContext/*!*/ context, object x, object y) {
  250. return PythonOps.Compare(context, x, y);
  251. }
  252. // having a cmp overload for double would be nice, but it breaks:
  253. // x = 1e66666
  254. // y = x/x
  255. // cmp(y,y)
  256. // which returns 0 because id(y) == id(y). If we added a double overload
  257. // we lose object identity.
  258. public static int cmp(CodeContext/*!*/ context, int x, int y) {
  259. return Int32Ops.Compare(x, y);
  260. }
  261. public static int cmp(CodeContext/*!*/ context, [NotNull]BigInteger x, [NotNull]BigInteger y) {
  262. if ((object)x == (object)y) {
  263. return 0;
  264. }
  265. return BigIntegerOps.Compare(x, y);
  266. }
  267. public static int cmp(CodeContext/*!*/ context, double x, [NotNull]BigInteger y) {
  268. return -BigIntegerOps.Compare(y, x);
  269. }
  270. public static int cmp(CodeContext/*!*/ context, [NotNull]BigInteger x, double y) {
  271. return BigIntegerOps.Compare(x, y);
  272. }
  273. public static int cmp(CodeContext/*!*/ context, [NotNull]string x, [NotNull]string y) {
  274. if ((object)x != (object)y) {
  275. int res = string.CompareOrdinal(x, y);
  276. if (res >= 1) {
  277. return 1;
  278. } else if (res <= -1) {
  279. return -1;
  280. }
  281. }
  282. return 0;
  283. }
  284. public static int cmp(CodeContext/*!*/ context, [NotNull]PythonTuple x, [NotNull]PythonTuple y) {
  285. if ((object)x == (object)y) {
  286. return 0;
  287. }
  288. return x.CompareTo(y);
  289. }
  290. public static PythonType complex {
  291. get {
  292. return DynamicHelpers.GetPythonTypeFromType(typeof(Complex64));
  293. }
  294. }
  295. public static void delattr(CodeContext/*!*/ context, object o, string name) {
  296. PythonOps.DeleteAttr(context, o, SymbolTable.StringToId(name));
  297. }
  298. public static PythonType dict {
  299. get {
  300. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonDictionary));
  301. }
  302. }
  303. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  304. public static List dir(CodeContext/*!*/ context) {
  305. List res = PythonOps.MakeListFromSequence(LocalsAsAttributesCollection(context).Keys);
  306. res.sort(context);
  307. return res;
  308. }
  309. public static List dir(CodeContext/*!*/ context, object o) {
  310. IList<object> ret = PythonOps.GetAttrNames(context, o);
  311. List lret = new List(ret);
  312. lret.sort(context);
  313. return lret;
  314. }
  315. public static object divmod(CodeContext/*!*/ context, object x, object y) {
  316. Debug.Assert(NotImplementedType.Value != null);
  317. return PythonContext.GetContext(context).DivMod(x, y);
  318. }
  319. public static PythonType enumerate {
  320. get {
  321. return DynamicHelpers.GetPythonTypeFromType(typeof(Enumerate));
  322. }
  323. }
  324. public static object eval(CodeContext/*!*/ context, FunctionCode code) {
  325. Debug.Assert(context != null);
  326. if (code == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  327. return eval(context, code, null);
  328. }
  329. public static object eval(CodeContext/*!*/ context, FunctionCode code, IAttributesCollection globals) {
  330. Debug.Assert(context != null);
  331. if (code == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  332. return eval(context, code, globals, globals);
  333. }
  334. public static object eval(CodeContext/*!*/ context, FunctionCode code, IAttributesCollection globals, object locals) {
  335. Debug.Assert(context != null);
  336. if (code == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  337. Scope localScope = GetExecEvalScopeOptional(context, globals, locals, false);
  338. return code.Call(localScope);
  339. }
  340. internal static IAttributesCollection GetAttrLocals(CodeContext/*!*/ context, object locals) {
  341. IAttributesCollection attrLocals = null;
  342. if (locals == null) {
  343. if (context.Scope.Parent != null) {
  344. attrLocals = LocalsAsAttributesCollection(context);
  345. }
  346. } else {
  347. attrLocals = locals as IAttributesCollection ?? new PythonDictionary(new ObjectAttributesAdapter(context, locals));
  348. }
  349. return attrLocals;
  350. }
  351. public static object eval(CodeContext/*!*/ context, string expression) {
  352. Debug.Assert(context != null);
  353. if (expression == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  354. return eval(context, expression, globals(context), locals(context));
  355. }
  356. public static object eval(CodeContext/*!*/ context, string expression, IAttributesCollection globals) {
  357. Debug.Assert(context != null);
  358. if (expression == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  359. return eval(context, expression, globals, globals);
  360. }
  361. public static object eval(CodeContext/*!*/ context, string expression, IAttributesCollection globals, object locals) {
  362. Debug.Assert(context != null);
  363. if (expression == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  364. if (locals != null && PythonOps.IsMappingType(context, locals) == RuntimeHelpers.False) {
  365. throw PythonOps.TypeError("locals must be mapping");
  366. }
  367. var scope = GetExecEvalScopeOptional(context, globals, locals, false);
  368. var pythonContext = PythonContext.GetContext(context);
  369. // TODO: remove TrimStart
  370. var sourceUnit = pythonContext.CreateSnippet(expression.TrimStart(' ', '\t'), SourceCodeKind.Expression);
  371. var compilerOptions = GetDefaultCompilerOptions(context, true, 0);
  372. var scriptCode = pythonContext.CompileSourceCode(sourceUnit, compilerOptions, ThrowingErrorSink.Default, true); // interpret
  373. return scriptCode.Run(scope);
  374. }
  375. public static void execfile(CodeContext/*!*/ context, object/*!*/ filename) {
  376. execfile(context, filename, null, null);
  377. }
  378. public static void execfile(CodeContext/*!*/ context, object/*!*/ filename, object globals) {
  379. execfile(context, filename, globals, null);
  380. }
  381. public static void execfile(CodeContext/*!*/ context, object/*!*/ filename, object globals, object locals) {
  382. if (filename == null) {
  383. throw PythonOps.TypeError("execfile() argument 1 must be string, not None");
  384. }
  385. IAttributesCollection g = globals as IAttributesCollection;
  386. if (g == null && globals != null) {
  387. throw PythonOps.TypeError("execfile() arg 2 must be dictionary");
  388. }
  389. IAttributesCollection l = locals as IAttributesCollection;
  390. if (l == null && locals != null) {
  391. throw PythonOps.TypeError("execfile() arg 3 must be dictionary");
  392. }
  393. if (l == null) {
  394. l = g;
  395. }
  396. Scope execScope = GetExecEvalScopeOptional(context, g, l, true);
  397. string path = Converter.ConvertToString(filename);
  398. PythonContext pc = PythonContext.GetContext(context);
  399. if (!pc.DomainManager.Platform.FileExists(path)) {
  400. throw PythonOps.IOError("execfile: specified file doesn't exist");
  401. }
  402. SourceUnit sourceUnit = pc.CreateFileUnit(path, pc.DefaultEncoding, SourceCodeKind.Statements);
  403. ScriptCode code;
  404. try {
  405. code = sourceUnit.Compile(GetDefaultCompilerOptions(context, true, 0), ThrowingErrorSink.Default);
  406. } catch (UnauthorizedAccessException x) {
  407. throw PythonOps.IOError(x);
  408. }
  409. // Do not attempt evaluation mode for execfile
  410. code.Run(execScope);
  411. }
  412. public static PythonType file {
  413. get {
  414. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonFile));
  415. }
  416. }
  417. public static string filter(CodeContext/*!*/ context, object function, [NotNull]string list) {
  418. if (function == null) return list;
  419. if (list == null) throw PythonOps.TypeError("NoneType is not iterable");
  420. StringBuilder sb = new StringBuilder();
  421. foreach (char c in list) {
  422. if (PythonOps.IsTrue(PythonCalls.Call(context, function, RuntimeHelpers.CharToString(c)))) sb.Append(c);
  423. }
  424. return sb.ToString();
  425. }
  426. public static string filter(CodeContext/*!*/ context, object function, [NotNull]ExtensibleString list) {
  427. StringBuilder sb = new StringBuilder();
  428. IEnumerator e = PythonOps.GetEnumerator(list);
  429. while (e.MoveNext()) {
  430. object o = e.Current;
  431. object t = (function != null) ? PythonCalls.Call(context, function, o) : o;
  432. if (PythonOps.IsTrue(t)) {
  433. sb.Append(Converter.ConvertToString(o));
  434. }
  435. }
  436. return sb.ToString();
  437. }
  438. /// <summary>
  439. /// Specialized version because enumerating tuples by Python's definition
  440. /// doesn't call __getitem__, but filter does!
  441. /// </summary>
  442. public static PythonTuple filter(CodeContext/*!*/ context, object function, [NotNull]PythonTuple tuple) {
  443. List<object> res = new List<object>(tuple.__len__());
  444. for (int i = 0; i < tuple.__len__(); i++) {
  445. object obj = tuple[i];
  446. object t = (function != null) ? PythonCalls.Call(context, function, obj) : obj;
  447. if (PythonOps.IsTrue(t)) {
  448. res.Add(obj);
  449. }
  450. }
  451. return PythonTuple.MakeTuple(res.ToArray());
  452. }
  453. public static List filter(CodeContext/*!*/ context, object function, object list) {
  454. if (list == null) throw PythonOps.TypeError("NoneType is not iterable");
  455. List ret = new List();
  456. IEnumerator i = PythonOps.GetEnumerator(list);
  457. while (i.MoveNext()) {
  458. if (function == null) {
  459. if (PythonOps.IsTrue(i.Current)) ret.AddNoLock(i.Current);
  460. } else {
  461. if (PythonOps.IsTrue(PythonCalls.Call(context, function, i.Current))) ret.AddNoLock(i.Current);
  462. }
  463. }
  464. return ret;
  465. }
  466. public static PythonType @float {
  467. get {
  468. return DynamicHelpers.GetPythonTypeFromType(typeof(double));
  469. }
  470. }
  471. public static object getattr(CodeContext/*!*/ context, object o, string name) {
  472. return PythonOps.GetBoundAttr(context, o, SymbolTable.StringToId(name));
  473. }
  474. public static object getattr(CodeContext/*!*/ context, object o, string name, object def) {
  475. object ret;
  476. if (PythonOps.TryGetBoundAttr(context, o, SymbolTable.StringToId(name), out ret)) return ret;
  477. else return def;
  478. }
  479. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  480. public static IAttributesCollection globals(CodeContext/*!*/ context) {
  481. return new PythonDictionary(new GlobalScopeDictionaryStorage(context.Scope));
  482. }
  483. public static bool hasattr(CodeContext/*!*/ context, object o, string name) {
  484. return PythonOps.HasAttr(context, o, SymbolTable.StringToId(name));
  485. }
  486. public static int hash(CodeContext/*!*/ context, object o) {
  487. return PythonContext.GetContext(context).Hash(o);
  488. }
  489. public static int hash(CodeContext/*!*/ context, [NotNull]PythonTuple o) {
  490. return ((IValueEquality)o).GetValueHashCode();
  491. }
  492. // this is necessary because overload resolution selects the int form.
  493. public static int hash(CodeContext/*!*/ context, char o) {
  494. return PythonContext.GetContext(context).Hash(o);
  495. }
  496. public static int hash(CodeContext/*!*/ context, int o) {
  497. return o;
  498. }
  499. public static int hash(CodeContext/*!*/ context, [NotNull]string o) {
  500. return o.GetHashCode();
  501. }
  502. // this is necessary because overload resolution will coerce extensible strings to strings.
  503. public static int hash(CodeContext/*!*/ context, [NotNull]ExtensibleString o) {
  504. return hash(context, (object)o);
  505. }
  506. public static int hash(CodeContext/*!*/ context, [NotNull]BigInteger o) {
  507. return BigIntegerOps.__hash__(o);
  508. }
  509. public static int hash(CodeContext/*!*/ context, [NotNull]Extensible<BigInteger> o) {
  510. return hash(context, (object)o);
  511. }
  512. public static int hash(CodeContext/*!*/ context, double o) {
  513. return DoubleOps.__hash__(o);
  514. }
  515. public static void help(CodeContext/*!*/ context, object o) {
  516. StringBuilder doc = new StringBuilder();
  517. List<object> doced = new List<object>(); // document things only once
  518. help(context, doced, doc, 0, o);
  519. if (doc.Length == 0) {
  520. if (!(o is string)) {
  521. help(context, DynamicHelpers.GetPythonType(o));
  522. return;
  523. }
  524. doc.Append("no documentation found for ");
  525. doc.Append(PythonOps.Repr(context, o));
  526. }
  527. string[] strings = doc.ToString().Split('\n');
  528. for (int i = 0; i < strings.Length; i++) {
  529. /* should read only a key, not a line, but we don't seem
  530. * to have a way to do that...
  531. if ((i % Console.WindowHeight) == 0) {
  532. Ops.Print(context.SystemState, "-- More --");
  533. Ops.ReadLineFromSrc(context.SystemState);
  534. }*/
  535. PythonOps.Print(context, strings[i]);
  536. }
  537. }
  538. private static void help(CodeContext/*!*/ context, List<object>/*!*/ doced, StringBuilder/*!*/ doc, int indent, object obj) {
  539. PythonType type;
  540. BuiltinFunction builtinFunction;
  541. PythonFunction function;
  542. BuiltinMethodDescriptor methodDesc;
  543. Method method;
  544. string strVal;
  545. Scope scope;
  546. OldClass oldClass;
  547. if (doced.Contains(obj)) return; // document things only once
  548. doced.Add(obj);
  549. if ((strVal = obj as string) != null) {
  550. if (indent != 0) return;
  551. // try and find things that string could refer to,
  552. // then call help on them.
  553. foreach (object module in PythonContext.GetContext(context).SystemStateModules.Values) {
  554. IList<object> attrs = PythonOps.GetAttrNames(context, module);
  555. List candidates = new List();
  556. foreach (string s in attrs) {
  557. if (s == strVal) {
  558. object modVal;
  559. if (!PythonOps.TryGetBoundAttr(context, module, SymbolTable.StringToId(strVal), out modVal))
  560. continue;
  561. candidates.append(modVal);
  562. }
  563. }
  564. // favor types, then built-in functions, then python functions,
  565. // and then only display help for one.
  566. type = null;
  567. builtinFunction = null;
  568. function = null;
  569. for (int i = 0; i < candidates.__len__(); i++) {
  570. if ((type = candidates[i] as PythonType) != null) {
  571. break;
  572. }
  573. if (builtinFunction == null && (builtinFunction = candidates[i] as BuiltinFunction) != null)
  574. continue;
  575. if (function == null && (function = candidates[i] as PythonFunction) != null)
  576. continue;
  577. }
  578. if (type != null) help(context, doced, doc, indent, type);
  579. else if (builtinFunction != null) help(context, doced, doc, indent, builtinFunction);
  580. else if (function != null) help(context, doced, doc, indent, function);
  581. }
  582. } else if ((type = obj as PythonType) != null) {
  583. // find all the functions, and display their
  584. // documentation
  585. if (indent == 0) {
  586. doc.AppendFormat("Help on {0} in module {1}\n\n", type.Name, PythonOps.GetBoundAttr(context, type, Symbols.Module));
  587. }
  588. PythonTypeSlot dts;
  589. if (type.TryResolveSlot(context, Symbols.Doc, out dts)) {
  590. object docText;
  591. if (dts.TryGetValue(context, null, type, out docText) && docText != null)
  592. AppendMultiLine(doc, docText.ToString() + Environment.NewLine, indent);
  593. AppendIndent(doc, indent);
  594. doc.AppendLine("Data and other attributes defined here:");
  595. AppendIndent(doc, indent);
  596. doc.AppendLine();
  597. }
  598. List names = type.GetMemberNames(context);
  599. names.sort(context);
  600. foreach (string name in names) {
  601. if (name == "__class__") continue;
  602. PythonTypeSlot value;
  603. object val;
  604. if (type.TryLookupSlot(context, SymbolTable.StringToId(name), out value) &&
  605. value.TryGetValue(context, null, type, out val)) {
  606. help(context, doced, doc, indent + 1, val);
  607. }
  608. }
  609. } else if ((methodDesc = obj as BuiltinMethodDescriptor) != null) {
  610. if (indent == 0) doc.AppendFormat("Help on method-descriptor {0}\n\n", methodDesc.__name__);
  611. AppendIndent(doc, indent);
  612. doc.Append(methodDesc.__name__);
  613. doc.Append("(...)\n");
  614. AppendMultiLine(doc, methodDesc.__doc__, indent + 1);
  615. } else if ((builtinFunction = obj as BuiltinFunction) != null) {
  616. if (indent == 0) doc.AppendFormat("Help on built-in function {0}\n\n", builtinFunction.Name);
  617. AppendIndent(doc, indent);
  618. doc.Append(builtinFunction.Name);
  619. doc.Append("(...)\n");
  620. AppendMultiLine(doc, builtinFunction.__doc__, indent + 1);
  621. } else if ((function = obj as PythonFunction) != null) {
  622. if (indent == 0) doc.AppendFormat("Help on function {0} in module {1}:\n\n", function.__name__, function.__module__);
  623. AppendIndent(doc, indent);
  624. doc.Append(function.GetSignatureString());
  625. string pfDoc = Converter.ConvertToString(function.__doc__);
  626. if (!String.IsNullOrEmpty(pfDoc)) {
  627. AppendMultiLine(doc, pfDoc, indent);
  628. }
  629. } else if ((method = obj as Method) != null && ((function = method.im_func as PythonFunction) != null)) {
  630. if (indent == 0) doc.AppendFormat("Help on method {0} in module {1}:\n\n", function.__name__, function.__module__);
  631. AppendIndent(doc, indent);
  632. doc.Append(function.GetSignatureString());
  633. if (method.im_self == null) {
  634. doc.AppendFormat(" unbound {0} method\n", PythonOps.ToString(method.im_class));
  635. } else {
  636. doc.AppendFormat(" method of {0} instance\n", PythonOps.ToString(method.im_class));
  637. }
  638. string pfDoc = Converter.ConvertToString(function.__doc__);
  639. if (!String.IsNullOrEmpty(pfDoc)) {
  640. AppendMultiLine(doc, pfDoc, indent);
  641. }
  642. } else if ((scope = obj as Scope) != null) {
  643. foreach (SymbolId name in scope.Keys) {
  644. if (name == Symbols.Class || name == Symbols.Builtins) continue;
  645. object value;
  646. if (scope.TryGetName(name, out value)) {
  647. help(context, doced, doc, indent + 1, value);
  648. }
  649. }
  650. } else if ((oldClass = obj as OldClass) != null) {
  651. if (indent == 0) {
  652. doc.AppendFormat("Help on {0} in module {1}\n\n", oldClass.__name__, PythonOps.GetBoundAttr(context, oldClass, Symbols.Module));
  653. }
  654. object docText;
  655. if (oldClass.TryLookupSlot(Symbols.Doc, out docText) && docText != null) {
  656. AppendMultiLine(doc, docText.ToString() + Environment.NewLine, indent);
  657. AppendIndent(doc, indent);
  658. doc.AppendLine("Data and other attributes defined here:");
  659. AppendIndent(doc, indent);
  660. doc.AppendLine();
  661. }
  662. IList<object> names = ((IMembersList)oldClass).GetMemberNames(context);
  663. List sortNames = new List(names);
  664. sortNames.sort(context);
  665. names = sortNames;
  666. foreach (string name in names) {
  667. if (name == "__class__") continue;
  668. object value;
  669. if (oldClass.TryLookupSlot(SymbolTable.StringToId(name), out value))
  670. help(context, doced, doc, indent + 1, value);
  671. }
  672. }
  673. }
  674. private static void AppendMultiLine(StringBuilder doc, string multiline, int indent) {
  675. string[] docs = multiline.Split('\n');
  676. for (int i = 0; i < docs.Length; i++) {
  677. AppendIndent(doc, indent + 1);
  678. doc.Append(docs[i]);
  679. doc.Append('\n');
  680. }
  681. }
  682. private static void AppendIndent(StringBuilder doc, int indent) {
  683. doc.Append(" | ");
  684. for (int i = 0; i < indent; i++) doc.Append(" ");
  685. }
  686. //??? type this to string
  687. public static object hex(object o) {
  688. return PythonOps.Hex(o);
  689. }
  690. public static object id(object o) {
  691. long res = PythonOps.Id(o);
  692. if (PythonOps.Id(o) <= Int32.MaxValue) {
  693. return (int)res;
  694. }
  695. return (BigInteger)res;
  696. }
  697. public static object input(CodeContext/*!*/ context) {
  698. return input(context, null);
  699. }
  700. public static object input(CodeContext/*!*/ context, object prompt) {
  701. return eval(context, raw_input(context, prompt));
  702. }
  703. public static PythonType @int {
  704. get {
  705. return DynamicHelpers.GetPythonTypeFromType(typeof(int));
  706. }
  707. }
  708. public static string intern(object o) {
  709. string s = o as string;
  710. if (s == null) {
  711. throw PythonOps.TypeError("intern: argument must be string");
  712. }
  713. return string.Intern(s);
  714. }
  715. public static bool isinstance(object o, [NotNull]PythonType typeinfo) {
  716. return PythonOps.IsInstance(o, typeinfo);
  717. }
  718. public static bool isinstance(object o, [NotNull]PythonTuple typeinfo) {
  719. return PythonOps.IsInstance(o, typeinfo);
  720. }
  721. public static bool isinstance(object o, object typeinfo) {
  722. return PythonOps.IsInstance(o, typeinfo);
  723. }
  724. public static bool issubclass([NotNull]OldClass c, object typeinfo) {
  725. return PythonOps.IsSubClass(c.TypeObject, typeinfo);
  726. }
  727. public static bool issubclass([NotNull]PythonType c, object typeinfo) {
  728. return PythonOps.IsSubClass(c, typeinfo);
  729. }
  730. public static bool issubclass([NotNull]PythonType c, [NotNull]PythonType typeinfo) {
  731. return PythonOps.IsSubClass(c, typeinfo);
  732. }
  733. public static bool issubclass(CodeContext/*!*/ context, object o, object typeinfo) {
  734. PythonTuple pt = typeinfo as PythonTuple;
  735. if (pt != null) {
  736. // Recursively inspect nested tuple(s)
  737. foreach (object subTypeInfo in pt) {
  738. try {
  739. PythonOps.FunctionPushFrame();
  740. if (issubclass(context, o, subTypeInfo)) {
  741. return true;
  742. }
  743. } finally {
  744. PythonOps.FunctionPopFrame();
  745. }
  746. }
  747. return false;
  748. }
  749. object bases;
  750. PythonTuple tupleBases;
  751. if (!PythonOps.TryGetBoundAttr(o, Symbols.Bases, out bases) || (tupleBases = bases as PythonTuple) == null) {
  752. throw PythonOps.TypeError("issubclass() arg 1 must be a class");
  753. }
  754. foreach (object baseCls in tupleBases) {
  755. PythonType pyType;
  756. OldClass oc;
  757. if (baseCls == typeinfo) {
  758. return true;
  759. } else if ((pyType = baseCls as PythonType) != null) {
  760. if (issubclass(pyType, typeinfo)) {
  761. return true;
  762. }
  763. } else if ((oc = baseCls as OldClass) != null) {
  764. if (issubclass(oc, typeinfo)) {
  765. return true;
  766. }
  767. } else if (hasattr(context, baseCls, "__bases__")) {
  768. if (issubclass(context, baseCls, typeinfo)) {
  769. return true;
  770. }
  771. }
  772. }
  773. return false;
  774. }
  775. public static IEnumerator iter(object o) {
  776. return PythonOps.GetEnumerator(o);
  777. }
  778. public static object iter(CodeContext/*!*/ context, object func, object sentinel) {
  779. if (!PythonOps.IsCallable(context, func)) {
  780. throw PythonOps.TypeError("iter(v, w): v must be callable");
  781. }
  782. return new SentinelIterator(context, func, sentinel);
  783. }
  784. public static int len(object o) {
  785. return PythonOps.Length(o);
  786. }
  787. public static PythonType set {
  788. get {
  789. return DynamicHelpers.GetPythonTypeFromType(typeof(SetCollection));
  790. }
  791. }
  792. public static PythonType frozenset {
  793. get {
  794. return DynamicHelpers.GetPythonTypeFromType(typeof(FrozenSetCollection));
  795. }
  796. }
  797. public static PythonType list {
  798. get {
  799. return DynamicHelpers.GetPythonTypeFromType(typeof(List));
  800. }
  801. }
  802. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  803. public static object locals(CodeContext/*!*/ context) {
  804. ObjectAttributesAdapter adapter = context.Scope.Dict as ObjectAttributesAdapter;
  805. if (adapter != null) {
  806. // we've wrapped Locals in an IAttributesCollection, give the user back the
  807. // original object.
  808. return adapter.Backing;
  809. }
  810. return LocalScopeDictionaryStorage.GetObjectFromScope(context.Scope);
  811. }
  812. internal static IAttributesCollection LocalsAsAttributesCollection(CodeContext/*!*/ context) {
  813. return LocalScopeDictionaryStorage.GetDictionaryFromScope(context.Scope);
  814. }
  815. public static PythonType @long {
  816. get {
  817. return TypeCache.BigInteger;
  818. }
  819. }
  820. private static CallSite<Func<CallSite, CodeContext, T, T1, object>> MakeMapSite<T, T1>(CodeContext/*!*/ context) {
  821. return CallSite<Func<CallSite, CodeContext, T, T1, object>>.Create(
  822. new InvokeBinder(
  823. PythonContext.GetContext(context).DefaultBinderState,
  824. new CallSignature(1)
  825. )
  826. );
  827. }
  828. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object, object>>> storage, object func, IEnumerable enumerator) {
  829. if (enumerator == null) {
  830. throw PythonOps.TypeError("NoneType is not iterable");
  831. }
  832. List ret = new List();
  833. CallSite<Func<CallSite, CodeContext, object, object, object>> mapSite = null;
  834. if (func != null) {
  835. mapSite = MakeMapSite<object, object>(context);
  836. }
  837. foreach (object o in enumerator) {
  838. if (func == null) {
  839. ret.AddNoLock(o);
  840. } else {
  841. ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
  842. }
  843. }
  844. return ret;
  845. }
  846. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object, object>>> storage, object func, [NotNull]string enumerator) {
  847. List ret = new List(enumerator.Length);
  848. CallSite<Func<CallSite, CodeContext, object, object, object>> mapSite = null;
  849. if (func != null) {
  850. if (storage.Data == null) {
  851. storage.Data = MakeMapSite<object, object>(context);
  852. }
  853. mapSite = storage.Data;
  854. }
  855. foreach (char o in enumerator) {
  856. if (func == null) {
  857. ret.AddNoLock(RuntimeHelpers.CharToString(o));
  858. } else {
  859. ret.AddNoLock(mapSite.Target(mapSite, context, func, RuntimeHelpers.CharToString(o)));
  860. }
  861. }
  862. return ret;
  863. }
  864. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, PythonType, object, object>>> storage, [NotNull]PythonType/*!*/ func, [NotNull]IEnumerable enumerator) {
  865. CallSite<Func<CallSite, CodeContext, PythonType, object, object>> mapSite;
  866. if (storage.Data == null) {
  867. storage.Data = MakeMapSite<PythonType, object>(context);
  868. }
  869. mapSite = storage.Data;
  870. List ret = new List();
  871. foreach (object o in enumerator) {
  872. ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
  873. }
  874. return ret;
  875. }
  876. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>>> storage, [NotNull]BuiltinFunction/*!*/ func, [NotNull]IEnumerable enumerator) {
  877. CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>> mapSite;
  878. if (storage.Data == null) {
  879. storage.Data = MakeMapSite<BuiltinFunction, object>(context);
  880. }
  881. mapSite = storage.Data;
  882. List ret = new List();
  883. foreach (object o in enumerator) {
  884. ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
  885. }
  886. return ret;
  887. }
  888. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>>> storage, [NotNull]BuiltinFunction/*!*/ func, [NotNull]string enumerator) {
  889. CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>> mapSite;
  890. if (storage.Data == null) {
  891. storage.Data = MakeMapSite<BuiltinFunction, object>(context);
  892. }
  893. mapSite = storage.Data;
  894. List ret = new List(enumerator.Length);
  895. foreach (char o in enumerator) {
  896. ret.AddNoLock(mapSite.Target(mapSite, context, func, RuntimeHelpers.CharToString(o)));
  897. }
  898. return ret;
  899. }
  900. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, PythonType, object, object>>> storage, [NotNull]PythonType/*!*/ func, [NotNull]string enumerator) {
  901. CallSite<Func<CallSite, CodeContext, PythonType, object, object>> mapSite;
  902. if (storage.Data == null) {
  903. storage.Data = MakeMapSite<PythonType, object>(context);
  904. }
  905. mapSite = storage.Data;
  906. List ret = new List(enumerator.Length);
  907. foreach (char o in enumerator) {
  908. ret.AddNoLock(mapSite.Target(mapSite, context, func, RuntimeHelpers.CharToString(o)));
  909. }
  910. return ret;
  911. }
  912. public static List map(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, PythonFunction, object, object>>> storage, [NotNull]PythonFunction/*!*/ func, [NotNull]IList enumerator) {
  913. CallSite<Func<CallSite, CodeContext, PythonFunction, object, object>> mapSite;
  914. if (storage.Data == null) {
  915. storage.Data = MakeMapSite<PythonFunction, object>(context);
  916. }
  917. mapSite = storage.Data;
  918. List ret = new List(enumerator.Count);
  919. foreach (object o in enumerator) {
  920. ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
  921. }
  922. return ret;
  923. }
  924. public static List map(CodeContext/*!*/ context, params object[] param) {
  925. if (param == null || param.Length < 2) {
  926. throw PythonOps.TypeError("at least 2 arguments required to map");
  927. }
  928. List ret = new List();
  929. object func = param[0];
  930. IEnumerator[] enums = new IEnumerator[param.Length - 1];
  931. for (int i = 0; i < enums.Length; i++) {
  932. enums[i] = PythonOps.GetEnumerator(param[i + 1]);
  933. }
  934. object[] args = new object[enums.Length];
  935. while (true) {
  936. bool done = true;
  937. for (int i = 0; i < enums.Length; i++) {
  938. if (enums[i].MoveNext()) {
  939. args[i] = enums[i].Current;
  940. done = false;
  941. } else {
  942. args[i] = null;
  943. }
  944. }
  945. if (done) {
  946. return ret;
  947. }
  948. if (func != null) {
  949. // splat call w/ args, can't use site here yet...
  950. ret.AddNoLock(PythonCalls.Call(context, func, args));
  951. } else if (args.Length == 1) {
  952. ret.AddNoLock(args[0]);
  953. } else {
  954. ret.AddNoLock(PythonTuple.MakeTuple(args));
  955. args = new object[enums.Length]; // Tuple does not copy the array, allocate new one.
  956. }
  957. }
  958. }
  959. public static object max(CodeContext/*!*/ context, object x) {
  960. IEnumerator i = PythonOps.GetEnumerator(x);
  961. if (!i.MoveNext())
  962. throw PythonOps.ValueError("max() arg is an empty sequence");
  963. object ret = i.Current;
  964. PythonContext pc = PythonContext.GetContext(context);

Large files files are truncated, but you can click here to view the full file