PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/DICK.B1/IronPython.Modules/_warnings.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 247 lines | 205 code | 23 blank | 19 comment | 70 complexity | 3108d0c8318b8a60fdeef6c11bebd083 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.Generic;
  17. using System.IO;
  18. using System.Runtime.CompilerServices;
  19. using System.Runtime.InteropServices;
  20. using System.Text;
  21. using System.Text.RegularExpressions;
  22. using IronPython.Runtime;
  23. using IronPython.Runtime.Exceptions;
  24. using IronPython.Runtime.Operations;
  25. using IronPython.Runtime.Types;
  26. using Microsoft.Scripting;
  27. using Microsoft.Scripting.Runtime;
  28. [assembly: PythonModule("_warnings", typeof(IronPython.Modules.PythonWarnings))]
  29. namespace IronPython.Modules {
  30. public static class PythonWarnings {
  31. public const string __doc__ = "Provides low-level functionality for reporting warnings";
  32. private static readonly object _keyFields = new object();
  33. private static readonly string _keyDefaultAction = "default_action";
  34. private static readonly string _keyFilters = "filters";
  35. private static readonly string _keyOnceRegistry = "once_registry";
  36. [SpecialName]
  37. public static void PerformModuleReload(PythonContext/*!*/ context, PythonDictionary/*!*/ dict) {
  38. context.GetOrCreateModuleState(_keyFields, () => {
  39. dict.Add(_keyDefaultAction, "default");
  40. dict.Add(_keyOnceRegistry, new PythonDictionary());
  41. dict.Add(_keyFilters, new List() {
  42. // Default filters
  43. PythonTuple.MakeTuple("ignore", null, PythonExceptions.PendingDeprecationWarning, null, 0),
  44. PythonTuple.MakeTuple("ignore", null, PythonExceptions.ImportWarning, null, 0),
  45. PythonTuple.MakeTuple("ignore", null, PythonExceptions.BytesWarning, null, 0)
  46. });
  47. return dict;
  48. });
  49. }
  50. #region Public API
  51. public static void warn(CodeContext context, object message, [DefaultParameterValue(null)]PythonType category, [DefaultParameterValue(1)]int stacklevel) {
  52. PythonContext pContext = PythonContext.GetContext(context);
  53. List argv = pContext.GetSystemStateValue("argv") as List;
  54. PythonDictionary dict = pContext.GetSystemStateValue("__dict__") as PythonDictionary;
  55. if (PythonOps.IsInstance(message, PythonExceptions.Warning)) {
  56. category = DynamicHelpers.GetPythonType(message);
  57. }
  58. if (category == null) {
  59. category = PythonExceptions.UserWarning;
  60. }
  61. if (!category.IsSubclassOf(PythonExceptions.Warning)) {
  62. throw PythonOps.ValueError("category is not a subclass of Warning");
  63. }
  64. // default behavior without sys._getframe
  65. PythonDictionary globals = Builtin.globals(context) as PythonDictionary;
  66. int lineno = 1;
  67. string module;
  68. string filename;
  69. if (globals != null && globals.ContainsKey("__name__")) {
  70. module = (string)globals.get("__name__");
  71. } else {
  72. module = "<string>";
  73. }
  74. filename = globals.get("__file__") as string;
  75. if (filename == null || filename == "") {
  76. if (module == "__main__") {
  77. if (argv != null && argv.Count > 0) {
  78. filename = argv[0] as string;
  79. } else {
  80. // interpreter lacks sys.argv
  81. filename = "__main__";
  82. }
  83. }
  84. if (filename == null || filename == "") {
  85. filename = module;
  86. }
  87. }
  88. PythonDictionary registry = (PythonDictionary)globals.setdefault("__warningregistry__", new PythonDictionary());
  89. warn_explicit(context, message, category, filename, lineno, module, registry, globals);
  90. }
  91. public static void warn_explicit(CodeContext context, object message, PythonType category, string filename, int lineno, [DefaultParameterValue(null)]string module, [DefaultParameterValue(null)]PythonDictionary registry, [DefaultParameterValue(null)]object module_globals) {
  92. PythonContext pContext = PythonContext.GetContext(context);
  93. PythonDictionary fields = (PythonDictionary)pContext.GetModuleState(_keyFields);
  94. PythonExceptions.BaseException msg;
  95. string text; // message text
  96. if (module == null || module == "") {
  97. module = (filename == null || filename == "") ? "<unknown>" : filename;
  98. if (module.EndsWith(".py")) {
  99. module = module.Substring(0, module.Length - 3);
  100. }
  101. }
  102. if (registry == null) {
  103. registry = new PythonDictionary();
  104. }
  105. if (PythonOps.IsInstance(message, PythonExceptions.Warning)) {
  106. msg = (PythonExceptions.BaseException)message;
  107. text = msg.ToString();
  108. category = DynamicHelpers.GetPythonType(msg);
  109. } else {
  110. text = message.ToString();
  111. msg = PythonExceptions.CreatePythonThrowable(category, message.ToString());
  112. }
  113. PythonTuple key = PythonTuple.MakeTuple(text, category, lineno);
  114. if (registry.ContainsKey(key)) {
  115. return;
  116. }
  117. string action = Converter.ConvertToString(fields[_keyDefaultAction]);
  118. PythonTuple last_filter = null;
  119. bool loop_break = false;
  120. foreach (PythonTuple filter in (List)fields[_keyFilters]) {
  121. last_filter = filter;
  122. action = (string)filter._data[0];
  123. PythonRegex.RE_Pattern fMsg = (PythonRegex.RE_Pattern)filter._data[1];
  124. PythonType fCat = (PythonType)filter._data[2];
  125. PythonRegex.RE_Pattern fMod = (PythonRegex.RE_Pattern)filter._data[3];
  126. int fLno;
  127. if (filter._data[4] is int) {
  128. fLno = (int)filter._data[4];
  129. } else {
  130. fLno = (Extensible<int>)filter._data[4];
  131. }
  132. if ((fMsg == null || fMsg.match(text) != null) &&
  133. category.IsSubclassOf(fCat) &&
  134. (fMod == null || fMod.match(module) != null) &&
  135. (fLno == 0 || fLno == lineno)) {
  136. loop_break = true;
  137. break;
  138. }
  139. }
  140. if (!loop_break) {
  141. action = Converter.ConvertToString(fields[_keyDefaultAction]);
  142. }
  143. switch (action) {
  144. case "ignore":
  145. registry.Add(key, 1);
  146. return;
  147. case "error":
  148. throw msg.GetClrException();
  149. case "once":
  150. registry.Add(key, 1);
  151. PythonTuple onceKey = PythonTuple.MakeTuple(text, category);
  152. PythonDictionary once_reg = (PythonDictionary)fields[_keyOnceRegistry];
  153. if (once_reg.ContainsKey(onceKey)) {
  154. return;
  155. }
  156. once_reg.Add(key, 1);
  157. break;
  158. case "always":
  159. break;
  160. case "module":
  161. registry.Add(key, 1);
  162. PythonTuple altKey = PythonTuple.MakeTuple(text, category, 0);
  163. if (registry.ContainsKey(altKey)) {
  164. return;
  165. }
  166. registry.Add(altKey, 1);
  167. break;
  168. case "default":
  169. registry.Add(key, 1);
  170. break;
  171. default:
  172. throw PythonOps.RuntimeError("Unrecognized action ({0}) in warnings.filters:\n {1}", action, last_filter);
  173. }
  174. object warnings = pContext.GetWarningsModule();
  175. if (warnings != null) {
  176. PythonCalls.Call(
  177. context,
  178. PythonOps.GetBoundAttr(context, warnings, "showwarning"),
  179. msg, category, filename, lineno, null, null);
  180. } else {
  181. showwarning(context, msg, category, filename, lineno, null, null);
  182. }
  183. }
  184. internal static string formatwarning(object message, PythonType category, string filename, int lineno, [DefaultParameterValue(null)]string line) {
  185. StringBuilder sb = new StringBuilder();
  186. sb.AppendFormat("{0}:{1}: {2}: {3}\n", filename, lineno, category.Name, message);
  187. if (line == null && lineno > 0 && File.Exists(filename)) {
  188. StreamReader reader = new StreamReader(filename);
  189. for (int i = 0; i < lineno - 1; i++) {
  190. reader.ReadLine();
  191. }
  192. line = reader.ReadLine();
  193. }
  194. if (line != null) {
  195. sb.AppendFormat(" {0}\n", line.strip());
  196. }
  197. return sb.ToString();
  198. }
  199. internal static void showwarning(CodeContext context, object message, PythonType category, string filename, int lineno, [DefaultParameterValue(null)]object file, [DefaultParameterValue(null)]string line) {
  200. string text = formatwarning(message, category, filename, lineno, line);
  201. try {
  202. if (file == null) {
  203. PythonContext pContext = PythonContext.GetContext(context);
  204. PythonFile stderr = pContext.GetSystemStateValue("stderr") as PythonFile;
  205. if (stderr != null) {
  206. stderr.write(text);
  207. } else {
  208. // use CLR stderr if python's is unavailable
  209. Console.Error.Write(text);
  210. }
  211. } else {
  212. if (file is PythonFile) {
  213. ((PythonFile)file).write(text);
  214. } else if (file is TextWriter) {
  215. ((TextWriter)file).Write(text);
  216. } // unrecognized file type - warning is lost
  217. }
  218. } catch (IOException) {
  219. // invalid file - warning is lost
  220. }
  221. }
  222. #endregion
  223. }
  224. }