Skip to content

Commit f42a14f

Browse files
committed
[GR-10278] [GR-10277] int and float types don't have defined real and imag getters.
PullRequest: graalpython/73
2 parents b68b8f5 + b84f656 commit f42a14f

File tree

5 files changed

+334
-3
lines changed

5 files changed

+334
-3
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_float.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,3 +575,74 @@ def fromhex(cls, value1, value2):
575575
f = F.fromhex('1', '1')
576576
self.assertEqual(17.0, f)
577577
self.assertEqual(F, type(f))
578+
579+
class MyFloat(float):
580+
pass
581+
582+
class RealImagConjugateTests(unittest.TestCase):
583+
584+
def test_real_imag(self):
585+
def builtinTest(number):
586+
a = float(number)
587+
b = a.real
588+
c = a.imag
589+
assert a == b
590+
assert a is b
591+
assert c == 0
592+
assert type(a) == float
593+
assert type(b) == float
594+
assert type(c) == float
595+
596+
builtinTest(-9.1)
597+
builtinTest(0.0)
598+
builtinTest(9.2)
599+
builtinTest(6227020800.90)
600+
builtinTest(9999992432902008176640000999999.1)
601+
602+
def test_real_imag_subclass(self):
603+
def subclassTest(number):
604+
a = MyFloat(number)
605+
b = a.real
606+
c = a.imag
607+
assert a == b
608+
assert a is not b
609+
assert c == 0.0
610+
assert type(a) == MyFloat
611+
assert type(b) == float
612+
assert type(c) == float
613+
614+
subclassTest(-9.0)
615+
subclassTest(0.0)
616+
subclassTest(9.1)
617+
subclassTest(6227020800.2)
618+
subclassTest(9999992432902008176640000999999.33)
619+
620+
def test_conjugate(self):
621+
def builtinTest(number):
622+
a = float(number)
623+
b = a.conjugate()
624+
assert a == b
625+
assert a is b
626+
assert type(a) == float
627+
assert type(b) == float
628+
629+
builtinTest(-9.1)
630+
builtinTest(0.0)
631+
builtinTest(9.2)
632+
builtinTest(6227020800.90)
633+
builtinTest(9999992432902008176640000999999.1)
634+
635+
def test_conjugate_subclass(self):
636+
def subclassTest(number):
637+
a = MyFloat(number)
638+
b = a.conjugate()
639+
assert a == b
640+
assert a is not b
641+
assert type(a) == MyFloat
642+
assert type(b) == float
643+
644+
subclassTest(-9.0)
645+
subclassTest(0.0)
646+
subclassTest(9.1)
647+
subclassTest(6227020800.2)
648+
subclassTest(9999992432902008176640000999999.33)

