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

/DICK.B1/IronPython/Modules/Builtin.cs

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