★ wanayoo — archive 1999 https://github.com/python/cpython/pull/12718Nouvelle recherche | Portail wanayoo
Skip to content

bpo-36551: Optimize list comprehensions with preallocate size and protect against overflow #12718

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

Closed
wants to merge 12 commits into from

Conversation

tonybaloney
Copy link
Contributor

@tonybaloney tonybaloney commented Apr 8, 2019

Py_ssize_t size = PyObject_LengthHint(target, 2);
Py_DECREF(target);
if (size < 0)
goto error;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMHO this should raise a ValueError or something other than OverflowError with an error message for an average Python user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have raised that separately in #12720 as it's out-of-scope for this change and impact other things

@pganssle
Copy link
Member

pganssle commented Apr 8, 2019

If you are adding a new error condition, I think you should also try to add a test for it. Assuming the OverflowError condition fails early, can you test something like:

with self.assertRaises(OverflowError):
    a = [x for x in range(2**256)]

Ideally you'd come up with something a bit more clever since the failure mode of that one is apparently that the process consumes all available memory and then crashes, but I can't think of any at the moment.

tonybaloney and others added 2 commits April 9, 2019 15:31
Replace LengthHint for HasLen and Object_Length
@@ -123,6 +123,13 @@
>>> test_func()
[2, 2, 2, 2, 2]

Verify that an overflow error is raised for listcomps with very-large iterators

>>> [y for y in range(2**256)] # doctest: +IGNORE_EXCEPTION_DETAIL
Copy link
Member

Choose a reason for hiding this comment

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

It's really weird to me that this module is tested entirely with doctests (though I know that's not part of this PR).

@@ -215,6 +215,12 @@ list_new_prealloc(Py_ssize_t size)
return (PyObject *) op;
}

PyObject *
_PyList_NewPrealloc(Py_ssize_t size)
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of adding a new function _PyList_NewPrealloc with identical functionality as list_new_prealloc, why not just rename list_new_prealloc to _PyList_NewPrealloc?

@jdemeyer
Copy link
Contributor

What happens if the __length_hint__ is not exact (returns a value which is too small or too large)? What if it returns a value which is way too large (such that allocation would fail)? These conditions should be tested.

@tonybaloney
Copy link
Contributor Author

Issue was rejected, closing PR

@tonybaloney tonybaloney closed this May 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants