PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/DLR_Main/Languages/IronPython/IronPython.Modules/_warnings.cs

https://bitbucket.org/mdavid/dlr
C# | 262 lines | 221 code | 24 blank | 17 comment | 72 complexity | e77d4d6388187b2dd124595eefd2ec61 MD5 | raw file
  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.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. List defaultFilters = new List();
  39. if (context.PythonOptions.WarnPython30) {
  40. defaultFilters.AddNoLock(PythonTuple.MakeTuple("ignore", null, PythonExceptions.DeprecationWarning, null, 0));
  41. }
  42. defaultFilters.AddNoLock(PythonTuple.MakeTuple("ignore", null, PythonExceptions.PendingDeprecationWarning, null, 0));
  43. defaultFilters.AddNoLock(PythonTuple.MakeTuple("ignore", null, PythonExceptions.ImportWarning, null, 0));
  44. defaultFilters.AddNoLock(PythonTuple.MakeTuple("ignore", null, PythonExceptions.BytesWarning, null, 0));
  45. context.GetOrCreateModuleState(_keyFields, () => {
  46. dict.Add(_keyDefaultAction, "default");
  47. dict.Add(_keyOnceRegistry, new PythonDictionary());
  48. dict.Add(_keyFilters, defaultFilters);
  49. return dict;
  50. });
  51. }
  52. #region Public API
  53. public static void warn(CodeContext context, object message, [DefaultParameterValue(null)]PythonType category, [DefaultParameterValue(1)]int stacklevel) {
  54. PythonContext pContext = PythonContext.GetContext(context);
  55. List argv = pContext.GetSystemStateValue("argv") as List;
  56. PythonDictionary dict = pContext.GetSystemStateValue("__dict__") as PythonDictionary;
  57. if (PythonOps.IsInstance(message, PythonExceptions.Warning)) {
  58. category = DynamicHelpers.GetPythonType(message);
  59. }
  60. if (category == null) {
  61. category = PythonExceptions.UserWarning;
  62. }
  63. if (!category.IsSubclassOf(PythonExceptions.Warning)) {
  64. throw PythonOps.ValueError("category is not a subclass of Warning");
  65. }
  66. TraceBackFrame caller = null;
  67. PythonDictionary globals;
  68. int lineno;
  69. if (PythonContext.GetContext(context).PythonOptions.Frames) {
  70. try {
  71. caller = SysModule._getframeImpl(context, stacklevel);
  72. } catch (ValueErrorException) { }
  73. }
  74. if (caller == null) {
  75. globals = Builtin.globals(context) as PythonDictionary;
  76. lineno = 1;
  77. } else {
  78. globals = caller.f_globals;
  79. lineno = (int)caller.f_lineno;
  80. }
  81. string module;
  82. string filename;
  83. if (globals != null && globals.ContainsKey("__name__")) {
  84. module = (string)globals.get("__name__");
  85. } else {
  86. module = "<string>";
  87. }
  88. filename = globals.get("__file__") as string;
  89. if (filename == null || filename == "") {
  90. if (module == "__main__") {
  91. if (argv != null && argv.Count > 0) {
  92. filename = argv[0] as string;
  93. } else {
  94. // interpreter lacks sys.argv
  95. filename = "__main__";
  96. }
  97. }
  98. if (filename == null || filename == "") {
  99. filename = module;
  100. }
  101. }
  102. PythonDictionary registry = (PythonDictionary)globals.setdefault("__warningregistry__", new PythonDictionary());
  103. warn_explicit(context, message, category, filename, lineno, module, registry, globals);
  104. }
  105. 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) {
  106. PythonContext pContext = PythonContext.GetContext(context);
  107. PythonDictionary fields = (PythonDictionary)pContext.GetModuleState(_keyFields);
  108. PythonExceptions.BaseException msg;
  109. string text; // message text
  110. if (string.IsNullOrEmpty(module)) {
  111. module = (filename == null || filename == "") ? "<unknown>" : filename;
  112. if (module.EndsWith(".py")) {
  113. module = module.Substring(0, module.Length - 3);
  114. }
  115. }
  116. if (registry == null) {
  117. registry = new PythonDictionary();
  118. }
  119. if (PythonOps.IsInstance(message, PythonExceptions.Warning)) {
  120. msg = (PythonExceptions.BaseException)message;
  121. text = msg.ToString();
  122. category = DynamicHelpers.GetPythonType(msg);
  123. } else {
  124. text = message.ToString();
  125. msg = PythonExceptions.CreatePythonThrowable(category, message.ToString());
  126. }
  127. PythonTuple key = PythonTuple.MakeTuple(text, category, lineno);
  128. if (registry.ContainsKey(key)) {
  129. return;
  130. }
  131. string action = Converter.ConvertToString(fields[_keyDefaultAction]);
  132. PythonTuple last_filter = null;
  133. bool loop_break = false;
  134. foreach (PythonTuple filter in (List)fields[_keyFilters]) {
  135. last_filter = filter;
  136. action = (string)filter._data[0];
  137. PythonRegex.RE_Pattern fMsg = (PythonRegex.RE_Pattern)filter._data[1];
  138. PythonType fCat = (PythonType)filter._data[2];
  139. PythonRegex.RE_Pattern fMod = (PythonRegex.RE_Pattern)filter._data[3];
  140. int fLno;
  141. if (filter._data[4] is int) {
  142. fLno = (int)filter._data[4];
  143. } else {
  144. fLno = (Extensible<int>)filter._data[4];
  145. }
  146. if ((fMsg == null || fMsg.match(text) != null) &&
  147. category.IsSubclassOf(fCat) &&
  148. (fMod == null || fMod.match(module) != null) &&
  149. (fLno == 0 || fLno == lineno)) {
  150. loop_break = true;
  151. break;
  152. }
  153. }
  154. if (!loop_break) {
  155. action = Converter.ConvertToString(fields[_keyDefaultAction]);
  156. }
  157. switch (action) {
  158. case "ignore":
  159. registry.Add(key, 1);
  160. return;
  161. case "error":
  162. throw msg.GetClrException();
  163. case "once":
  164. registry.Add(key, 1);
  165. PythonTuple onceKey = PythonTuple.MakeTuple(text, category);
  166. PythonDictionary once_reg = (PythonDictionary)fields[_keyOnceRegistry];
  167. if (once_reg.ContainsKey(onceKey)) {
  168. return;
  169. }
  170. once_reg.Add(key, 1);
  171. break;
  172. case "always":
  173. break;
  174. case "module":
  175. registry.Add(key, 1);
  176. PythonTuple altKey = PythonTuple.MakeTuple(text, category, 0);
  177. if (registry.ContainsKey(altKey)) {
  178. return;
  179. }
  180. registry.Add(altKey, 1);
  181. break;
  182. case "default":
  183. registry.Add(key, 1);
  184. break;
  185. default:
  186. throw PythonOps.RuntimeError("Unrecognized action ({0}) in warnings.filters:\n {1}", action, last_filter);
  187. }
  188. object warnings = pContext.GetWarningsModule();
  189. if (warnings != null) {
  190. PythonCalls.Call(
  191. context,
  192. PythonOps.GetBoundAttr(context, warnings, "showwarning"),
  193. msg, category, filename, lineno, null, null);
  194. } else {
  195. showwarning(context, msg, category, filename, lineno, null, null);
  196. }
  197. }
  198. internal static string formatwarning(object message, PythonType category, string filename, int lineno, [DefaultParameterValue(null)]string line) {
  199. StringBuilder sb = new StringBuilder();
  200. sb.AppendFormat("{0}:{1}: {2}: {3}\n", filename, lineno, category.Name, message);
  201. if (line == null && lineno > 0 && File.Exists(filename)) {
  202. StreamReader reader = new StreamReader(filename);
  203. for (int i = 0; i < lineno - 1; i++) {
  204. reader.ReadLine();
  205. }
  206. line = reader.ReadLine();
  207. }
  208. if (line != null) {
  209. sb.AppendFormat(" {0}\n", line.strip());
  210. }
  211. return sb.ToString();
  212. }
  213. internal static void showwarning(CodeContext context, object message, PythonType category, string filename, int lineno, [DefaultParameterValue(null)]object file, [DefaultParameterValue(null)]string line) {
  214. string text = formatwarning(message, category, filename, lineno, line);
  215. try {
  216. if (file == null) {
  217. PythonContext pContext = PythonContext.GetContext(context);
  218. PythonFile stderr = pContext.GetSystemStateValue("stderr") as PythonFile;
  219. if (stderr != null) {
  220. stderr.write(text);
  221. } else {
  222. // use CLR stderr if python's is unavailable
  223. Console.Error.Write(text);
  224. }
  225. } else {
  226. if (file is PythonFile) {
  227. ((PythonFile)file).write(text);
  228. } else if (file is TextWriter) {
  229. ((TextWriter)file).Write(text);
  230. } // unrecognized file type - warning is lost
  231. }
  232. } catch (IOException) {
  233. // invalid file - warning is lost
  234. }
  235. }
  236. #endregion
  237. }
  238. }