Skip to content

Wave_write throws an error if a setter to an written header information is set to the same value #132445

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

Open
ygerlach opened this issue Apr 12, 2025 · 3 comments
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@ygerlach
Copy link

ygerlach commented Apr 12, 2025

Feature or enhancement

Proposal:

The Wave_write class does not allow to "reset" the same value. This makes some implementations quite complicated, as if you want to continuously append data to the wav file, you need to differentiate between first and the other writes.
Libraries, that use this class (for example piper-tts) are sometimes making it hard to do this right. Which is probably a bug in those libraries, but i think python should make it easier for them to not make this mistake.

import wave

with wave.open(open('out.wav', 'wb'), 'w') as w:
	w.setframerate(44100)
	w.setnchannels(1)
	w.setsampwidth(1)
	w.writeframes(b'0' * 44100)

	w.setframerate(44100)  # should not fail
	w.setnchannels(1)  # should not fail
	w.setsampwidth(1)  # should not fail

	w.setframerate(22050)  # should still fail
	w.setnchannels(2)  # should still fail
	w.setsampwidth(2)  # should still fail

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

@ygerlach ygerlach added the type-feature A feature request or enhancement label Apr 12, 2025
@picnixz picnixz added the stdlib Python modules in the Lib dir label Apr 12, 2025
@picnixz
Copy link
Member

picnixz commented Apr 12, 2025

I think we can make it a no-op if we use the same value, but I'm not familiar with this module. Checking for whether something can be silently ignored or not requires to call the getters whenever we call the setters. I don't think it'll become slower by much but, ideally, I'd think it's more of an API misuse.

That being said, it's also better if we don't make existing librairies unsable (piper-tts seems to have 30k downloads per month, not necessarily much but still noticable I'd say). Since the module is also quite niche on our side, I think we can do this kind of work on our side.

@serhiy-storchaka any thoughts on this one?

@serhiy-storchaka
Copy link
Member

I do not think that this is a common case. Setters should be called after opening a file and before writing any data. If setter fails with some values and successes with other value, this can lead to bugs, when the code was tested with same values, but users use different values.

ygerlach added a commit to ygerlach/cpython that referenced this issue Apr 23, 2025
@ygerlach
Copy link
Author

ygerlach commented Apr 23, 2025

If setter fails with some values and successes with other value, this can lead to bugs

We already have this case. Imagine a function that writes wave frames to a wave object, after setting its parameters.

  • We pass a newly opened wave object: everything is fine
  • We pass another wave object (that - god forbid - was already written too) - we get an exception, despite calling it with the same values.
  • Even worse: we pass the same wave object multiple times: it works great the first time and raises an exception every other time. And that is exactly the problem / bug i ran into. Sure it is not that hard to throw a try/except around every one of your setters, but it is ugly and easy to miss something (like forgetting to check the getters for the correct values if it fails). See here, where i did that, to work around this "feature". A simple one line setter call grows into an ugly 5 line abomination.

requires to call the getters whenever we call the setters

That is not possible for all the getters in their current state, as they may also raise an Error. Also some values do not have a getter. That's why i opted to use those member variables directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants