FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-137044: Make resource.RLIM_INFINITY always positive by serhiy-storchaka · Pull Request #137511 · python/cpython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .py  (1) .rst  (3) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
5 changes: 5 additions & 0 deletions Doc/library/resource.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.15.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,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
-----------------
Expand Down
44 changes: 22 additions & 22 deletions Lib/test/test_resource.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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)
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -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.
Comment on lines +1 to +4

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I don't think we test/guarantee that RLIM_INFINITY is bigger than limited values. AFAIK, POSIX would have no problem with RLIM_INFINITY being zero.
So, this should be:

Suggested change
: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.
:data:`resource.RLIM_INFINITY` is now always a positive integer.
Previously, it could be negative, such as -1 or -3, depending on
platform.

or:

Suggested change
: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.
:data:`resource.RLIM_INFINITY` is now always a positive integer.
On supported platforms, it is larger than any limited resource value,
which simplifies comparison of the resource values.
Previously, it could be negative, such as -1 or -3, depending on
platform.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrlimit.html

The value RLIM_INFINITY, defined in <sys/resource.h>, shall be considered to be larger than any other limit value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

To be clear, I do not think this should have been merged without this change.

12 changes: 8 additions & 4 deletions Modules/resource.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down

Back | FazBrowse Home | New Git URL