bpo-46852: Remove the float.__set_format__() method (GH-31585)

Remove the undocumented private float.__set_format__() method,
previously known as float.__set_format__() in Python 3.7. Its
docstring said: "You probably don't want to use this function. It
exists mainly to be used in Python's test suite."
This commit is contained in:
Victor Stinner 2022-02-26 00:53:27 +01:00 committed by GitHub
parent 4060111f9d
commit 5ab745fc51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 15 additions and 214 deletions

View file

@ -2165,7 +2165,7 @@ Magic methods that are supported but not setup by default in ``MagicMock`` are:
* ``__reversed__`` and ``__missing__`` * ``__reversed__`` and ``__missing__``
* ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``, * ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``,
``__getstate__`` and ``__setstate__`` ``__getstate__`` and ``__setstate__``
* ``__getformat__`` and ``__setformat__`` * ``__getformat__``

View file

@ -574,6 +574,12 @@ Removed
because it was not used and added by mistake in previous versions. because it was not used and added by mistake in previous versions.
(Contributed by Nikita Sobolev in :issue:`46483`.) (Contributed by Nikita Sobolev in :issue:`46483`.)
* Remove the undocumented private ``float.__set_format__()`` method, previously
known as ``float.__setformat__()`` in Python 3.7. Its docstring said: "You
probably don't want to use this function. It exists mainly to be used in
Python's test suite."
(Contributed by Victor Stinner in :issue:`46852`.)
Porting to Python 3.11 Porting to Python 3.11
====================== ======================

View file

