mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-137044: Make resource.RLIM_INFINITY always positive (GH-137511)
It is now a positive integer larger larger than any limited resource value. This simplifies comparison of the resource values. Previously, it could be negative, such as -1 or -3, depending on platform. Deprecation warning is emitted if the old negative value is passed.
This commit is contained in:
parent
138ed6db9f
commit
0324c726de
5 changed files with 45 additions and 26 deletions
|
|
@ -50,6 +50,11 @@ this module for those platforms.
|
||||||
.. data:: RLIM_INFINITY
|
.. data:: RLIM_INFINITY
|
||||||
|
|
||||||
Constant used to represent the limit for an unlimited resource.
|
Constant used to represent the limit for an unlimited resource.
|
||||||
|
Its value is larger than any limited resource value.
|
||||||
|
|
||||||
|
.. versionchanged:: next
|
||||||
|
It is now always positive.
|
||||||
|
Previously, it could be negative, such as -1 or -3.
|
||||||
|
|
||||||
|
|
||||||
.. function:: getrlimit(resource)
|
.. function:: getrlimit(resource)
|
||||||
|
|
|
||||||
|
|
@ -595,6 +595,12 @@ Porting to Python 3.15
|
||||||
The |pythoncapi_compat_project| can be used to get most of these new
|
The |pythoncapi_compat_project| can be used to get most of these new
|
||||||
functions on Python 3.14 and older.
|
functions on Python 3.14 and older.
|
||||||
|
|
||||||
|
* :data:`resource.RLIM_INFINITY` is now always positive.
|
||||||
|
Passing a negative integer value that corresponded to its old value
|
||||||
|
(such as ``-1`` or ``-3``, depending on platform) to
|
||||||
|
:func:`resource.setrlimit` and :func:`resource.prlimit` is now deprecated.
|
||||||
|
(Contributed by Serhiy Storchaka in :gh:`137044`.)
|
||||||
|
|
||||||
|
|
||||||
Deprecated C APIs
|
Deprecated C APIs
|
||||||
-----------------
|
-----------------
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,10 @@ def test_fsize_ismax(self):
|
||||||
# we need to test that the get/setrlimit functions properly convert
|
# we need to test that the get/setrlimit functions properly convert
|
||||||
# the number to a C long long and that the conversion doesn't raise
|
# the number to a C long long and that the conversion doesn't raise
|
||||||
# an error.
|
# an error.
|
||||||
|
self.assertGreater(resource.RLIM_INFINITY, 0)
|
||||||
self.assertEqual(resource.RLIM_INFINITY, max)
|
self.assertEqual(resource.RLIM_INFINITY, max)
|
||||||
|
self.assertLessEqual(cur, max)
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (max, max))
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform == "vxworks",
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
|
|
@ -113,56 +116,53 @@ def test_fsize_not_too_big(self):
|
||||||
self.addCleanup(resource.setrlimit, resource.RLIMIT_FSIZE, (cur, max))
|
self.addCleanup(resource.setrlimit, resource.RLIMIT_FSIZE, (cur, max))
|
||||||
|
|
||||||
def expected(cur):
|
def expected(cur):
|
||||||
if resource.RLIM_INFINITY < 0:
|
return (min(cur, resource.RLIM_INFINITY), max)
|
||||||
return [(cur, max), (resource.RLIM_INFINITY, max)]
|
|
||||||
elif resource.RLIM_INFINITY < cur:
|
|
||||||
return [(resource.RLIM_INFINITY, max)]
|
|
||||||
else:
|
|
||||||
return [(cur, max)]
|
|
||||||
|
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31-5, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31-5, max))
|
||||||
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**31-5, max))
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**31-5, max))
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31, max))
|
||||||
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**31))
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32-5, max))
|
||||||
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32-5))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32, max))
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31, max))
|
pass
|
||||||
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**31))
|
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32-5, max))
|
|
||||||
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32-5))
|
|
||||||
else:
|
else:
|
||||||
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32))
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32))
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31, max))
|
|
||||||
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**31, max))
|
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32-5, max))
|
|
||||||
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**32-5, max))
|
|
||||||
|
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63-5, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63-5, max))
|
||||||
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63-5))
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63-5))
|
||||||
try:
|
try:
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63, max))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# There is a hard limit on macOS.
|
# There is a hard limit on macOS.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63))
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63))
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (2**64-5, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**64-5, max))
|
||||||
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**64-5))
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**64-5))
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform == "vxworks",
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
||||||
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
||||||
def test_fsize_negative(self):
|
def test_fsize_negative(self):
|
||||||
|
self.assertGreater(resource.RLIM_INFINITY, 0)
|
||||||
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||||
for value in -5, -2**31, -2**32-5, -2**63, -2**64-5, -2**1000:
|
for value in -5, -2**31, -2**32-5, -2**63, -2**64-5, -2**1000:
|
||||||
with self.subTest(value=value):
|
with self.subTest(value=value):
|
||||||
# This test assumes that the values don't map to RLIM_INFINITY,
|
|
||||||
# though Posix doesn't guarantee it.
|
|
||||||
self.assertNotEqual(value, resource.RLIM_INFINITY)
|
|
||||||
|
|
||||||
self.assertRaises(ValueError, resource.setrlimit, resource.RLIMIT_FSIZE, (value, max))
|
self.assertRaises(ValueError, resource.setrlimit, resource.RLIMIT_FSIZE, (value, max))
|
||||||
self.assertRaises(ValueError, resource.setrlimit, resource.RLIMIT_FSIZE, (cur, value))
|
self.assertRaises(ValueError, resource.setrlimit, resource.RLIMIT_FSIZE, (cur, value))
|
||||||
|
|
||||||
|
if resource.RLIM_INFINITY in (2**32-3, 2**32-1, 2**64-3, 2**64-1):
|
||||||
|
value = (resource.RLIM_INFINITY & 0xffff) - 0x10000
|
||||||
|
with self.assertWarnsRegex(DeprecationWarning, "RLIM_INFINITY"):
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (value, max))
|
||||||
|
with self.assertWarnsRegex(DeprecationWarning, "RLIM_INFINITY"):
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, value))
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(resource, "getrusage"), "needs getrusage")
|
@unittest.skipUnless(hasattr(resource, "getrusage"), "needs getrusage")
|
||||||
def test_getrusage(self):
|
def test_getrusage(self):
|
||||||
self.assertRaises(TypeError, resource.getrusage)
|
self.assertRaises(TypeError, resource.getrusage)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
:data:`resource.RLIM_INFINITY` is now always a positive integer larger than
|
||||||
|
any limited resource value. This simplifies comparison of the resource
|
||||||
|
values. Previously, it could be negative, such as -1 or -3, depending on
|
||||||
|
platform.
|
||||||
|
|
@ -164,7 +164,14 @@ py2rlim(PyObject *obj, rlim_t *out)
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (neg && (*out != RLIM_INFINITY || bytes > (Py_ssize_t)sizeof(*out))) {
|
else if (neg && *out == RLIM_INFINITY && bytes <= (Py_ssize_t)sizeof(*out)) {
|
||||||
|
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||||
|
"Use RLIM_INFINITY instead of negative limit value.", 1))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (neg) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Cannot convert negative int");
|
"Cannot convert negative int");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -210,9 +217,6 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
||||||
static PyObject*
|
static PyObject*
|
||||||
rlim2py(rlim_t value)
|
rlim2py(rlim_t value)
|
||||||
{
|
{
|
||||||
if (value == RLIM_INFINITY) {
|
|
||||||
return PyLong_FromNativeBytes(&value, sizeof(value), -1);
|
|
||||||
}
|
|
||||||
return PyLong_FromUnsignedNativeBytes(&value, sizeof(value), -1);
|
return PyLong_FromUnsignedNativeBytes(&value, sizeof(value), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue