[pypy-svn] pypy default: Improve api.py to detect when we mess up the return type -- at least
arigo
commits-noreply at bitbucket.org
Thu Jan 27 15:53:35 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r41395:c68ceebd52ab
Date: 2011-01-27 15:52 +0100
http://bitbucket.org/pypy/pypy/changeset/c68ceebd52ab/
Log: Improve api.py to detect when we mess up the return type -- at least
when we return an integer when a wrapped object is expected or vice-
versa. Fix cdatetime.py accordingly.
diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py
--- a/pypy/module/cpyext/test/test_datetime.py
+++ b/pypy/module/cpyext/test/test_datetime.py
@@ -10,11 +10,9 @@
assert api.PyDate_Check(w_date)
assert api.PyDate_CheckExact(w_date)
- assert space.unwrap(space.newtuple([
- api.PyDateTime_GET_YEAR(w_date),
- api.PyDateTime_GET_MONTH(w_date),
- api.PyDateTime_GET_DAY(w_date)])) == (
- 2010, 06, 03)
+ assert api.PyDateTime_GET_YEAR(w_date) == 2010
+ assert api.PyDateTime_GET_MONTH(w_date) == 6
+ assert api.PyDateTime_GET_DAY(w_date) == 3
def test_time(self, space, api):
w_time = api.PyTime_FromTime(23, 15, 40, 123456)
@@ -23,12 +21,10 @@
assert api.PyTime_Check(w_time)
assert api.PyTime_CheckExact(w_time)
- assert space.unwrap(space.newtuple([
- api.PyDateTime_TIME_GET_HOUR(w_time),
- api.PyDateTime_TIME_GET_MINUTE(w_time),
- api.PyDateTime_TIME_GET_SECOND(w_time),
- api.PyDateTime_TIME_GET_MICROSECOND(w_time)])) == (
- 23, 15, 40, 123456)
+ assert api.PyDateTime_TIME_GET_HOUR(w_time) == 23
+ assert api.PyDateTime_TIME_GET_MINUTE(w_time) == 15
+ assert api.PyDateTime_TIME_GET_SECOND(w_time) == 40
+ assert api.PyDateTime_TIME_GET_MICROSECOND(w_time) == 123456
def test_datetime(self, space, api):
w_date = api.PyDateTime_FromDateAndTime(
@@ -40,15 +36,13 @@
assert api.PyDate_Check(w_date)
assert not api.PyDate_CheckExact(w_date)
- assert space.unwrap(space.newtuple([
- api.PyDateTime_GET_YEAR(w_date),
- api.PyDateTime_GET_MONTH(w_date),
- api.PyDateTime_GET_DAY(w_date),
- api.PyDateTime_DATE_GET_HOUR(w_date),
- api.PyDateTime_DATE_GET_MINUTE(w_date),
- api.PyDateTime_DATE_GET_SECOND(w_date),
- api.PyDateTime_DATE_GET_MICROSECOND(w_date)])) == (
- 2010, 06, 03, 23, 15, 40, 123456)
+ assert api.PyDateTime_GET_YEAR(w_date) == 2010
+ assert api.PyDateTime_GET_MONTH(w_date) == 6
+ assert api.PyDateTime_GET_DAY(w_date) == 3
+ assert api.PyDateTime_DATE_GET_HOUR(w_date) == 23
+ assert api.PyDateTime_DATE_GET_MINUTE(w_date) == 15
+ assert api.PyDateTime_DATE_GET_SECOND(w_date) == 40
+ assert api.PyDateTime_DATE_GET_MICROSECOND(w_date) == 123456
def test_delta(self, space, api):
w_delta = space.appexec(
@@ -63,11 +57,9 @@
assert api.PyDelta_Check(w_delta)
assert api.PyDelta_CheckExact(w_delta)
- assert space.unwrap(space.newtuple([
- api.PyDateTime_DELTA_GET_DAYS(w_delta),
- api.PyDateTime_DELTA_GET_SECONDS(w_delta),
- api.PyDateTime_DELTA_GET_MICROSECONDS(w_delta)])) == (
- 10, 20, 30)
+ assert api.PyDateTime_DELTA_GET_DAYS(w_delta) == 10
+ assert api.PyDateTime_DELTA_GET_SECONDS(w_delta) == 20
+ assert api.PyDateTime_DELTA_GET_MICROSECONDS(w_delta) == 30
def test_fromtimestamp(self, space, api):
w_args = space.wrap((0,))
diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py
--- a/pypy/module/cpyext/cdatetime.py
+++ b/pypy/module/cpyext/cdatetime.py
@@ -171,67 +171,67 @@
def PyDateTime_GET_YEAR(space, w_obj):
"""Return the year, as a positive int.
"""
- return space.getattr(w_obj, space.wrap("year"))
+ return space.int_w(space.getattr(w_obj, space.wrap("year")))
@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_GET_MONTH(space, w_obj):
"""Return the month, as an int from 1 through 12.
"""
- return space.getattr(w_obj, space.wrap("month"))
+ return space.int_w(space.getattr(w_obj, space.wrap("month")))
@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_GET_DAY(space, w_obj):
"""Return the day, as an int from 1 through 31.
"""
- return space.getattr(w_obj, space.wrap("day"))
+ return space.int_w(space.getattr(w_obj, space.wrap("day")))
@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_HOUR(space, w_obj):
"""Return the hour, as an int from 0 through 23.
"""
- return space.getattr(w_obj, space.wrap("hour"))
+ return space.int_w(space.getattr(w_obj, space.wrap("hour")))
@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_MINUTE(space, w_obj):
"""Return the minute, as an int from 0 through 59.
"""
- return space.getattr(w_obj, space.wrap("minute"))
+ return space.int_w(space.getattr(w_obj, space.wrap("minute")))
@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_SECOND(space, w_obj):
"""Return the second, as an int from 0 through 59.
"""
- return space.getattr(w_obj, space.wrap("second"))
+ return space.int_w(space.getattr(w_obj, space.wrap("second")))
@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_MICROSECOND(space, w_obj):
"""Return the microsecond, as an int from 0 through 999999.
"""
- return space.getattr(w_obj, space.wrap("microsecond"))
+ return space.int_w(space.getattr(w_obj, space.wrap("microsecond")))
@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_HOUR(space, w_obj):
"""Return the hour, as an int from 0 through 23.
"""
- return space.getattr(w_obj, space.wrap("hour"))
+ return space.int_w(space.getattr(w_obj, space.wrap("hour")))
@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_MINUTE(space, w_obj):
"""Return the minute, as an int from 0 through 59.
"""
- return space.getattr(w_obj, space.wrap("minute"))
+ return space.int_w(space.getattr(w_obj, space.wrap("minute")))
@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_SECOND(space, w_obj):
"""Return the second, as an int from 0 through 59.
"""
- return space.getattr(w_obj, space.wrap("second"))
+ return space.int_w(space.getattr(w_obj, space.wrap("second")))
@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_MICROSECOND(space, w_obj):
"""Return the microsecond, as an int from 0 through 999999.
"""
- return space.getattr(w_obj, space.wrap("microsecond"))
+ return space.int_w(space.getattr(w_obj, space.wrap("microsecond")))
# XXX these functions are not present in the Python API
# But it does not seem possible to expose a different structure
@@ -239,12 +239,12 @@
@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DELTA_GET_DAYS(space, w_obj):
- return space.getattr(w_obj, space.wrap("days"))
+ return space.int_w(space.getattr(w_obj, space.wrap("days")))
@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DELTA_GET_SECONDS(space, w_obj):
- return space.getattr(w_obj, space.wrap("seconds"))
+ return space.int_w(space.getattr(w_obj, space.wrap("seconds")))
@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DELTA_GET_MICROSECONDS(space, w_obj):
- return space.getattr(w_obj, space.wrap("microseconds"))
+ return space.int_w(space.getattr(w_obj, space.wrap("microseconds")))
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -199,6 +199,8 @@
error = CANNOT_FAIL
if type(error) is int:
error = rffi.cast(restype, error)
+ expect_integer = (isinstance(restype, lltype.Primitive) and
+ rffi.cast(restype, 0) == 0)
def decorate(func):
func_name = func.func_name
@@ -268,6 +270,9 @@
return None
else:
return api_function.error_value
+ if not we_are_translated():
+ got_integer = isinstance(res, (int, long, float))
+ assert got_integer == expect_integer
if res is None:
return None
elif isinstance(res, Reference):
More information about the Pypy-commit
mailing list