Kaydet (Commit) d0dc72b4 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #26995: Added tests for "f", "d", "D", "S", "Y", and "U" format codes

in PyArg_ParseTuple().
üst c6a7c96a
import unittest
import math
import sys
from test import test_support
# Skip this test if the _testcapi module isn't available.
test_support.import_module('_testcapi')
......@@ -42,7 +44,11 @@ VERY_LARGE = 0xFF0000121212121212121242L
from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
SHRT_MIN, SHRT_MAX
SHRT_MIN, SHRT_MAX, FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX
DBL_MAX_EXP = sys.float_info.max_exp
INF = float('inf')
NAN = float('nan')
try:
from _testcapi import getargs_L, getargs_K
......@@ -64,6 +70,55 @@ class Int:
def __int__(self):
return 99
class Float:
def __float__(self):
return 4.25
class FloatSubclass(float):
pass
class FloatSubclass2(float):
def __float__(self):
return 4.25
class BadFloat:
def __float__(self):
return 687
class BadFloat2:
def __float__(self):
return FloatSubclass(4.25)
class BadFloat3(float):
def __float__(self):
return FloatSubclass(4.25)
class Complex:
def __complex__(self):
return 4.25+0.5j
class ComplexSubclass(complex):
pass
class ComplexSubclass2(complex):
def __complex__(self):
return 4.25+0.5j
class BadComplex:
def __complex__(self):
return 1.25
class BadComplex2:
def __complex__(self):
return ComplexSubclass(4.25+0.5j)
class BadComplex3(complex):
def __complex__(self):
return ComplexSubclass(4.25+0.5j)
class TupleSubclass(tuple):
pass
......@@ -273,6 +328,80 @@ class LongLong_TestCase(unittest.TestCase):
self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
class Float_TestCase(unittest.TestCase):
def assertEqualWithSign(self, actual, expected):
self.assertEqual(actual, expected)
self.assertEqual(math.copysign(1, actual), math.copysign(1, expected))
def test_f(self):
from _testcapi import getargs_f
self.assertEqual(getargs_f(4.25), 4.25)
self.assertEqual(getargs_f(4), 4.0)
self.assertRaises(TypeError, getargs_f, 4.25+0j)
self.assertEqual(getargs_f(Float()), 4.25)
self.assertEqual(getargs_f(FloatSubclass(7.5)), 7.5)
self.assertEqual(getargs_f(FloatSubclass2(7.5)), 7.5)
self.assertRaises(TypeError, getargs_f, BadFloat())
self.assertEqual(getargs_f(BadFloat2()), 4.25)
self.assertEqual(getargs_f(BadFloat3(7.5)), 7.5)
for x in (FLT_MIN, -FLT_MIN, FLT_MAX, -FLT_MAX, INF, -INF):
self.assertEqual(getargs_f(x), x)
if FLT_MAX < DBL_MAX:
self.assertEqual(getargs_f(DBL_MAX), INF)
self.assertEqual(getargs_f(-DBL_MAX), -INF)
if FLT_MIN > DBL_MIN:
self.assertEqualWithSign(getargs_f(DBL_MIN), 0.0)
self.assertEqualWithSign(getargs_f(-DBL_MIN), -0.0)
self.assertEqualWithSign(getargs_f(0.0), 0.0)
self.assertEqualWithSign(getargs_f(-0.0), -0.0)
r = getargs_f(NAN)
self.assertNotEqual(r, r)
def test_d(self):
from _testcapi import getargs_d
self.assertEqual(getargs_d(4.25), 4.25)
self.assertEqual(getargs_d(4), 4.0)
self.assertRaises(TypeError, getargs_d, 4.25+0j)
self.assertEqual(getargs_d(Float()), 4.25)
self.assertEqual(getargs_d(FloatSubclass(7.5)), 7.5)
self.assertEqual(getargs_d(FloatSubclass2(7.5)), 7.5)
self.assertRaises(TypeError, getargs_d, BadFloat())
self.assertEqual(getargs_d(BadFloat2()), 4.25)
self.assertEqual(getargs_d(BadFloat3(7.5)), 7.5)
for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF):
self.assertEqual(getargs_d(x), x)
self.assertRaises(OverflowError, getargs_d, 1<<DBL_MAX_EXP)
self.assertRaises(OverflowError, getargs_d, -1<<DBL_MAX_EXP)
self.assertEqualWithSign(getargs_d(0.0), 0.0)
self.assertEqualWithSign(getargs_d(-0.0), -0.0)
r = getargs_d(NAN)
self.assertNotEqual(r, r)
def test_D(self):
from _testcapi import getargs_D
self.assertEqual(getargs_D(4.25+0.5j), 4.25+0.5j)
self.assertEqual(getargs_D(4.25), 4.25+0j)
self.assertEqual(getargs_D(4), 4.0+0j)
self.assertEqual(getargs_D(Complex()), 4.25+0.5j)
self.assertEqual(getargs_D(ComplexSubclass(7.5+0.25j)), 7.5+0.25j)
self.assertEqual(getargs_D(ComplexSubclass2(7.5+0.25j)), 7.5+0.25j)
self.assertRaises(TypeError, getargs_D, BadComplex())
self.assertEqual(getargs_D(BadComplex2()), 4.25+0.5j)
self.assertEqual(getargs_D(BadComplex3(7.5+0.25j)), 7.5+0.25j)
for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF):
c = complex(x, 1.0)
self.assertEqual(getargs_D(c), c)
c = complex(1.0, x)
self.assertEqual(getargs_D(c), c)
self.assertEqualWithSign(getargs_D(complex(0.0, 1.0)).real, 0.0)
self.assertEqualWithSign(getargs_D(complex(-0.0, 1.0)).real, -0.0)
self.assertEqualWithSign(getargs_D(complex(1.0, 0.0)).imag, 0.0)
self.assertEqualWithSign(getargs_D(complex(1.0, -0.0)).imag, -0.0)
class Tuple_TestCase(unittest.TestCase):
def test_args(self):
from _testcapi import get_args
......@@ -676,5 +805,40 @@ def test_main():
Bytes_TestCase, String_TestCase, Unicode_TestCase]
test_support.run_unittest(*tests)
class Object_TestCase(unittest.TestCase):
def test_S(self):
from _testcapi import getargs_S
obj = 'str'
self.assertIs(getargs_S(obj), obj)
self.assertRaises(TypeError, getargs_S, bytearray('bytearray'))
if test_support.have_unicode:
self.assertRaises(TypeError, getargs_S, u'unicode')
self.assertRaises(TypeError, getargs_S, None)
self.assertRaises(TypeError, getargs_S, memoryview(obj))
self.assertRaises(TypeError, getargs_S, buffer(obj))
def test_Y(self):
from _testcapi import getargs_Y
obj = bytearray('bytearray')
self.assertIs(getargs_Y(obj), obj)
self.assertRaises(TypeError, getargs_Y, 'str')
if test_support.have_unicode:
self.assertRaises(TypeError, getargs_Y, u'unicode')
self.assertRaises(TypeError, getargs_Y, None)
self.assertRaises(TypeError, getargs_Y, memoryview(obj))
self.assertRaises(TypeError, getargs_Y, buffer(obj))
@test_support.requires_unicode
def test_U(self):
from _testcapi import getargs_U
obj = u'unicode'
self.assertIs(getargs_U(obj), obj)
self.assertRaises(TypeError, getargs_U, 'str')
self.assertRaises(TypeError, getargs_U, bytearray('bytearray'))
self.assertRaises(TypeError, getargs_U, None)
self.assertRaises(TypeError, getargs_U, memoryview(obj))
self.assertRaises(TypeError, getargs_U, buffer(obj))
if __name__ == "__main__":
test_main()
......@@ -1135,6 +1135,65 @@ test_k_code(PyObject *self)
return Py_None;
}
static PyObject *
getargs_f(PyObject *self, PyObject *args)
{
float f;
if (!PyArg_ParseTuple(args, "f", &f))
return NULL;
return PyFloat_FromDouble(f);
}
static PyObject *
getargs_d(PyObject *self, PyObject *args)
{
double d;
if (!PyArg_ParseTuple(args, "d", &d))
return NULL;
return PyFloat_FromDouble(d);
}
static PyObject *
getargs_D(PyObject *self, PyObject *args)
{
Py_complex cval;
if (!PyArg_ParseTuple(args, "D", &cval))
return NULL;
return PyComplex_FromCComplex(cval);
}
static PyObject *
getargs_S(PyObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "S", &obj))
return NULL;
Py_INCREF(obj);
return obj;
}
static PyObject *
getargs_Y(PyObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "Y", &obj))
return NULL;
Py_INCREF(obj);
return obj;
}
#ifdef Py_USING_UNICODE
static PyObject *
getargs_U(PyObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "U", &obj))
return NULL;
Py_INCREF(obj);
return obj;
}
#endif
static PyObject *
getargs_c(PyObject *self, PyObject *args)
{
......@@ -2376,6 +2435,14 @@ static PyMethodDef TestMethods[] = {
{"test_long_long_and_overflow",
(PyCFunction)test_long_long_and_overflow, METH_NOARGS},
{"test_L_code", (PyCFunction)test_L_code, METH_NOARGS},
#endif
{"getargs_f", getargs_f, METH_VARARGS},
{"getargs_d", getargs_d, METH_VARARGS},
{"getargs_D", getargs_D, METH_VARARGS},
{"getargs_S", getargs_S, METH_VARARGS},
{"getargs_Y", getargs_Y, METH_VARARGS},
#ifdef Py_USING_UNICODE
{"getargs_U", getargs_U, METH_VARARGS},
#endif
{"getargs_c", getargs_c, METH_VARARGS},
{"getargs_s", getargs_s, METH_VARARGS},
......
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