Unable to revert tag changes with backup variable / save() does not apply changes to file
Hello,
I am attempting to update some tags on audio files and I use user input to validate / revert changes.
My issue is that .save() actually never saves the tags after I revert the tags to a backed up state, and ends up leaving my file without tags as I use .delete() to get a clean state and remove tags that I don't care about.
Here's my code (simplified, example using a FLAC file for file_path):
import copy
import mutagen
def get_new_file_metadata((file):
file.delete() # get rid of unwanted tags, e.g., cover art
# re assign all the tags to keep with updated values
album = file_path.split("/")[-2].split(". ")[1].split(" (")[0].split(" [")[0]
file.tags["ALBUM"] = album
def main (file_path):
file = mutagen.File(file_path)
old_tags = copy.deepcopy(file.tags)
print("===== Old tags ====")
print(old_tags.pprint())
print("=========")
get_new_file_metadata(file)
print("===== New tags ====")
print(file.tags.pprint())
print("=========")
user_validation = input('Confirm metadata change (Y/n): ').strip() or "Y"
if user_validation != "Y":
file.tags = old_tags
file.save()
If I validate the changes, then everything works great, but if I do not, the file ends up with all the tags erased.
The "file" variable itself seems to contain the metadata, and print(file.tags.pprint()) still works after file.tags = old_tags but file.save() does not.
I am using Python 3.12.3 and Mutagen 1.47.0
I suppose one workaround could be to specifcally look for every tag I do not want and .pop() them after user validation, but it is quite bothersome.
Anyway, let me know if it is actually a bug or if there's something wrong with my code
Cheers
The problem is that you are messing with the internal structure of the FLAC class. The tags property is not supposed to be set directly. When loading data from a FLAC it is an instance of VCFLACDict, which also is internally referenced in a list of loaded blocks to write back to the file.
When you call file.delete() both references are removed. When you do file.tags = something you only set those tags.
If file.tags is None you should instead run file.add_tags() and then fill the tags on the newly created file.tags (and not replace it).
Closing this as answered, see my answer above on how to properly handle the file.