Skip to content

wave: handle short payload writes before advancing Wave_write frame position #158769

Description

@augusto-rehfeldt

Bug report

Bug description:

Documented behaviour: The wave documentation for Wave_write.tell() says: "Return current position in the file, with the same disclaimer for Wave_read.tell()." Wave_read.tell() specifies: "Return current file pointer position, in audio frames."

Expected: tell() returns 2 for the two complete audio frames actually written, or writeframesraw() completes the remaining writes before reporting 4.

Actual: tell() returns 4 although only 2 audio frames were written.

import io
import wave

class ShortWrite(io.BytesIO):
    def write(self, data):
        return super().write(data[:2] if self.tell() == 44 else data)

case = dict(channels=1, sample_width=1, rate=8000,
            data=b'\x00\x01\x02\x03', accepted_frames=2)
try:
    frame_size = case["channels"] * case["sample_width"]
    if not (case["channels"] > 0 and 1 <= case["sample_width"] <= 4
            and case["rate"] > 0 and len(case["data"]) % frame_size == 0):
        raise ValueError("invalid PCM input")
    stream = ShortWrite()
    if not stream.seekable():
        raise ValueError("stream is not seekable")
    writer = wave.open(stream, "wb")
    writer.setparams((1, 1, 8000, 0, "NONE", "not compressed"))
    writer.writeframesraw(case["data"])
    actual = writer.tell()
    raw = stream.getvalue()
    if raw[:4] != b"RIFF" or raw[8:12] != b"WAVE" or raw[36:40] != b"data":
        raise ValueError("header was not written completely")
    expected = len(raw[44:]) // frame_size
    writer.close()
    if actual != expected:
        print("REFUTATION CONFIRMED:", case, "actual:", actual, "expected:", expected)
    else:
        print("REFUTATION REJECTED:", "tell() matches actual complete frames")
except Exception as exc:
    print("REFUTATION REJECTED:", str(exc))

Output on Python 3.14.6 (Windows-11-10.0.26220-SP0), standard library wave:

REFUTATION CONFIRMED: {'channels': 1, 'sample_width': 1, 'rate': 8000, 'data': b'\x00\x01\x02\x03', 'accepted_frames': 2} actual: 4 expected: 2

This report was found and written by an automated property-testing tool I run (bugforge). The reproducer above was executed and its output is pasted unedited; no person reviewed the report before it was filed. The search script is in https://github.com/augusto-rehfeldt/bugforge-results/tree/main/wave-20261003-111327-c2

CPython versions tested on:

3.14

Operating systems tested on:

Windows

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions