PageRenderTime 61ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Languages/IronPython/IronPython/Runtime/Exceptions/PythonExceptions.cs

http://github.com/IronLanguages/main
C# | 1342 lines | 929 code | 173 blank | 240 comment | 199 complexity | b6cca5e5f731ce27488ca926897f25d6 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full 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. #if FEATURE_CORE_DLR
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. #if !FEATURE_REMOTING
  21. using MarshalByRefObject = System.Object;
  22. #endif
  23. using System;
  24. using System.Collections.Generic;
  25. using System.ComponentModel;
  26. using System.Diagnostics;
  27. using System.Dynamic;
  28. using System.IO;
  29. using System.Reflection;
  30. using System.Runtime.CompilerServices;
  31. using System.Security;
  32. using System.Text;
  33. using System.Threading;
  34. using Microsoft.Scripting;
  35. using Microsoft.Scripting.Actions;
  36. using Microsoft.Scripting.Generation;
  37. using Microsoft.Scripting.Interpreter;
  38. using Microsoft.Scripting.Runtime;
  39. using Microsoft.Scripting.Utils;
  40. using IronPython.Runtime;
  41. using IronPython.Runtime.Operations;
  42. using IronPython.Runtime.Types;
  43. [assembly: PythonModule("exceptions", typeof(IronPython.Runtime.Exceptions.PythonExceptions))]
  44. namespace IronPython.Runtime.Exceptions {
  45. /// <summary>
  46. /// Implementation of the Python exceptions module and the IronPython/CLR exception mapping
  47. /// mechanism. The exception module is the parent module for all Python exception classes
  48. /// and therefore is built-in to IronPython.dll instead of IronPython.Modules.dll.
  49. ///
  50. /// The exception mapping mechanism is exposed as internal surface area available to only
  51. /// IronPython / IronPython.Modules.dll. The actual exceptions themselves are all public.
  52. ///
  53. /// Because the oddity of the built-in exception types all sharing the same physical layout
  54. /// (see also PythonExceptions.BaseException) some classes are defined as classes w/ their
  55. /// proper name and some classes are defined as PythonType fields. When a class is defined
  56. /// for convenience their's also an _TypeName version which is the PythonType.
  57. /// </summary>
  58. public static partial class PythonExceptions {
  59. private static object _pythonExceptionKey = typeof(BaseException);
  60. internal const string DefaultExceptionModule = "exceptions";
  61. public const string __doc__ = "Provides the most commonly used exceptions for Python programs";
  62. /// <summary>
  63. /// Base class for all Python exception objects.
  64. ///
  65. /// When users throw exceptions they typically throw an exception which is
  66. /// a subtype of this. A mapping is maintained between Python exceptions
  67. /// and .NET exceptions and a corresponding .NET exception is thrown which
  68. /// is associated with the Python exception. This class represents the
  69. /// base class for the Python exception hierarchy.
  70. ///
  71. /// Users can catch exceptions rooted in either hierarchy. The hierarchy
  72. /// determines whether the user catches the .NET exception object or the
  73. /// Python exception object.
  74. ///
  75. /// Most built-in Python exception classes are actually instances of the BaseException
  76. /// class here. This is important because in CPython the exceptions do not
  77. /// add new members and therefore their layouts are compatible for multiple
  78. /// inheritance. The exceptions to this rule are the classes which define
  79. /// their own fields within their type, therefore altering their layout:
  80. /// EnvironmentError
  81. /// SyntaxError
  82. /// IndentationError (same layout as SyntaxError)
  83. /// TabError (same layout as SyntaxError)
  84. /// SystemExit
  85. /// UnicodeDecodeError
  86. /// UnicodeEncodeError
  87. /// UnicodeTranslateError
  88. ///
  89. /// These exceptions cannot be combined in multiple inheritance, e.g.:
  90. /// class foo(EnvironmentError, IndentationError): pass
  91. ///
  92. /// fails but they can be combined with anything which is just a BaseException:
  93. /// class foo(UnicodeDecodeError, SystemError): pass
  94. ///
  95. /// Therefore the majority of the classes are just BaseException instances with a
  96. /// custom PythonType object. The specialized ones have their own .NET class
  97. /// which inherits from BaseException. User defined exceptions likewise inherit
  98. /// from this and have their own .NET class.
  99. /// </summary>
  100. [PythonType("BaseException"), DynamicBaseTypeAttribute, Serializable]
  101. public class BaseException : ICodeFormattable, IPythonObject, IDynamicMetaObjectProvider, IWeakReferenceable {
  102. private PythonType/*!*/ _type; // the actual Python type of the Exception object
  103. private object _message = String.Empty; // the message object, cached at __init__ time, not updated on args assignment
  104. private PythonTuple _args; // the tuple of args provided at creation time
  105. private PythonDictionary _dict; // the dictionary for extra values, created on demand
  106. private System.Exception _clrException; // the cached CLR exception that is thrown
  107. private object[] _slots; // slots, only used for storage of our weak reference.
  108. public static string __doc__ = "Common base class for all non-exit exceptions.";
  109. #region Public API Surface
  110. public BaseException(PythonType/*!*/ type) {
  111. ContractUtils.RequiresNotNull(type, "type");
  112. _type = type;
  113. }
  114. public static object __new__(PythonType/*!*/ cls, params object[] args\u00F8) {
  115. if (cls.UnderlyingSystemType == typeof(BaseException)) {
  116. return new BaseException(cls);
  117. }
  118. return Activator.CreateInstance(cls.UnderlyingSystemType, cls);
  119. }
  120. public static object __new__(PythonType/*!*/ cls, [ParamDictionary]IDictionary<object, object> kwArgs\u00F8, params object[] args\u00F8) {
  121. if (cls.UnderlyingSystemType == typeof(BaseException)) {
  122. return new BaseException(cls);
  123. }
  124. return Activator.CreateInstance(cls.UnderlyingSystemType, cls);
  125. }
  126. /// <summary>
  127. /// Initializes the Exception object with an unlimited number of arguments
  128. /// </summary>
  129. public virtual void __init__(params object[] args\u00F8) {
  130. _args = PythonTuple.MakeTuple(args\u00F8 ?? new object[] { null });
  131. if (_args.__len__() == 1) {
  132. _message = _args[0];
  133. }
  134. }
  135. /// <summary>
  136. /// Returns the exception 'message' if only a single argument was provided
  137. /// during creation or an empty string.
  138. /// </summary>
  139. public object message {
  140. [Python3Warning("BaseException.message has been deprecated as of Python 2.6")]
  141. get { return _message; }
  142. [Python3Warning("BaseException.message has been deprecated as of Python 2.6")]
  143. set { _message = value; }
  144. }
  145. /// <summary>
  146. /// Gets or sets the arguments used for creating the exception
  147. /// </summary>
  148. public object/*!*/ args {
  149. get {
  150. return _args ?? PythonTuple.EMPTY;
  151. }
  152. set { _args = PythonTuple.Make(value); }
  153. }
  154. /// <summary>
  155. /// Returns a tuple of (type, (arg0, ..., argN)) for implementing pickling/copying
  156. /// </summary>
  157. public virtual object/*!*/ __reduce__() {
  158. return PythonTuple.MakeTuple(DynamicHelpers.GetPythonType(this), args);
  159. }
  160. /// <summary>
  161. /// Returns a tuple of (type, (arg0, ..., argN)) for implementing pickling/copying
  162. /// </summary>
  163. public virtual object/*!*/ __reduce_ex__(int protocol) {
  164. return __reduce__();
  165. }
  166. /// <summary>
  167. /// Gets the nth member of the args property
  168. /// </summary>
  169. public object this[int index] {
  170. [Python3Warning("__getitem__ not supported for exception classes in 3.x; use args attribute")]
  171. get {
  172. return ((PythonTuple)args)[index];
  173. }
  174. }
  175. [Python3Warning("__getslice__ not supported for exception classes in 3.x; use args attribute")]
  176. public PythonTuple/*!*/ __getslice__(int start, int stop) {
  177. PythonTuple argTuple = (PythonTuple)args;
  178. Slice.FixSliceArguments(argTuple._data.Length, ref start, ref stop);
  179. return PythonTuple.MakeTuple(ArrayOps.GetSlice(argTuple._data, start, stop));
  180. }
  181. /// <summary>
  182. /// Gets or sets the dictionary which is used for storing members not declared to have space reserved
  183. /// within the exception object.
  184. /// </summary>
  185. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
  186. public PythonDictionary/*!*/ __dict__ {
  187. get {
  188. EnsureDict();
  189. return _dict;
  190. }
  191. set {
  192. if (_dict == null) {
  193. throw PythonOps.TypeError("__dict__ must be a dictionary");
  194. }
  195. _dict = value;
  196. }
  197. }
  198. /// <summary>
  199. /// Updates the exception's state (dictionary) with the new values
  200. /// </summary>
  201. public void __setstate__(PythonDictionary state) {
  202. foreach (KeyValuePair<object, object> pair in state) {
  203. __dict__[pair.Key] = pair.Value;
  204. }
  205. }
  206. /// <summary>
  207. /// Gets the CLR exception associated w/ this Python exception. Not visible
  208. /// until a .NET namespace is imported.
  209. /// </summary>
  210. public System.Exception/*!*/ clsException {
  211. [PythonHidden]
  212. get {
  213. return GetClrException();
  214. }
  215. internal set {
  216. _clrException = value;
  217. }
  218. }
  219. public override string/*!*/ ToString() {
  220. if (_args == null) return string.Empty;
  221. if (_args.__len__() == 0) return String.Empty;
  222. if (_args.__len__() == 1) {
  223. string str;
  224. Extensible<string> extStr;
  225. if ((str = _args[0] as string) != null) {
  226. return str;
  227. } else if ((extStr = _args[0] as Extensible<string>) != null) {
  228. return extStr.Value;
  229. }
  230. return PythonOps.ToString(_args[0]);
  231. }
  232. return _args.ToString();
  233. }
  234. public string __unicode__() {
  235. return ToString();
  236. }
  237. #endregion
  238. #region Member access operators
  239. /// <summary>
  240. /// Provides custom member lookup access that fallbacks to the dictionary
  241. /// </summary>
  242. [SpecialName]
  243. public object GetBoundMember(string name) {
  244. if (_dict != null) {
  245. object res;
  246. if (_dict.TryGetValue(name, out res)) {
  247. return res;
  248. }
  249. }
  250. return OperationFailed.Value;
  251. }
  252. /// <summary>
  253. /// Provides custom member assignment which stores values in the dictionary
  254. /// </summary>
  255. [SpecialName]
  256. public void SetMemberAfter(string name, object value) {
  257. EnsureDict();
  258. _dict[name] = value;
  259. }
  260. /// <summary>
  261. /// Provides custom member deletion which deletes values from the dictionary
  262. /// or allows clearing 'message'.
  263. /// </summary>
  264. [SpecialName]
  265. public bool DeleteCustomMember(string name) {
  266. if (name == "message") {
  267. _message = null;
  268. return true;
  269. }
  270. if (_dict == null) return false;
  271. return _dict.Remove(name);
  272. }
  273. private void EnsureDict() {
  274. if (_dict == null) {
  275. Interlocked.CompareExchange<PythonDictionary>(ref _dict, PythonDictionary.MakeSymbolDictionary(), null);
  276. }
  277. }
  278. #endregion
  279. #region ICodeFormattable Members
  280. /// <summary>
  281. /// Implements __repr__ which returns the type name + the args
  282. /// tuple code formatted.
  283. /// </summary>
  284. public virtual string/*!*/ __repr__(CodeContext/*!*/ context) {
  285. return _type.Name + ((ICodeFormattable)args).__repr__(context);
  286. }
  287. #endregion
  288. #region IPythonObject Members
  289. PythonDictionary IPythonObject.Dict {
  290. get { return _dict; }
  291. }
  292. PythonDictionary IPythonObject.SetDict(PythonDictionary dict) {
  293. Interlocked.CompareExchange<PythonDictionary>(ref _dict, dict, null);
  294. return _dict;
  295. }
  296. bool IPythonObject.ReplaceDict(PythonDictionary dict) {
  297. return Interlocked.CompareExchange<PythonDictionary>(ref _dict, dict, null) == null;
  298. }
  299. PythonType IPythonObject.PythonType {
  300. get { return _type; }
  301. }
  302. void IPythonObject.SetPythonType(PythonType/*!*/ newType) {
  303. if (_type.IsSystemType || newType.IsSystemType) {
  304. throw PythonOps.TypeError("__class__ assignment can only be performed on user defined types");
  305. }
  306. _type = newType;
  307. }
  308. object[] IPythonObject.GetSlots() { return _slots; }
  309. object[] IPythonObject.GetSlotsCreate() {
  310. if (_slots == null) {
  311. Interlocked.CompareExchange(ref _slots, new object[1], null);
  312. }
  313. return _slots;
  314. }
  315. #endregion
  316. #region Internal .NET Exception production
  317. /// <summary>
  318. /// Initializes the Python exception from a .NET exception
  319. /// </summary>
  320. /// <param name="exception"></param>
  321. [PythonHidden]
  322. protected internal virtual void InitializeFromClr(System.Exception/*!*/ exception) {
  323. if (exception.Message != null) {
  324. __init__(exception.Message);
  325. } else {
  326. __init__();
  327. }
  328. }
  329. /// <summary>
  330. /// Helper to get the CLR exception associated w/ this Python exception
  331. /// creating it if one has not already been created.
  332. /// </summary>
  333. internal/*!*/ System.Exception GetClrException() {
  334. if (_clrException != null) {
  335. return _clrException;
  336. }
  337. string stringMessage = _message as string;
  338. if (String.IsNullOrEmpty(stringMessage)) {
  339. stringMessage = _type.Name;
  340. }
  341. System.Exception newExcep = _type._makeException(stringMessage);
  342. newExcep.SetPythonException(this);
  343. Interlocked.CompareExchange<System.Exception>(ref _clrException, newExcep, null);
  344. return _clrException;
  345. }
  346. internal System.Exception/*!*/ InitAndGetClrException(params object[] args) {
  347. __init__(args);
  348. return GetClrException();
  349. }
  350. #endregion
  351. #region IDynamicMetaObjectProvider Members
  352. DynamicMetaObject/*!*/ IDynamicMetaObjectProvider.GetMetaObject(Expression/*!*/ parameter) {
  353. return new Binding.MetaUserObject(parameter, BindingRestrictions.Empty, null, this);
  354. }
  355. #endregion
  356. #region IWeakReferenceable Members
  357. WeakRefTracker IWeakReferenceable.GetWeakRef() {
  358. return UserTypeOps.GetWeakRefHelper(this);
  359. }
  360. bool IWeakReferenceable.SetWeakRef(WeakRefTracker value) {
  361. return UserTypeOps.SetWeakRefHelper(this, value);
  362. }
  363. void IWeakReferenceable.SetFinalizer(WeakRefTracker value) {
  364. UserTypeOps.SetFinalizerHelper(this, value);
  365. }
  366. #endregion
  367. }
  368. #region Custom Exception Code
  369. public partial class _SyntaxError : BaseException {
  370. public override string ToString() {
  371. PythonTuple t = ((PythonTuple)args) as PythonTuple;
  372. if (t != null) {
  373. switch (t.__len__()) {
  374. case 0: return PythonOps.ToString(null);
  375. case 1: return PythonOps.ToString(t[0]);
  376. case 2:
  377. string msg = t[0] as string;
  378. if (msg != null) {
  379. return msg;
  380. }
  381. goto default;
  382. default: return PythonOps.ToString(t);
  383. }
  384. }
  385. return String.Empty;
  386. }
  387. public override void __init__(params object[] args) {
  388. base.__init__(args);
  389. if (args != null && args.Length != 0) {
  390. msg = args[0];
  391. if (args.Length >= 2) {
  392. // args can be provided either as:
  393. // (msg, filename, lineno, offset, text, printFileandLineStr)
  394. // or:
  395. // (msg, (filename, lineno, offset, text, printFileandLineStr))
  396. PythonTuple locationInfo = args[1] as PythonTuple;
  397. if(locationInfo != null) {
  398. if (locationInfo.__len__() != 4) {
  399. throw PythonOps.IndexError("SyntaxError expected tuple with 4 arguments, got {0}", locationInfo.__len__());
  400. }
  401. filename = locationInfo[0];
  402. lineno = locationInfo[1];
  403. offset = locationInfo[2];
  404. text = locationInfo[3];
  405. }
  406. }
  407. }
  408. }
  409. }
  410. public partial class _EnvironmentError : BaseException {
  411. public override object __reduce__() {
  412. if (_filename != null) {
  413. return PythonTuple.MakeTuple(DynamicHelpers.GetPythonType(this), PythonTuple.MakeTuple(ArrayUtils.Append(((PythonTuple)args)._data, _filename)));
  414. }
  415. return base.__reduce__();
  416. }
  417. public override void __init__(params object[] args) {
  418. if (args != null) {
  419. switch (args.Length) {
  420. case 0:
  421. case 1: // do nothing special
  422. break;
  423. case 2: // errno + strerror
  424. _errno = args[0];
  425. _strerror = args[1];
  426. break;
  427. case 3: // errno, str error, filename
  428. _errno = args[0];
  429. _strerror = args[1];
  430. _filename = args[2];
  431. // CPython doesn't include filename in args, remove
  432. // it before calling base init.
  433. args = ArrayUtils.RemoveLast(args);
  434. break;
  435. default:
  436. // do nothing special for four or more args
  437. break;
  438. }
  439. }
  440. base.__init__(args);
  441. }
  442. public override string ToString() {
  443. if (_errno != null && _strerror != null) {
  444. if (_filename != null) {
  445. return String.Format("[Errno {0}] {1}: {2}", _errno, _strerror, _filename);
  446. } else {
  447. return String.Format("[Errno {0}] {1}", _errno, _strerror);
  448. }
  449. } else if (args is PythonTuple && ((PythonTuple)args).Count > 0) {
  450. return PythonOps.ToString(((PythonTuple)args)[0]);
  451. }
  452. return String.Empty;
  453. }
  454. private const int EACCES = 13;
  455. private const int ENOENT = 2;
  456. private const int EPIPE = 32;
  457. [PythonHidden]
  458. protected internal override void InitializeFromClr(System.Exception/*!*/ exception) {
  459. if (exception is FileNotFoundException ||
  460. exception is DirectoryNotFoundException ||
  461. exception is PathTooLongException
  462. #if FEATURE_DRIVENOTFOUNDEXCEPTION
  463. || exception is DriveNotFoundException
  464. #endif
  465. ) {
  466. __init__(ENOENT, exception.Message);
  467. return;
  468. }
  469. UnauthorizedAccessException noAccess = exception as UnauthorizedAccessException;
  470. if (noAccess != null) {
  471. __init__(EACCES, exception.Message);
  472. return;
  473. }
  474. #if !SILVERLIGHT5
  475. var ioExcep = exception as System.IO.IOException;
  476. if (ioExcep != null) {
  477. try {
  478. uint hr = (uint)GetHRForException(exception);
  479. if ((hr & 0xffff0000U) == 0x80070000U) {
  480. if ((hr & 0xffff) == _WindowsError.ERROR_BROKEN_PIPE) {
  481. __init__(EPIPE, exception.Message);
  482. } else {
  483. // win32 error code, get the real error code...
  484. __init__(hr & 0xffff, exception.Message);
  485. }
  486. return;
  487. }
  488. } catch (MethodAccessException) {
  489. } catch(SecurityException) {
  490. // not enough permissions to do this...
  491. }
  492. }
  493. #endif
  494. base.InitAndGetClrException(exception);
  495. }
  496. #if !SILVERLIGHT5
  497. [MethodImpl(MethodImplOptions.NoInlining)] // don't inline so the link demand is always evaluated here.
  498. private static int GetHRForException(System.Exception exception) {
  499. return System.Runtime.InteropServices.Marshal.GetHRForException(exception);
  500. }
  501. #endif
  502. }
  503. public partial class _UnicodeTranslateError : BaseException {
  504. public override void __init__(params object[] args) {
  505. if (args.Length != 4) {
  506. throw PythonOps.TypeError("function takes exactly 4 arguments ({0} given)", args.Length);
  507. }
  508. if (args[0] is string || args[0] is Extensible<string>) {
  509. @object = args[0];
  510. } else {
  511. throw PythonOps.TypeError("argument 4 must be unicode, not {0}", DynamicHelpers.GetPythonType(args[0]).Name);
  512. }
  513. start = args[1];
  514. end = args[2];
  515. if (args[3] is string || args[3] is Extensible<string>) {
  516. reason = args[3];
  517. } else {
  518. throw PythonOps.TypeError("argument 4 must be str, not {0}", DynamicHelpers.GetPythonType(args[3]).Name);
  519. }
  520. base.__init__(args);
  521. }
  522. }
  523. public partial class _WindowsError : _EnvironmentError {
  524. public override void __init__(params object[] args) {
  525. if (args.Length == 2 || args.Length == 3) {
  526. if (!(args[0] is int)) {
  527. throw PythonOps.TypeError("an integer is required for the 1st argument of WindowsError");
  528. }
  529. }
  530. base.__init__(args);
  531. if (args != null && (args.Length == 2 || args.Length == 3)) {
  532. winerror = args[0];
  533. }
  534. /*
  535. * errors were generated using this script run against CPython:
  536. f = file(r'C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\WinError.h', 'r')
  537. allErrors = []
  538. toError = {}
  539. for x in f:
  540. if x.startswith('#define ERROR_'):
  541. name = x[8:]
  542. endName = name.find(' ')
  543. justName = name[:endName]
  544. error = name[endName + 1:].strip()
  545. for i in xrange(len(error)):
  546. if error[i] < '0' or error[i] > '9':
  547. error = error[:i]
  548. break
  549. if not error:
  550. continue
  551. errNo = WindowsError(int(error), justName).errno
  552. if errNo == 22:
  553. continue
  554. allErrors.append( (justName, error) )
  555. l = toError.get(errNo)
  556. if l is None:
  557. toError[errNo] = l = []
  558. l.append(justName)
  559. for name, err in allErrors:
  560. print 'internal const int %s = %s;' % (name, err)
  561. for k, v in toError.iteritems():
  562. for name in v:
  563. print 'case %s:' % (name, )
  564. print ' errno = %d;' % (k, )
  565. print ' break;'
  566. */
  567. // map from win32 error code to errno
  568. object errCode = errno;
  569. if (errCode is int) {
  570. switch ((int)errCode) {
  571. case ERROR_BROKEN_PIPE:
  572. case ERROR_NO_DATA:
  573. errno = 32;
  574. break;
  575. case ERROR_FILE_NOT_FOUND:
  576. case ERROR_PATH_NOT_FOUND:
  577. case ERROR_INVALID_DRIVE:
  578. case ERROR_NO_MORE_FILES:
  579. case ERROR_BAD_NETPATH:
  580. case ERROR_BAD_NET_NAME:
  581. case ERROR_BAD_PATHNAME:
  582. case ERROR_FILENAME_EXCED_RANGE:
  583. errno = 2;
  584. break;
  585. case ERROR_BAD_ENVIRONMENT:
  586. errno = 7;
  587. break;
  588. case ERROR_BAD_FORMAT:
  589. case ERROR_INVALID_STARTING_CODESEG:
  590. case ERROR_INVALID_STACKSEG:
  591. case ERROR_INVALID_MODULETYPE:
  592. case ERROR_INVALID_EXE_SIGNATURE:
  593. case ERROR_EXE_MARKED_INVALID:
  594. case ERROR_BAD_EXE_FORMAT:
  595. case ERROR_ITERATED_DATA_EXCEEDS_64k:
  596. case ERROR_INVALID_MINALLOCSIZE:
  597. case ERROR_DYNLINK_FROM_INVALID_RING:
  598. case ERROR_IOPL_NOT_ENABLED:
  599. case ERROR_INVALID_SEGDPL:
  600. case ERROR_AUTODATASEG_EXCEEDS_64k:
  601. case ERROR_RING2SEG_MUST_BE_MOVABLE:
  602. case ERROR_RELOC_CHAIN_XEEDS_SEGLIM:
  603. case ERROR_INFLOOP_IN_RELOC_CHAIN:
  604. errno = 8;
  605. break;
  606. case ERROR_INVALID_HANDLE:
  607. case ERROR_INVALID_TARGET_HANDLE:
  608. case ERROR_DIRECT_ACCESS_HANDLE:
  609. errno = 9;
  610. break;
  611. case ERROR_WAIT_NO_CHILDREN:
  612. case ERROR_CHILD_NOT_COMPLETE:
  613. errno = 10;
  614. break;
  615. case ERROR_NO_PROC_SLOTS:
  616. case ERROR_MAX_THRDS_REACHED:
  617. case ERROR_NESTING_NOT_ALLOWED:
  618. errno = 11;
  619. break;
  620. case ERROR_ARENA_TRASHED:
  621. case ERROR_NOT_ENOUGH_MEMORY:
  622. case ERROR_INVALID_BLOCK:
  623. case ERROR_NOT_ENOUGH_QUOTA:
  624. errno = 12;
  625. break;
  626. case ERROR_ACCESS_DENIED:
  627. case ERROR_CURRENT_DIRECTORY:
  628. case ERROR_WRITE_PROTECT:
  629. case ERROR_BAD_UNIT:
  630. case ERROR_NOT_READY:
  631. case ERROR_BAD_COMMAND:
  632. case ERROR_CRC:
  633. case ERROR_BAD_LENGTH:
  634. case ERROR_SEEK:
  635. case ERROR_NOT_DOS_DISK:
  636. case ERROR_SECTOR_NOT_FOUND:
  637. case ERROR_OUT_OF_PAPER:
  638. case ERROR_WRITE_FAULT:
  639. case ERROR_READ_FAULT:
  640. case ERROR_GEN_FAILURE:
  641. case ERROR_SHARING_VIOLATION:
  642. case ERROR_LOCK_VIOLATION:
  643. case ERROR_WRONG_DISK:
  644. case ERROR_SHARING_BUFFER_EXCEEDED:
  645. case ERROR_NETWORK_ACCESS_DENIED:
  646. case ERROR_CANNOT_MAKE:
  647. case ERROR_FAIL_I24:
  648. case ERROR_DRIVE_LOCKED:
  649. case ERROR_SEEK_ON_DEVICE:
  650. case ERROR_NOT_LOCKED:
  651. case ERROR_LOCK_FAILED:
  652. errno = 13;
  653. break;
  654. case ERROR_FILE_EXISTS:
  655. case ERROR_ALREADY_EXISTS:
  656. errno = 17;
  657. break;
  658. case ERROR_NOT_SAME_DEVICE:
  659. errno = 18;
  660. break;
  661. case ERROR_DIR_NOT_EMPTY:
  662. errno = 41;
  663. break;
  664. case ERROR_TOO_MANY_OPEN_FILES:
  665. errno = 24;
  666. break;
  667. case ERROR_DISK_FULL:
  668. errno = 28;
  669. break;
  670. default:
  671. errno = 22;
  672. break;
  673. }
  674. }
  675. }
  676. internal const int ERROR_FILE_NOT_FOUND = 2;
  677. internal const int ERROR_PATH_NOT_FOUND = 3;
  678. internal const int ERROR_TOO_MANY_OPEN_FILES = 4;
  679. internal const int ERROR_ACCESS_DENIED = 5;
  680. internal const int ERROR_INVALID_HANDLE = 6;
  681. internal const int ERROR_ARENA_TRASHED = 7;
  682. internal const int ERROR_NOT_ENOUGH_MEMORY = 8;
  683. internal const int ERROR_INVALID_BLOCK = 9;
  684. internal const int ERROR_BAD_ENVIRONMENT = 10;
  685. internal const int ERROR_BAD_FORMAT = 11;
  686. internal const int ERROR_INVALID_DRIVE = 15;
  687. internal const int ERROR_CURRENT_DIRECTORY = 16;
  688. internal const int ERROR_NOT_SAME_DEVICE = 17;
  689. internal const int ERROR_NO_MORE_FILES = 18;
  690. internal const int ERROR_WRITE_PROTECT = 19;
  691. internal const int ERROR_BAD_UNIT = 20;
  692. internal const int ERROR_NOT_READY = 21;
  693. internal const int ERROR_BAD_COMMAND = 22;
  694. internal const int ERROR_CRC = 23;
  695. internal const int ERROR_BAD_LENGTH = 24;
  696. internal const int ERROR_SEEK = 25;
  697. internal const int ERROR_NOT_DOS_DISK = 26;
  698. internal const int ERROR_SECTOR_NOT_FOUND = 27;
  699. internal const int ERROR_OUT_OF_PAPER = 28;
  700. internal const int ERROR_WRITE_FAULT = 29;
  701. internal const int ERROR_READ_FAULT = 30;
  702. internal const int ERROR_GEN_FAILURE = 31;
  703. internal const int ERROR_SHARING_VIOLATION = 32;
  704. internal const int ERROR_LOCK_VIOLATION = 33;
  705. internal const int ERROR_WRONG_DISK = 34;
  706. internal const int ERROR_SHARING_BUFFER_EXCEEDED = 36;
  707. internal const int ERROR_BAD_NETPATH = 53;
  708. internal const int ERROR_NETWORK_ACCESS_DENIED = 65;
  709. internal const int ERROR_BAD_NET_NAME = 67;
  710. internal const int ERROR_FILE_EXISTS = 80;
  711. internal const int ERROR_CANNOT_MAKE = 82;
  712. internal const int ERROR_FAIL_I24 = 83;
  713. internal const int ERROR_NO_PROC_SLOTS = 89;
  714. internal const int ERROR_DRIVE_LOCKED = 108;
  715. internal const int ERROR_BROKEN_PIPE = 109;
  716. internal const int ERROR_DISK_FULL = 112;
  717. internal const int ERROR_INVALID_TARGET_HANDLE = 114;
  718. internal const int ERROR_WAIT_NO_CHILDREN = 128;
  719. internal const int ERROR_CHILD_NOT_COMPLETE = 129;
  720. internal const int ERROR_DIRECT_ACCESS_HANDLE = 130;
  721. internal const int ERROR_SEEK_ON_DEVICE = 132;
  722. internal const int ERROR_DIR_NOT_EMPTY = 145;
  723. internal const int ERROR_NOT_LOCKED = 158;
  724. internal const int ERROR_BAD_PATHNAME = 161;
  725. internal const int ERROR_MAX_THRDS_REACHED = 164;
  726. internal const int ERROR_LOCK_FAILED = 167;
  727. internal const int ERROR_ALREADY_EXISTS = 183;
  728. internal const int ERROR_INVALID_STARTING_CODESEG = 188;
  729. internal const int ERROR_INVALID_STACKSEG = 189;
  730. internal const int ERROR_INVALID_MODULETYPE = 190;
  731. internal const int ERROR_INVALID_EXE_SIGNATURE = 191;
  732. internal const int ERROR_EXE_MARKED_INVALID = 192;
  733. internal const int ERROR_BAD_EXE_FORMAT = 193;
  734. internal const int ERROR_ITERATED_DATA_EXCEEDS_64k = 194;
  735. internal const int ERROR_INVALID_MINALLOCSIZE = 195;
  736. internal const int ERROR_DYNLINK_FROM_INVALID_RING = 196;
  737. internal const int ERROR_IOPL_NOT_ENABLED = 197;
  738. internal const int ERROR_INVALID_SEGDPL = 198;
  739. internal const int ERROR_AUTODATASEG_EXCEEDS_64k = 199;
  740. internal const int ERROR_RING2SEG_MUST_BE_MOVABLE = 200;
  741. internal const int ERROR_RELOC_CHAIN_XEEDS_SEGLIM = 201;
  742. internal const int ERROR_INFLOOP_IN_RELOC_CHAIN = 202;
  743. internal const int ERROR_FILENAME_EXCED_RANGE = 206;
  744. internal const int ERROR_NESTING_NOT_ALLOWED = 215;
  745. internal const int ERROR_NO_DATA = 232; // The pipe is being closed.
  746. internal const int ERROR_NOT_ENOUGH_QUOTA = 1816;
  747. // These map to POSIX errno 22 and are added by hand as needed.
  748. internal const int ERROR_INVALID_PARAMETER = 87;
  749. internal const int ERROR_INVALID_NAME = 123;
  750. internal const int ERROR_FILE_INVALID = 1006;
  751. internal const int ERROR_MAPPED_ALIGNMENT = 1132;
  752. }
  753. public partial class _UnicodeDecodeError : BaseException {
  754. [PythonHidden]
  755. protected internal override void InitializeFromClr(System.Exception/*!*/ exception) {
  756. DecoderFallbackException ex = exception as DecoderFallbackException;
  757. if (ex != null) {
  758. StringBuilder sb = new StringBuilder();
  759. if (ex.BytesUnknown != null) {
  760. for (int i = 0; i < ex.BytesUnknown.Length; i++) {
  761. sb.Append((char)ex.BytesUnknown[i]);
  762. }
  763. }
  764. __init__("unknown", sb.ToString(), ex.Index, ex.Index + 1, "");
  765. } else {
  766. base.InitializeFromClr(exception);
  767. }
  768. }
  769. }
  770. public partial class _UnicodeEncodeError : BaseException {
  771. [PythonHidden]
  772. protected internal override void InitializeFromClr(System.Exception/*!*/ exception) {
  773. EncoderFallbackException ex = exception as EncoderFallbackException;
  774. if (ex != null) {
  775. __init__((exception.Data.Contains("encoding")) ? exception.Data["encoding"] : "unknown",
  776. new string(ex.CharUnknown, 1), ex.Index, ex.Index + 1, exception.Message);
  777. } else {
  778. base.InitializeFromClr(exception);
  779. }
  780. }
  781. }
  782. public partial class _SystemExit : BaseException {
  783. public override void __init__(params object[] args) {
  784. base.__init__(args);
  785. if (args != null && args.Length != 0) {
  786. code = message;
  787. }
  788. }
  789. }
  790. #endregion
  791. #region Exception translation
  792. internal static System.Exception CreateThrowable(PythonType type, params object[] args) {
  793. BaseException be = CreatePythonThrowable(type, args);
  794. return be.GetClrException();
  795. }
  796. internal static BaseException CreatePythonThrowable(PythonType type, params object[] args) {
  797. BaseException be;
  798. if (type.UnderlyingSystemType == typeof(BaseException)) {
  799. be = new BaseException(type);
  800. } else {
  801. be = (BaseException)Activator.CreateInstance(type.UnderlyingSystemType, type);
  802. }
  803. be.__init__(args);
  804. return be;
  805. }
  806. /// <summary>
  807. /// Creates a new throwable exception of type type where the type is an new-style exception.
  808. ///
  809. /// Used at runtime when creating the exception from a user provided type via the raise statement.
  810. /// </summary>
  811. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Throwable")]
  812. internal static System.Exception CreateThrowableForRaise(CodeContext/*!*/ context, PythonType/*!*/ type, object value) {
  813. object pyEx;
  814. if (PythonOps.IsInstance(value, type)) {
  815. pyEx = value;
  816. } else if (value is PythonTuple) {
  817. pyEx = PythonOps.CallWithArgsTuple(type, ArrayUtils.EmptyObjects, value);
  818. } else if (value != null) {
  819. pyEx = PythonCalls.Call(context, type, value);
  820. } else {
  821. pyEx = PythonCalls.Call(context, type);
  822. }
  823. if (PythonOps.IsInstance(pyEx, type)) {
  824. // overloaded __new__ can return anything, if
  825. // it's the right exception type use the normal conversion...
  826. // If it's wrong return an ObjectException which remembers the type.
  827. return ((BaseException)pyEx).GetClrException();
  828. }
  829. // user returned arbitrary object from overridden __new__, let it throw...
  830. return new ObjectException(type, pyEx);
  831. }
  832. /// <summary>
  833. /// Creates a throwable exception of type type where the type is an OldClass.
  834. ///
  835. /// Used at runtime when creating the exception form a user provided type that's an old class (via the raise statement).
  836. /// </summary>
  837. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Throwable")]
  838. internal static System.Exception CreateThrowableForRaise(CodeContext/*!*/ context, OldClass type, object value) {
  839. object pyEx;
  840. if (PythonOps.IsInstance(context, value, type)) {
  841. pyEx = value;
  842. } else if (value is PythonTuple) {
  843. pyEx = PythonOps.CallWithArgsTuple(type, ArrayUtils.EmptyObjects, value);
  844. } else {
  845. pyEx = PythonCalls.Call(context, type, value);
  846. }
  847. return new OldInstanceException((OldInstance)pyEx);
  848. }
  849. /// <summary>
  850. /// Returns the CLR exception associated with a Python exception
  851. /// creating a new exception if necessary
  852. /// </summary>
  853. internal static System.Exception ToClr(object pythonException) {
  854. PythonExceptions.BaseException pyExcep = pythonException as PythonExceptions.BaseException;
  855. if (pyExcep != null) {
  856. return pyExcep.GetClrException();
  857. }
  858. System.Exception res;
  859. OldInstance oi = pythonException as OldInstance;
  860. if(oi != null) {
  861. res = new OldInstanceException(oi);
  862. } else {
  863. // default exception message is the exception type (from Python)
  864. res = new System.Exception(PythonOps.ToString(pythonException));
  865. }
  866. res.SetPythonException(pythonException);
  867. return res;
  868. }
  869. /// <summary>
  870. /// Given a CLR exception returns the Python exception which most closely maps to the CLR exception.
  871. /// </summary>
  872. internal static object ToPython(System.Exception/*!*/ clrException) {
  873. Debug.Assert(clrException != null);
  874. // certain Python exceptions (StringException, OldInstanceException, ObjectException)
  875. // expose the underlying object they're wrapping directly.
  876. IPythonException ipe = clrException as IPythonException;
  877. if (ipe != null) {
  878. return ipe.ToPythonException();
  879. }
  880. object res = clrException.GetPythonException();
  881. if (res == null) {
  882. SyntaxErrorException syntax;
  883. // explicit extra conversions that need a special transformation
  884. if ((syntax = clrException as SyntaxErrorException) != null) {
  885. return SyntaxErrorToPython(syntax);
  886. }
  887. #if FEATURE_EXCEPTION_STATE
  888. ThreadAbortException ta;
  889. if ((ta = clrException as ThreadAbortException) != null) {
  890. // transform TA w/ our reason into a KeyboardInterrupt exception.
  891. KeyboardInterruptException reason = ta.ExceptionState as KeyboardInterruptException;
  892. if (reason != null) {
  893. ta.Data[typeof(KeyboardInterruptException)] = reason;
  894. return ToPython(reason);
  895. }
  896. // check for cleared but saved reason...
  897. reason = ta.Data[typeof(KeyboardInterruptException)] as KeyboardInterruptException;
  898. if (reason != null) {
  899. return ToPython(reason);
  900. }
  901. }
  902. #endif
  903. if (res == null) {
  904. res = ToPythonNewStyle(clrException);
  905. }
  906. clrException.SetPythonException(res);
  907. }
  908. return res;
  909. }
  910. /// <summary>
  911. /// Creates a new style Python exception from the .NET exception
  912. /// </summary>
  913. private static BaseException/*!*/ ToPythonNewStyle(System.Exception/*!*/ clrException) {
  914. BaseException pyExcep;
  915. if (clrException is InvalidCastException || clrException is ArgumentNullException) {
  916. // explicit extra conversions outside the generated hierarchy
  917. pyExcep = new BaseException(TypeError);
  918. } else if (clrException is Win32Exception) {
  919. Win32Exception win32 = (Win32Exception)clrException;
  920. #if NETSTANDARD
  921. int errorCode = win32.HResult;
  922. #else
  923. int errorCode = win32.ErrorCode;
  924. #endif
  925. pyExcep = new _WindowsError();
  926. if ((errorCode & 0x80070000) == 0x80070000) {
  927. pyExcep.__init__(errorCode & 0xffff, win32.Message);
  928. } else {
  929. pyExcep.__init__(errorCode, win32.Message);
  930. }
  931. return pyExcep;
  932. } else {
  933. // conversions from generated code (in the generated hierarchy)...
  934. pyExcep = ToPythonHelper(clrException);
  935. }
  936. pyExcep.InitializeFromClr(clrException);
  937. return pyExcep;
  938. }
  939. [Serializable]
  940. private class ExceptionDataWrapper : MarshalByRefObject {
  941. private readonly object _value;
  942. public ExceptionDataWrapper(object value) {
  943. _value = value;
  944. }
  945. public object Value {
  946. get {
  947. return _value;
  948. }
  949. }
  950. }
  951. /// <summary>
  952. /// Internal helper to associate a .NET exception and a Python exception.
  953. /// </summary>
  954. private static void SetPythonException(this Exception e, object exception) {
  955. IPythonAwareException pyAware = e as IPythonAwareException;
  956. if (pyAware != null) {
  957. pyAware.PythonException = exception;
  958. } else {
  959. e.SetData(_pythonExceptionKey, new ExceptionDataWrapper(exception));
  960. }
  961. BaseException be = exception as BaseException;
  962. if (be != null) {
  963. be.clsException = e;
  964. }
  965. }
  966. /// <summary>
  967. /// Internal helper to get the associated Python exception from a .NET exception.
  968. /// </summary>
  969. private static object GetPythonException(this Exception e) {
  970. IPythonAwareException pyAware = e as IPythonAwareException;
  971. if (pyAware != null) {
  972. return pyAware.PythonException;
  973. }
  974. var wrapper = e.GetData(_pythonExceptionKey) as ExceptionDataWrapper;
  975. if (wrapper != null) {
  976. return wrapper.Value;
  977. }
  978. return null;
  979. }
  980. internal static List<DynamicStackFrame> GetFrameList(this Exception e) {
  981. IPythonAwareException pyAware = e as IPythonAwareException;
  982. if (pyAware != null) {
  983. return pyAware.Frames;
  984. } else {
  985. return e.GetData(typeof(DynamicStackFrame)) as List<DynamicStackFrame>;
  986. }
  987. }
  988. internal static void SetFrameList(this Exception e, List<DynamicStackFrame> frames) {
  989. IPythonAwareException pyAware = e as IPythonAwareException;
  990. if (pyAware != null) {
  991. pyAware.Frames = frames;
  992. } else {
  993. e.SetData(typeof(DynamicStackFrame), frames);
  994. }
  995. }
  996. internal static void RemoveFrameList(this Exception e) {
  997. IPythonAwareException pyAware = e as IPythonAwareException;
  998. if (pyAware != null) {
  999. pyAware.Frames = null;
  1000. } else {
  1001. e.RemoveData(typeof(DynamicStackFrame));
  1002. }
  1003. }
  1004. internal static TraceBack GetTraceBack(this Exception e) {
  1005. IPythonAwareException pyAware = e as IPythonAwareException;
  1006. if (pyAware != null) {
  1007. return pyAware.TraceBack;
  1008. } else {
  1009. return e.GetData(typeof(TraceBack)) as TraceBack;
  1010. }
  1011. }
  1012. internal static void SetTraceBack(this Exception e, TraceBack traceback) {
  1013. IPythonAwareException pyAware = e as IPythonAwareException;
  1014. if (pyAware != null) {
  1015. pyAware.TraceBack = traceback;
  1016. } else {
  1017. e.SetData(typeof(TraceBack), traceback);
  1018. }
  1019. }
  1020. internal static void RemoveTraceBack(this Exception e) {
  1021. IPythonAwareException pyAware = e as IPythonAwareException;
  1022. if (pyAware != null) {
  1023. pyAware.TraceBack = null;
  1024. } else {
  1025. e.RemoveData(typeof(TraceBack));
  1026. }
  1027. }
  1028. /// <summary>
  1029. /// Converts the DLR SyntaxErrorException into a Python new-style SyntaxError instance.
  1030. /// </summary>
  1031. private static BaseException/*!*/ SyntaxErrorToPython(SyntaxErrorException/*!*/ e) {
  1032. PythonExceptions._SyntaxError se;
  1033. if (e.GetType() == typeof(IndentationException)) {
  1034. se = new _SyntaxError(IndentationError);
  1035. } else if (e.GetType() == typeof(TabException)) {
  1036. se = new _SyntaxError(TabError);
  1037. } else {
  1038. se = new _SyntaxError();
  1039. }
  1040. string sourceLine = PythonContext.GetSourceLine(e);
  1041. string fileName = e.GetSymbolDocumentName();
  1042. object column = (e.Column ==

Large files files are truncated, but you can click here to view the full file