Proposal: add a `PyByteArray_ResizeExact` function

I saw that bytearray has an API function, PyByteArray_Resize, which lets you resize the underlying buffer, but it overallocates. There’s no way to resize the buffer to a specific size without overallocation in the current API, so I added an API function, PyByteArray_ResizeExact, which can do this. I also replaced some PyByteArray_Resize calls with PyByteArray_ResizeExact calls in bytearray_clear_impl and in some places in bytearray___init___impl since resizing to or from size 0 should be an exact resize anyways.

Can you explain in what (real-world) use case you care about the over-allocation? We use the same strategy for lists and I don’t think anyone has a problem with it.

I saw that the fastest way to zero a bytearray is by calling its __init__ method. But you aren’t supposed to directly call __init__, so I was thinking about making a method which does the same thing as calling the __init__ method with an int argument. Then I noticed that you can’t really use PyByteArray_Resize for that since it might overallocate, so I made this function as a way to avoid that happening.
I was thinking about this because the latest comment under this stackoverflow answer said it’s not uncommon to need to quickly zero memory.
https://stackoverflow.com/a/36653960/15101476

I don’t think I see the issue? The structure tracks internally how much of the allocated space is actually “used”.

It’s because I was thinking it would be better if it had exactly the same end result as __init__, and if it overallocates then the end result is different.

It looks like a simple oversight. If size is 0, PyByteArray_Resize() does not free all memory. It allocates a new 1-byte array, or even larger if there were deletions from the left.

The newly created bytearray object has no underlying memory buffer, so it is safe.

No new API is needed, we can just tweak the allocation strategy yet a bit.