Change strategy for memory allocation and resizing in frame functions
Change strategy for memory allocation and resizing in frame functions

Previously the strategy was:

  - Create a Python Bytes or ByteArray object using the relevant
    _FromStringAndSize func
  - Get a pointer to the underlying storage
  - Populate the underlying storage by calls to the LZ4F_* API
  - Once done, resize the object if it was less than 75% used,
    otherwise call Py_SIZE on the object to set the size without
    resizing the underlying storage

This had several problems:

  - If the LZ4F_* functions didn't write any bytes to the storage,
    it could remain unitialized. This causes a problem for the
    empty bytes object (b''), for which the Python interpreter
    expects the first byte to be '\0'. As a result, comparing an
    uninitialized 0 size bytes object with a normal b'' returned
    False, rather than True.
  - Calling Py_SIZE on a bytearray or bytes object is not documented
    functionality, and could break.
  - In any case we weren't placing a terminal '\0' at the end of the
    object storage, which could cause bugs down the line. The correct
    but undocumented way to use Py_SIZE on these objects would be to
    call Py_SIZE(object) = N, and set object.buf[N+1]='\0'. This is
    still undocumented and unsupported.
  - We were using _PyBytes_Resize, which is also not part of the
    public API

So, instead we adopt a simpler strategy:

 - Use a normal C buffer during the calls to the LZ4 API
 - Once we're ready to return a Python object, create it with
   PyBytes_FromStringAndSize or PyByteArray_FromStringAndSize. This
   makes a copy of the normal C buffer with the right size, and adds
   the terminal '\0'.
 - This does mean one extra memory copy of the storage buffer and so
   will impact performance slightly.
 - However, one advantage is that in the (common) case of the buffer
   size being 0, rather than returning objects with a single char ('\0'),
   a pointer to a singleton empty object will be returned, saving memory.

python-lz4/python-lz4,python-lz4/python-lz4