[Python-checkins] cpython (2.7): Issue #26995: Added tests for "f", "d", "D", "S", "Y", and "U" format codes
serhiy.storchaka
python-checkins at python.org
Mon May 16 03:13:15 EDT 2016
https://hg.python.org/cpython/rev/c3346c89f6d4
changeset: 101366:c3346c89f6d4
branch: 2.7
parent: 101363:621e0a3249c2
user: Serhiy Storchaka <storchaka at gmail.com>
date: Mon May 16 10:12:02 2016 +0300
summary:
Issue #26995: Added tests for "f", "d", "D", "S", "Y", and "U" format codes
in PyArg_ParseTuple().
files:
Lib/test/test_getargs2.py | 166 +++++++++++++++++++++++++-
Modules/_testcapimodule.c | 67 ++++++++++
2 files changed, 232 insertions(+), 1 deletions(-)
diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py
--- a/Lib/test/test_getargs2.py
+++ b/Lib/test/test_getargs2.py
@@ -1,4 +1,6 @@
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 @@
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 @@
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 @@
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 @@
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()
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -1136,6 +1136,65 @@
}
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)
{
char c;
@@ -2377,6 +2436,14 @@
(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},
{"getargs_s_star", getargs_s_star, METH_VARARGS},
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list