graalpython/com.oracle.graal.python.test/src/tests/test_int.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,155 @@ def test_int_bit_length():
9797
assert (int(-2432902008176640000)).bit_length() == 62
9898
assert (int(9999992432902008176640000999999)).bit_length() == 103
9999
assert (int(-9999992432902008176640000999999)).bit_length() == 103
100+
101+
class MyInt(int):
102+
pass
103+
104+
def test_int():
105+
def builtinTest(number):
106+
a = int(number)
107+
b = a.__int__()
108+
assert a == b
109+
assert a is b
110+
assert type(a) == int
111+
assert type(b) == int
112+
113+
builtinTest(-9)
114+
builtinTest(0)
115+
builtinTest(9)
116+
builtinTest(6227020800)
117+
builtinTest(9999992432902008176640000999999)
118+
119+
assert True.__int__() == 1
120+
assert False.__int__() == 0
121+
122+
123+
def test_int_subclass():
124+
def subclassTest(number):
125+
a = MyInt(number)
126+
b = a.__int__()
127+
assert a == b
128+
assert a is not b
129+
assert type(a) == MyInt
130+
assert type(b) == int
131+
132+
subclassTest(-9)
133+
subclassTest(0)
134+
subclassTest(9)
135+
subclassTest(6227020800)
136+
subclassTest(9999992432902008176640000999999)
137+
138+
def test_real_imag():
139+
def builtinTest(number):
140+
a = int(number)
141+
b = a.real
142+
c = a.imag
143+
assert a == b
144+
assert a is b
145+
assert c == 0
146+
assert type(a) == int
147+
assert type(b) == int
148+
assert type(c) == int
149+
150+
builtinTest(-9)
151+
builtinTest(0)
152+
builtinTest(9)
153+
builtinTest(6227020800)
154+
builtinTest(9999992432902008176640000999999)
155+
156+
assert True.real == 1
157+
assert False.real == 0
158+
assert True.imag == 0
159+
assert False.imag == 0
160+
161+
def test_real_imag_subclass():
162+
def subclassTest(number):
163+
a = MyInt(number)
164+
b = a.real
165+
c = a.imag
166+
assert a == b
167+
assert a is not b
168+
assert c == 0
169+
assert type(a) == MyInt
170+
assert type(b) == int
171+
assert type(c) == int
172+
173+
subclassTest(-9)
174+
subclassTest(0)
175+
subclassTest(9)
176+
subclassTest(6227020800)
177+
subclassTest(9999992432902008176640000999999)
178+
179+
def test_numerator_denominator():
180+
def builtinTest(number):
181+
a = int(number)
182+
b = a.numerator
183+
c = a.denominator
184+
assert a == b
185+
assert a is b
186+
assert c == 1
187+
assert type(a) == int
188+
assert type(b) == int
189+
assert type(c) == int
190+
191+
builtinTest(-9)
192+
builtinTest(0)
193+
builtinTest(9)
194+
builtinTest(6227020800)
195+
builtinTest(9999992432902008176640000999999)
196+
197+
assert True.numerator == 1
198+
assert False.numerator == 0
199+
assert True.denominator == 1
200+
assert False.denominator == 1
201+
202+
def test_mumerator_denominator_subclass():
203+
def subclassTest(number):
204+
a = MyInt(number)
205+
b = a.numerator
206+
c = a.denominator
207+
assert a == b
208+
assert a is not b
209+
assert c == 1
210+
assert type(a) == MyInt
211+
assert type(b) == int
212+
assert type(c) == int
213+
214+
subclassTest(-9)
215+
subclassTest(0)
216+
subclassTest(9)
217+
subclassTest(6227020800)
218+
subclassTest(9999992432902008176640000999999)
219+
220+
def test_conjugate():
221+
def builtinTest(number):
222+
a = int(number)
223+
b = a.conjugate()
224+
assert a == b
225+
assert a is b
226+
assert type(a) == int
227+
assert type(b) == int
228+
229+
builtinTest(-9)
230+
builtinTest(0)
231+
builtinTest(9)
232+
builtinTest(6227020800)
233+
builtinTest(9999992432902008176640000999999)
234+
235+
assert True.conjugate() == 1
236+
assert False.conjugate() == 0
237+
238+
def test_conjugate_subclass():
239+
def subclassTest(number):
240+
a = MyInt(number)
241+
b = a.conjugate()
242+
assert a == b
243+
assert a is not b
244+
assert type(a) == MyInt
245+
assert type(b) == int
246+
247+
subclassTest(-9)
248+
subclassTest(0)
249+
subclassTest(9)
250+
subclassTest(6227020800)
251+
subclassTest(9999992432902008176640000999999)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ public Object createInt(PythonClass cls, PythonObject obj, PNone keywordArg,
710710
return createInt(cls, (long) result, keywordArg, isIntProfile);
711711
} else if (result instanceof PInt) {
712712
// TODO warn if 'result' not of exact Python type 'int'
713-
return result;
713+
return isPrimitiveInt(cls) ? result : factory().createInt(cls, ((PInt) result).getValue());
714714
} else {
715715
throw raise(TypeError, "__int__ returned non-int (type %p)", result);
716716
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@
7171
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
7272
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
7373
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
74+
import com.oracle.graal.python.nodes.object.GetClassNode;
7475
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
7576
import com.oracle.graal.python.runtime.JavaTypeConversions;
7677
import com.oracle.graal.python.runtime.exception.PythonErrorType;
78+
import com.oracle.truffle.api.CompilerDirectives;
7779
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
7880
import com.oracle.truffle.api.dsl.Cached;
7981
import com.oracle.truffle.api.dsl.Fallback;
@@ -875,6 +877,53 @@ abstract static class NegNode extends PythonUnaryBuiltinNode {
875877
}
876878
}
877879

