It sounds to me like the Python buffer protocol is under-specified, which can lead to data races in native code.
Here's an example of how this could occur without Rust being involved:
- Two python threads with a shared buffer object
- One thread instructs a C extension to write into the buffer
- The other thread instructs a C extension to read from the buffer
- The buffer is implemented to return the same pointer for reads and writes (not forbidden by the spec https://docs.python.org/3/c-api/buffer.html#buffer-request-t...)
- The C extension releases the GIL while accessing the buffer (explicitly allowed by the spec)
In this case, the C extension is reading and writing to the same buffer at the same time without the use of atomics, which is the definition of a data race, and therefore triggers UB.
IMO, the best fix would be for the buffer implementation to expose a "concurrency mode", and require that users of the buffer API use the concurrency mode specified by the buffer when accessing it. In one mode, no synchronization is necessary because the buffer only ever hands out one writable pointer or multiple readable pointers but never both. In another mode, you might be required to have the GIL, in another mode there might be a buffer-specific RWLock you have to hold while accessing it.