Skip to content

Commit 3ec9cf9

Browse files
committed
Merge pull request #1064 from Daetalus/numpy_fixing_2
Some minor fixing which found in numpy tests
2 parents bf7972d + 7819995 commit 3ec9cf9

File tree

5 files changed

+84
-60
lines changed

5 files changed

+84
-60
lines changed

src/runtime/float.cpp

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -838,59 +838,15 @@ Box* floatNonzero(BoxedFloat* self) {
838838
return boxBool(floatNonzeroUnboxed(self));
839839
}
840840

841-
template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == CAPI) {
842-
if (a->cls == float_cls) {
843-
return static_cast<BoxedFloat*>(a);
844-
} else if (PyInt_Check(a)) {
845-
return new BoxedFloat(static_cast<BoxedInt*>(a)->n);
846-
847-
} else if (PyLong_Check(a)) {
848-
double a_f = PyLong_AsDouble(a);
849-
if (a_f == -1.0 && PyErr_Occurred()) {
850-
if (S == CAPI)
851-
return NULL;
852-
else
853-
throwCAPIException();
854-
}
855-
856-
// Make sure that we're not in an error state when we return a non-NULL value.
857-
assert(!PyErr_Occurred());
858-
return new BoxedFloat(a_f);
859-
} else if (a->cls == str_cls || a->cls == unicode_cls) {
860-
BoxedFloat* res = (BoxedFloat*)PyFloat_FromString(a, NULL);
861-
862-
if (!res) {
863-
if (S == CAPI)
864-
return NULL;
865-
else
866-
throwCAPIException();
867-
}
868-
869-
return res;
870-
} else {
871-
static BoxedString* float_str = internStringImmortal("__float__");
872-
Box* r = callattrInternal<S, NOT_REWRITABLE>(a, float_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL,
873-
NULL, NULL);
874-
875-
if (!r) {
876-
if (S == CAPI) {
877-
if (!PyErr_Occurred())
878-
PyErr_SetString(PyExc_TypeError, "float() argument must be a string or a number");
879-
return NULL;
880-
} else {
881-
raiseExcHelper(TypeError, "float() argument must be a string or a number");
882-
}
883-
}
884-
885-
if (!PyFloat_Check(r)) {
886-
if (S == CAPI) {
887-
PyErr_Format(TypeError, "__float__ returned non-float (type %s)", r->cls->tp_name);
888-
return NULL;
889-
} else
890-
raiseExcHelper(TypeError, "__float__ returned non-float (type %s)", r->cls->tp_name);
891-
}
892-
return static_cast<BoxedFloat*>(r);
893-
}
841+
template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* x) noexcept(S == CAPI) {
842+
Box* rtn;
843+
if (PyString_CheckExact(x))
844+
rtn = PyFloat_FromString(x, NULL);
845+
else
846+
rtn = PyNumber_Float(x);
847+
if (!rtn && S == CXX)
848+
throwCAPIException();
849+
return static_cast<BoxedFloat*>(rtn);
894850
}
895851