880+
@GenerateNodeFactory
881+
@Builtin(name = "real", fixedNumOfArguments = 1, isGetter = true, doc = "the real part of a complex number")
882+
static abstract class RealNode extends PythonBuiltinNode {
883+
884+
@Child private GetClassNode getClassNode;
885+
886+
protected PythonClass getClass(Object value) {
887+
if (getClassNode == null) {
888+
CompilerDirectives.transferToInterpreterAndInvalidate();
889+
getClassNode = insert(GetClassNode.create());
890+
}
891+
return getClassNode.execute(value);
892+
}
893+
894+
@Specialization
895+
double get(double self) {
896+
return self;
897+
}
898+
899+
@Specialization(guards = "cannotBeOverridden(getClass(self))")
900+
PFloat getPFloat(PFloat self) {
901+
return self;
902+
}
903+
904+
@Specialization(guards = "!cannotBeOverridden(getClass(self))")
905+
PFloat getPFloatOverriden(PFloat self) {
906+
return factory().createFloat(self.getValue());
907+
}
908+
}
909+
910+
@GenerateNodeFactory
911+
@Builtin(name = "imag", fixedNumOfArguments = 1, isGetter = true, doc = "the imaginary part of a complex number")
912+
static abstract class ImagNode extends PythonBuiltinNode {
913+
914+
@Specialization
915+
double get(@SuppressWarnings("unused") Object self) {
916+
return 0;
917+
}
918+
919+
}
920+
921+
@GenerateNodeFactory
922+
@Builtin(name = "conjugate", fixedNumOfArguments = 1, doc = "Returns self, the complex conjugate of any float.")
923+
static abstract class ConjugateNode extends RealNode {
924+
925+
}
926+
878927
@Builtin(name = __GETFORMAT__, fixedNumOfArguments = 2)
879928
@GenerateNodeFactory
880929
abstract static class GetFormatNode extends PythonUnaryBuiltinNode {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,16 @@
4747
import com.oracle.graal.python.builtins.objects.PNone;
4848
import com.oracle.graal.python.builtins.objects.PNotImplemented;
4949
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
50+
import com.oracle.graal.python.builtins.objects.type.PythonClass;
5051
import com.oracle.graal.python.nodes.SpecialMethodNames;
5152
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
5253
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5354
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
55+
import com.oracle.graal.python.nodes.object.GetClassNode;
5456
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
5557
import com.oracle.graal.python.runtime.ArithmeticUtil;
5658
import com.oracle.graal.python.runtime.exception.PythonErrorType;
59+
import com.oracle.truffle.api.CompilerDirectives;
5760
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5861
import com.oracle.truffle.api.dsl.Fallback;
5962
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -1849,9 +1852,60 @@ int bitLength(PInt argument) {
18491852
}
18501853
}
18511854

1855+
@GenerateNodeFactory
1856+
@Builtin(name = "real", fixedNumOfArguments = 1, isGetter = true, doc = "the real part of a complex number")
1857+
static abstract class RealNode extends IntNode {
1858+
1859+
}
1860+
1861+
@GenerateNodeFactory
1862+
@Builtin(name = "imag", fixedNumOfArguments = 1, isGetter = true, doc = "the imaginary part of a complex number")
1863+
static abstract class ImagNode extends PythonBuiltinNode {
1864+
@Specialization
1865+
int get(@SuppressWarnings("unused") Object self) {
1866+
return 0;
1867+
}
1868+
}
1869+
1870+
@GenerateNodeFactory
1871+
@Builtin(name = "numerator", fixedNumOfArguments = 1, isGetter = true, doc = "the numerator of a rational number in lowest terms")
1872+
static abstract class NumeratorNode extends IntNode {
1873+
1874+
}
1875+
1876+
@GenerateNodeFactory
1877+
@Builtin(name = "conjugate", fixedNumOfArguments = 1, doc = "Returns self, the complex conjugate of any int.")
1878+
static abstract class ConjugateNode extends IntNode {
1879+
1880+
}
1881+
1882+
@GenerateNodeFactory
1883+
@Builtin(name = "denominator", fixedNumOfArguments = 1, isGetter = true, doc = "the denominator of a rational number in lowest terms")
1884+
static abstract class DenominatorNode extends PythonBuiltinNode {
1885+
@Specialization
1886+
int get(@SuppressWarnings("unused") Object self) {
1887+
return 1;
1888+
}
1889+
}
1890+
18521891
@Builtin(name = SpecialMethodNames.__INT__, fixedNumOfArguments = 1)
18531892
@GenerateNodeFactory
18541893
abstract static class IntNode extends PythonBuiltinNode {
1894+
@Child private GetClassNode getClassNode;
1895+
1896+
protected PythonClass getClass(Object value) {
1897+
if (getClassNode == null) {
1898+
CompilerDirectives.transferToInterpreterAndInvalidate();
1899+
getClassNode = insert(GetClassNode.create());
1900+
}
1901+
return getClassNode.execute(value);
1902+
}
1903+
1904+
@Specialization
1905+
int doB(boolean self) {
1906+
return self ? 1 : 0;
1907+
}
1908+
18551909
@Specialization
18561910
int doI(int self) {
18571911
return self;
@@ -1862,8 +1916,13 @@ long doL(long self) {
18621916
return self;
18631917
}
18641918

1865-
@Specialization
1866-
PInt doPi(PInt self) {
1919+
@Specialization(guards = "cannotBeOverridden(getClass(self))")
1920+
PInt doPInt(PInt self) {
1921+
return self;
1922+
}
1923+
1924+
@Specialization(guards = "!cannotBeOverridden(getClass(self))")
1925+
PInt doPIntOverriden(PInt self) {
18671926
return factory().createInt(self.getValue());
18681927
}
18691928
}

0 commit comments

Comments
 (0)