Skip to content

Commit

Permalink
Exceptions cleanup (#1862)
Browse files Browse the repository at this point in the history
  • Loading branch information
slozier authored Jan 5, 2025
1 parent d42aa93 commit b6e8595
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Src/IronPython/Runtime/Exceptions/PythonExceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ internal static BaseException CreateBaseExceptionForRaise(CodeContext/*!*/ conte
/// <summary>
/// Given a CLR exception returns the Python exception which most closely maps to the CLR exception.
/// </summary>
public static object ToPython(System.Exception/*!*/ clrException) {
public static BaseException ToPython(System.Exception/*!*/ clrException) {
var res = clrException.GetPythonException();
if (res is null) {
// explicit extra conversions that need a special transformation
Expand Down
41 changes: 22 additions & 19 deletions Src/IronPython/Runtime/Exceptions/SystemExitException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

#nullable enable

using System;
using System.Runtime.Serialization;

using IronPython.Modules;
using IronPython.Runtime.Operations;
using IronPython.Runtime.Types;
Expand All @@ -15,15 +18,19 @@ namespace IronPython.Runtime.Exceptions {
[Serializable]
public sealed class SystemExitException : Exception {
public SystemExitException() : base() { }

public SystemExitException(string msg)
: base(msg) {
}

public SystemExitException(string message, Exception innerException)
: base(message, innerException) {
}

#if FEATURE_SERIALIZATION
private SystemExitException(SerializationInfo info, StreamingContext context) : base(info, context) { }
#endif

/// <summary>
/// Result of sys.exit(n)
/// </summary>
Expand All @@ -36,30 +43,26 @@ private SystemExitException(SerializationInfo info, StreamingContext context) :
/// int_value if the script exited using "sys.exit(int_value)"
/// 1 otherwise
/// </returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate")]
[PythonHidden]
public int GetExitCode(out object otherCode) {
public int GetExitCode(out object? otherCode) {
otherCode = null;
object pyObj = PythonExceptions.ToPython(this);
var pyObj = PythonExceptions.ToPython(this);

object args;
PythonTuple t;

if (!PythonOps.TryGetBoundAttr(pyObj, "args", out args) ||
(t = args as PythonTuple) == null ||
t.__len__() == 0) {
return 0;
} else if (Builtin.isinstance(t[0], TypeCache.Int32)) {
return Converter.ConvertToInt32(t[0]);
} else if (Builtin.isinstance(t[0], TypeCache.BigInteger)) {
var b = Converter.ConvertToBigInteger(t[0]);
if (b > int.MaxValue || b < int.MinValue) {
return -1;
if (PythonOps.TryGetBoundAttr(pyObj, "code", out object? code)) {
if (code is null) {
return 0;
} else if (Builtin.isinstance(code, TypeCache.Int32)) {
return Converter.ConvertToInt32(code);
} else if (Builtin.isinstance(code, TypeCache.BigInteger)) {
var b = Converter.ConvertToBigInteger(code);
if (b > int.MaxValue || b < int.MinValue) {
return -1;
}
return (int)b;
} else {
otherCode = code;
}
return (int)b;
}

otherCode = t[0];
return 1;
}
}
Expand Down
25 changes: 11 additions & 14 deletions Src/IronPython/Runtime/Exceptions/TraceBack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@
using System.Runtime.CompilerServices;
using System.Text;

using Microsoft.Scripting;
using Microsoft.Scripting.Runtime;

using IronPython.Runtime.Operations;

[module: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "IronPython.Runtime.Exceptions.TraceBackFrame..ctor(System.Object,System.Object,System.Object)", MessageId = "0#globals")]
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "IronPython.Runtime.Exceptions.TraceBackFrame.Globals", MessageId = "Globals")]
using Microsoft.Scripting;
using Microsoft.Scripting.Runtime;

namespace IronPython.Runtime.Exceptions {
[PythonType("traceback")]
[Serializable]
public class TraceBack {
public sealed class TraceBack {
private readonly TraceBack _next;
private readonly TraceBackFrame _frame;
private int _line;
Expand Down Expand Up @@ -79,7 +76,7 @@ internal string Extract() {
[PythonType("frame")]
[DebuggerDisplay("Code = {f_code.co_name}, Line = {f_lineno}")]
[Serializable]
public class TraceBackFrame {
public sealed class TraceBackFrame {
private readonly PythonTracebackListener _traceAdapter;
private TracebackDelegate _trace;
private object _traceObject;
Expand Down Expand Up @@ -118,11 +115,11 @@ internal TraceBackFrame(PythonTracebackListener traceAdapter, FunctionCode code,

[SpecialName, PropertyMethod]
public object Getf_trace() {
if (_traceAdapter != null) {
return _traceObject;
} else {
return null;
}
if (_traceAdapter != null) {
return _traceObject;
} else {
return null;
}
}

[SpecialName, PropertyMethod]
Expand Down Expand Up @@ -230,7 +227,7 @@ private void SetLineNumber(int newLineNum) {

Dictionary<int, bool> currentLoopIds = null;
bool inForLoopOrFinally = loopAndFinallyLocations != null && loopAndFinallyLocations.TryGetValue(_lineNo, out currentLoopIds);

int originalNewLine = newLineNum;

if (newLineNum < funcCode.Span.Start.Line) {
Expand All @@ -246,7 +243,7 @@ private void SetLineNumber(int newLineNum) {
// Check if we're jumping onto a handler
bool handlerIsFinally;
if (handlerLocations != null && handlerLocations.TryGetValue(newLineNum, out handlerIsFinally)) {
throw PythonOps.ValueError("can't jump to 'except' line");
throw PythonOps.ValueError("can't jump to 'except' line");
}

// Check if we're jumping into a for-loop
Expand Down
17 changes: 3 additions & 14 deletions Src/IronPython/Runtime/Operations/PythonOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2457,20 +2457,9 @@ public static PythonTuple GetExceptionInfo(CodeContext/*!*/ context) {
return PythonTuple.MakeTuple(null, null, null);
}

PythonContext pc = context.LanguageContext;

object pyExcep = PythonExceptions.ToPython(ex);
TraceBack? tb = CreateTraceBack(pc, ex);

object excType;
if (pyExcep is IPythonObject pyObj) {
// class is always the Python type for new-style types (this is also the common case)
excType = pyObj.PythonType;
} else {
excType = PythonOps.GetBoundAttr(context, pyExcep, "__class__");
}

return PythonTuple.MakeTuple(excType, pyExcep, tb);
var pyExcep = PythonExceptions.ToPython(ex);
TraceBack? tb = CreateTraceBack(context.LanguageContext, ex);
return PythonTuple.MakeTuple(((IPythonObject)pyExcep).PythonType, pyExcep, tb);
}

/// <summary>
Expand Down
23 changes: 9 additions & 14 deletions Src/IronPython/Runtime/PythonContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@ public override string FormatException(Exception exception) {

StringBuilder result = new StringBuilder();

object pythonEx = PythonExceptions.ToPython(exception);
var pythonEx = PythonExceptions.ToPython(exception);

if (exception.InnerException != null) {
if (exception.InnerException.GetPythonException() is PythonExceptions.BaseException pythonInnerException) {
Expand Down Expand Up @@ -1438,28 +1438,24 @@ private static string FormatCLSException(Exception e) {
return result.ToString();
}

internal static string FormatPythonException(object pythonException) {
internal static string FormatPythonException(PythonExceptions.BaseException pythonException) {
string result = "";

// dump the python exception.
if (pythonException != null) {
if (pythonException is string str) {
result += str;
} else {
result += GetPythonExceptionClassName(pythonException);
result += GetPythonExceptionClassName(pythonException);

string excepStr = PythonOps.ToString(pythonException);
string excepStr = PythonOps.ToString(pythonException);

if (!string.IsNullOrEmpty(excepStr)) {
result += ": " + excepStr;
}
if (!string.IsNullOrEmpty(excepStr)) {
result += ": " + excepStr;
}
}

return result;
}

private static string GetPythonExceptionClassName(object pythonException) {
private static string GetPythonExceptionClassName(PythonExceptions.BaseException pythonException) {
string className = string.Empty;
if (PythonOps.TryGetBoundAttr(pythonException, "__class__", out object val)) {
if (PythonOps.TryGetBoundAttr(val, "__name__", out val)) {
Expand Down Expand Up @@ -1644,9 +1640,8 @@ public override CompilerOptions GetCompilerOptions()
}

public override void GetExceptionMessage(Exception exception, out string message, out string typeName) {
object pythonEx = PythonExceptions.ToPython(exception);

message = FormatPythonException(PythonExceptions.ToPython(exception));
var pythonEx = PythonExceptions.ToPython(exception);
message = FormatPythonException(pythonEx);
typeName = GetPythonExceptionClassName(pythonEx);
}

Expand Down

0 comments on commit b6e8595

Please sign in to comment.