Commit e9dcdec0 authored by Stefan Behnel's avatar Stefan Behnel

call PyNumber_Int() for builtin int() function

parent 1b646b6a
......@@ -1990,6 +1990,28 @@ class OptimizeBuiltinCalls(Visitor.MethodDispatcherTransform):
utility_code = load_c_utility('pyobject_as_double'),
py_name = "float")
PyNumber_Int_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("o", PyrexTypes.py_object_type, None)
])
def _handle_simple_function_int(self, node, function, pos_args):
"""Transform int() into a faster C function call.
"""
if len(pos_args) == 0:
return ExprNodes.IntNode(node, value="0", constant_result=0,
type=PyrexTypes.c_int_type)
elif len(pos_args) != 1:
return node # int(x, base)
func_arg = pos_args[0]
if isinstance(func_arg, ExprNodes.CoerceToPyTypeNode):
return node # handled in visit_CoerceFromPyTypeNode()
if func_arg.type.is_pyobject and node.type.is_pyobject:
return ExprNodes.PythonCapiCallNode(
node.pos, "PyNumber_Int", self.PyNumber_Int_func_type,
args=pos_args, is_temp=True)
return node
def _handle_simple_function_bool(self, node, function, pos_args):
"""Transform bool(x) into a type coercion to a boolean.
"""
......
......@@ -218,6 +218,7 @@
#define PyInt_AsSsize_t PyLong_AsSsize_t
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
#define PyNumber_Int PyNumber_Long
#endif
#if PY_MAJOR_VERSION >= 3
......
......@@ -137,3 +137,47 @@ def double_to_double_int(double x):
"""
cdef double r = int(x)
return r
@cython.test_fail_if_path_exists("//SimpleCallNode")
@cython.test_assert_path_exists("//PythonCapiCallNode")
def object_float(x):
"""
>>> 4.05 < object_float(4.1) < 4.15
True
>>> object_float(2**100) == float(2**100)
True
>>> object_float(2.5**100) == float(2.5**100)
True
>>> object_float(4)
4.0
>>> object_float('4')
4.0
>>> object_float('4.0')
4.0
>>> object_float('4'.encode('ascii'))
4.0
>>> object_float('4.0'.encode('ascii'))
4.0
"""
return float(x)
@cython.test_fail_if_path_exists("//SimpleCallNode")
@cython.test_assert_path_exists("//PythonCapiCallNode")
def object_int(x):
"""
>>> object_int(4)
4
>>> object_int(2**100) == 2**100 or object_int(2**100)
True
>>> object_int(-(2**100)) == -(2**100) or object_int(-(2**100))
True
>>> object_int(4.1)
4
>>> object_int(4.0)
4
>>> object_int('4')
4
>>> object_int('4'.encode('ascii'))
4
"""
return int(x)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment