#!/usr/bin/python3 from __future__ import annotations from tinytag import TinyTag, UnsupportedFormatError if False: # just stole this lazy import type hinting trick from tinytag from collections.abc import Callable, Iterator # noqa from typing import Any, BinaryIO, Dict, List class SmallTag(TinyTag): @classmethod def _get_parser_class( cls, filename: str | None = None, filehandle: BinaryIO | None = None ) -> type[SmallTag]: if cls != SmallTag: return cls if filename: parser_class = cls._get_parser_for_filename(filename) if parser_class is not None: return parser_class # try determining the file type by magic byte header if filehandle: parser_class = cls._get_parser_for_file_handle(filehandle) if parser_class is not None: return parser_class raise UnsupportedFormatError( 'No tag reader found to support file type') def write(self, file_obj: BinaryIO = None): raise NotImplementedError def _set_filehandler_for_writing(self, file_obj: BinaryIO) -> bool: should_close_file = file_obj is None and not self._filehandler.writable() if self.filename is None and should_close_file: raise ValueError( "You must specify a new file object that is in write mode. " "(Has to be from the same file as specified while creating this TinyTag instance.)" ) if file_obj is not None and not self._filehandler.closed(): self._filehandler.close() if file_obj is not None: self._filehandler = file_obj else: self._filehandler = open(self.filename, "rb+") return should_close_file # import formats after SmallTag definition to avoid circular imports # (this solution is stupid, but I don't know anything better.) from ._formats import _ID3 # noqa SmallTag._file_extension_mapping = { ('.mp1', '.mp2', '.mp3'): _ID3, # ('.oga', '.ogg', '.opus', '.spx'): _Ogg, (Not yet implemented.) # ('.wav',): _Wave, # ('.flac',): _Flac, # ('.wma',): _Wma, # ('.m4b', '.m4a', '.m4r', '.m4v', '.mp4', # '.aax', '.aaxc'): _MP4, # ('.aiff', '.aifc', '.aif', '.afc'): _Aiff, }