896852
template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S == CAPI) {

src/runtime/int.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs) {
430430
if (PyInt_Check(rhs)) {
431431
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
432432
return add_i64_i64(lhs->n, rhs_int->n);
433-
} else if (PyFloat_Check(rhs)) {
433+
} else if (PyFloat_CheckExact(rhs)) {
434434
BoxedFloat* rhs_float = static_cast<BoxedFloat*>(rhs);
435435
return boxFloat(lhs->n + rhs_float->d);
436436
} else {
@@ -559,7 +559,7 @@ extern "C" Box* intDiv(BoxedInt* lhs, Box* rhs) {
559559

560560
if (PyInt_Check(rhs)) {
561561
return intDivInt(lhs, static_cast<BoxedInt*>(rhs));
562-
} else if (PyFloat_Check(rhs)) {
562+
} else if (PyFloat_CheckExact(rhs)) {
563563
return intDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
564564
} else {
565565
return NotImplemented;
@@ -601,7 +601,7 @@ extern "C" Box* intFloordiv(BoxedInt* lhs, Box* rhs) {
601601

602602
if (PyInt_Check(rhs)) {
603603
return intFloordivInt(lhs, static_cast<BoxedInt*>(rhs));
604-
} else if (PyFloat_Check(rhs)) {
604+
} else if (PyFloat_CheckExact(rhs)) {
605605
return intFloordivFloat(lhs, static_cast<BoxedFloat*>(rhs));
606606
} else {
607607
return NotImplemented;
@@ -647,7 +647,7 @@ extern "C" Box* intTruediv(BoxedInt* lhs, Box* rhs) {
647647

648648
if (PyInt_Check(rhs)) {
649649
return intTruedivInt(lhs, static_cast<BoxedInt*>(rhs));
650-
} else if (PyFloat_Check(rhs)) {
650+
} else if (PyFloat_CheckExact(rhs)) {
651651
return intTruedivFloat(lhs, static_cast<BoxedFloat*>(rhs));
652652
} else {
653653
return NotImplemented;
@@ -790,7 +790,7 @@ extern "C" Box* intMul(BoxedInt* lhs, Box* rhs) {
790790
if (PyInt_Check(rhs)) {
791791
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
792792
return intMulInt(lhs, rhs_int);
793-
} else if (PyFloat_Check(rhs)) {
793+
} else if (PyFloat_CheckExact(rhs)) {
794794
BoxedFloat* rhs_float = static_cast<BoxedFloat*>(rhs);
795795
return intMulFloat(lhs, rhs_float);
796796
} else {
@@ -842,7 +842,7 @@ extern "C" Box* intPow(BoxedInt* lhs, Box* rhs, Box* mod) {
842842

843843
if (PyLong_Check(rhs))
844844
return intPowLong(lhs, static_cast<BoxedLong*>(rhs), mod);
845-
else if (PyFloat_Check(rhs))
845+
else if (PyFloat_CheckExact(rhs))
846846
return intPowFloat(lhs, static_cast<BoxedFloat*>(rhs), mod);
847847
else if (!PyInt_Check(rhs))
848848
return NotImplemented;
@@ -937,7 +937,7 @@ extern "C" Box* intSub(BoxedInt* lhs, Box* rhs) {
937937
if (PyInt_Check(rhs)) {
938938
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
939939
return intSubInt(lhs, rhs_int);
940-
} else if (PyFloat_Check(rhs)) {
940+
} else if (PyFloat_CheckExact(rhs)) {
941941
BoxedFloat* rhs_float = static_cast<BoxedFloat*>(rhs);
942942
return intSubFloat(lhs, rhs_float);
943943
} else {

src/runtime/long.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,39 @@ Box* longStr(BoxedLong* v) {
841841
return _PyLong_Format(v, 10, 0 /* no L */, 0);
842842
}
843843

844+
Box* long__format__(BoxedLong* self, Box* format_spec) noexcept {
845+
if (PyBytes_Check(format_spec))
846+
return _PyLong_FormatAdvanced(self, PyBytes_AS_STRING(format_spec), PyBytes_GET_SIZE(format_spec));
847+
if (PyUnicode_Check(format_spec)) {
848+
/* Convert format_spec to a str */
849+
PyObject* result;
850+
PyObject* str_spec = PyObject_Str(format_spec);
851+
852+
if (str_spec == NULL)
853+
return NULL;
854+
855+
result = _PyLong_FormatAdvanced(self, PyBytes_AS_STRING(str_spec), PyBytes_GET_SIZE(str_spec));
856+
857+
Py_DECREF(str_spec);
858+
return result;
859+
}
860+
PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
861+
return NULL;
862+
}
863+
864+
Box* longFormat(BoxedLong* self, Box* format_spec) {
865+
if (!PyLong_Check(self))
866+
raiseExcHelper(TypeError, "descriptor '__format__' requires a 'long' object but received a '%s'",
867+
getTypeName(self));
868+
869+
Box* res = long__format__(self, format_spec);
870+
871+
if (res == NULL)
872+
throwCAPIException();
873+
874+
return res;
875+
}
876+
844877
Box* longBin(BoxedLong* v) {
845878
if (!PyLong_Check(v))
846879
raiseExcHelper(TypeError, "descriptor '__bin__' requires a 'long' object but received a '%s'", getTypeName(v));
@@ -1713,6 +1746,7 @@ void setupLong() {
17131746
long_cls->giveAttr("__float__", new BoxedFunction(FunctionMetadata::create((void*)longFloat, UNKNOWN, 1)));
17141747
long_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)longRepr, STR, 1)));
17151748
long_cls->giveAttr("__str__", new BoxedFunction(FunctionMetadata::create((void*)longStr, STR, 1)));
1749+
long_cls->giveAttr("__format__", new BoxedFunction(FunctionMetadata::create((void*)longFormat, STR, 2)));
17161750
long_cls->giveAttr("__bin__", new BoxedFunction(FunctionMetadata::create((void*)longBin, STR, 1)));
17171751
long_cls->giveAttr("__hex__", new BoxedFunction(FunctionMetadata::create((void*)longHex, STR, 1)));
17181752
long_cls->giveAttr("__oct__", new BoxedFunction(FunctionMetadata::create((void*)longOct, STR, 1)));

test/tests/float.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,35 @@ class F2(float):
141141
arg2=y)))
142142
except Exception as e:
143143
print(e.message)
144+
145+
146+
class Foo1(float):
147+
def __rdiv__(self, other):
148+
print("float custom operation called")
149+
return self / other
150+
151+
152+
class Foo2(long):
153+
def __rdiv__(self, other):
154+
print("long custom operation called")
155+
return self / other
156+
157+
158+
class Foo3(int):
159+
def __rdiv__(self, other):
160+
print("int custom operation called")
161+
return self / other
162+
163+
a = Foo1(1.5)
164+
b = Foo2(1L)
165+
c = Foo3(1)
166+
167+
print(1.5 / a)
168+
print(1.5 / b)
169+
print(1.5 / c)
170+
print(1 / a)
171+
print(1 / b)
172+
print(1 / c)
173+
print(1L / a)
174+
print(1L / b)
175+
print(1L / c)

test/tests/long.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,5 @@ class long2(long):
203203
arg2=y)))
204204
except Exception as e:
205205
print(e.message)
206+
207+
print(long.__format__(130L, 'd'))

0 commit comments

Comments
 (0)