https://github.com/python/cpython/commit/0324c726dea702282a0300225e989b19ae23b759
commit: 0324c726dea702282a0300225e989b19ae23b759
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-08-18T19:28:56+03:00
summary:
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.
files:
A Misc/NEWS.d/next/Library/2025-08-07-12-32-23.gh-issue-137044.abNoIy.rst
M Doc/library/resource.rst
M Doc/whatsnew/3.15.rst
M Lib/test/test_resource.py
M Modules/resource.c
diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst
index 0515d205bbca0b..0421b355056419 100644
--- a/Doc/library/resource.rst
+++ b/Doc/library/resource.rst
@@ -50,6 +50,11 @@ this module for those platforms.
.. data:: RLIM_INFINITY
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)
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index 81aa12184ed35c..eb073cae9be491 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -595,6 +595,12 @@ Porting to Python 3.15
The |pythoncapi_compat_project| can be used to get most of these new
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
-----------------
diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py
index fe05224828bd27..7391ce59da0ec4 100644
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -40,7 +40,10 @@ def test_fsize_ismax(self):
# 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
# an error.
+ self.assertGreater(resource.RLIM_INFINITY, 0)
self.assertEqual(resource.RLIM_INFINITY, max)
+ self.assertLessEqual(cur, max)
+ resource.setrlimit(resource.RLIMIT_FSIZE, (max, max))
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
@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))
def expected(cur):
- if resource.RLIM_INFINITY < 0:
- return [(cur, max), (resource.RLIM_INFINITY, max)]
- elif resource.RLIM_INFINITY < cur:
- return [(resource.RLIM_INFINITY, max)]
- else:
- return [(cur, max)]
+ return (min(cur, resource.RLIM_INFINITY), max)
resource.setrlimit(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:
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32, max))
except OverflowError:
- resource.setrlimit(resource.RLIMIT_FSIZE, (2**31, max))
- 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))
+ pass
else:
- self.assertIn(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))
+ self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE),
expected(2**32))
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:
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63, max))
except ValueError:
# There is a hard limit on macOS.
pass
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))
- 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",
"setting RLIMIT_FSIZE is not supported on VxWorks")
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires
resource.RLIMIT_FSIZE')
def test_fsize_negative(self):
+ self.assertGreater(resource.RLIM_INFINITY, 0)
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
for value in -5, -2**31, -2**32-5, -2**63, -2**64-5, -2**1000:
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, (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")
def test_getrusage(self):
self.assertRaises(TypeError, resource.getrusage)
diff --git
a/Misc/NEWS.d/next/Library/2025-08-07-12-32-23.gh-issue-137044.abNoIy.rst
b/Misc/NEWS.d/next/Library/2025-08-07-12-32-23.gh-issue-137044.abNoIy.rst
new file mode 100644
index 00000000000000..4bbf3075dfcafe
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-08-07-12-32-23.gh-issue-137044.abNoIy.rst
@@ -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.
diff --git a/Modules/resource.c b/Modules/resource.c
index 2353bc6653abd8..263730288c3dcf 100644
--- a/Modules/resource.c
+++ b/Modules/resource.c
@@ -164,7 +164,14 @@ py2rlim(PyObject *obj, rlim_t *out)
if (bytes < 0) {
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,
"Cannot convert negative int");
return -1;
@@ -210,9 +217,6 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out)
static PyObject*
rlim2py(rlim_t value)
{
- if (value == RLIM_INFINITY) {
- return PyLong_FromNativeBytes(&value, sizeof(value), -1);
- }
return PyLong_FromUnsignedNativeBytes(&value, sizeof(value), -1);
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]