Skip to content

Commit e5b2421

Browse files
getzzesbraz
authored andcommitted
QA: correct linter and type errors
This makes MediaInfo.`parse`'s optional arguments positional-only to avoid https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt.
1 parent bf780d1 commit e5b2421

File tree

4 files changed

+149
-109
lines changed

4 files changed

+149
-109
lines changed

src/pymediainfo/__init__.py

+81-41
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
# vim: set fileencoding=utf-8 :
21
"""
32
This module is a wrapper around the MediaInfo library.
43
"""
4+
5+
from __future__ import annotations
6+
57
import ctypes
68
import json
79
import os
@@ -10,12 +12,8 @@
1012
import sys
1113
import warnings
1214
import xml.etree.ElementTree as ET
13-
from typing import Any, Dict, List, Optional, Tuple, Union
14-
15-
try:
16-
from importlib import metadata
17-
except ImportError:
18-
import importlib_metadata as metadata # type: ignore
15+
from importlib import metadata
16+
from typing import Any, overload
1917

2018
try:
2119
__version__ = metadata.version("pymediainfo")
@@ -50,23 +48,25 @@ class Track:
5048
All available attributes can be obtained by calling :func:`to_data`.
5149
"""
5250

53-
def __eq__(self, other): # type: ignore
51+
def __eq__(self, other: object) -> bool:
52+
if not isinstance(other, Track):
53+
return False
5454
return self.__dict__ == other.__dict__
5555

56-
def __getattribute__(self, name): # type: ignore
56+
def __getattribute__(self, name: str) -> Any:
5757
try:
5858
return object.__getattribute__(self, name)
5959
except AttributeError:
6060
pass
6161
return None
6262

63-
def __getstate__(self): # type: ignore
63+
def __getstate__(self) -> dict[str, Any]:
6464
return self.__dict__
6565

66-
def __setstate__(self, state): # type: ignore
66+
def __setstate__(self, state: dict[str, Any]) -> None:
6767
self.__dict__ = state
6868

69-
def __init__(self, xml_dom_fragment: ET.Element):
69+
def __init__(self, xml_dom_fragment: ET.Element) -> None:
7070
self.track_type = xml_dom_fragment.attrib["type"]
7171
repeated_attributes = []
7272
for elem in xml_dom_fragment:
@@ -104,10 +104,10 @@ def __init__(self, xml_dom_fragment: ET.Element):
104104
except ValueError:
105105
pass
106106

107-
def __repr__(self): # type: ignore
107+
def __repr__(self) -> str:
108108
return "<Track track_id='{}', track_type='{}'>".format(self.track_id, self.track_type)
109109

110-
def to_data(self) -> Dict[str, Any]:
110+
def to_data(self) -> dict[str, Any]:
111111
"""
112112
Returns a dict representation of the track attributes.
113113
@@ -157,10 +157,12 @@ class MediaInfo:
157157
<Track track_id='1', track_type='Text'>
158158
"""
159159

160-
def __eq__(self, other): # type: ignore
160+
def __eq__(self, other: object) -> bool:
161+
if not isinstance(other, MediaInfo):
162+
return False
161163
return self.tracks == other.tracks
162164

163-
def __init__(self, xml: str, encoding_errors: str = "strict"):
165+
def __init__(self, xml: str, encoding_errors: str = "strict") -> None:
164166
xml_dom = ET.fromstring(xml.encode("utf-8", encoding_errors))
165167
self.tracks = []
166168
# This is the case for libmediainfo < 18.03
@@ -173,59 +175,59 @@ def __init__(self, xml: str, encoding_errors: str = "strict"):
173175
for xml_track in xml_dom.iterfind(xpath):
174176
self.tracks.append(Track(xml_track))
175177

176-
def _tracks(self, track_type: str) -> List[Track]:
178+
def _tracks(self, track_type: str) -> list[Track]:
177179
return [track for track in self.tracks if track.track_type == track_type]
178180

179181
@property
180-
def general_tracks(self) -> List[Track]:
182+
def general_tracks(self) -> list[Track]:
181183
"""
182184
:return: All :class:`Track`\\s of type ``General``.
183185
:rtype: list of :class:`Track`\\s
184186
"""
185187
return self._tracks("General")
186188

187189
@property
188-
def video_tracks(self) -> List[Track]:
190+
def video_tracks(self) -> list[Track]:
189191
"""
190192
:return: All :class:`Track`\\s of type ``Video``.
191193
:rtype: list of :class:`Track`\\s
192194
"""
193195
return self._tracks("Video")
194196

195197
@property
196-
def audio_tracks(self) -> List[Track]:
198+
def audio_tracks(self) -> list[Track]:
197199
"""
198200
:return: All :class:`Track`\\s of type ``Audio``.
199201
:rtype: list of :class:`Track`\\s
200202
"""
201203
return self._tracks("Audio")
202204

203205
@property
204-
def text_tracks(self) -> List[Track]:
206+
def text_tracks(self) -> list[Track]:
205207
"""
206208
:return: All :class:`Track`\\s of type ``Text``.
207209
:rtype: list of :class:`Track`\\s
208210
"""
209211
return self._tracks("Text")
210212

211213
@property
212-
def other_tracks(self) -> List[Track]:
214+
def other_tracks(self) -> list[Track]:
213215
"""
214216
:return: All :class:`Track`\\s of type ``Other``.
215217
:rtype: list of :class:`Track`\\s
216218
"""
217219
return self._tracks("Other")
218220

219221
@property
220-
def image_tracks(self) -> List[Track]:
222+
def image_tracks(self) -> list[Track]:
221223
"""
222224
:return: All :class:`Track`\\s of type ``Image``.
223225
:rtype: list of :class:`Track`\\s
224226
"""
225227
return self._tracks("Image")
226228

227229
@property
228-
def menu_tracks(self) -> List[Track]:
230+
def menu_tracks(self) -> list[Track]:
229231
"""
230232
:return: All :class:`Track`\\s of type ``Menu``.
231233
:rtype: list of :class:`Track`\\s
@@ -277,8 +279,8 @@ def _define_library_prototypes(cls, lib: Any) -> Any:
277279
lib.MediaInfo_Close.restype = None
278280

