Repository navigation
Wave_write throws an error if a setter to an written header information is set to the same value #132445
Description
Activity
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?
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.
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/exceptaround 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.
Look at this as an implementation of the Builder pattern. Before any data has been written, the Wave_write object is still in the stage of building. open() + set*() methods is a constructor.
If we did it now, it would be better to use more traditional idioms -- either pass framerate, nchannels, etc, as keyword arguments to constructor, or have a separate Builder or Factory class which allow to set parameters and then produce completely initialized Wave_write object. But what's done is done.
Consider a newly opened Wave_write object as partially initialized. All set*() methods should be called by the code that calls open(). The function that takes the Wave_write object should not call set*() methods.
The wave module is legacy. Its sister modules for other formats have been removed. We are not planning to add new features or new interface.
The constructor-phase behavior is by design, and wave is a legacy module which does not get new features. Closing as not planned.
Feature or enhancement
Proposal:
The
Wave_writeclass 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.
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response
Linked PRs