Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Doc/library/unittest.mock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2165,7 +2165,7 @@ Magic methods that are supported but not setup by default in ``MagicMock`` are:
* ``__reversed__`` and ``__missing__``
* ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``,
``__getstate__`` and ``__setstate__``
* ``__getformat__`` and ``__setformat__``
* ``__getformat__``



Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,12 @@ Removed
because it was not used and added by mistake in previous versions.
(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
======================

Expand Down
70 changes: 0 additions & 70 deletions Lib/test/test_float.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
have_getformat = hasattr(float, "__getformat__")
requires_getformat = unittest.skipUnless(have_getformat,
"requires __getformat__")
requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
"requires __setformat__")

#locate file with float format test values
test_dir = os.path.dirname(__file__) or os.curdir
Expand Down Expand Up @@ -612,44 +610,6 @@ class F(float, H):
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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't these tests still relevant?

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'
LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
Expand All @@ -660,36 +620,6 @@ def test_setformat(self):
BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
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
# representing infinities or NaNs do not raise an exception; all else
# is accident (today).
Expand Down
2 changes: 1 addition & 1 deletion Lib/unittest/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1943,7 +1943,7 @@ def _patch_stopall():
_non_defaults = {
'__get__', '__set__', '__delete__', '__reversed__', '__missing__',
'__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__',
'__getstate__', '__setstate__', '__getformat__', '__setformat__',
'__getstate__', '__setstate__', '__getformat__',
'__repr__', '__dir__', '__subclasses__', '__format__',
'__getnewargs_ex__',
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
69 changes: 1 addition & 68 deletions Objects/clinic/floatobject.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 2 additions & 74 deletions Objects/floatobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,6 @@ typedef enum {
} float_format_type;

static float_format_type double_format, float_format;
static float_format_type detected_double_format, detected_float_format;

/*[clinic input]
@classmethod
Expand Down Expand Up @@ -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 *
float_getreal(PyObject *v, void *closure)
Expand Down Expand Up @@ -1885,7 +1812,6 @@ static PyMethodDef float_methods[] = {
FLOAT_IS_INTEGER_METHODDEF
FLOAT___GETNEWARGS___METHODDEF
FLOAT___GETFORMAT___METHODDEF
FLOAT___SETFORMAT___METHODDEF
FLOAT___FORMAT___METHODDEF
{NULL, NULL} /* sentinel */
};
Expand Down Expand Up @@ -1989,6 +1915,8 @@ _PyFloat_InitState(PyInterpreterState *interp)
return;
}

float_format_type detected_double_format, detected_float_format;

/* We attempt to determine if this machine is using IEEE
floating point formats by peering at the bits of some
carefully chosen values. If it looks like we are on an
Expand Down