279281
@staticmethod
280-
def _get_library_paths(os_is_nt: bool) -> Tuple[str, ...]:
281-
library_paths: Tuple[str, ...]
282+
def _get_library_paths(os_is_nt: bool) -> tuple[str, ...]:
283+
library_paths: tuple[str, ...]
282284
if os_is_nt:
283285
library_paths = ("MediaInfo.dll",)
284286
elif sys.platform == "darwin":
@@ -298,13 +300,10 @@ def _get_library_paths(os_is_nt: bool) -> Tuple[str, ...]:
298300
@classmethod
299301
def _get_library(
300302
cls,
301-
library_file: Optional[str] = None,
302-
) -> Tuple[Any, Any, str, Tuple[int, ...]]:
303+
library_file: str | None = None,
304+
) -> tuple[Any, Any, str, tuple[int, ...]]:
303305
os_is_nt = os.name in ("nt", "dos", "os2", "ce")
304-
if os_is_nt:
305-
lib_type = ctypes.WinDLL # type: ignore
306-
else:
307-
lib_type = ctypes.CDLL
306+
lib_type = ctypes.WinDLL if os_is_nt else ctypes.CDLL # type: ignore[attr-defined]
308307
if library_file is None:
309308
library_paths = cls._get_library_paths(os_is_nt)
310309
else:
@@ -334,7 +333,7 @@ def _get_library(
334333
)
335334

336335
@classmethod
337-
def can_parse(cls, library_file: Optional[str] = None) -> bool:
336+
def can_parse(cls, library_file: str | None = None) -> bool:
338337
"""
339338
Checks whether media files can be analyzed using libmediainfo.
340339
@@ -350,22 +349,63 @@ def can_parse(cls, library_file: Optional[str] = None) -> bool:
350349
except Exception: # pylint: disable=broad-except
351350
return False
352351

352+
# The method may be called with output=<str>, in which case it returns a str
353+
@overload
354+
@classmethod
355+
def parse(
356+
# pylint: disable=too-many-arguments, too-many-locals
357+
# pylint: disable=too-many-branches, too-many-statements
358+
cls,
359+
filename: Any,
360+
*,
361+
library_file: str | None = None,
362+
cover_data: bool = False,
363+
encoding_errors: str = "strict",
364+
parse_speed: float = 0.5,
365+
full: bool = True,
366+
legacy_stream_display: bool = False,
367+
mediainfo_options: dict[str, str] | None = None,
368+
output: str,
369+
buffer_size: int | None = 64 * 1024,
370+
) -> str: ...
371+
372+
# Or it may be called with output=None, in which case it returns a MediaInfo object
373+
@overload
374+
@classmethod
375+
def parse(
376+
# pylint: disable=too-many-arguments, too-many-locals
377+
# pylint: disable=too-many-branches, too-many-statements
378+
cls,
379+
filename: Any,
380+
*,
381+
library_file: str | None = None,
382+
cover_data: bool = False,
383+
encoding_errors: str = "strict",
384+
parse_speed: float = 0.5,
385+
full: bool = True,
386+
legacy_stream_display: bool = False,
387+
mediainfo_options: dict[str, str] | None = None,
388+
output: None = None,
389+
buffer_size: int | None = 64 * 1024,
390+
) -> MediaInfo: ...
391+
353392
@classmethod
354393
def parse(
355-
# pylint: disable=too-many-statements
356-
# pylint: disable=too-many-branches, too-many-locals, too-many-arguments
394+
# pylint: disable=too-many-arguments, too-many-locals
395+
# pylint: disable=too-many-branches, too-many-statements
357396
cls,
358397
filename: Any,
359-
library_file: Optional[str] = None,
398+
*,
399+
library_file: str | None = None,
360400
cover_data: bool = False,
361401
encoding_errors: str = "strict",
362402
parse_speed: float = 0.5,
363403
full: bool = True,
364404
legacy_stream_display: bool = False,
365-
mediainfo_options: Optional[Dict[str, str]] = None,
366-
output: Optional[str] = None,
367-
buffer_size: Optional[int] = 64 * 1024,
368-
) -> Union[str, "MediaInfo"]:
405+
mediainfo_options: dict[str, str] | None = None,
406+
output: str | None = None,
407+
buffer_size: int | None = 64 * 1024,
408+
) -> MediaInfo | str:
369409
"""
370410
Analyze a media file using libmediainfo.
371411
@@ -515,7 +555,7 @@ def parse(
515555
return cls(info, encoding_errors)
516556
return info
517557

518-
def to_data(self) -> Dict[str, Any]:
558+
def to_data(self) -> dict[str, Any]:
519559
"""
520560
Returns a dict representation of the object's :py:class:`Tracks <Track>`.
521561

src/pymediainfo/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)