Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions mediafile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@
import os
import re

import mutagen
import mutagen.mp3
from mutagen._file import File as MutagenFileFactory
from mutagen.mp3 import BitrateMode

from ._types import MutagenFile
from .constants import TYPES, ImageType
from .exceptions import FileTypeError, MutagenError, UnreadableFileError
from .fields import (
BaseMediaField,
CoverArtField,
DateField,
DateItemField,
Expand Down Expand Up @@ -92,6 +94,8 @@ class MediaFile:
metadata.
"""

mgfile: MutagenFile

@loadfile()
def __init__(self, filething, id3v23=False):
"""Constructs a new `MediaFile` reflecting the provided file.
Expand All @@ -106,7 +110,7 @@ def __init__(self, filething, id3v23=False):
"""
self.filething = filething

self.mgfile = mutagen_call("open", self.filename, mutagen.File, filething)
self.mgfile = mutagen_call("open", self.filename, MutagenFileFactory, filething)

if self.mgfile is None:
# Mutagen couldn't guess the type
Expand Down Expand Up @@ -230,7 +234,7 @@ def fields(cls):
:class:`MediaField`).
"""
for property, descriptor in cls.__dict__.items():
if isinstance(descriptor, MediaField):
if isinstance(descriptor, BaseMediaField):
if isinstance(property, bytes):
# On Python 2, class field names are bytes. This method
# produces text strings.
Expand Down Expand Up @@ -870,9 +874,9 @@ def bitrate_mode(self):
"""
if hasattr(self.mgfile.info, "bitrate_mode"):
return {
mutagen.mp3.BitrateMode.CBR: "CBR",
mutagen.mp3.BitrateMode.VBR: "VBR",
mutagen.mp3.BitrateMode.ABR: "ABR",
BitrateMode.CBR: "CBR",
BitrateMode.VBR: "VBR",
BitrateMode.ABR: "ABR",
}.get(self.mgfile.info.bitrate_mode, "")
else:
return ""
Expand Down
10 changes: 10 additions & 0 deletions mediafile/_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Type definitions for MediaFile."""

from typing import Any, TypeAlias

# It is close to impossible to type the Mutagen File
# correctly due to Mutagen's dynamic typing. We might be able
# to create a Protocol that defines the minimum interface
# MediaFile needs, using an alias here should allow us to migrate
# to a more precise type later.
MutagenFile: TypeAlias = Any
16 changes: 16 additions & 0 deletions mediafile/constants.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import enum
from typing import TypeVar, cast

T = TypeVar("T")

# Human-readable type names.
TYPES = {
Expand Down Expand Up @@ -42,3 +45,16 @@ class ImageType(enum.Enum):
illustration = 18
artist_logo = 19
publisher_logo = 20


NULL_VALUES = {
int: 0,
bool: False,
str: "",
float: 0.0,
}


def null_value(out_type: type[T]) -> T | None:
"""Get an appropriate "null" value for the given type."""
return cast(T, NULL_VALUES.get(out_type))
Loading