PageRenderTime 37ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

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

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