Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5130aaa
Overload operators except for bit shifts and default args.
christabella Dec 16, 2020
0d0ca87
Remove params array tests since they are unrelated to operator overlo…
christabella Dec 17, 2020
253f9c7
Fix type bug; rename variables pynargs etc.
christabella Dec 17, 2020
8cdb61c
Remove unused variables and add comments.
christabella Dec 17, 2020
c26e589
Add comments and remove unused in operatormethod.cs
christabella Dec 18, 2020
3222a54
Address review by @lostmsu; Add forward operator test.
christabella Dec 20, 2020
550ff31
Add forward operator tests (OpObj, int).
christabella Dec 21, 2020
eab8edc
Address @amos402's comment on raising branch.
christabella Dec 21, 2020
c2be3f1
Add operator overload and rename pynargs, clrnargs
christabella Dec 21, 2020
581a047
Revert variable renames
christabella Dec 22, 2020
e11327f
Update AUTHORS and CHANGELOG
christabella Dec 22, 2020
35be4bc
Revert rename to pynargs
christabella Dec 23, 2020
f19c281
Address @tminka's comments.
christabella Dec 23, 2020
d7f52d2
Remove whitespace
christabella Dec 23, 2020
5855a1b
Fix nits
christabella Dec 24, 2020
e7da0bc
Support reverse binary operations
christabella Dec 28, 2020
a376838
Use reverse instead of forward (semantics)
christabella Dec 29, 2020
6923a78
Address @tminka's comments
christabella Dec 30, 2020
4c992d8
Support unary neg and pos operators
christabella Dec 30, 2020
8cce61d
Remove isOperator from MatchesArgumentCount (simplify), add test.
christabella Jan 4, 2021
09a2047
Revert "Remove isOperator from MatchesArgumentCount (simplify)"
christabella Jan 4, 2021
41bd07f
Properly remove isOperator from MatchesArgumentCount (@tminka comment)
christabella Jan 4, 2021
10ccf1e
Update changelog.
christabella Jan 4, 2021
5682e0c
Add ones complement and modulo tests (@tminka comment)
christabella Jan 4, 2021
5f45c70
Merge branch 'master' into feat/operator-overloads
lostmsu Jan 5, 2021
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
Support unary neg and pos operators
  • Loading branch information
christabella committed Dec 30, 2020
commit 4c992d821f587dafa88a7847d9e299cb8a39d378
19 changes: 18 additions & 1 deletion src/embed_tests/TestOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ public OperableObject(int num)
Num = num;
}

public static OperableObject operator +(OperableObject a)
{
return new OperableObject(+a.Num);
}

public static OperableObject operator -(OperableObject a)
{
return new OperableObject(-a.Num);
}

public static OperableObject operator +(int a, OperableObject b)
{
return new OperableObject(a + b.Num);
Expand Down Expand Up @@ -143,8 +153,15 @@ public void OperatorOverloads()
PythonEngine.Exec($@"
from {module} import *
cls = {name}
a = cls(2)
a = cls(-2)
b = cls(10)
c = +a
assert c.Num == +a.Num

a = cls(2)
c = -a
assert c.Num == -a.Num

c = a + b
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

At this point, both of these calls will succeed (and do the same thing):

a.op_Addition(b)
a.op_Addition(a,b)

Is that desirable behavior?

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.

So the first statement would have previously failed and now succeeds. I guess this is a question for @lostmsu if we want to let something that's wrongly written, not fail

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.

a.op_Addition(a, b) must be failing for operators, defined in C#.

Copy link
Copy Markdown
Contributor

@tminka tminka Dec 30, 2020

Choose a reason for hiding this comment

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

The code I wrote is Python code. If a.op_Addition(a,b) now fails in Python.NET, then it will break existing code using Python.NET.

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.

Breaking should not be a big deal, since we are making major version bump with (hopefully) a good overhaul.
But I don't think a.op_Addition(a, b) should be working now.

assert c.Num == a.Num + b.Num

Expand Down
14 changes: 9 additions & 5 deletions src/runtime/methodbinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
if (isOperator && !isReverse) {
// The first Python arg is the right operand, while the bound instance is the left.
// We need to skip the first (left operand) CLR argument.
pi = pi.Skip(1).Take(1).ToArray();
pi = pi.Skip(1).ToArray();
}
else if (isOperator && isReverse) {
// The first Python arg is the left operand.
Expand All @@ -375,14 +375,18 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
{
if (ManagedType.GetManagedObject(inst) is CLRObject co)
{
bool isUnary = pynargs == 0;
// Postprocessing to extend margs.
var margsTemp = new object[2];
// If reverse, the passed instance is the left operand.
int passedOperandIndex= isReverse ? 0 : 1;
var margsTemp = isUnary ? new object[1] : new object[2];
// If reverse, the bound instance is the right operand.
int boundOperandIndex = isReverse ? 1 : 0;
// If reverse, the passed instance is the left operand.
int passedOperandIndex = isReverse ? 0 : 1;
margsTemp[boundOperandIndex] = co.inst;
margsTemp[passedOperandIndex] = margs[0];
if (!isUnary)
{
margsTemp[passedOperandIndex] = margs[0];
}
margs = margsTemp;
}
else { break; }
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/native/ITypeOffsets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ interface ITypeOffsets
int mp_length { get; }
int mp_subscript { get; }
int name { get; }
int nb_positive { get; }
int nb_negative { get; }
int nb_add { get; }
int nb_subtract { get; }
int nb_multiply { get; }
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/native/TypeOffset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ static partial class TypeOffset
internal static int mp_length { get; private set; }
internal static int mp_subscript { get; private set; }
internal static int name { get; private set; }
internal static int nb_positive { get; private set; }
internal static int nb_negative { get; private set; }
internal static int nb_add { get; private set; }
internal static int nb_subtract { get; private set; }
internal static int nb_multiply { get; private set; }
Expand Down
4 changes: 3 additions & 1 deletion src/runtime/operatormethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ static OperatorMethod()
["op_LeftShift"] = new SlotDefinition("__lshift__", TypeOffset.nb_lshift),
["op_RightShift"] = new SlotDefinition("__rshift__", TypeOffset.nb_rshift),
["op_Modulus"] = new SlotDefinition("__mod__", TypeOffset.nb_remainder),
["op_OneComplement"] = new SlotDefinition("__invert__", TypeOffset.nb_invert)
["op_OneComplement"] = new SlotDefinition("__invert__", TypeOffset.nb_invert),
["op_UnaryNegation"] = new SlotDefinition("__neg__", TypeOffset.nb_negative),
["op_UnaryPlus"] = new SlotDefinition("__pos__", TypeOffset.nb_positive),
};
}

Expand Down