Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Style (TryGetValue), formatting, and minor changes
  • Loading branch information
christabella committed Jan 12, 2021
commit 6a64678207ba251568d6f566975fa400872d29a9
2 changes: 1 addition & 1 deletion src/embed_tests/TestOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class OperableObject

public override int GetHashCode()
{
return 159832395 + Num.GetHashCode();
return unchecked(159832395 + Num.GetHashCode());
}

public override bool Equals(object obj)
Expand Down
63 changes: 30 additions & 33 deletions src/runtime/classbase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class ClassBase : ManagedType
[NonSerialized]
internal List<string> dotNetMembers;
internal Indexer indexer;
internal Hashtable richcompare;
internal Dictionary<int, MethodObject> richcompare;
internal MaybeType type;

internal ClassBase(Type tp)
Expand All @@ -36,14 +36,14 @@ internal virtual bool CanSubclass()
return !type.Value.IsEnum;
}

public readonly static Dictionary<int, string> PyToCilOpMap = new Dictionary<int, string>
public readonly static Dictionary<string, int> CilToPyOpMap = new Dictionary<string, int>
{
[Runtime.Py_EQ] = "op_Equality",
[Runtime.Py_NE] = "op_Inequality",
[Runtime.Py_LE] = "op_LessThanOrEqual",
[Runtime.Py_GE] = "op_GreaterThanOrEqual",
[Runtime.Py_LT] = "op_LessThan",
[Runtime.Py_GT] = "op_GreaterThan",
["op_Equality"] = Runtime.Py_EQ,
["op_Inequality"] = Runtime.Py_NE,
["op_LessThanOrEqual"] = Runtime.Py_LE,
["op_GreaterThanOrEqual"] = Runtime.Py_GE,
["op_LessThan"] = Runtime.Py_LT,
["op_GreaterThan"] = Runtime.Py_GT,
};

/// <summary>
Expand Down Expand Up @@ -87,35 +87,32 @@ public static IntPtr tp_richcompare(IntPtr ob, IntPtr other, int op)
// C# operator methods take precedence over IComparable.
// We first check if there's a comparison operator by looking up the richcompare table,
// otherwise fallback to checking if an IComparable interface is handled.
if (PyToCilOpMap.ContainsKey(op)) {
string CilOp = PyToCilOpMap[op];
if (cls.richcompare.Contains(CilOp)) {
var methodObject = (MethodObject)cls.richcompare[CilOp];
IntPtr args = other;
var free = false;
if (!Runtime.PyTuple_Check(other))
{
// Wrap the `other` argument of a binary comparison operator in a PyTuple.
args = Runtime.PyTuple_New(1);
Runtime.XIncref(other);
Runtime.PyTuple_SetItem(args, 0, other);
free = true;
}
if (cls.richcompare.TryGetValue(op, out var methodObject))
{
IntPtr args = other;
var free = false;
if (true)
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, remove unnecessary if and free boolean (always true)

// Wrap the `other` argument of a binary comparison operator in a PyTuple.
args = Runtime.PyTuple_New(1);
Runtime.XIncref(other);
Runtime.PyTuple_SetItem(args, 0, other);
free = true;
}

IntPtr value;
try
{
value = methodObject.Invoke(ob, args, IntPtr.Zero);
}
finally
IntPtr value;
try
{
value = methodObject.Invoke(ob, args, IntPtr.Zero);
}
finally
{
if (free)
{
if (free)
{
Runtime.XDecref(args); // Free args pytuple
}
Runtime.XDecref(args); // Free args pytuple
}
return value;
}
return value;
}

switch (op)
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/classmanager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ private static void InitClassBase(Type type, ClassBase impl)
ClassInfo info = GetClassInfo(type);

impl.indexer = info.indexer;
impl.richcompare = new Hashtable();
impl.richcompare = new Dictionary<int, MethodObject>();

// Now we allocate the Python type object to reflect the given
// managed type, filling the Python type slots with thunks that
Expand All @@ -285,8 +285,8 @@ private static void InitClassBase(Type type, ClassBase impl)
Runtime.PyDict_SetItemString(dict, name, item.pyHandle);
// Decref the item now that it's been used.
item.DecrRefCount();
if (ClassBase.PyToCilOpMap.ContainsValue(name)) {
impl.richcompare.Add(name, iter.Value);
if (ClassBase.CilToPyOpMap.TryGetValue(name, out var pyOp)) {
impl.richcompare.Add(pyOp, (MethodObject)item);
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/runtime/operatormethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ public static void FixupSlots(IntPtr pyType, Type clrType)
Debug.Assert(_opType != null);
foreach (var method in clrType.GetMethods(flags))
{
if (!IsOperatorMethod(method) || IsComparisonOp(method)) // We don't want to override ClassBase.tp_richcompare.
// We don't want to override slots for either non-operators or
// comparison operators, which are handled by ClassBase.tp_richcompare.
if (!IsOperatorMethod(method) || IsComparisonOp(method))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: !OpMethodMap .ContainsKey(method)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, thanks!

{
continue;
}
Expand Down