PageRenderTime 70ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/IronPython_Main/Languages/IronPython/IronPython/Modules/Builtin.cs

#
C# | 2444 lines | 1970 code | 387 blank | 87 comment | 547 complexity | 706f312386539879a298f0829e19be28 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
  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. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Diagnostics;
  19. using System.IO;
  20. using System.Runtime.CompilerServices;
  21. using System.Runtime.InteropServices;
  22. using System.Text;
  23. using System.Threading;
  24. using Microsoft.Scripting;
  25. using Microsoft.Scripting.Actions;
  26. using Microsoft.Scripting.Runtime;
  27. using Microsoft.Scripting.Utils;
  28. using IronPython.Compiler;
  29. using IronPython.Runtime;
  30. using IronPython.Runtime.Binding;
  31. using IronPython.Runtime.Exceptions;
  32. using IronPython.Runtime.Operations;
  33. using IronPython.Runtime.Types;
  34. #if CLR2
  35. using Microsoft.Scripting.Math;
  36. using Complex = Microsoft.Scripting.Math.Complex64;
  37. #else
  38. using System.Numerics;
  39. #endif
  40. [assembly: PythonModule("__builtin__", typeof(IronPython.Modules.Builtin))]
  41. namespace IronPython.Modules {
  42. [Documentation("")] // Documentation suppresses XML Doc on startup.
  43. public static partial class Builtin {
  44. public const string __doc__ = "Provides access to commonly used built-in functions, exception objects, etc...";
  45. public const object __package__ = null;
  46. public const string __name__ = "__builtin__";
  47. public static object True {
  48. get {
  49. return ScriptingRuntimeHelpers.True;
  50. }
  51. }
  52. public static object False {
  53. get {
  54. return ScriptingRuntimeHelpers.False;
  55. }
  56. }
  57. // This will always stay null
  58. public static readonly object None;
  59. public static IronPython.Runtime.Types.Ellipsis Ellipsis {
  60. get {
  61. return IronPython.Runtime.Types.Ellipsis.Value;
  62. }
  63. }
  64. public static NotImplementedType NotImplemented {
  65. get {
  66. return NotImplementedType.Value;
  67. }
  68. }
  69. public static object exit {
  70. get {
  71. return "Use Ctrl-Z plus Return to exit";
  72. }
  73. }
  74. public static object quit {
  75. get {
  76. return "Use Ctrl-Z plus Return to exit";
  77. }
  78. }
  79. [Documentation("__import__(name) -> module\n\nImport a module.")]
  80. [LightThrowing]
  81. public static object __import__(CodeContext/*!*/ context, string name) {
  82. return __import__(context, name, null, null, null, -1);
  83. }
  84. [Documentation("__import__(name, globals, locals, fromlist, level) -> module\n\nImport a module.")]
  85. [LightThrowing]
  86. public static object __import__(CodeContext/*!*/ context, string name, [DefaultParameterValue(null)]object globals, [DefaultParameterValue(null)]object locals, [DefaultParameterValue(null)]object fromlist, [DefaultParameterValue(-1)]int level) {
  87. if (fromlist is string || fromlist is Extensible<string>) {
  88. fromlist = new List<object> { fromlist };
  89. }
  90. IList from = fromlist as IList;
  91. PythonContext pc = PythonContext.GetContext(context);
  92. object ret = Importer.ImportModule(context, globals, name, from != null && from.Count > 0, level);
  93. if (ret == null) {
  94. return LightExceptions.Throw(PythonOps.ImportError("No module named {0}", name));
  95. }
  96. PythonModule mod = ret as PythonModule;
  97. if (mod != null && from != null) {
  98. string strAttrName;
  99. for (int i = 0; i < from.Count; i++) {
  100. object attrName = from[i];
  101. if (pc.TryConvertToString(attrName, out strAttrName) &&
  102. !String.IsNullOrEmpty(strAttrName) &&
  103. strAttrName != "*") {
  104. try {
  105. Importer.ImportFrom(context, mod, strAttrName);
  106. } catch (ImportException) {
  107. continue;
  108. }
  109. }
  110. }
  111. }
  112. return ret;
  113. }
  114. [Documentation("abs(number) -> number\n\nReturn the absolute value of the argument.")]
  115. public static object abs(CodeContext/*!*/ context, object o) {
  116. if (o is int) return Int32Ops.Abs((int)o);
  117. if (o is long) return Int64Ops.Abs((long)o);
  118. if (o is double) return DoubleOps.Abs((double)o);
  119. if (o is bool) return (((bool)o) ? 1 : 0);
  120. if (o is BigInteger) return BigIntegerOps.__abs__((BigInteger)o);
  121. if (o is Complex) return ComplexOps.Abs((Complex)o);
  122. object value;
  123. if (PythonTypeOps.TryInvokeUnaryOperator(context, o, "__abs__", out value)) {
  124. return value;
  125. }
  126. throw PythonOps.TypeError("bad operand type for abs(): '{0}'", PythonTypeOps.GetName(o));
  127. }
  128. public static bool all(object x) {
  129. IEnumerator i = PythonOps.GetEnumerator(x);
  130. while (i.MoveNext()) {
  131. if (!PythonOps.IsTrue(i.Current)) return false;
  132. }
  133. return true;
  134. }
  135. public static bool any(object x) {
  136. IEnumerator i = PythonOps.GetEnumerator(x);
  137. while (i.MoveNext()) {
  138. if (PythonOps.IsTrue(i.Current)) return true;
  139. }
  140. return false;
  141. }
  142. [Documentation("apply(object[, args[, kwargs]]) -> value\n\nDeprecated.\nInstead, use:\n function(*args, **keywords).")]
  143. public static object apply(CodeContext/*!*/ context, object func) {
  144. return PythonOps.CallWithContext(context, func);
  145. }
  146. public static object apply(CodeContext/*!*/ context, object func, object args) {
  147. return PythonOps.CallWithArgsTupleAndContext(context, func, ArrayUtils.EmptyObjects, args);
  148. }
  149. public static object apply(CodeContext/*!*/ context, object func, object args, object kws) {
  150. return context.LanguageContext.CallWithKeywords(func, args, kws);
  151. }
  152. public static PythonType basestring {
  153. get {
  154. return DynamicHelpers.GetPythonTypeFromType(typeof(string));
  155. }
  156. }
  157. public static string bin(int number) {
  158. return Int32Ops.ToBinary(number);
  159. }
  160. public static string bin(Index number) {
  161. return Int32Ops.ToBinary(Converter.ConvertToIndex(number));
  162. }
  163. public static string bin(BigInteger number) {
  164. return BigIntegerOps.ToBinary(number);
  165. }
  166. public static string bin(double number) {
  167. throw PythonOps.TypeError("'float' object cannot be interpreted as an index");
  168. }
  169. public static PythonType @bool {
  170. get {
  171. return DynamicHelpers.GetPythonTypeFromType(typeof(bool));
  172. }
  173. }
  174. public static PythonType buffer {
  175. get {
  176. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonBuffer));
  177. }
  178. }
  179. public static PythonType bytes {
  180. get {
  181. return DynamicHelpers.GetPythonTypeFromType(typeof(Bytes));
  182. }
  183. }
  184. public static PythonType bytearray {
  185. get {
  186. return DynamicHelpers.GetPythonTypeFromType(typeof(ByteArray));
  187. }
  188. }
  189. [Documentation("callable(object) -> bool\n\nReturn whether the object is callable (i.e., some kind of function).")]
  190. [Python3Warning("callable() is removed in 3.x. instead call hasattr(obj, '__call__')")]
  191. public static bool callable(CodeContext/*!*/ context, object o) {
  192. return PythonOps.IsCallable(context, o);
  193. }
  194. [Documentation("chr(i) -> character\n\nReturn a string of one character with ordinal i; 0 <= i< 256.")]
  195. [LightThrowing]
  196. public static object chr(int value) {
  197. if (value < 0 || value > 0xFF) {
  198. return LightExceptions.Throw(PythonOps.ValueError("{0} is not in required range", value));
  199. }
  200. return ScriptingRuntimeHelpers.CharToString((char)value);
  201. }
  202. internal static object TryCoerce(CodeContext/*!*/ context, object x, object y) {
  203. PythonTypeSlot pts;
  204. PythonType xType = DynamicHelpers.GetPythonType(x);
  205. if (xType.TryResolveSlot(context, "__coerce__", out pts)) {
  206. object callable;
  207. if (pts.TryGetValue(context, x, xType, out callable)) {
  208. return PythonCalls.Call(context, callable, y);
  209. }
  210. }
  211. return NotImplementedType.Value;
  212. }
  213. [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.")]
  214. public static object coerce(CodeContext/*!*/ context, object x, object y) {
  215. object converted;
  216. if (x == null && y == null) {
  217. return PythonTuple.MakeTuple(null, null);
  218. }
  219. converted = TryCoerce(context, x, y);
  220. if (converted != null && converted != NotImplementedType.Value) {
  221. return converted;
  222. }
  223. converted = TryCoerce(context, y, x);
  224. if (converted != null && converted != NotImplementedType.Value) {
  225. PythonTuple pt = converted as PythonTuple;
  226. if (pt != null && pt.Count == 2) {
  227. return PythonTuple.MakeTuple(pt[1], pt[0]);
  228. }
  229. }
  230. throw PythonOps.TypeError("coercion failed");
  231. }
  232. [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")]
  233. public static object compile(CodeContext/*!*/ context, string source, string filename, string mode, [DefaultParameterValue(null)]object flags, [DefaultParameterValue(null)]object dont_inherit) {
  234. if (source.IndexOf('\0') != -1) {
  235. throw PythonOps.TypeError("compile() expected string without null bytes");
  236. }
  237. source = RemoveBom(source);
  238. bool inheritContext = GetCompilerInheritance(dont_inherit);
  239. CompileFlags cflags = GetCompilerFlags(flags);
  240. PythonCompilerOptions opts = GetRuntimeGeneratedCodeCompilerOptions(context, inheritContext, cflags);
  241. if ((cflags & CompileFlags.CO_DONT_IMPLY_DEDENT) != 0) {
  242. opts.DontImplyDedent = true;
  243. }
  244. SourceUnit sourceUnit;
  245. string unitPath = String.IsNullOrEmpty(filename) ? null : filename;
  246. switch (mode) {
  247. case "exec": sourceUnit = context.LanguageContext.CreateSnippet(source, filename, SourceCodeKind.Statements); break;
  248. case "eval": sourceUnit = context.LanguageContext.CreateSnippet(source, filename, SourceCodeKind.Expression); break;
  249. case "single": sourceUnit = context.LanguageContext.CreateSnippet(source, filename, SourceCodeKind.InteractiveCode); break;
  250. default:
  251. throw PythonOps.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'");
  252. }
  253. return FunctionCode.FromSourceUnit(sourceUnit, opts, true);
  254. }
  255. private static string RemoveBom(string source) {
  256. // skip BOM (TODO: this is ugly workaround that is in fact not strictly correct, we need binary strings to handle it correctly)
  257. if (source.StartsWith("\u00ef\u00bb\u00bf", StringComparison.Ordinal)) {
  258. source = source.Substring(3, source.Length - 3);
  259. }
  260. return source;
  261. }
  262. public static PythonType classmethod {
  263. get {
  264. return DynamicHelpers.GetPythonTypeFromType(typeof(classmethod));
  265. }
  266. }
  267. public static int cmp(CodeContext/*!*/ context, object x, object y) {
  268. return PythonOps.Compare(context, x, y);
  269. }
  270. // having a cmp overload for double would be nice, but it breaks:
  271. // x = 1e66666
  272. // y = x/x
  273. // cmp(y,y)
  274. // which returns 0 because id(y) == id(y). If we added a double overload
  275. // we lose object identity.
  276. public static int cmp(CodeContext/*!*/ context, int x, int y) {
  277. return Int32Ops.Compare(x, y);
  278. }
  279. public static int cmp(CodeContext/*!*/ context, [NotNull]BigInteger x, [NotNull]BigInteger y) {
  280. if ((object)x == (object)y) {
  281. return 0;
  282. }
  283. return BigIntegerOps.Compare(x, y);
  284. }
  285. public static int cmp(CodeContext/*!*/ context, double x, [NotNull]BigInteger y) {
  286. return -BigIntegerOps.Compare(y, x);
  287. }
  288. public static int cmp(CodeContext/*!*/ context, [NotNull]BigInteger x, double y) {
  289. return BigIntegerOps.Compare(x, y);
  290. }
  291. public static int cmp(CodeContext/*!*/ context, [NotNull]string x, [NotNull]string y) {
  292. if ((object)x != (object)y) {
  293. int res = string.CompareOrdinal(x, y);
  294. if (res >= 1) {
  295. return 1;
  296. } else if (res <= -1) {
  297. return -1;
  298. }
  299. }
  300. return 0;
  301. }
  302. public static int cmp(CodeContext/*!*/ context, [NotNull]PythonTuple x, [NotNull]PythonTuple y) {
  303. if ((object)x == (object)y) {
  304. return 0;
  305. }
  306. return x.CompareTo(y);
  307. }
  308. public static PythonType complex {
  309. get {
  310. return DynamicHelpers.GetPythonTypeFromType(typeof(Complex));
  311. }
  312. }
  313. public static void delattr(CodeContext/*!*/ context, object o, string name) {
  314. PythonOps.DeleteAttr(context, o, name);
  315. }
  316. public static PythonType dict {
  317. get {
  318. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonDictionary));
  319. }
  320. }
  321. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  322. public static List dir(CodeContext/*!*/ context) {
  323. List res = PythonOps.MakeListFromSequence(context.Dict.Keys);
  324. res.sort(context);
  325. return res;
  326. }
  327. public static List dir(CodeContext/*!*/ context, object o) {
  328. IList<object> ret = PythonOps.GetAttrNames(context, o);
  329. List lret = new List(ret);
  330. lret.sort(context);
  331. return lret;
  332. }
  333. public static object divmod(CodeContext/*!*/ context, object x, object y) {
  334. Debug.Assert(NotImplementedType.Value != null);
  335. return PythonContext.GetContext(context).DivMod(x, y);
  336. }
  337. public static PythonType enumerate {
  338. get {
  339. return DynamicHelpers.GetPythonTypeFromType(typeof(Enumerate));
  340. }
  341. }
  342. public static object eval(CodeContext/*!*/ context, FunctionCode code) {
  343. Debug.Assert(context != null);
  344. if (code == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  345. return eval(context, code, null);
  346. }
  347. public static object eval(CodeContext/*!*/ context, FunctionCode code, PythonDictionary globals) {
  348. Debug.Assert(context != null);
  349. if (code == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  350. return eval(context, code, globals, globals);
  351. }
  352. public static object eval(CodeContext/*!*/ context, FunctionCode code, PythonDictionary globals, object locals) {
  353. Debug.Assert(context != null);
  354. if (code == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  355. return code.Call(GetExecEvalScopeOptional(context, globals, locals, false));
  356. }
  357. internal static PythonDictionary GetAttrLocals(CodeContext/*!*/ context, object locals) {
  358. PythonDictionary attrLocals = null;
  359. if (locals == null) {
  360. if (context.IsTopLevel) {
  361. attrLocals = context.Dict;
  362. }
  363. } else {
  364. attrLocals = locals as PythonDictionary ?? new PythonDictionary(new ObjectAttributesAdapter(context, locals));
  365. }
  366. return attrLocals;
  367. }
  368. [LightThrowing]
  369. public static object eval(CodeContext/*!*/ context, string expression) {
  370. Debug.Assert(context != null);
  371. if (expression == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  372. return eval(context, expression, globals(context), locals(context));
  373. }
  374. [LightThrowing]
  375. public static object eval(CodeContext/*!*/ context, string expression, PythonDictionary globals) {
  376. Debug.Assert(context != null);
  377. if (expression == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  378. return eval(context, expression, globals, globals);
  379. }
  380. [LightThrowing]
  381. public static object eval(CodeContext/*!*/ context, string expression, PythonDictionary globals, object locals) {
  382. Debug.Assert(context != null);
  383. if (expression == null) throw PythonOps.TypeError("eval() argument 1 must be string or code object");
  384. if (locals != null && PythonOps.IsMappingType(context, locals) == ScriptingRuntimeHelpers.False) {
  385. throw PythonOps.TypeError("locals must be mapping");
  386. }
  387. expression = RemoveBom(expression);
  388. var scope = GetExecEvalScopeOptional(context, globals, locals, false);
  389. var pythonContext = PythonContext.GetContext(context);
  390. // TODO: remove TrimStart
  391. var sourceUnit = pythonContext.CreateSnippet(expression.TrimStart(' ', '\t'), SourceCodeKind.Expression);
  392. var compilerOptions = GetRuntimeGeneratedCodeCompilerOptions(context, true, 0);
  393. compilerOptions.Module |= ModuleOptions.LightThrow;
  394. compilerOptions.Module &= ~ModuleOptions.ModuleBuiltins;
  395. var code = FunctionCode.FromSourceUnit(sourceUnit, compilerOptions, false);
  396. return code.Call(scope);
  397. }
  398. public static void execfile(CodeContext/*!*/ context, object/*!*/ filename) {
  399. execfile(context, filename, null, null);
  400. }
  401. public static void execfile(CodeContext/*!*/ context, object/*!*/ filename, object globals) {
  402. execfile(context, filename, globals, null);
  403. }
  404. public static void execfile(CodeContext/*!*/ context, object/*!*/ filename, object globals, object locals) {
  405. if (filename == null) {
  406. throw PythonOps.TypeError("execfile() argument 1 must be string, not None");
  407. }
  408. PythonDictionary g = globals as PythonDictionary;
  409. if (g == null && globals != null) {
  410. throw PythonOps.TypeError("execfile() arg 2 must be dictionary");
  411. }
  412. PythonDictionary l = locals as PythonDictionary;
  413. if (l == null && locals != null) {
  414. throw PythonOps.TypeError("execfile() arg 3 must be dictionary");
  415. }
  416. if (l == null) {
  417. l = g;
  418. }
  419. var execScope = GetExecEvalScopeOptional(context, g, l, true);
  420. string path = Converter.ConvertToString(filename);
  421. PythonContext pc = PythonContext.GetContext(context);
  422. if (!pc.DomainManager.Platform.FileExists(path)) {
  423. throw PythonOps.IOError("execfile: specified file doesn't exist");
  424. }
  425. SourceUnit sourceUnit = pc.CreateFileUnit(path, pc.DefaultEncoding, SourceCodeKind.Statements);
  426. FunctionCode code;
  427. var options = GetRuntimeGeneratedCodeCompilerOptions(context, true, 0);
  428. //always generate an unoptimized module since we run these against a dictionary namespace
  429. options.Module &= ~ModuleOptions.Optimized;
  430. try {
  431. code = FunctionCode.FromSourceUnit(sourceUnit, options, false);
  432. } catch (UnauthorizedAccessException x) {
  433. throw PythonOps.IOError(x);
  434. }
  435. // Do not attempt evaluation mode for execfile
  436. code.Call(execScope);
  437. }
  438. public static PythonType file {
  439. get {
  440. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonFile));
  441. }
  442. }
  443. public static string filter(CodeContext/*!*/ context, object function, [NotNull]string list) {
  444. if (function == null) return list;
  445. if (list == null) throw PythonOps.TypeError("NoneType is not iterable");
  446. StringBuilder sb = new StringBuilder();
  447. foreach (char c in list) {
  448. if (PythonOps.IsTrue(PythonCalls.Call(context, function, ScriptingRuntimeHelpers.CharToString(c)))) sb.Append(c);
  449. }
  450. return sb.ToString();
  451. }
  452. public static string filter(CodeContext/*!*/ context, object function, [NotNull]ExtensibleString list) {
  453. StringBuilder sb = new StringBuilder();
  454. IEnumerator e = PythonOps.GetEnumerator(list);
  455. while (e.MoveNext()) {
  456. object o = e.Current;
  457. object t = (function != null) ? PythonCalls.Call(context, function, o) : o;
  458. if (PythonOps.IsTrue(t)) {
  459. sb.Append(Converter.ConvertToString(o));
  460. }
  461. }
  462. return sb.ToString();
  463. }
  464. /// <summary>
  465. /// Specialized version because enumerating tuples by Python's definition
  466. /// doesn't call __getitem__, but filter does!
  467. /// </summary>
  468. public static PythonTuple filter(CodeContext/*!*/ context, object function, [NotNull]PythonTuple tuple) {
  469. List<object> res = new List<object>(tuple.__len__());
  470. for (int i = 0; i < tuple.__len__(); i++) {
  471. object obj = tuple[i];
  472. object t = (function != null) ? PythonCalls.Call(context, function, obj) : obj;
  473. if (PythonOps.IsTrue(t)) {
  474. res.Add(obj);
  475. }
  476. }
  477. return PythonTuple.MakeTuple(res.ToArray());
  478. }
  479. public static List filter(CodeContext/*!*/ context, object function, object list) {
  480. if (list == null) throw PythonOps.TypeError("NoneType is not iterable");
  481. List ret = new List();
  482. IEnumerator i = PythonOps.GetEnumerator(list);
  483. while (i.MoveNext()) {
  484. if (function == null) {
  485. if (PythonOps.IsTrue(i.Current)) ret.AddNoLock(i.Current);
  486. } else {
  487. if (PythonOps.IsTrue(PythonCalls.Call(context, function, i.Current))) ret.AddNoLock(i.Current);
  488. }
  489. }
  490. return ret;
  491. }
  492. public static PythonType @float {
  493. get {
  494. return DynamicHelpers.GetPythonTypeFromType(typeof(double));
  495. }
  496. }
  497. public static string format(CodeContext/*!*/ context, object argValue, [DefaultParameterValue("")]string formatSpec) {
  498. object res, formatMethod;
  499. OldInstance oi = argValue as OldInstance;
  500. if (oi != null && oi.TryGetBoundCustomMember(context, "__format__", out formatMethod)) {
  501. res = PythonOps.CallWithContext(context, formatMethod, formatSpec);
  502. } else {
  503. // call __format__ with the format spec (__format__ is defined on object, so this always succeeds)
  504. PythonTypeOps.TryInvokeBinaryOperator(
  505. context,
  506. argValue,
  507. formatSpec,
  508. "__format__",
  509. out res);
  510. }
  511. string strRes = res as string;
  512. if (strRes == null) {
  513. throw PythonOps.TypeError("{0}.__format__ must return string or unicode, not {1}", PythonTypeOps.GetName(argValue), PythonTypeOps.GetName(res));
  514. }
  515. return strRes;
  516. }
  517. public static object getattr(CodeContext/*!*/ context, object o, string name) {
  518. return PythonOps.GetBoundAttr(context, o, name);
  519. }
  520. public static object getattr(CodeContext/*!*/ context, object o, string name, object def) {
  521. object ret;
  522. if (PythonOps.TryGetBoundAttr(context, o, name, out ret)) return ret;
  523. else return def;
  524. }
  525. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  526. public static PythonDictionary globals(CodeContext/*!*/ context) {
  527. return context.ModuleContext.Globals;
  528. }
  529. public static bool hasattr(CodeContext/*!*/ context, object o, string name) {
  530. return PythonOps.HasAttr(context, o, name);
  531. }
  532. public static int hash(CodeContext/*!*/ context, object o) {
  533. return PythonContext.Hash(o);
  534. }
  535. public static int hash(CodeContext/*!*/ context, [NotNull]PythonTuple o) {
  536. return ((IStructuralEquatable)o).GetHashCode(PythonContext.GetContext(context).EqualityComparerNonGeneric);
  537. }
  538. // this is necessary because overload resolution selects the int form.
  539. public static int hash(CodeContext/*!*/ context, char o) {
  540. return PythonContext.Hash(o);
  541. }
  542. public static int hash(CodeContext/*!*/ context, int o) {
  543. return o;
  544. }
  545. public static int hash(CodeContext/*!*/ context, [NotNull]string o) {
  546. return o.GetHashCode();
  547. }
  548. // this is necessary because overload resolution will coerce extensible strings to strings.
  549. public static int hash(CodeContext/*!*/ context, [NotNull]ExtensibleString o) {
  550. return hash(context, (object)o);
  551. }
  552. public static int hash(CodeContext/*!*/ context, [NotNull]BigInteger o) {
  553. return BigIntegerOps.__hash__(o);
  554. }
  555. public static int hash(CodeContext/*!*/ context, [NotNull]Extensible<BigInteger> o) {
  556. return hash(context, (object)o);
  557. }
  558. public static int hash(CodeContext/*!*/ context, double o) {
  559. return DoubleOps.__hash__(o);
  560. }
  561. public static void help(CodeContext/*!*/ context, object o) {
  562. StringBuilder doc = new StringBuilder();
  563. List<object> doced = new List<object>(); // document things only once
  564. help(context, doced, doc, 0, o);
  565. if (doc.Length == 0) {
  566. if (!(o is string)) {
  567. help(context, DynamicHelpers.GetPythonType(o));
  568. return;
  569. }
  570. doc.Append("no documentation found for ");
  571. doc.Append(PythonOps.Repr(context, o));
  572. }
  573. string[] strings = doc.ToString().Split('\n');
  574. for (int i = 0; i < strings.Length; i++) {
  575. /* should read only a key, not a line, but we don't seem
  576. * to have a way to do that...
  577. if ((i % Console.WindowHeight) == 0) {
  578. Ops.Print(context.SystemState, "-- More --");
  579. Ops.ReadLineFromSrc(context.SystemState);
  580. }*/
  581. PythonOps.Print(context, strings[i]);
  582. }
  583. }
  584. private static void help(CodeContext/*!*/ context, List<object>/*!*/ doced, StringBuilder/*!*/ doc, int indent, object obj) {
  585. PythonType type;
  586. BuiltinFunction builtinFunction;
  587. PythonFunction function;
  588. BuiltinMethodDescriptor methodDesc;
  589. Method method;
  590. string strVal;
  591. PythonModule pyModule;
  592. OldClass oldClass;
  593. if (doced.Contains(obj)) return; // document things only once
  594. doced.Add(obj);
  595. if ((strVal = obj as string) != null) {
  596. if (indent != 0) return;
  597. // try and find things that string could refer to,
  598. // then call help on them.
  599. foreach (object module in PythonContext.GetContext(context).SystemStateModules.Values) {
  600. IList<object> attrs = PythonOps.GetAttrNames(context, module);
  601. List candidates = new List();
  602. foreach (string s in attrs) {
  603. if (s == strVal) {
  604. object modVal;
  605. if (!PythonOps.TryGetBoundAttr(context, module, strVal, out modVal))
  606. continue;
  607. candidates.append(modVal);
  608. }
  609. }
  610. // favor types, then built-in functions, then python functions,
  611. // and then only display help for one.
  612. type = null;
  613. builtinFunction = null;
  614. function = null;
  615. for (int i = 0; i < candidates.__len__(); i++) {
  616. if ((type = candidates[i] as PythonType) != null) {
  617. break;
  618. }
  619. if (builtinFunction == null && (builtinFunction = candidates[i] as BuiltinFunction) != null)
  620. continue;
  621. if (function == null && (function = candidates[i] as PythonFunction) != null)
  622. continue;
  623. }
  624. if (type != null) help(context, doced, doc, indent, type);
  625. else if (builtinFunction != null) help(context, doced, doc, indent, builtinFunction);
  626. else if (function != null) help(context, doced, doc, indent, function);
  627. }
  628. } else if ((type = obj as PythonType) != null) {
  629. // find all the functions, and display their
  630. // documentation
  631. if (indent == 0) {
  632. doc.AppendFormat("Help on {0} in module {1}\n\n", type.Name, PythonOps.GetBoundAttr(context, type, "__module__"));
  633. }
  634. PythonTypeSlot dts;
  635. if (type.TryResolveSlot(context, "__doc__", out dts)) {
  636. object docText;
  637. if (dts.TryGetValue(context, null, type, out docText) && docText != null)
  638. AppendMultiLine(doc, docText.ToString() + Environment.NewLine, indent);
  639. AppendIndent(doc, indent);
  640. doc.AppendLine("Data and other attributes defined here:");
  641. AppendIndent(doc, indent);
  642. doc.AppendLine();
  643. }
  644. List names = type.GetMemberNames(context);
  645. names.sort(context);
  646. foreach (string name in names) {
  647. if (name == "__class__") continue;
  648. PythonTypeSlot value;
  649. object val;
  650. if (type.TryLookupSlot(context, name, out value) &&
  651. value.TryGetValue(context, null, type, out val)) {
  652. help(context, doced, doc, indent + 1, val);
  653. }
  654. }
  655. } else if ((methodDesc = obj as BuiltinMethodDescriptor) != null) {
  656. if (indent == 0) doc.AppendFormat("Help on method-descriptor {0}\n\n", methodDesc.__name__);
  657. AppendIndent(doc, indent);
  658. doc.Append(methodDesc.__name__);
  659. doc.Append("(...)\n");
  660. AppendMultiLine(doc, methodDesc.__doc__, indent + 1);
  661. } else if ((builtinFunction = obj as BuiltinFunction) != null) {
  662. if (indent == 0) doc.AppendFormat("Help on built-in function {0}\n\n", builtinFunction.Name);
  663. AppendIndent(doc, indent);
  664. doc.Append(builtinFunction.Name);
  665. doc.Append("(...)\n");
  666. AppendMultiLine(doc, builtinFunction.__doc__, indent + 1);
  667. } else if ((function = obj as PythonFunction) != null) {
  668. if (indent == 0) doc.AppendFormat("Help on function {0} in module {1}:\n\n", function.__name__, function.__module__);
  669. AppendIndent(doc, indent);
  670. doc.Append(function.GetSignatureString());
  671. string pfDoc = Converter.ConvertToString(function.__doc__);
  672. if (!String.IsNullOrEmpty(pfDoc)) {
  673. AppendMultiLine(doc, pfDoc, indent);
  674. }
  675. } else if ((method = obj as Method) != null && ((function = method.im_func as PythonFunction) != null)) {
  676. if (indent == 0) doc.AppendFormat("Help on method {0} in module {1}:\n\n", function.__name__, function.__module__);
  677. AppendIndent(doc, indent);
  678. doc.Append(function.GetSignatureString());
  679. if (method.im_self == null) {
  680. doc.AppendFormat(" unbound {0} method\n", PythonOps.ToString(method.im_class));
  681. } else {
  682. doc.AppendFormat(" method of {0} instance\n", PythonOps.ToString(method.im_class));
  683. }
  684. string pfDoc = Converter.ConvertToString(function.__doc__);
  685. if (!String.IsNullOrEmpty(pfDoc)) {
  686. AppendMultiLine(doc, pfDoc, indent);
  687. }
  688. } else if ((pyModule = obj as PythonModule) != null) {
  689. foreach (string name in pyModule.__dict__.Keys) {
  690. if (name == "__class__" || name == "__builtins__") continue;
  691. object value;
  692. if (pyModule.__dict__.TryGetValue(name, out value)) {
  693. help(context, doced, doc, indent + 1, value);
  694. }
  695. }
  696. } else if ((oldClass = obj as OldClass) != null) {
  697. if (indent == 0) {
  698. doc.AppendFormat("Help on {0} in module {1}\n\n", oldClass.Name, PythonOps.GetBoundAttr(context, oldClass, "__module__"));
  699. }
  700. object docText;
  701. if (oldClass.TryLookupSlot("__doc__", out docText) && docText != null) {
  702. AppendMultiLine(doc, docText.ToString() + Environment.NewLine, indent);
  703. AppendIndent(doc, indent);
  704. doc.AppendLine("Data and other attributes defined here:");
  705. AppendIndent(doc, indent);
  706. doc.AppendLine();
  707. }
  708. IList<object> names = ((IPythonMembersList)oldClass).GetMemberNames(context);
  709. List sortNames = new List(names);
  710. sortNames.sort(context);
  711. names = sortNames;
  712. foreach (string name in names) {
  713. if (name == "__class__") continue;
  714. object value;
  715. if (oldClass.TryLookupSlot(name, out value))
  716. help(context, doced, doc, indent + 1, value);
  717. }
  718. }
  719. }
  720. private static void AppendMultiLine(StringBuilder doc, string multiline, int indent) {
  721. string[] docs = multiline.Split('\n');
  722. for (int i = 0; i < docs.Length; i++) {
  723. AppendIndent(doc, indent + 1);
  724. doc.Append(docs[i]);
  725. doc.Append('\n');
  726. }
  727. }
  728. private static void AppendIndent(StringBuilder doc, int indent) {
  729. doc.Append(" | ");
  730. for (int i = 0; i < indent; i++) doc.Append(" ");
  731. }
  732. //??? type this to string
  733. public static object hex(object o) {
  734. return PythonOps.Hex(o);
  735. }
  736. public static object id(object o) {
  737. long res = PythonOps.Id(o);
  738. if (PythonOps.Id(o) <= Int32.MaxValue) {
  739. return (int)res;
  740. }
  741. return (BigInteger)res;
  742. }
  743. [LightThrowing]
  744. public static object input(CodeContext/*!*/ context) {
  745. return input(context, null);
  746. }
  747. [LightThrowing]
  748. public static object input(CodeContext/*!*/ context, object prompt) {
  749. return eval(context, raw_input(context, prompt));
  750. }
  751. public static PythonType @int {
  752. get {
  753. return DynamicHelpers.GetPythonTypeFromType(typeof(int));
  754. }
  755. }
  756. public static string intern(object o) {
  757. string s = o as string;
  758. if (s == null) {
  759. throw PythonOps.TypeError("intern: argument must be string");
  760. }
  761. return string.Intern(s);
  762. }
  763. public static bool isinstance(object o, [NotNull]PythonType typeinfo) {
  764. return PythonOps.IsInstance(o, typeinfo);
  765. }
  766. public static bool isinstance(CodeContext context, object o, [NotNull]PythonTuple typeinfo) {
  767. return PythonOps.IsInstance(context, o, typeinfo);
  768. }
  769. public static bool isinstance(CodeContext context, object o, object typeinfo) {
  770. return PythonOps.IsInstance(context, o, typeinfo);
  771. }
  772. public static bool issubclass(CodeContext context, [NotNull]OldClass c, object typeinfo) {
  773. return PythonOps.IsSubClass(context, c.TypeObject, typeinfo);
  774. }
  775. public static bool issubclass(CodeContext context, [NotNull]PythonType c, object typeinfo) {
  776. return PythonOps.IsSubClass(context, c, typeinfo);
  777. }
  778. public static bool issubclass(CodeContext context, [NotNull]PythonType c, [NotNull]PythonType typeinfo) {
  779. return PythonOps.IsSubClass(c, typeinfo);
  780. }
  781. [LightThrowing]
  782. public static object issubclass(CodeContext/*!*/ context, object o, object typeinfo) {
  783. PythonTuple pt = typeinfo as PythonTuple;
  784. if (pt != null) {
  785. // Recursively inspect nested tuple(s)
  786. foreach (object subTypeInfo in pt) {
  787. try {
  788. PythonOps.FunctionPushFrame(PythonContext.GetContext(context));
  789. var res = issubclass(context, o, subTypeInfo);
  790. if (res == ScriptingRuntimeHelpers.True) {
  791. return ScriptingRuntimeHelpers.True;
  792. } else if (LightExceptions.IsLightException(res)) {
  793. return res;
  794. }
  795. } finally {
  796. PythonOps.FunctionPopFrame();
  797. }
  798. }
  799. return ScriptingRuntimeHelpers.False;
  800. }
  801. object bases;
  802. PythonTuple tupleBases;
  803. if (!PythonOps.TryGetBoundAttr(o, "__bases__", out bases) || (tupleBases = bases as PythonTuple) == null) {
  804. return LightExceptions.Throw(PythonOps.TypeError("issubclass() arg 1 must be a class"));
  805. }
  806. if (o == typeinfo) {
  807. return ScriptingRuntimeHelpers.True;
  808. }
  809. foreach (object baseCls in tupleBases) {
  810. PythonType pyType;
  811. OldClass oc;
  812. if (baseCls == typeinfo) {
  813. return ScriptingRuntimeHelpers.True;
  814. } else if ((pyType = baseCls as PythonType) != null) {
  815. if (issubclass(context, pyType, typeinfo)) {
  816. return ScriptingRuntimeHelpers.True;
  817. }
  818. } else if ((oc = baseCls as OldClass) != null) {
  819. if (issubclass(context, oc, typeinfo)) {
  820. return ScriptingRuntimeHelpers.True;
  821. }
  822. } else if (hasattr(context, baseCls, "__bases__")) {
  823. var res = issubclass(context, baseCls, typeinfo);
  824. if (res == ScriptingRuntimeHelpers.True) {
  825. return ScriptingRuntimeHelpers.True;
  826. } else if (LightExceptions.IsLightException(res)) {
  827. return res;
  828. }
  829. }
  830. }
  831. return ScriptingRuntimeHelpers.False;
  832. }
  833. public static object iter(CodeContext/*!*/ context, object o) {
  834. return PythonOps.GetEnumeratorObject(context, o);
  835. }
  836. public static object iter(CodeContext/*!*/ context, object func, object sentinel) {
  837. if (!PythonOps.IsCallable(context, func)) {
  838. throw PythonOps.TypeError("iter(v, w): v must be callable");
  839. }
  840. return new SentinelIterator(context, func, sentinel);
  841. }
  842. public static int len([NotNull]string/*!*/ str) {
  843. return str.Length;
  844. }
  845. public static int len([NotNull]ExtensibleString/*!*/ str) {
  846. return str.__len__();
  847. }
  848. public static int len([NotNull]List/*!*/ list) {
  849. return list.__len__();
  850. }
  851. public static int len([NotNull]PythonTuple/*!*/ tuple) {
  852. return tuple.__len__();
  853. }
  854. public static int len([NotNull]PythonDictionary/*!*/ dict) {
  855. return dict.__len__();
  856. }
  857. public static int len([NotNull]ICollection/*!*/ collection) {
  858. return collection.Count;
  859. }
  860. public static int len(object o) {
  861. return PythonOps.Length(o);
  862. }
  863. public static PythonType set {
  864. get {
  865. return DynamicHelpers.GetPythonTypeFromType(typeof(SetCollection));
  866. }
  867. }
  868. public static PythonType frozenset {
  869. get {
  870. return DynamicHelpers.GetPythonTypeFromType(typeof(FrozenSetCollection));
  871. }
  872. }
  873. public static PythonType list {
  874. get {
  875. return DynamicHelpers.GetPythonTypeFromType(typeof(List));
  876. }
  877. }
  878. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  879. public static object locals(CodeContext/*!*/ context) {
  880. PythonDictionary dict = context.Dict;
  881. ObjectAttributesAdapter adapter = dict._storage as ObjectAttributesAdapter;
  882. if (adapter != null) {
  883. // we've wrapped Locals in an PythonDictionary, give the user back the
  884. // original object.
  885. return adapter.Backing;
  886. }
  887. return context.Dict;
  888. }
  889. public static PythonType @long {
  890. get {
  891. return TypeCache.BigInteger;
  892. }
  893. }
  894. public static PythonType memoryview {
  895. get {
  896. return DynamicHelpers.GetPythonTypeFromType(typeof(MemoryView));
  897. }
  898. }
  899. private static CallSite<Func<CallSite, CodeContext, T, T1, object>> MakeMapSite<T, T1>(CodeContext/*!*/ context) {
  900. return CallSite<Func<CallSite, CodeContext, T, T1, object>>.Create(
  901. PythonContext.GetContext(context).InvokeOne
  902. );
  903. }
  904. public static List map(CodeContext/*!*/ context, object func, [NotNull]IEnumerable enumerator) {
  905. IEnumerator en = PythonOps.GetEnumerator(enumerator);
  906. List ret = new List();
  907. CallSite<Func<CallSite, CodeContext, object, object, object>> mapSite = null;
  908. if (func != null) {
  909. mapSite = MakeMapSite<object, object>(context);
  910. }
  911. while (en.MoveNext()) {
  912. if (func == null) {
  913. ret.AddNoLock(en.Current);
  914. } else {
  915. ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
  916. }
  917. }
  918. return ret;
  919. }
  920. public static List map(
  921. CodeContext/*!*/ context,
  922. SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object, object>>> storage,
  923. object func,
  924. [NotNull]string enumerator
  925. ) {
  926. CallSite<Func<CallSite, CodeContext, object, object, object>> mapSite;
  927. if (storage.Data == null && func != null) {
  928. storage.Data = MakeMapSite<object, object>(context);
  929. }
  930. mapSite = storage.Data;
  931. List ret = new List(enumerator.Length);
  932. foreach (char o in enumerator) {
  933. if (func == null) {
  934. ret.AddNoLock(ScriptingRuntimeHelpers.CharToString(o));
  935. } else {
  936. ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
  937. }
  938. }
  939. return ret;
  940. }
  941. public static List map(
  942. CodeContext/*!*/ context,
  943. SiteLocalStorage<CallSite<Func<CallSite, CodeContext, PythonType, object, object>>> storage,
  944. [NotNull]PythonType/*!*/ func,
  945. [NotNull]string enumerator
  946. ) {
  947. CallSite<Func<CallSite, CodeContext, PythonType, string, object>> mapSite = MakeMapSite<PythonType, string>(context);
  948. List ret = new List(enumerator.Length);
  949. foreach (char o in enumerator) {
  950. ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
  951. }
  952. return ret;
  953. }
  954. public static List map(
  955. CodeContext/*!*/ context,
  956. SiteLocalStorage<CallSite<Func<CallSite, CodeContext, PythonType, object, object>>> storage,
  957. [NotNull]PythonType/*!*/ func,
  958. [NotNull]IEnumerable enumerator
  959. ) {
  960. CallSite<Func<CallSite, CodeContext, PythonType, object, object>> mapSite;
  961. if (storage.Data == null) {
  962. storage.Data = MakeMapSite<PythonType, object>(context);
  963. }
  964. mapSite = storage.Data;
  965. IEnumerator en = PythonOps.GetEnumerator(enumerator);
  966. List ret = new List();
  967. while (en.MoveNext()) {
  968. ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
  969. }
  970. return ret;
  971. }
  972. public static List map(
  973. CodeContext/*!*/ context,
  974. SiteLocalStorage<CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>>> storage,
  975. [NotNull]BuiltinFunction/*!*/ func,
  976. [NotNull]string enumerator
  977. ) {
  978. CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>> mapSite;
  979. if (storage.Data == null) {
  980. storage.Data = MakeMapSite<BuiltinFunction, object>(context);
  981. }
  982. mapSite = storage.Data;
  983. List ret = new List(enumerator.Length);
  984. foreach (char o in enumerator) {
  985. ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
  986. }
  987. return ret;
  988. }
  989. public static List map(
  990. CodeContext/*!*/ context,
  991. SiteLocalStorage<CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>>> storage,
  992. [NotNull]BuiltinFunction/*!*/ func,
  993. [NotNull]IEnumerable enumerator
  994. ) {
  995. CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object>> mapSite;
  996. if (storage.Data == null) {
  997. storage.Data = MakeMapSite<BuiltinFunction, object>(context);
  998. }
  999. mapSite = storage.Data;
  1000. IEnumerator en = PythonOps.GetEnumerator(enumerator);
  1001. List ret = new List();
  1002. while (en.MoveNext()) {
  1003. ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
  1004. }
  1005. return ret;
  1006. }
  1007. public static List map(
  1008. CodeContext/*!*/ context,
  1009. SiteLocalStorage<CallSite<Func<CallSite, CodeContext, PythonFunction, object, object>>> storage,
  1010. [NotNull]PythonFunction/*!*/ func,
  1011. [NotNull]IList enumerator
  1012. ) {
  1013. CallSite<Func<CallSite, CodeContext, PythonFunction, object, object>> mapSite;
  1014. if (storage.Data == null) {
  1015. storage.Data = MakeMapSite<PythonFunction, object>(context);
  1016. }
  1017. mapSite = storage.Data;
  1018. IEnumerator en = PythonOps.GetEnumerator(enumerator);
  1019. List ret = new List(enumerator.Count);
  1020. while (en.MoveNext()) {
  1021. ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
  1022. }
  1023. return ret;
  1024. }
  1025. public static List map(CodeContext/*!*/ context, params object[] param) {
  1026. if (param == null || param.Length < 2) {
  1027. throw PythonOps.TypeError("at least 2 arguments required to map");
  1028. }
  1029. List ret = new List();
  1030. object func = param[0];
  1031. IEnumerator[] enums = new IEnumerator[param.Length - 1];
  1032. for (int i = 0; i < enums.Length; i++) {
  1033. enums[i] = PythonOps.GetEnumerator(param[i + 1]);
  1034. }
  1035. object[] args = new object[enums.Length];
  1036. while (true) {
  1037. bool done = true;
  1038. for (int i = 0; i < enums.Length; i++) {
  1039. if (enums[i].MoveNext()) {
  1040. args[i] = enums[i].Current;
  1041. done = false;
  1042. } else {
  1043. args[i] = null;
  1044. }
  1045. }
  1046. if (done) {
  1047. return ret;
  1048. }
  1049. if (func != null) {
  1050. // splat call w/ args, can't use site here yet...
  1051. ret.AddNoLock(PythonCalls.Call(context, func, args));
  1052. } else if (args.Length == 1) {
  1053. ret.AddNoLock(args[0]);
  1054. } else {
  1055. ret.AddNoLock(PythonTuple.MakeTuple(args));
  1056. args = new object[enums.Length]; // Tuple does not copy the array, allocate new one.
  1057. }
  1058. }
  1059. }
  1060. public static object max(CodeContext/*!*/ context, object x) {
  1061. IEnumerator i = PythonOps.GetEnumerator(x);
  1062. if (!i.MoveNext())
  1063. throw PythonOps.ValueError("max() arg is an empty sequence");
  1064. object ret = i.Current;
  1065. PythonContext pc = PythonContext.GetContext(context);
  1066. while (i.MoveNext()) {
  1067. if (pc.GreaterThan(i.Current, ret)) ret = i.Current;
  1068. }
  1069. return ret;
  1070. }
  1071. public static object max(CodeContext/*!*/ context, object x, object y) {
  1072. return PythonContext.GetContext(context).GreaterThan(x, y) ? x : y;
  1073. }
  1074. public static object max(CodeContext/*!*/ context, params object[] args) {
  1075. if (args.Length > 0) {
  1076. object ret = args[0];
  1077. if (args.Length == 1) {
  1078. return max(context, ret);
  1079. }
  1080. PythonContext pc = PythonContext.GetContext(context);
  1081. for (int i = 1; i < args.Length; i++) {
  1082. if (pc.GreaterThan(args[i], ret)) {
  1083. ret = args[i];
  1084. }
  1085. }
  1086. return ret;
  1087. } else {
  1088. throw PythonOps.TypeError("max expecting 1 arguments, got 0");
  1089. }
  1090. }
  1091. public static object max(CodeContext/*!*/ context, object x, [ParamDictionary]IDictionary<object, object> dict) {
  1092. IEnumerator i = PythonOps.GetEnumerator(x);
  1093. if (!i.MoveNext())
  1094. throw PythonOps.ValueError(" max() arg is an empty sequence");
  1095. object method = GetMaxKwArg(dict);
  1096. object ret = i.Current;
  1097. object retValue = PythonCalls.Call(context, method, i.Current);
  1098. PythonContext pc = PythonContext.GetContext(context);
  1099. while (i.MoveNext()) {
  1100. object tmpRetValue = PythonCalls.Call(context, method, i.Current);
  1101. if (pc.GreaterThan(tmpRetValue, retValue)) {
  1102. ret = i.Current;
  1103. retValue = tmpRetValue;
  1104. }
  1105. }
  1106. return ret;
  1107. }
  1108. public static object max(CodeContext/*!*/ context, object x, object y, [ParamDictionary] IDictionary<object, object> dict) {
  1109. object method = GetMaxKwArg(dict);
  1110. PythonContext pc = PythonContext.GetContext(context);
  1111. return pc.GreaterThan(PythonCalls.Call(context, method, x), PythonCalls.Call(context, method, y)) ? x : y;
  1112. }
  1113. public static object max(CodeContext/*!*/ context, [ParamDictionary]IDictionary<object, object> dict, params object[] args) {
  1114. if (args.Length > 0) {
  1115. int retIndex = 0;
  1116. if (args.Length == 1) {
  1117. return max(context, args[retIndex], dict);
  1118. }
  1119. object method = GetMaxKwArg(dict);
  1120. object retValue = PythonCalls.Call(context, method, args[retIndex]);
  1121. PythonContext pc = PythonContext.GetContext(context);
  1122. for (int i = 1; i < args.Length; i++) {
  1123. object tmpRetValue = PythonCalls.Call(context, method, args[i]);
  1124. if (pc.GreaterThan(tmpRetValue, retValue)) {
  1125. retIndex = i;
  1126. retValue = tmpRetValue;
  1127. }
  1128. }
  1129. return args[retIndex];
  1130. } else {
  1131. throw PythonOps.TypeError("max expecting 1 arguments, got 0");
  1132. }
  1133. }
  1134. private static object GetMaxKwArg(IDictionary<object, object> dict) {
  1135. if (dict.Count != 1)
  1136. throw PythonOps.TypeError(" max() should have only 1 keyword argument, but got {0} keyword arguments", dict.Count);
  1137. return VerifyKeys("max", dict);
  1138. }
  1139. public static object min(CodeContext/*!*/ context, object x) {
  1140. IEnumerator i = PythonOps.GetEnumerator(x);
  1141. if (!i.MoveNext()) {
  1142. throw PythonOps.ValueError("empty sequence");
  1143. }
  1144. object ret = i.Current;
  1145. PythonContext pc = PythonContext.GetContext(context);
  1146. while (i.MoveNext()) {
  1147. if (pc.LessThan(i.Current, ret)) ret = i.Current;
  1148. }
  1149. return ret;
  1150. }
  1151. public static object min(CodeContext/*!*/ context, object x, object y) {
  1152. return PythonContext.GetContext(context).LessThan(x, y) ? x : y;
  1153. }
  1154. public static object min(CodeContext/*!*/ context, params object[] args) {
  1155. if (args.Length > 0) {
  1156. object ret = args[0];
  1157. if (args.Length == 1) {
  1158. return min(context, ret);
  1159. }
  1160. PythonContext pc = PythonContext.GetContext(context);
  1161. for (int i = 1; i < args.Length; i++) {
  1162. if (pc.LessThan(args[i], ret)) ret = args[i];
  1163. }
  1164. return ret;
  1165. } else {
  1166. throw PythonOps.TypeError("min expecting 1 arguments, got 0");
  1167. }
  1168. }
  1169. public static object min(CodeContext/*!*/ context, object x, [ParamDictionary]IDictionary<object, object> dict) {
  1170. IEnumerator i = PythonOps.GetEnumerator(x);
  1171. if (!i.MoveNext())
  1172. throw PythonOps.ValueError(" min() arg is an empty sequence");
  1173. object method = GetMinKwArg(dict);
  1174. object ret = i.Current;
  1175. object retValue = PythonCalls.Call(context, method, i.Current);
  1176. PythonContext pc = PythonContext.GetContext(context);
  1177. while (i.MoveNext()) {
  1178. object tmpRetValue = PythonCalls.Call(context, method, i.Current);
  1179. if (pc.LessThan(tmpRetValue, retValue)) {
  1180. ret = i.Current;
  1181. retValue = tmpRetValue;
  1182. }
  1183. }
  1184. return ret;
  1185. }
  1186. public static object min(CodeContext/*!*/ context, object x, object y, [ParamDictionary]IDictionary<object, object> dict) {
  1187. object method = GetMinKwArg(dict);
  1188. return PythonContext.GetContext(context).LessThan(PythonCalls.Call(context, method, x), PythonCalls.Call(context, method, y)) ? x : y;
  1189. }
  1190. public static object min(CodeContext/*!*/ context, [ParamDictionary]IDictionary<object, object> dict, params object[] args) {
  1191. if (args.Length > 0) {
  1192. int retIndex = 0;
  1193. if (args.Length == 1) {
  1194. return min(context, args[retIndex], dict);
  1195. }
  1196. object method = GetMinKwArg(dict);
  1197. object retValue = PythonCalls.Call(context, method, args[retIndex]);
  1198. PythonContext pc = PythonContext.GetContext(context);
  1199. for (int i = 1; i < args.Length; i++) {
  1200. object tmpRetValue = PythonCalls.Call(context, method, args[i]);
  1201. if (pc.LessThan(tmpRetValue, retValue)) {
  1202. retIndex = i;
  1203. retValue = tmpRetValue;
  1204. }
  1205. }
  1206. return args[retIndex];
  1207. } else {
  1208. throw PythonOps.TypeError("min expecting 1 arguments, got 0");
  1209. }
  1210. }
  1211. private static object GetMinKwArg([ParamDictionary]IDictionary<object, object> dict) {
  1212. if (dict.Count != 1)
  1213. throw PythonOps.TypeError(" min() should have only 1 keyword argument, but got {0} keyword arguments", dict.Count);
  1214. return VerifyKeys("min", dict);
  1215. }
  1216. private static object VerifyKeys(string name, IDictionary<object, object> dict) {
  1217. object value;
  1218. if (!dict.TryGetValue("key", out value)) {
  1219. ICollection<object> keys = dict.Keys;
  1220. IEnumerator<object> en = keys.GetEnumerator();
  1221. if (en.MoveNext()) {
  1222. throw PythonOps.TypeError(" {1}() got an unexpected keyword argument ({0})", en.Current, name);
  1223. }
  1224. }
  1225. return value;
  1226. }
  1227. public static object next(IEnumerator iter) {
  1228. if (iter.MoveNext()) {
  1229. return iter.Current;
  1230. } else {
  1231. throw PythonOps.StopIteration();
  1232. }
  1233. }
  1234. public static object next(IEnumerator iter, object defaultVal) {
  1235. if (iter.MoveNext()) {
  1236. return iter.Current;
  1237. } else {
  1238. return defaultVal;
  1239. }
  1240. }
  1241. [LightThrowing]
  1242. public static object next(PythonGenerator gen) {
  1243. return gen.next();
  1244. }
  1245. [LightThrowing]
  1246. public static object next(PythonGenerator gen, object defaultVal) {
  1247. object res = gen.next();
  1248. Exception exc = LightExceptions.GetLightException(res);
  1249. if (exc != null && exc is StopIterationException) {
  1250. return defaultVal;
  1251. }
  1252. return res;
  1253. }
  1254. public static object next(CodeContext/*!*/ context, object iter) {
  1255. return PythonOps.Invoke(context, iter, "next");
  1256. }
  1257. public static object next(CodeContext/*!*/ context, object iter, object defaultVal) {
  1258. try {
  1259. return PythonOps.Invoke(context, iter, "next");
  1260. } catch (StopIterationException) {
  1261. return defaultVal;
  1262. }
  1263. }
  1264. public static PythonType @object {
  1265. get {
  1266. return DynamicHelpers.GetPythonTypeFromType(typeof(object));
  1267. }
  1268. }
  1269. public static object oct(object o) {
  1270. return PythonOps.Oct(o);
  1271. }
  1272. /// <summary>
  1273. /// Opens a file and returns a new file object.
  1274. ///
  1275. /// name -> the name of the file to open.
  1276. /// mode -> the mode to open the file (r for reading, w for writing, a for appending, default is r).
  1277. /// bufsize -> the size of the buffer to be used (&lt;= 0 indicates to use the default size)
  1278. /// </summary>
  1279. public static PythonFile open(CodeContext context, string name, [DefaultParameterValue("r")]string mode, [DefaultParameterValue(-1)]int buffering) {
  1280. PythonFile res = new PythonFile(context);
  1281. res.__init__(context, name, mode, buffering);
  1282. return res;
  1283. }
  1284. /// <summary>
  1285. /// Creates a new Python file object from a .NET stream object.
  1286. ///
  1287. /// stream -> the stream to wrap in a file object.
  1288. /// </summary>
  1289. public static PythonFile open(CodeContext context, [NotNull]Stream stream) {
  1290. PythonFile res = new PythonFile(context);
  1291. res.__init__(context, stream);
  1292. return res;
  1293. }
  1294. public static int ord(object value) {
  1295. if (value is char) {
  1296. return (char)value;
  1297. }
  1298. string stringValue = value as string;
  1299. if (stringValue == null) {
  1300. ExtensibleString es = value as ExtensibleString;
  1301. if (es != null) stringValue = es.Value;
  1302. }
  1303. if (stringValue != null) {
  1304. if (stringValue.Length != 1) {
  1305. throw PythonOps.TypeError("expected a character, but string of length {0} found", stringValue.Length);
  1306. }
  1307. return stringValue[0];
  1308. }
  1309. IList<byte> bytes = value as IList<byte>;
  1310. if (bytes != null) {
  1311. if (bytes.Count != 1) {
  1312. throw PythonOps.TypeError("expected a character, but string of length {0} found", bytes.Count);
  1313. }
  1314. return bytes[0];
  1315. }
  1316. throw PythonOps.TypeError("expected a character, but {0} found", PythonTypeOps.GetName(value));
  1317. }
  1318. public static object pow(CodeContext/*!*/ context, object x, object y) {
  1319. return PythonContext.GetContext(context).Operation(PythonOperationKind.Power, x, y);
  1320. }
  1321. public static object pow(CodeContext/*!*/ context, object x, object y, object z) {
  1322. try {
  1323. return PythonOps.PowerMod(context, x, y, z);
  1324. } catch (DivideByZeroException) {
  1325. throw PythonOps.ValueError("3rd argument cannot be 0");
  1326. }
  1327. }
  1328. public static void print(CodeContext/*!*/ context, params object[] args) {
  1329. print(context, " ", "\n", null, args);
  1330. }
  1331. public static void print(CodeContext/*!*/ context, [ParamDictionary]IDictionary<object, object> kwargs, params object[] args) {
  1332. object sep = AttrCollectionPop(kwargs, "sep", " ");
  1333. if (sep != null && !(sep is string)) {
  1334. throw PythonOps.TypeError("sep must be None or str, not {0}", PythonTypeOps.GetName(sep));
  1335. }
  1336. object end = AttrCollectionPop(kwargs, "end", "\n");
  1337. if (sep != null && !(sep is string)) {
  1338. throw PythonOps.TypeError("end must be None or str, not {0}", PythonTypeOps.GetName(end));
  1339. }
  1340. object file = AttrCollectionPop(kwargs, "file", null);
  1341. if (kwargs.Count != 0) {
  1342. throw PythonOps.TypeError(
  1343. "'{0}' is an invalid keyword argument for this function",
  1344. new List<object>(kwargs.Keys)[0]
  1345. );
  1346. }
  1347. print(context, (string)sep ?? " ", (string)end ?? "\n", file, args);
  1348. }
  1349. private static object AttrCollectionPop(IDictionary<object, object> kwargs, string name, object defaultValue) {
  1350. object res;
  1351. if (kwargs.TryGetValue(name, out res)) {
  1352. kwargs.Remove(name);
  1353. } else {
  1354. res = defaultValue;
  1355. }
  1356. return res;
  1357. }
  1358. private static void print(CodeContext/*!*/ context, string/*!*/ sep, string/*!*/ end, object file, object[]/*!*/ args) {
  1359. PythonContext pc = PythonContext.GetContext(context);
  1360. if (file == null) {
  1361. file = pc.SystemStandardOut;
  1362. }
  1363. if (file == null) {
  1364. throw PythonOps.RuntimeError("lost sys.std_out");
  1365. }
  1366. if (args == null) {
  1367. // passing None to print passes a null object array
  1368. args = new object[1];
  1369. }
  1370. PythonFile pf = file as PythonFile;
  1371. for (int i = 0; i < args.Length; i++) {
  1372. string text = PythonOps.ToString(context, args[i]);
  1373. if (pf != null) {
  1374. pf.write(text);
  1375. } else {
  1376. pc.WriteCallSite.Target(
  1377. pc.WriteCallSite,
  1378. context,
  1379. PythonOps.GetBoundAttr(context, file, "write"),
  1380. text
  1381. );
  1382. }
  1383. if (i != args.Length - 1) {
  1384. if (pf != null) {
  1385. pf.write(sep);
  1386. } else {
  1387. pc.WriteCallSite.Target(
  1388. pc.WriteCallSite,
  1389. context,
  1390. PythonOps.GetBoundAttr(context, file, "write"),
  1391. sep
  1392. );
  1393. }
  1394. }
  1395. }
  1396. if (pf != null) {
  1397. pf.write(end);
  1398. } else {
  1399. pc.WriteCallSite.Target(
  1400. pc.WriteCallSite,
  1401. context,
  1402. PythonOps.GetBoundAttr(context, file, "write"),
  1403. end
  1404. );
  1405. }
  1406. }
  1407. public static PythonType property {
  1408. get {
  1409. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonProperty));
  1410. }
  1411. }
  1412. [return: SequenceTypeInfo(typeof(int))]
  1413. public static List range(int stop) {
  1414. return rangeWorker(stop);
  1415. }
  1416. [return: SequenceTypeInfo(typeof(int))]
  1417. public static List range(BigInteger stop) {
  1418. return rangeWorker(stop);
  1419. }
  1420. private static List rangeWorker(int stop) {
  1421. if (stop < 0) {
  1422. stop = 0;
  1423. }
  1424. List ret = PythonOps.MakeEmptyList(stop);
  1425. for (int i = 0; i < stop; i++) ret.AddNoLock(ScriptingRuntimeHelpers.Int32ToObject(i));
  1426. return ret;
  1427. }
  1428. private static List rangeWorker(BigInteger stop) {
  1429. if (stop < BigInteger.Zero) {
  1430. return range(0);
  1431. }
  1432. int istop;
  1433. if (stop.AsInt32(out istop)) {
  1434. return range(istop);
  1435. }
  1436. throw PythonOps.OverflowError("too many items in the range");
  1437. }
  1438. [return: SequenceTypeInfo(typeof(int))]
  1439. public static List range(int start, int stop) {
  1440. return rangeWorker(start, stop);
  1441. }
  1442. [return: SequenceTypeInfo(typeof(int))]
  1443. public static List range(BigInteger start, BigInteger stop) {
  1444. return rangeWorker(start, stop);
  1445. }
  1446. private static List rangeWorker(int start, int stop) {
  1447. if (start > stop) {
  1448. stop = start;
  1449. }
  1450. long length = (long)stop - (long)start;
  1451. if (Int32.MinValue <= length && length <= Int32.MaxValue) {
  1452. List ret = PythonOps.MakeEmptyList(stop - start);
  1453. for (int i = start; i < stop; i++) ret.AddNoLock(ScriptingRuntimeHelpers.Int32ToObject(i));
  1454. return ret;
  1455. }
  1456. throw PythonOps.OverflowError("too many items in the list");
  1457. }
  1458. private static List rangeWorker(BigInteger start, BigInteger stop) {
  1459. if (start > stop) {
  1460. stop = start;
  1461. }
  1462. BigInteger length = stop - start;
  1463. int ilength;
  1464. if (length.AsInt32(out ilength)) {
  1465. List ret = PythonOps.MakeEmptyList(ilength);
  1466. for (int i = 0; i < ilength; i++) {
  1467. ret.AddNoLock(start + i);
  1468. }
  1469. return ret;
  1470. }
  1471. throw PythonOps.OverflowError("too many items in the range");
  1472. }
  1473. [return: SequenceTypeInfo(typeof(int))]
  1474. public static List range(int start, int stop, int step) {
  1475. return rangeWorker(start, stop, step);
  1476. }
  1477. [return: SequenceTypeInfo(typeof(int))]
  1478. public static List range(BigInteger start, BigInteger stop, BigInteger step) {
  1479. return rangeWorker(start, stop, step);
  1480. }
  1481. private static List rangeWorker(int start, int stop, int step) {
  1482. if (step == 0) {
  1483. throw PythonOps.ValueError("step of 0");
  1484. }
  1485. List ret;
  1486. if (step > 0) {
  1487. if (start > stop) stop = start;
  1488. ret = PythonOps.MakeEmptyList((stop - start) / step);
  1489. for (int i = start; i < stop; i += step) {
  1490. ret.AddNoLock(ScriptingRuntimeHelpers.Int32ToObject(i));
  1491. }
  1492. } else {
  1493. if (start < stop) stop = start;
  1494. ret = PythonOps.MakeEmptyList((stop - start) / step);
  1495. for (int i = start; i > stop; i += step) {
  1496. ret.AddNoLock(ScriptingRuntimeHelpers.Int32ToObject(i));
  1497. }
  1498. }
  1499. return ret;
  1500. }
  1501. private static List rangeWorker(BigInteger start, BigInteger stop, BigInteger step) {
  1502. if (step == BigInteger.Zero) {
  1503. throw PythonOps.ValueError("step of 0");
  1504. }
  1505. BigInteger length;
  1506. if (step > BigInteger.Zero) {
  1507. if (start > stop) stop = start;
  1508. length = (stop - start + step - 1) / step;
  1509. } else {
  1510. if (start < stop) stop = start;
  1511. length = (stop - start + step + 1) / step;
  1512. }
  1513. int ilength;
  1514. if (length.AsInt32(out ilength)) {
  1515. List ret = PythonOps.MakeEmptyList(ilength);
  1516. for (int i = 0; i < ilength; i++) {
  1517. ret.AddNoLock(start);
  1518. start = start + step;
  1519. }
  1520. return ret;
  1521. }
  1522. throw PythonOps.OverflowError("too many items for list");
  1523. }
  1524. /// <summary>
  1525. /// object overload of range - attempts to convert via __int__, and __trunc__ if arg is
  1526. /// an OldInstance
  1527. /// </summary>
  1528. [return: SequenceTypeInfo(typeof(int))]
  1529. public static List range(CodeContext/*!*/ context, object stop) {
  1530. return range(GetRangeInt(context, stop, "end"));
  1531. }
  1532. /// <summary>
  1533. /// object overload of range - attempts to convert via __int__, and __trunc__ if arg is
  1534. /// an OldInstance
  1535. /// </summary>
  1536. [return: SequenceTypeInfo(typeof(int))]
  1537. public static List range(CodeContext/*!*/ context, object start, object stop, [DefaultParameterValue(1)]object step) {
  1538. BigInteger stopInt = GetRangeInt(context, stop, "end");
  1539. BigInteger startInt = GetRangeInt(context, start, "start");
  1540. BigInteger stepInt = GetRangeInt(context, step, "step");
  1541. return range(startInt, stopInt, stepInt);
  1542. }
  1543. private static bool FastGetRangeInt(object arg, out BigInteger res) {
  1544. if (arg is int) {
  1545. res = (BigInteger)(int)arg;
  1546. return true;
  1547. } else if (arg is BigInteger) {
  1548. res = (BigInteger)arg;
  1549. return true;
  1550. }
  1551. Extensible<int> ei;
  1552. Extensible<BigInteger> ebi;
  1553. if ((ei = arg as Extensible<int>) != null) {
  1554. res = (BigInteger)ei.Value;
  1555. return true;
  1556. } else if ((ebi = arg as Extensible<BigInteger>) != null) {
  1557. res = ebi.Value;
  1558. return true;
  1559. }
  1560. res = BigInteger.Zero;
  1561. return false;
  1562. }
  1563. private static BigInteger GetRangeInt(CodeContext/*!*/ context, object arg, string pos) {
  1564. BigInteger res;
  1565. if (FastGetRangeInt(arg, out res)) {
  1566. return res;
  1567. }
  1568. if (arg is double || arg is Extensible<double>) {
  1569. throw PythonOps.TypeError(
  1570. "range() integer {0} argument expected, got {1}.",
  1571. pos, PythonTypeOps.GetName(arg)
  1572. );
  1573. }
  1574. object Conversion;
  1575. if (PythonOps.TryGetBoundAttr(context, arg, "__int__", out Conversion)) {
  1576. if (!FastGetRangeInt(PythonOps.CallWithContext(context, Conversion), out res)) {
  1577. throw PythonOps.TypeError("__int__ should return int object");
  1578. }
  1579. return res;
  1580. } else if (arg is OldInstance) {
  1581. if (PythonOps.TryGetBoundAttr(context, arg, "__trunc__", out Conversion)) {
  1582. if (!FastGetRangeInt(PythonOps.CallWithContext(context, Conversion), out res)) {
  1583. throw PythonOps.TypeError(
  1584. "__trunc__ returned non-Integral (type {0})",
  1585. PythonTypeOps.GetOldName(arg)
  1586. );
  1587. }
  1588. return res;
  1589. }
  1590. throw PythonOps.AttributeError(
  1591. "{0} instance has no attribute __trunc__",
  1592. PythonTypeOps.GetOldName(arg)
  1593. );
  1594. }
  1595. throw PythonOps.TypeError(
  1596. "range() integer {0} argument expected, got {1}.",
  1597. pos, PythonTypeOps.GetName(arg)
  1598. );
  1599. }
  1600. public static string raw_input(CodeContext/*!*/ context) {
  1601. return raw_input(context, null);
  1602. }
  1603. public static string raw_input(CodeContext/*!*/ context, object prompt) {
  1604. if (prompt != null) {
  1605. PythonOps.PrintNoNewline(context, prompt);
  1606. }
  1607. string line = PythonOps.ReadLineFromSrc(context, PythonContext.GetContext(context).SystemStandardIn) as string;
  1608. if (line != null && line.EndsWith("\n")) return line.Substring(0, line.Length - 1);
  1609. return line;
  1610. }
  1611. public static object reduce(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object, object, object>>> siteData, object func, object seq) {
  1612. IEnumerator i = PythonOps.GetEnumerator(seq);
  1613. if (!i.MoveNext()) {
  1614. throw PythonOps.TypeError("reduce() of empty sequence with no initial value");
  1615. }
  1616. EnsureReduceData(context, siteData);
  1617. CallSite<Func<CallSite, CodeContext, object, object, object, object>> site = siteData.Data;
  1618. object ret = i.Current;
  1619. while (i.MoveNext()) {
  1620. ret = site.Target(site, context, func, ret, i.Current);
  1621. }
  1622. return ret;
  1623. }
  1624. public static object reduce(CodeContext/*!*/ context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object, object, object>>> siteData, object func, object seq, object initializer) {
  1625. IEnumerator i = PythonOps.GetEnumerator(seq);
  1626. EnsureReduceData(context, siteData);
  1627. CallSite<Func<CallSite, CodeContext, object, object, object, object>> site = siteData.Data;
  1628. object ret = initializer;
  1629. while (i.MoveNext()) {
  1630. ret = site.Target(site, context, func, ret, i.Current);
  1631. }
  1632. return ret;
  1633. }
  1634. private static void EnsureReduceData(CodeContext context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object, object, object>>> siteData) {
  1635. if (siteData.Data == null) {
  1636. siteData.Data = CallSite<Func<CallSite, CodeContext, object, object, object, object>>.Create(
  1637. PythonContext.GetContext(context).Invoke(
  1638. new CallSignature(2)
  1639. )
  1640. );
  1641. }
  1642. }
  1643. [ThreadStatic]
  1644. private static List<PythonModule> _reloadStack;
  1645. public static object reload(CodeContext/*!*/ context, PythonModule/*!*/ module) {
  1646. if (module == null) {
  1647. throw PythonOps.TypeError("unexpected type: NoneType");
  1648. }
  1649. if (_reloadStack == null) {
  1650. Interlocked.CompareExchange(ref _reloadStack, new List<PythonModule>(), null);
  1651. }
  1652. // if a module attempts to reload it's self while already reloading it's
  1653. // self we just return the original module.
  1654. if (_reloadStack.Contains(module)) {
  1655. return module;
  1656. }
  1657. _reloadStack.Add(module);
  1658. try {
  1659. return Importer.ReloadModule(context, module);
  1660. } finally {
  1661. _reloadStack.RemoveAt(_reloadStack.Count - 1);
  1662. }
  1663. }
  1664. public static object repr(CodeContext/*!*/ context, object o) {
  1665. object res = PythonOps.Repr(context, o);
  1666. if (!(res is String) && !(res is ExtensibleString)) {
  1667. throw PythonOps.TypeError("__repr__ returned non-string (type {0})", PythonOps.GetPythonTypeName(o));
  1668. }
  1669. return res;
  1670. }
  1671. public static PythonType reversed {
  1672. get {
  1673. return DynamicHelpers.GetPythonTypeFromType(typeof(ReversedEnumerator));
  1674. }
  1675. }
  1676. public static double round(double number) {
  1677. return MathUtils.RoundAwayFromZero(number);
  1678. }
  1679. public static double round(double number, int ndigits) {
  1680. return PythonOps.CheckMath(number, MathUtils.RoundAwayFromZero(number, ndigits));
  1681. }
  1682. public static double round(double number, BigInteger ndigits) {
  1683. int n;
  1684. if (ndigits.AsInt32(out n)) {
  1685. return round(number, n);
  1686. }
  1687. return ndigits > 0 ? number : 0.0;
  1688. }
  1689. public static double round(double number, double ndigits) {
  1690. throw PythonOps.TypeError("'float' object cannot be interpreted as an index");
  1691. }
  1692. public static void setattr(CodeContext/*!*/ context, object o, string name, object val) {
  1693. PythonOps.SetAttr(context, o, name, val);
  1694. }
  1695. public static PythonType slice {
  1696. get {
  1697. return DynamicHelpers.GetPythonTypeFromType(typeof(Slice));
  1698. }
  1699. }
  1700. public static List sorted(CodeContext/*!*/ context, object iterable) {
  1701. return sorted(context, iterable, null, null, false);
  1702. }
  1703. public static List sorted(CodeContext/*!*/ context, object iterable, object cmp) {
  1704. return sorted(context, iterable, cmp, null, false);
  1705. }
  1706. public static List sorted(CodeContext/*!*/ context, object iterable, object cmp, object key) {
  1707. return sorted(context, iterable, cmp, key, false);
  1708. }
  1709. public static List sorted(CodeContext/*!*/ context,
  1710. [DefaultParameterValue(null)] object iterable,
  1711. [DefaultParameterValue(null)]object cmp,
  1712. [DefaultParameterValue(null)]object key,
  1713. [DefaultParameterValue(false)]bool reverse) {
  1714. IEnumerator iter = PythonOps.GetEnumerator(iterable);
  1715. List l = PythonOps.MakeEmptyList(10);
  1716. while (iter.MoveNext()) {
  1717. l.AddNoLock(iter.Current);
  1718. }
  1719. l.sort(context, cmp, key, reverse);
  1720. return l;
  1721. }
  1722. public static PythonType staticmethod {
  1723. get {
  1724. return DynamicHelpers.GetPythonTypeFromType(typeof(staticmethod));
  1725. }
  1726. }
  1727. public static object sum(CodeContext/*!*/ context, object sequence) {
  1728. return sum(context, sequence, 0);
  1729. }
  1730. public static object sum(CodeContext/*!*/ context, [NotNull]List sequence) {
  1731. return sum(context, sequence, 0);
  1732. }
  1733. public static object sum(CodeContext/*!*/ context, [NotNull]PythonTuple sequence) {
  1734. return sum(context, sequence, 0);
  1735. }
  1736. public static object sum(CodeContext/*!*/ context, object sequence, object start) {
  1737. IEnumerator i = PythonOps.GetEnumerator(sequence);
  1738. if (start is string) {
  1739. throw PythonOps.TypeError("Cannot sum strings, use '{0}'.join(seq)", start);
  1740. }
  1741. var sumState = new SumState(context.LanguageContext, start);
  1742. object ret = start;
  1743. while (i.MoveNext()) {
  1744. SumOne(ref sumState, i.Current);
  1745. }
  1746. return sumState.CurrentValue;
  1747. }
  1748. public static object sum(CodeContext/*!*/ context, [NotNull]List sequence, object start) {
  1749. if (start is string) {
  1750. throw PythonOps.TypeError("Cannot sum strings, use '{0}'.join(seq)", start);
  1751. }
  1752. var sumState = new SumState(context.LanguageContext, start);
  1753. for (int i = 0; i < sequence._size; i++) {
  1754. SumOne(ref sumState, sequence._data[i]);
  1755. }
  1756. return sumState.CurrentValue;
  1757. }
  1758. public static object sum(CodeContext/*!*/ context, [NotNull]PythonTuple sequence, object start) {
  1759. if (start is string) {
  1760. throw PythonOps.TypeError("Cannot sum strings, use '{0}'.join(seq)", start);
  1761. }
  1762. var sumState = new SumState(context.LanguageContext, start);
  1763. var arr = sequence._data;
  1764. for (int i = 0; i < arr.Length; i++) {
  1765. SumOne(ref sumState, arr[i]);
  1766. }
  1767. return sumState.CurrentValue;
  1768. }
  1769. #region Optimized sum
  1770. private static void SumOne(ref SumState state, object current) {
  1771. if (current != null) {
  1772. if (state.CurType == SumVariantType.Int) {
  1773. if (current.GetType() == typeof(int)) {
  1774. try {
  1775. state.IntVal = checked(state.IntVal + ((int)current));
  1776. } catch (OverflowException) {
  1777. state.BigIntVal = (BigInteger)state.IntVal + (BigInteger)(int)current;
  1778. state.CurType = SumVariantType.BigInt;
  1779. }
  1780. } else if (current.GetType() == typeof(double)) {
  1781. state.DoubleVal = state.IntVal + ((double)current);
  1782. state.CurType = SumVariantType.Double;
  1783. } else if (current.GetType() == typeof(BigInteger)) {
  1784. state.BigIntVal = (BigInteger)state.IntVal + (BigInteger)current;
  1785. state.CurType = SumVariantType.BigInt;
  1786. } else {
  1787. SumObject(ref state, state.IntVal, current);
  1788. }
  1789. } else if (state.CurType == SumVariantType.Double) {
  1790. if (current.GetType() == typeof(double)) {
  1791. state.DoubleVal = state.DoubleVal + ((double)current);
  1792. } else if (current.GetType() == typeof(int)) {
  1793. state.DoubleVal = state.DoubleVal + ((int)current);
  1794. } else if (current.GetType() == typeof(BigInteger)) {
  1795. SumBigIntAndDouble(ref state, (BigInteger)current, state.DoubleVal);
  1796. } else {
  1797. SumObject(ref state, state.DoubleVal, current);
  1798. }
  1799. } else if (state.CurType == SumVariantType.BigInt) {
  1800. if (current.GetType() == typeof(BigInteger)) {
  1801. state.BigIntVal = state.BigIntVal + ((BigInteger)current);
  1802. } else if (current.GetType() == typeof(int)) {
  1803. state.BigIntVal = state.BigIntVal + ((int)current);
  1804. } else if (current.GetType() == typeof(double)) {
  1805. SumBigIntAndDouble(ref state, state.BigIntVal, (double)current);
  1806. } else {
  1807. SumObject(ref state, state.BigIntVal, current);
  1808. }
  1809. } else if (state.CurType == SumVariantType.Object) {
  1810. state.ObjectVal = state.AddSite.Target(state.AddSite, state.ObjectVal, current);
  1811. }
  1812. } else {
  1813. SumObject(ref state, state.BigIntVal, current);
  1814. }
  1815. }
  1816. #if CLR2
  1817. private static BigInteger MaxDouble = BigInteger.Create(Double.MaxValue);
  1818. private static BigInteger MinDouble = BigInteger.Create(Double.MinValue);
  1819. #else
  1820. private static BigInteger MaxDouble = new BigInteger(Double.MaxValue);
  1821. private static BigInteger MinDouble = new BigInteger(Double.MinValue);
  1822. #endif
  1823. private static void SumBigIntAndDouble(ref SumState state, BigInteger bigInt, double dbl) {
  1824. if (bigInt <= MaxDouble && bigInt >= MinDouble) {
  1825. state.DoubleVal = (double)bigInt + dbl;
  1826. state.CurType = SumVariantType.Double;
  1827. } else {
  1828. // fallback to normal add to report error
  1829. SumObject(ref state, dbl, bigInt);
  1830. }
  1831. }
  1832. private static void SumObject(ref SumState state, object value, object current) {
  1833. state.ObjectVal = state.AddSite.Target(state.AddSite, value, current);
  1834. state.CurType = SumVariantType.Object;
  1835. }
  1836. enum SumVariantType {
  1837. Double,
  1838. Int,
  1839. BigInt,
  1840. Object
  1841. }
  1842. struct SumState {
  1843. public double DoubleVal;
  1844. public int IntVal;
  1845. public object ObjectVal;
  1846. public BigInteger BigIntVal;
  1847. public SumVariantType CurType;
  1848. public CallSite<Func<CallSite, object, object, object>> AddSite;
  1849. public SumState(PythonContext context, object start) {
  1850. DoubleVal = 0;
  1851. IntVal = 0;
  1852. ObjectVal = start;
  1853. BigIntVal = BigInteger.Zero;
  1854. AddSite = context.EnsureAddSite();
  1855. if (start != null) {
  1856. if (start.GetType() == typeof(int)) {
  1857. CurType = SumVariantType.Int;
  1858. IntVal = (int)start;
  1859. } else if (start.GetType() == typeof(double)) {
  1860. CurType = SumVariantType.Double;
  1861. DoubleVal = (double)start;
  1862. } else if (start.GetType() == typeof(BigInteger)) {
  1863. CurType = SumVariantType.BigInt;
  1864. BigIntVal = (BigInteger)start;
  1865. } else {
  1866. CurType = SumVariantType.Object;
  1867. }
  1868. } else {
  1869. CurType = SumVariantType.Object;
  1870. }
  1871. }
  1872. public object CurrentValue {
  1873. get {
  1874. switch (CurType) {
  1875. case SumVariantType.BigInt: return BigIntVal;
  1876. case SumVariantType.Double: return DoubleVal;
  1877. case SumVariantType.Int: return IntVal;
  1878. case SumVariantType.Object: return ObjectVal;
  1879. default: throw Assert.Unreachable;
  1880. }
  1881. }
  1882. }
  1883. }
  1884. #endregion
  1885. public static PythonType super {
  1886. get {
  1887. return DynamicHelpers.GetPythonTypeFromType(typeof(Super));
  1888. }
  1889. }
  1890. public static PythonType str {
  1891. get {
  1892. return DynamicHelpers.GetPythonTypeFromType(typeof(string));
  1893. }
  1894. }
  1895. public static PythonType tuple {
  1896. get {
  1897. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonTuple));
  1898. }
  1899. }
  1900. public static PythonType type {
  1901. get {
  1902. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonType));
  1903. }
  1904. }
  1905. public static string unichr(int i) {
  1906. if (i < Char.MinValue || i > Char.MaxValue) {
  1907. throw PythonOps.ValueError("{0} is not in required range", i);
  1908. }
  1909. return ScriptingRuntimeHelpers.CharToString((char)i);
  1910. }
  1911. public static PythonType unicode {
  1912. get {
  1913. return DynamicHelpers.GetPythonTypeFromType(typeof(string));
  1914. }
  1915. }
  1916. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
  1917. [Documentation("vars([object]) -> dictionary\n\nWithout arguments, equivalent to locals().\nWith an argument, equivalent to object.__dict__.")]
  1918. public static object vars(CodeContext/*!*/ context) {
  1919. return locals(context);
  1920. }
  1921. public static object vars(CodeContext/*!*/ context, object @object) {
  1922. object value;
  1923. if (!PythonOps.TryGetBoundAttr(@object, "__dict__", out value)) {
  1924. throw PythonOps.TypeError("vars() argument must have __dict__ attribute");
  1925. }
  1926. return value;
  1927. }
  1928. public static PythonType xrange {
  1929. get {
  1930. return DynamicHelpers.GetPythonTypeFromType(typeof(XRange));
  1931. }
  1932. }
  1933. public static List zip(object s0, object s1) {
  1934. IEnumerator i0 = PythonOps.GetEnumerator(s0);
  1935. IEnumerator i1 = PythonOps.GetEnumerator(s1);
  1936. List ret = new List();
  1937. while(true) {
  1938. object obj0, obj1;
  1939. if(!i0.MoveNext()) {
  1940. break;
  1941. }
  1942. obj0 = i0.Current;
  1943. if(!i1.MoveNext()) {
  1944. break;
  1945. }
  1946. obj1 = i1.Current;
  1947. ret.AddNoLock(PythonTuple.MakeTuple(obj0, obj1));
  1948. }
  1949. return ret;
  1950. }
  1951. //??? should we fastpath the 1,2,3 item cases???
  1952. public static List zip(params object[] seqs) {
  1953. if (seqs == null) throw PythonOps.TypeError("zip argument must support iteration, got None");
  1954. int N = seqs.Length;
  1955. if (N == 2) return zip(seqs[0], seqs[1]);
  1956. if (N == 0) return PythonOps.MakeList();
  1957. IEnumerator[] iters = new IEnumerator[N];
  1958. for (int i = 0; i < N; i++) iters[i] = PythonOps.GetEnumerator(seqs[i]);
  1959. List ret = new List();
  1960. while (true) {
  1961. object[] items = new object[N];
  1962. for (int i = 0; i < N; i++) {
  1963. // first iterator which is no longer iterable ends the
  1964. // loop.
  1965. if (!iters[i].MoveNext()) return ret;
  1966. items[i] = iters[i].Current;
  1967. }
  1968. ret.AddNoLock(PythonTuple.MakeTuple(items));
  1969. }
  1970. }
  1971. public static PythonType BaseException {
  1972. get {
  1973. return DynamicHelpers.GetPythonTypeFromType(typeof(PythonExceptions.BaseException));
  1974. }
  1975. }
  1976. /// <summary>
  1977. /// Gets the appropriate LanguageContext to be used for code compiled with Python's compile, eval, execfile, etc...
  1978. /// </summary>
  1979. internal static PythonCompilerOptions GetRuntimeGeneratedCodeCompilerOptions(CodeContext/*!*/ context, bool inheritContext, CompileFlags cflags) {
  1980. PythonCompilerOptions pco;
  1981. if (inheritContext) {
  1982. pco = new PythonCompilerOptions(context.ModuleContext.Features);
  1983. } else {
  1984. pco = DefaultContext.DefaultPythonContext.GetPythonCompilerOptions();
  1985. }
  1986. if (((cflags & (CompileFlags.CO_FUTURE_DIVISION | CompileFlags.CO_FUTURE_ABSOLUTE_IMPORT | CompileFlags.CO_FUTURE_WITH_STATEMENT)) != 0)) {
  1987. ModuleOptions langFeat = ModuleOptions.None;
  1988. if ((cflags & CompileFlags.CO_FUTURE_DIVISION) != 0) {
  1989. langFeat |= ModuleOptions.TrueDivision;
  1990. }
  1991. if ((cflags & CompileFlags.CO_FUTURE_WITH_STATEMENT) != 0) {
  1992. langFeat |= ModuleOptions.WithStatement;
  1993. }
  1994. if ((cflags & CompileFlags.CO_FUTURE_ABSOLUTE_IMPORT) != 0) {
  1995. langFeat |= ModuleOptions.AbsoluteImports;
  1996. }
  1997. pco.Module |= langFeat;
  1998. }
  1999. // The options created this way never creates
  2000. // optimized module (exec, compile)
  2001. pco.Module &= ~(ModuleOptions.Optimized | ModuleOptions.Initialize);
  2002. pco.Module |= ModuleOptions.Interpret | ModuleOptions.ExecOrEvalCode;
  2003. pco.CompilationMode = CompilationMode.Lookup;
  2004. return pco;
  2005. }
  2006. /// <summary> Returns true if we should inherit our callers context (true division, etc...), false otherwise </summary>
  2007. private static bool GetCompilerInheritance(object dontInherit) {
  2008. return dontInherit == null || Converter.ConvertToInt32(dontInherit) == 0;
  2009. }
  2010. /// <summary> Returns the default compiler flags or the flags the user specified. </summary>
  2011. private static CompileFlags GetCompilerFlags(object flags) {
  2012. CompileFlags cflags = 0;
  2013. if (flags != null) {
  2014. cflags = (CompileFlags)Converter.ConvertToInt32(flags);
  2015. if ((cflags & ~(CompileFlags.CO_NESTED | CompileFlags.CO_GENERATOR_ALLOWED | CompileFlags.CO_FUTURE_DIVISION | CompileFlags.CO_DONT_IMPLY_DEDENT |
  2016. CompileFlags.CO_FUTURE_ABSOLUTE_IMPORT | CompileFlags.CO_FUTURE_WITH_STATEMENT)) != 0) {
  2017. throw PythonOps.ValueError("unrecognized flags");
  2018. }
  2019. }
  2020. return cflags;
  2021. }
  2022. /// <summary>
  2023. /// Gets a scope used for executing new code in optionally replacing the globals and locals dictionaries.
  2024. /// </summary>
  2025. private static CodeContext/*!*/ GetExecEvalScopeOptional(CodeContext/*!*/ context, PythonDictionary globals, object localsDict, bool copyModule) {
  2026. Assert.NotNull(context);
  2027. if (globals == null) globals = Builtin.globals(context);
  2028. if (localsDict == null) localsDict = locals(context);
  2029. return GetExecEvalScope(context, globals, GetAttrLocals(context, localsDict), copyModule, true);
  2030. }
  2031. internal static CodeContext/*!*/ GetExecEvalScope(CodeContext/*!*/ context, PythonDictionary/*!*/ globals,
  2032. PythonDictionary locals, bool copyModule, bool setBuiltinsToModule) {
  2033. Assert.NotNull(context, globals);
  2034. PythonContext python = PythonContext.GetContext(context);
  2035. // TODO: Need to worry about propagating changes to MC out?
  2036. var mc = new ModuleContext(PythonDictionary.FromIAC(context, globals), context.LanguageContext);
  2037. CodeContext localContext;
  2038. if (locals == null) {
  2039. localContext = mc.GlobalContext;
  2040. } else {
  2041. localContext = new CodeContext(PythonDictionary.FromIAC(context, locals), mc);
  2042. }
  2043. if (!globals.ContainsKey("__builtins__")) {
  2044. if (setBuiltinsToModule) {
  2045. globals["__builtins__"] = python.SystemStateModules["__builtin__"];
  2046. } else {
  2047. globals["__builtins__"] = python.BuiltinModuleDict;
  2048. }
  2049. }
  2050. return localContext;
  2051. }
  2052. [SpecialName]
  2053. public static void PerformModuleReload(PythonContext context, PythonDictionary dict) {
  2054. dict["__debug__"] = ScriptingRuntimeHelpers.BooleanToObject(!context.PythonOptions.Optimize);
  2055. }
  2056. }
  2057. }