@ -19,8 +19,6 @@ NAN = float("nan")
have_getformat = hasattr(float, "__getformat__") have_getformat = hasattr(float, "__getformat__")
requires_getformat = unittest.skipUnless(have_getformat, requires_getformat = unittest.skipUnless(have_getformat,
"requires __getformat__") "requires __getformat__")
requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
"requires __setformat__")
#locate file with float format test values #locate file with float format test values
test_dir = os.path.dirname(__file__) or os.curdir test_dir = os.path.dirname(__file__) or os.curdir
@ -612,44 +610,6 @@ class GeneralFloatCases(unittest.TestCase):
self.assertEqual(hash(value), object.__hash__(value)) self.assertEqual(hash(value), object.__hash__(value))
@requires_setformat
class FormatFunctionsTestCase(unittest.TestCase):
def setUp(self):
self.save_formats = {'double':float.__getformat__('double'),
'float':float.__getformat__('float')}
def tearDown(self):
float.__setformat__('double', self.save_formats['double'])
float.__setformat__('float', self.save_formats['float'])
def test_getformat(self):
self.assertIn(float.__getformat__('double'),
['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
self.assertIn(float.__getformat__('float'),
['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
self.assertRaises(ValueError, float.__getformat__, 'chicken')
self.assertRaises(TypeError, float.__getformat__, 1)
def test_setformat(self):
for t in 'double', 'float':
float.__setformat__(t, 'unknown')
if self.save_formats[t] == 'IEEE, big-endian':
self.assertRaises(ValueError, float.__setformat__,
t, 'IEEE, little-endian')
elif self.save_formats[t] == 'IEEE, little-endian':
self.assertRaises(ValueError, float.__setformat__,
t, 'IEEE, big-endian')
else:
self.assertRaises(ValueError, float.__setformat__,
t, 'IEEE, big-endian')
self.assertRaises(ValueError, float.__setformat__,
t, 'IEEE, little-endian')
self.assertRaises(ValueError, float.__setformat__,
t, 'chicken')
self.assertRaises(ValueError, float.__setformat__,
'chicken', 'unknown')
BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00' BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF)) LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00' BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
@ -660,36 +620,6 @@ LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
BE_FLOAT_NAN = b'\x7f\xc0\x00\x00' BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN)) LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
# on non-IEEE platforms, attempting to unpack a bit pattern
# representing an infinity or a NaN should raise an exception.
@requires_setformat
class UnknownFormatTestCase(unittest.TestCase):
def setUp(self):
self.save_formats = {'double':float.__getformat__('double'),
'float':float.__getformat__('float')}
float.__setformat__('double', 'unknown')
float.__setformat__('float', 'unknown')
def tearDown(self):
float.__setformat__('double', self.save_formats['double'])
float.__setformat__('float', self.save_formats['float'])
def test_double_specials_dont_unpack(self):
for fmt, data in [('>d', BE_DOUBLE_INF),
('>d', BE_DOUBLE_NAN),
('<d', LE_DOUBLE_INF),
('<d', LE_DOUBLE_NAN)]:
self.assertRaises(ValueError, struct.unpack, fmt, data)
def test_float_specials_dont_unpack(self):
for fmt, data in [('>f', BE_FLOAT_INF),
('>f', BE_FLOAT_NAN),
('<f', LE_FLOAT_INF),
('<f', LE_FLOAT_NAN)]:
self.assertRaises(ValueError, struct.unpack, fmt, data)
# on an IEEE platform, all we guarantee is that bit patterns # on an IEEE platform, all we guarantee is that bit patterns
# representing infinities or NaNs do not raise an exception; all else # representing infinities or NaNs do not raise an exception; all else
# is accident (today). # is accident (today).

View file

@ -1943,7 +1943,7 @@ right = ' '.join('r%s' % n for n in numerics.split())
_non_defaults = { _non_defaults = {
'__get__', '__set__', '__delete__', '__reversed__', '__missing__', '__get__', '__set__', '__delete__', '__reversed__', '__missing__',
'__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__',
'__getstate__', '__setstate__', '__getformat__', '__setformat__', '__getstate__', '__setstate__', '__getformat__',
'__repr__', '__dir__', '__subclasses__', '__format__', '__repr__', '__dir__', '__subclasses__', '__format__',
'__getnewargs_ex__', '__getnewargs_ex__',
} }

View file

@ -0,0 +1,4 @@
Remove the undocumented private ``float.__set_format__()`` method, previously
known as ``float.__setformat__()`` in Python 3.7. Its docstring said: "You
probably don't want to use this function. It exists mainly to be used in
Python's test suite." Patch by Victor Stinner.

View file

@ -290,73 +290,6 @@ exit:
return return_value; return return_value;
} }
PyDoc_STRVAR(float___setformat____doc__,
"__setformat__($type, typestr, fmt, /)\n"
"--\n"
"\n"
"You probably don\'t want to use this function.\n"
"\n"
" typestr\n"
" Must be \'double\' or \'float\'.\n"
" fmt\n"
" Must be one of \'unknown\', \'IEEE, big-endian\' or \'IEEE, little-endian\',\n"
" and in addition can only be one of the latter two if it appears to\n"
" match the underlying C reality.\n"
"\n"
"It exists mainly to be used in Python\'s test suite.\n"
"\n"
"Override the automatic determination of C-level floating point type.\n"
"This affects how floats are converted to and from binary strings.");
#define FLOAT___SETFORMAT___METHODDEF \
{"__setformat__", (PyCFunction)(void(*)(void))float___setformat__, METH_FASTCALL|METH_CLASS, float___setformat____doc__},
static PyObject *
float___setformat___impl(PyTypeObject *type, const char *typestr,
const char *fmt);
static PyObject *
float___setformat__(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
const char *typestr;
const char *fmt;
if (!_PyArg_CheckPositional("__setformat__", nargs, 2, 2)) {
goto exit;
}
if (!PyUnicode_Check(args[0])) {
_PyArg_BadArgument("__setformat__", "argument 1", "str", args[0]);
goto exit;
}
Py_ssize_t typestr_length;
typestr = PyUnicode_AsUTF8AndSize(args[0], &typestr_length);
if (typestr == NULL) {
goto exit;
}
if (strlen(typestr) != (size_t)typestr_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
if (!PyUnicode_Check(args[1])) {
_PyArg_BadArgument("__setformat__", "argument 2", "str", args[1]);
goto exit;
}
Py_ssize_t fmt_length;
fmt = PyUnicode_AsUTF8AndSize(args[1], &fmt_length);
if (fmt == NULL) {
goto exit;
}
if (strlen(fmt) != (size_t)fmt_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
return_value = float___setformat___impl(type, typestr, fmt);
exit:
return return_value;
}
PyDoc_STRVAR(float___format____doc__, PyDoc_STRVAR(float___format____doc__,
"__format__($self, format_spec, /)\n" "__format__($self, format_spec, /)\n"
"--\n" "--\n"
@ -388,4 +321,4 @@ float___format__(PyObject *self, PyObject *arg)
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=3fb0c0624cc87dff input=a9049054013a1b77]*/ /*[clinic end generated code: output=604cb27bf751ea16 input=a9049054013a1b77]*/

View file

@ -1708,7 +1708,6 @@ typedef enum {
} float_format_type; } float_format_type;
static float_format_type double_format, float_format; static float_format_type double_format, float_format;
static float_format_type detected_double_format, detected_float_format;
/*[clinic input] /*[clinic input]
@classmethod @classmethod
@ -1760,78 +1759,6 @@ float___getformat___impl(PyTypeObject *type, const char *typestr)
} }
} }
/*[clinic input]
@classmethod
float.__setformat__
typestr: str
Must be 'double' or 'float'.
fmt: str
Must be one of 'unknown', 'IEEE, big-endian' or 'IEEE, little-endian',
and in addition can only be one of the latter two if it appears to
match the underlying C reality.
/
You probably don't want to use this function.
It exists mainly to be used in Python's test suite.
Override the automatic determination of C-level floating point type.
This affects how floats are converted to and from binary strings.
[clinic start generated code]*/
static PyObject *
float___setformat___impl(PyTypeObject *type, const char *typestr,
const char *fmt)
/*[clinic end generated code: output=06864de1fb5f1f04 input=c0e9e04dd87f9988]*/
{
float_format_type f;
float_format_type detected;
float_format_type *p;
if (strcmp(typestr, "double") == 0) {
p = &double_format;
detected = detected_double_format;
}
else if (strcmp(typestr, "float") == 0) {
p = &float_format;
detected = detected_float_format;
}
else {
PyErr_SetString(PyExc_ValueError,
"__setformat__() argument 1 must "
"be 'double' or 'float'");
return NULL;
}
if (strcmp(fmt, "unknown") == 0) {
f = unknown_format;
}
else if (strcmp(fmt, "IEEE, little-endian") == 0) {
f = ieee_little_endian_format;
}
else if (strcmp(fmt, "IEEE, big-endian") == 0) {
f = ieee_big_endian_format;
}
else {
PyErr_SetString(PyExc_ValueError,
"__setformat__() argument 2 must be "
"'unknown', 'IEEE, little-endian' or "
"'IEEE, big-endian'");
return NULL;
}
if (f != unknown_format && f != detected) {
PyErr_Format(PyExc_ValueError,
"can only set %s format to 'unknown' or the "
"detected platform value", typestr);
return NULL;
}
*p = f;
Py_RETURN_NONE;
}
static PyObject * static PyObject *
float_getreal(PyObject *v, void *closure) float_getreal(PyObject *v, void *closure)
@ -1885,7 +1812,6 @@ static PyMethodDef float_methods[] = {
FLOAT_IS_INTEGER_METHODDEF FLOAT_IS_INTEGER_METHODDEF
FLOAT___GETNEWARGS___METHODDEF FLOAT___GETNEWARGS___METHODDEF
FLOAT___GETFORMAT___METHODDEF FLOAT___GETFORMAT___METHODDEF
FLOAT___SETFORMAT___METHODDEF
FLOAT___FORMAT___METHODDEF FLOAT___FORMAT___METHODDEF
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
@ -1989,6 +1915,8 @@ _PyFloat_InitState(PyInterpreterState *interp)
return; return;
} }
float_format_type detected_double_format, detected_float_format;
/* We attempt to determine if this machine is using IEEE /* We attempt to determine if this machine is using IEEE
floating point formats by peering at the bits of some floating point formats by peering at the bits of some
carefully chosen values. If it looks like we are on an carefully chosen values. If it looks like we are on an