diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index ea75c8b2b98924..fb5f9b8be160b6 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -50,11 +50,6 @@ 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. .. data:: RLIM_SAVED_CUR diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 43c40e4d0f3154..b5a480b5514f77 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -604,12 +604,6 @@ 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 f73914b9b92c83..8e48563cf43555 100644 --- a/Lib/test/test_resource.py +++ b/Lib/test/test_resource.py @@ -40,10 +40,7 @@ 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", @@ -116,53 +113,56 @@ def test_fsize_not_too_big(self): self.addCleanup(resource.setrlimit, resource.RLIMIT_FSIZE, (cur, max)) def expected(cur): - return (min(cur, resource.RLIM_INFINITY), max) + 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)] 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: - pass + 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)) else: - self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32)) + 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)) resource.setrlimit(resource.RLIMIT_FSIZE, (2**63-5, max)) - self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63-5)) + self.assertIn(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.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63)) + self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63)) resource.setrlimit(resource.RLIMIT_FSIZE, (2**64-5, max)) - self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**64-5)) + self.assertIn(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 deleted file mode 100644 index 4bbf3075dfcafe..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-08-07-12-32-23.gh-issue-137044.abNoIy.rst +++ /dev/null @@ -1,4 +0,0 @@ -: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 a463355f424d48..0ffa950a6bfb75 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -164,14 +164,7 @@ py2rlim(PyObject *obj, rlim_t *out) if (bytes < 0) { return -1; } - 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) { + else if (neg && (*out != RLIM_INFINITY || bytes > (Py_ssize_t)sizeof(*out))) { PyErr_SetString(PyExc_ValueError, "Cannot convert negative int"); return -1; @@ -217,6 +210,9 @@ 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); }