@@ -15,6 +15,7 @@ public class TestOperator
15
15
public void SetUp ( )
16
16
{
17
17
PythonEngine . Initialize ( ) ;
18
+ OwnIntCodec . Setup ( ) ;
18
19
}
19
20
20
21
[ OneTimeTearDown ]
@@ -23,6 +24,120 @@ public void Dispose()
23
24
PythonEngine . Shutdown ( ) ;
24
25
}
25
26
27
+ // Mock Integer class to test math ops on non-native dotnet types
28
+ public struct OwnInt
29
+ {
30
+ private int _value ;
31
+
32
+ public int Num => _value ;
33
+
34
+ public OwnInt ( )
35
+ {
36
+ _value = 0 ;
37
+ }
38
+
39
+ public OwnInt ( int value )
40
+ {
41
+ _value = value ;
42
+ }
43
+
44
+ public static OwnInt operator - ( OwnInt p1 , OwnInt p2 )
45
+ {
46
+ return new OwnInt ( p1 . _value - p2 . _value ) ;
47
+ }
48
+
49
+ public static OwnInt operator + ( OwnInt p1 , OwnInt p2 )
50
+ {
51
+ return new OwnInt ( p1 . _value + p2 . _value ) ;
52
+ }
53
+
54
+ public static OwnInt operator * ( OwnInt p1 , OwnInt p2 )
55
+ {
56
+ return new OwnInt ( p1 . _value * p2 . _value ) ;
57
+ }
58
+
59
+ public static OwnInt operator / ( OwnInt p1 , OwnInt p2 )
60
+ {
61
+ return new OwnInt ( p1 . _value / p2 . _value ) ;
62
+ }
63
+
64
+ public static OwnInt operator % ( OwnInt p1 , OwnInt p2 )
65
+ {
66
+ return new OwnInt ( p1 . _value % p2 . _value ) ;
67
+ }
68
+
69
+ public static OwnInt operator ^ ( OwnInt p1 , OwnInt p2 )
70
+ {
71
+ return new OwnInt ( p1 . _value ^ p2 . _value ) ;
72
+ }
73
+
74
+ public static bool operator < ( OwnInt p1 , OwnInt p2 )
75
+ {
76
+ return p1 . _value < p2 . _value ;
77
+ }
78
+
79
+ public static bool operator > ( OwnInt p1 , OwnInt p2 )
80
+ {
81
+ return p1 . _value > p2 . _value ;
82
+ }
83
+
84
+ public static bool operator == ( OwnInt p1 , OwnInt p2 )
85
+ {
86
+ return p1 . _value == p2 . _value ;
87
+ }
88
+
89
+ public static bool operator != ( OwnInt p1 , OwnInt p2 )
90
+ {
91
+ return p1 . _value != p2 . _value ;
92
+ }
93
+
94
+ public static OwnInt operator | ( OwnInt p1 , OwnInt p2 )
95
+ {
96
+ return new OwnInt ( p1 . _value | p2 . _value ) ;
97
+ }
98
+
99
+ public static OwnInt operator & ( OwnInt p1 , OwnInt p2 )
100
+ {
101
+ return new OwnInt ( p1 . _value & p2 . _value ) ;
102
+ }
103
+
104
+ public static bool operator <= ( OwnInt p1 , OwnInt p2 )
105
+ {
106
+ return p1 . _value <= p2 . _value ;
107
+ }
108
+
109
+ public static bool operator >= ( OwnInt p1 , OwnInt p2 )
110
+ {
111
+
9E81
return p1 . _value >= p2 . _value ;
112
+ }
113
+ }
114
+
115
+ // Codec for mock class above.
116
+ public class OwnIntCodec : IPyObjectDecoder
117
+ {
118
+ public static void Setup ( )
119
+ {
120
+ PyObjectConversions . RegisterDecoder ( new OwnIntCodec ( ) ) ;
121
+ }
122
+
123
+ public bool CanDecode ( PyType objectType , Type targetType )
124
+ {
125
+ return objectType . Name == "int" && targetType == typeof ( OwnInt ) ;
126
+ }
127
+
128
+ public bool TryDecode < T > ( PyObject pyObj , out T ? value )
129
+ {
130
+ if ( pyObj . PyType . Name != "int" || typeof ( T ) != typeof ( OwnInt ) )
131
+ {
132
+ value = default ( T ) ;
133
+ return false ;
134
+ }
135
+
136
+ value = ( T ) ( object ) new OwnInt ( pyObj . As < int > ( ) ) ;
137
+ return true ;
138
+ }
139
+ }
140
+
26
141
public class OperableObject
27
142
{
28
143
public int Num { get ; set ; }
@@ -524,6 +639,121 @@ public void ShiftOperatorOverloads()
524
639
525
640
c = a >> b.Num
526
641
assert c.Num == a.Num >> b.Num
642
+ " ) ;
643
+ }
644
+
645
+ [ Test ]
646
+ public void ReverseOperatorWithCodec ( )
647
+ {
648
+ string name = string . Format ( "{0}.{1}" ,
649
+ typeof ( OwnInt ) . DeclaringType . Name ,
650
+ typeof ( OwnInt ) . Name ) ;
651
+ string module = MethodBase . GetCurrentMethod ( ) . DeclaringType . Namespace ;
652
+
653
+ PythonEngine . Exec ( $@ "
654
+ from { module } import *
655
+ cls = { name }
656
+ a = 2
657
+ b = cls(10)
658
+
659
+ c = a + b
660
+ assert c.Num == a + b.Num
661
+
662
+ c = a - b
663
+ assert c.Num == a - b.Num
664
+
665
+ c = a * b
666
+ assert c.Num == a * b.Num
667
+
668
+ c = a / b
669
+ assert c.Num == a // b.Num
670
+
671
+ c = a % b
672
+ assert c.Num == a % b.Num
673
+
674
+ c = a & b
675
+ assert c.Num == a & b.Num
676
+
677
+ c = a | b
678
+ assert c.Num == a | b.Num
679
+
680
+ c = a ^ b
681
+ assert c.Num == a ^ b.Num
682
+
683
+ c = a == b
684
+ assert c == (a == b.Num)
685
+
686
+ c = a != b
687
+ assert c == (a != b.Num)
688
+
689
+ c = a <= b
690
+ assert c == (a <= b.Num)
691
+
692
+ c = a >= b
693
+ assert c == (a >= b.Num)
694
+
695
+ c = a < b
696
+ assert c == (a < b.Num)
697
+
698
+ c = a > b
699
+ assert c == (a > b.Num)
700
+ " ) ;
701
+ }
702
+
703
+ [ Test ]
704
+ public void ForwardOperatorWithCodec ( )
705
+ {
706
+ string name = string . Format ( "{0}.{1}" ,
707
+ typeof ( OwnInt ) . DeclaringType . Name ,
708
+ typeof ( OwnInt ) . Name ) ;
709
+ string module = MethodBase . GetCurrentMethod ( ) . DeclaringType . Namespace ;
710
+
711
+ PythonEngine . Exec ( $@ "
712
+ from { module } import *
713
+ cls = { name }
714
+ a = cls(2)
715
+ b = 10
716
+ c = a + b
717
+ assert c.Num == a.Num + b
718
+
719
+ c = a - b
720
+ assert c.Num == a.Num - b
721
+
722
+ c = a * b
723
+ assert c.Num == a.Num * b
724
+
725
+ c = a / b
726
+ assert c.Num == a.Num // b
727
+
728
+ c = a % b
729
+ assert c.Num == a.Num % b
730
+
731
+ c = a & b
732
+ assert c.Num == a.Num & b
733
+
734
+ c = a | b
735
+ assert c.Num == a.Num | b
736
+
737
+ c = a ^ b
738
+ assert c.Num == a.Num ^ b
739
+
740
+ c = a == b
741
+ assert c == (a.Num == b)
742
+
743
+ c = a != b
744
+ assert c == (a.Num != b)
745
+
746
+ c = a <= b
747
+ assert c == (a.Num <= b)
748
+
749
+ c = a >= b
750
+ assert c == (a.Num >= b)
751
+
752
+ c = a < b
753
+ assert c == (a.Num < b)
754
+
755
+ c = a > b
756
+ assert c == (a.Num > b)
527
757
" ) ;
528
758
}
529
759
}
0 commit comments