Hello community,

here is the log from the commit of package python-pymediainfo for 
openSUSE:Factory checked in at 2019-04-23 14:36:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pymediainfo (Old)
 and      /work/SRC/openSUSE:Factory/.python-pymediainfo.new.5536 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pymediainfo"

Tue Apr 23 14:36:10 2019 rev:4 rq:696774 version:4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pymediainfo/python-pymediainfo.changes    
2018-09-13 12:14:06.514118215 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pymediainfo.new.5536/python-pymediainfo.changes
  2019-04-23 14:36:13.533479678 +0200
@@ -1,0 +2,29 @@
+Mon Apr 22 13:56:26 UTC 2019 - Luigi Baldoni <[email protected]>
+
+- Update to version 4.0
+  * Drop Python 2.6 compatibility
+  * Allow pickling of Track instances (#68)
+  * Remove xml attributes from Track and MediaInfo objects,
+    populate the tracks attribute immediately (03f6242)
+  * Implement __eq__ forTrack and MediaInfo objects
+  * Add an option to obtain MediaInfo's text output (#66)
+  * Add an option to return non-complete MediaInfo (#66)
+  * Disable LegacyStreamDisplay explicitly by default, make it
+    configurable (see 9aa65d8 for details)
+  version 3.2.1:
+  * Generate sdists on Linux instead of OSX (#67)
+  version 3.2:
+  * Publish wheels containing libmediainfo (#59, thanks to
+    @bgermann)
+  version 3.1:
+  * Add an option to control parsing speed (#65)
+  version 3.0:
+  * Do not ignore exceptions when invalid XML is passed (#53)
+  * Raise RuntimeError if parsing fails
+  * Add an option to ignore UTF-8 encoding errors, fixes (#54)
+  * Use proper XPath to detect track elements in XML (#55)
+  * Fix handling of non-existent files
+  * Fix tests with libmediainfo ≥ 18.08 (#58)
+  * Try to load libmediainfo from the module folder
+
+-------------------------------------------------------------------

Old:
----
  pymediainfo-2.3.0.tar.gz

New:
----
  pymediainfo-4.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pymediainfo.spec ++++++
--- /var/tmp/diff_new_pack.dXqGpK/_old  2019-04-23 14:36:14.057480027 +0200
+++ /var/tmp/diff_new_pack.dXqGpK/_new  2019-04-23 14:36:14.061480030 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pymediainfo
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,13 +12,13 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-pymediainfo
-Version:        2.3.0
+Version:        4.0
 Release:        0
 Summary:        Python wrapper for the mediainfo library
 License:        MIT

++++++ pymediainfo-2.3.0.tar.gz -> pymediainfo-4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/PKG-INFO 
new/pymediainfo-4.0/PKG-INFO
--- old/pymediainfo-2.3.0/PKG-INFO      2018-05-14 16:15:37.000000000 +0200
+++ new/pymediainfo-4.0/PKG-INFO        2019-04-04 17:46:38.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pymediainfo
-Version: 2.3.0
+Version: 4.0
 Summary: A Python wrapper for the mediainfo library.
 Home-page: https://github.com/sbraz/pymediainfo
 Author: Louis Sautier
@@ -15,6 +15,9 @@
         .. image:: https://img.shields.io/pypi/pyversions/pymediainfo.svg
           :target: https://pypi.org/project/pymediainfo
         
+        .. image:: https://repology.org/badge/tiny-repos/python:pymediainfo.svg
+          :target: https://repology.org/metapackage/python:pymediainfo
+        
         .. image:: https://img.shields.io/pypi/implementation/pymediainfo.svg
           :target: https://pypi.org/project/pymediainfo
         
@@ -27,17 +30,17 @@
         
         This small package is a wrapper around the MediaInfo library.
         
-        It works on Linux, Mac OS X and Windows and is tested with Python 2.6, 
2.7, 3.4, 3.5, 3.6, PyPy and PyPy3.
+        It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 
3.4, 3.5, 3.6, 3.7, PyPy and PyPy3.
         
         See https://pymediainfo.readthedocs.io/ for more information.
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Operating System :: POSIX :: Linux
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/README.rst 
new/pymediainfo-4.0/README.rst
--- old/pymediainfo-2.3.0/README.rst    2018-05-14 16:15:08.000000000 +0200
+++ new/pymediainfo-4.0/README.rst      2019-04-04 17:46:33.000000000 +0200
@@ -7,6 +7,9 @@
 .. image:: https://img.shields.io/pypi/pyversions/pymediainfo.svg
   :target: https://pypi.org/project/pymediainfo
 
+.. image:: https://repology.org/badge/tiny-repos/python:pymediainfo.svg
+  :target: https://repology.org/metapackage/python:pymediainfo
+
 .. image:: https://img.shields.io/pypi/implementation/pymediainfo.svg
   :target: https://pypi.org/project/pymediainfo
 
@@ -19,6 +22,6 @@
 
 This small package is a wrapper around the MediaInfo library.
 
-It works on Linux, Mac OS X and Windows and is tested with Python 2.6, 2.7, 
3.4, 3.5, 3.6, PyPy and PyPy3.
+It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 3.4, 
3.5, 3.6, 3.7, PyPy and PyPy3.
 
 See https://pymediainfo.readthedocs.io/ for more information.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/appveyor.yml 
new/pymediainfo-4.0/appveyor.yml
--- old/pymediainfo-2.3.0/appveyor.yml  2018-05-14 16:15:08.000000000 +0200
+++ new/pymediainfo-4.0/appveyor.yml    2019-04-04 17:46:33.000000000 +0200
@@ -1,26 +1,32 @@
 environment:
+  MEDIAINFO_VERSION: 18.12
+  TWINE_PASSWORD:
+    secure: /EO8CxTxhQVNsGNZZvU51jjHwPW524rgddNlwOAyLoA=
   matrix:
     - PYTHON: "C:/Python27"
     - PYTHON: "C:/Python34"
     - PYTHON: "C:/Python35"
     - PYTHON: "C:/Python36"
+    - PYTHON: "C:/Python37"
     - PYTHON: "C:/Python27-x64"
     - PYTHON: "C:/Python34-x64"
     - PYTHON: "C:/Python35-x64"
     - PYTHON: "C:/Python36-x64"
+    - PYTHON: "C:/Python37-x64"
 install:
     - "SET PATH=%PYTHON%;%PYTHON%/Scripts;%PATH%"
     - "python --version"
     - "IF %PYTHON:~-4% == -x64 (SET ARCH=x64) ELSE (SET ARCH=i386)"
-    - ps: "Start-FileDownload 
https://mediaarea.net/download/binary/mediainfo/18.05/MediaInfo_CLI_18.05_Windows_${Env:ARCH}.zip";
-    - ps: "unzip -o MediaInfo_CLI_18.05_Windows_${Env:ARCH}.zip"
-    - ps: "Start-FileDownload 
https://mediaarea.net/download/binary/libmediainfo0/18.05/MediaInfo_DLL_18.05_Windows_${Env:ARCH}_WithoutInstaller.7z";
-    - ps: "7z -y x MediaInfo_DLL_18.05_Windows_${Env:ARCH}_WithoutInstaller.7z"
-    - "pip install pytest"
-    # see https://phabricator.wikimedia.org/T186991
-    # and 
https://github.com/wikimedia/pywikibot/commit/c503a9bb225933066f2b9f40b061b0279c7f6ad3
-    - "IF %PYTHON:~0,11% == C:/Python34 (pip install pytest-runner==3.0) ELSE 
(pip install pytest-runner)"
+    - ps: "Start-FileDownload 
https://mediaarea.net/download/binary/mediainfo/${Env:MEDIAINFO_VERSION}/MediaInfo_CLI_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}.zip";
+    - ps: "unzip -o 
MediaInfo_CLI_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}.zip LIBCURL.DLL"
+    - ps: "Start-FileDownload 
https://mediaarea.net/download/binary/libmediainfo0/${Env:MEDIAINFO_VERSION}/MediaInfo_DLL_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}_WithoutInstaller.7z";
+    - ps: "7z -y x 
MediaInfo_DLL_${Env:MEDIAINFO_VERSION}_Windows_${Env:ARCH}_WithoutInstaller.7z 
MediaInfo.dll Developers/License.html"
+    - "move MediaInfo.dll pymediainfo"
+    - "move Developers\\License.html docs"
+    - "pip install --upgrade setuptools pytest pytest-runner twine wheel"
 build_script:
-  - "python setup.py build"
+  - "python setup.py bdist_wheel"
 test_script:
   - "python setup.py test"
+deploy_script:
+  - ps: If ($env:APPVEYOR_REPO_TAG -eq "true") { Invoke-Expression "twine 
upload --skip-existing -u sbraz dist/*" }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/docs/conf.py 
new/pymediainfo-4.0/docs/conf.py
--- old/pymediainfo-2.3.0/docs/conf.py  2018-05-14 16:15:08.000000000 +0200
+++ new/pymediainfo-4.0/docs/conf.py    2019-04-04 17:46:33.000000000 +0200
@@ -113,7 +113,10 @@
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {}
+html_theme_options = {
+    "page_width": "auto",
+    "fixed_sidebar": True
+}
 
 # Add any paths that contain custom themes here, relative to this directory.
 #html_theme_path = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/docs/index.rst 
new/pymediainfo-4.0/docs/index.rst
--- old/pymediainfo-2.3.0/docs/index.rst        2018-05-14 16:15:08.000000000 
+0200
+++ new/pymediainfo-4.0/docs/index.rst  2019-04-04 17:46:33.000000000 +0200
@@ -15,6 +15,10 @@
 This is a simple wrapper around the MediaInfo library, which you can find
 at https://mediaarea.net/en/MediaInfo
 
+Binary wheels containing the library are provided for Windows and Mac OS X.
+
+Packages are available for `several Linux distributions 
<https://repology.org/metapackage/python:pymediainfo>`_.
+
 ===============
 Using MediaInfo
 ===============
@@ -28,7 +32,7 @@
  media_info = MediaInfo.parse('my_video_file.mov')
  for track in media_info.tracks:
      if track.track_type == 'Video':
-         print track.bit_rate, track.bit_rate_mode, track.codec
+         print(track.bit_rate, track.bit_rate_mode, track.codec)
  
  # output: 46033920 CBR DV
 
@@ -56,12 +60,14 @@
  media_info = MediaInfo.parse('my_video_file.mov')
  for track in media_info.tracks:
      if track.bit_rate is not None:
-         print "%s: %s" % (track.track_type, track.bit_rate)
+         print("{}: {}".format(track.track_type, track.bit_rate))
      else:
-         print """%s tracks do not have bit rate
-                  associated with them.""" % track.track_type
+         print("""{} tracks do not have bit rate
+                  associated with them.""".format(track.track_type))
+
+Output:
 
-Output::
+.. code-block:: text
 
  General tracks do not have bit rate associated with them.
  Video: 46033920
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/pymediainfo/__init__.py 
new/pymediainfo-4.0/pymediainfo/__init__.py
--- old/pymediainfo-2.3.0/pymediainfo/__init__.py       2018-05-14 
16:15:08.000000000 +0200
+++ new/pymediainfo-4.0/pymediainfo/__init__.py 2019-04-04 17:46:33.000000000 
+0200
@@ -1,11 +1,12 @@
+# vim: set fileencoding=utf-8 :
 import os
 import re
 import locale
 import json
+import ctypes
 import sys
 from pkg_resources import get_distribution, DistributionNotFound
 import xml.etree.ElementTree as ET
-from ctypes import *
 
 try:
     import pathlib
@@ -47,16 +48,21 @@
 
     All available attributes can be obtained by calling :func:`to_data`.
     """
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
     def __getattribute__(self, name):
         try:
             return object.__getattribute__(self, name)
         except:
             pass
         return None
+    def __getstate__(self):
+        return self.__dict__
+    def __setstate__(self, state):
+        self.__dict__ = state
     def __init__(self, xml_dom_fragment):
-        self.xml_dom_fragment = xml_dom_fragment
         self.track_type = xml_dom_fragment.attrib['type']
-        for el in self.xml_dom_fragment:
+        for el in xml_dom_fragment:
             node_name = el.tag.lower().strip().strip('_')
             if node_name == 'id':
                 node_name = 'track_id'
@@ -84,7 +90,7 @@
                     except:
                         pass
     def __repr__(self):
-        return("<Track track_id='{0}', 
track_type='{1}'>".format(self.track_id, self.track_type))
+        return("<Track track_id='{}', track_type='{}'>".format(self.track_id, 
self.track_type))
     def to_data(self):
         """
         Returns a dict representation of the track attributes.
@@ -117,42 +123,87 @@
     >>> pymediainfo.MediaInfo.parse("/path/to/file.mp4")
 
     Alternatively, objects may be created from MediaInfo's XML output.
-    XML output can be obtained using the `XML` output format on versions older 
than v17.10
-    and the `OLDXML` format on newer versions.
+    Such output can be obtained using the ``XML`` output format on versions 
older than v17.10
+    and the ``OLDXML`` format on newer versions.
 
     Using such an XML file, we can create a :class:`MediaInfo` object:
 
     >>> with open("output.xml") as f:
     ...     mi = pymediainfo.MediaInfo(f.read())
 
-    :param str xml: XML output obtained from MediaInfo
-    """
-    def __init__(self, xml):
-        self.xml_dom = MediaInfo._parse_xml_data_into_dom(xml)
+    :param str xml: XML output obtained from MediaInfo.
+    :param str encoding_errors: option to pass to :func:`str.encode`'s `errors`
+        parameter before parsing `xml`.
+    :raises xml.etree.ElementTree.ParseError: if passed invalid XML.
+    :var tracks: A list of :py:class:`Track` objects which the media file 
contains.
+        For instance:
 
-    @staticmethod
-    def _parse_xml_data_into_dom(xml_data):
-        try:
-            return ET.fromstring(xml_data.encode("utf-8"))
-        except:
-            return None
+        >>> mi = pymediainfo.MediaInfo.parse("/path/to/file.mp4")
+        >>> for t in mi.tracks:
+        ...     print(t)
+        <Track track_id='None', track_type='General'>
+        <Track track_id='1', track_type='Text'>
+    """
+    def __eq__(self, other):
+        return self.tracks == other.tracks
+    def __init__(self, xml, encoding_errors="strict"):
+        xml_dom = ET.fromstring(xml.encode("utf-8", encoding_errors))
+        self.tracks = []
+        # This is the case for libmediainfo < 18.03
+        # https://github.com/sbraz/pymediainfo/issues/57
+        # 
https://github.com/MediaArea/MediaInfoLib/commit/575a9a32e6960ea34adb3bc982c64edfa06e95eb
+        if xml_dom.tag == "File":
+            xpath = "track"
+        else:
+            xpath = "File/track"
+        for xml_track in xml_dom.iterfind(xpath):
+            self.tracks.append(Track(xml_track))
     @staticmethod
     def _get_library(library_file=None):
         os_is_nt = os.name in ("nt", "dos", "os2", "ce")
-        if library_file is not None:
+        if os_is_nt:
+            lib_type = ctypes.WinDLL
+        else:
+            lib_type = ctypes.CDLL
+        if library_file is None:
             if os_is_nt:
-                return WinDLL(library_file)
+                library_names = ("MediaInfo.dll",)
+            elif sys.platform == "darwin":
+                library_names = ("libmediainfo.0.dylib", "libmediainfo.dylib")
             else:
-                return CDLL(library_file)
-        elif os_is_nt:
-            return windll.MediaInfo
-        elif sys.platform == "darwin":
+                library_names = ("libmediainfo.so.0",)
+            script_dir = os.path.dirname(__file__)
+            # Look for the library file in the script folder
+            for library in library_names:
+                lib_path = os.path.join(script_dir, library)
+                if os.path.isfile(lib_path):
+                    # If we find it, don't try any other filename
+                    library_names = (lib_path,)
+                    break
+        else:
+            library_names = (library_file,)
+        for i, library in enumerate(library_names, start=1):
             try:
-                return CDLL("libmediainfo.0.dylib")
+                lib = lib_type(library)
+                # Define arguments and return types
+                lib.MediaInfo_Inform.restype = ctypes.c_wchar_p
+                lib.MediaInfo_New.argtypes = []
+                lib.MediaInfo_New.restype  = ctypes.c_void_p
+                lib.MediaInfo_Option.argtypes = [ctypes.c_void_p, 
ctypes.c_wchar_p, ctypes.c_wchar_p]
+                lib.MediaInfo_Option.restype = ctypes.c_wchar_p
+                lib.MediaInfo_Inform.argtypes = [ctypes.c_void_p, 
ctypes.c_size_t]
+                lib.MediaInfo_Inform.restype = ctypes.c_wchar_p
+                lib.MediaInfo_Open.argtypes = [ctypes.c_void_p, 
ctypes.c_wchar_p]
+                lib.MediaInfo_Open.restype = ctypes.c_size_t
+                lib.MediaInfo_Delete.argtypes = [ctypes.c_void_p]
+                lib.MediaInfo_Delete.restype  = None
+                lib.MediaInfo_Close.argtypes = [ctypes.c_void_p]
+                lib.MediaInfo_Close.restype = None
+                return lib
             except OSError:
-                return CDLL("libmediainfo.dylib")
-        else:
-            return CDLL("libmediainfo.so.0")
+                # If we've tried all possible filenames
+                if i == len(library_names):
+                    raise
     @classmethod
     def can_parse(cls, library_file=None):
         """
@@ -166,7 +217,9 @@
         except:
             return False
     @classmethod
-    def parse(cls, filename, library_file=None, cover_data=False):
+    def parse(cls, filename, library_file=None, cover_data=False,
+            encoding_errors="strict", parse_speed=0.5, text=False,
+            full=True, legacy_stream_display=False):
         """
         Analyze a media file using libmediainfo.
         If libmediainfo is located in a non-standard location, the 
`library_file` parameter can be used:
@@ -175,38 +228,46 @@
         ...     library_file="/path/to/libmediainfo.dylib")
 
         :param filename: path to the media file which will be analyzed.
+            A URL can also be used if libmediainfo was compiled
+            with CURL support.
         :param str library_file: path to the libmediainfo library, this should 
only be used if the library cannot be auto-detected.
         :param bool cover_data: whether to retrieve cover data as base64.
+        :param str encoding_errors: option to pass to :func:`str.encode`'s 
`errors`
+            parameter before parsing MediaInfo's XML output.
+        :param float parse_speed: passed to the library as `ParseSpeed`,
+            this option takes values between 0 and 1.
+            A higher value will yield more precise results in some cases
+            but will also increase parsing time.
+        :param bool text: if ``True``, MediaInfo's text output will be 
returned instead
+            of a :class:`MediaInfo` object.
+        :param bool full: display additional tags, including computer-readable 
values
+            for sizes and durations.
+        :param bool legacy_stream_display: display additional information 
about streams.
         :type filename: str or pathlib.Path
-        :rtype: MediaInfo
+        :rtype: str if `text` is ``True``.
+        :rtype: :class:`MediaInfo` otherwise.
+        :raises FileNotFoundError: if passed a non-existent file
+            (Python ≥ 3.3), does not work on Windows.
+        :raises IOError: if passed a non-existent file (Python < 3.3),
+            does not work on Windows.
+        :raises RuntimeError: if parsing fails, this should not
+            happen unless libmediainfo itself fails.
         """
         lib = cls._get_library(library_file)
         if pathlib is not None and isinstance(filename, pathlib.PurePath):
             filename = str(filename)
+            url = False
         else:
             url = urlparse.urlparse(filename)
-            # Test whether the filename is actually a URL
-            if url.scheme is None:
-                # Test whether the file is readable
-                with open(filename, "rb"):
-                    pass
-        # Define arguments and return types
-        lib.MediaInfo_Inform.restype = c_wchar_p
-        lib.MediaInfo_New.argtypes = []
-        lib.MediaInfo_New.restype  = c_void_p
-        lib.MediaInfo_Option.argtypes = [c_void_p, c_wchar_p, c_wchar_p]
-        lib.MediaInfo_Option.restype = c_wchar_p
-        lib.MediaInfo_Inform.argtypes = [c_void_p, c_size_t]
-        lib.MediaInfo_Inform.restype = c_wchar_p
-        lib.MediaInfo_Open.argtypes = [c_void_p, c_wchar_p]
-        lib.MediaInfo_Open.restype = c_size_t
-        lib.MediaInfo_Delete.argtypes = [c_void_p]
-        lib.MediaInfo_Delete.restype  = None
-        lib.MediaInfo_Close.argtypes = [c_void_p]
-        lib.MediaInfo_Close.restype = None
+        # Try to open the file (if it's not a URL)
+        # Doesn't work on Windows because paths are URLs
+        if not (url and url.scheme):
+            # Test whether the file is readable
+            with open(filename, "rb"):
+                pass
         # Obtain the library version
         lib_version = lib.MediaInfo_Option(None, "Info_Version", "")
-        lib_version = tuple(int(_) for _ in re.search("^MediaInfoLib - 
v(\S+)", lib_version).group(1).split("."))
+        lib_version = tuple(int(_) for _ in re.search("^MediaInfoLib - 
v(\\S+)", lib_version).group(1).split("."))
         # The XML option was renamed starting with version 17.10
         if lib_version >= (17, 10):
             xml_option = "OLDXML"
@@ -225,38 +286,21 @@
         if (sys.version_info < (3,) and os.name == "posix"
                 and locale.getlocale() == (None, None)):
             locale.setlocale(locale.LC_CTYPE, locale.getdefaultlocale())
-        lib.MediaInfo_Option(None, "Inform", xml_option)
-        lib.MediaInfo_Option(None, "Complete", "1")
-        lib.MediaInfo_Open(handle, filename)
-        xml = lib.MediaInfo_Inform(handle, 0)
+        lib.MediaInfo_Option(None, "Inform", "" if text else xml_option)
+        lib.MediaInfo_Option(None, "Complete", "1" if full else "")
+        lib.MediaInfo_Option(None, "ParseSpeed", str(parse_speed))
+        lib.MediaInfo_Option(None, "LegacyStreamDisplay", "1" if 
legacy_stream_display else "")
+        if lib.MediaInfo_Open(handle, filename) == 0:
+            raise RuntimeError("An eror occured while opening {}"
+                    " with libmediainfo".format(filename))
+        output = lib.MediaInfo_Inform(handle, 0)
         # Delete the handle
         lib.MediaInfo_Close(handle)
         lib.MediaInfo_Delete(handle)
-        return cls(xml)
-    def _populate_tracks(self):
-        if self.xml_dom is None:
-            return
-        iterator = "getiterator" if sys.version_info < (2, 7) else "iter"
-        for xml_track in getattr(self.xml_dom, iterator)("track"):
-            self._tracks.append(Track(xml_track))
-    @property
-    def tracks(self):
-        """
-        A list of :py:class:`Track` objects which the media file contains.
-
-        For instance:
-
-        >>> mi = pymediainfo.MediaInfo.parse("/path/to/file.mp4")
-        >>> for t in mi.tracks:
-        ...     print(t)
-        <Track track_id='None', track_type='General'>
-        <Track track_id='1', track_type='Text'>
-        """
-        if not hasattr(self, "_tracks"):
-            self._tracks = []
-        if len(self._tracks) == 0:
-            self._populate_tracks()
-        return self._tracks
+        if text:
+            return output
+        else:
+            return cls(output, encoding_errors)
     def to_data(self):
         """
         Returns a dict representation of the object's :py:class:`Tracks 
<Track>`.
@@ -269,7 +313,7 @@
         return data
     def to_json(self):
         """
-        Returns a json representation of the object's :py:class:`Tracks 
<Track>`.
+        Returns a JSON representation of the object's :py:class:`Tracks 
<Track>`.
 
         :rtype: str
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/pymediainfo.egg-info/PKG-INFO 
new/pymediainfo-4.0/pymediainfo.egg-info/PKG-INFO
--- old/pymediainfo-2.3.0/pymediainfo.egg-info/PKG-INFO 2018-05-14 
16:15:37.000000000 +0200
+++ new/pymediainfo-4.0/pymediainfo.egg-info/PKG-INFO   2019-04-04 
17:46:38.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pymediainfo
-Version: 2.3.0
+Version: 4.0
 Summary: A Python wrapper for the mediainfo library.
 Home-page: https://github.com/sbraz/pymediainfo
 Author: Louis Sautier
@@ -15,6 +15,9 @@
         .. image:: https://img.shields.io/pypi/pyversions/pymediainfo.svg
           :target: https://pypi.org/project/pymediainfo
         
+        .. image:: https://repology.org/badge/tiny-repos/python:pymediainfo.svg
+          :target: https://repology.org/metapackage/python:pymediainfo
+        
         .. image:: https://img.shields.io/pypi/implementation/pymediainfo.svg
           :target: https://pypi.org/project/pymediainfo
         
@@ -27,17 +30,17 @@
         
         This small package is a wrapper around the MediaInfo library.
         
-        It works on Linux, Mac OS X and Windows and is tested with Python 2.6, 
2.7, 3.4, 3.5, 3.6, PyPy and PyPy3.
+        It works on Linux, Mac OS X and Windows and is tested with Python 2.7, 
3.4, 3.5, 3.6, 3.7, PyPy and PyPy3.
         
         See https://pymediainfo.readthedocs.io/ for more information.
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Operating System :: POSIX :: Linux
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/pymediainfo.egg-info/SOURCES.txt 
new/pymediainfo-4.0/pymediainfo.egg-info/SOURCES.txt
--- old/pymediainfo-2.3.0/pymediainfo.egg-info/SOURCES.txt      2018-05-14 
16:15:37.000000000 +0200
+++ new/pymediainfo-4.0/pymediainfo.egg-info/SOURCES.txt        2019-04-04 
17:46:38.000000000 +0200
@@ -19,9 +19,12 @@
 pymediainfo.egg-info/requires.txt
 pymediainfo.egg-info/top_level.txt
 tests/test_pymediainfo.py
+tests/data/aac_he_v2.aac
 tests/data/accentué.txt
 tests/data/invalid.xml
+tests/data/issue55.flv
 tests/data/sample.mkv
 tests/data/sample.mp4
 tests/data/sample.xml
-tests/data/sample_with_cover.mp3
\ No newline at end of file
+tests/data/sample_with_cover.mp3
+tests/data/vbr_requires_parsespeed_1.mp4
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/setup.cfg 
new/pymediainfo-4.0/setup.cfg
--- old/pymediainfo-2.3.0/setup.cfg     2018-05-14 16:15:37.000000000 +0200
+++ new/pymediainfo-4.0/setup.cfg       2019-04-04 17:46:38.000000000 +0200
@@ -12,6 +12,12 @@
 [aliases]
 test = pytest
 
+[tool:pytest]
+addopts = -vv
+
+[bdist_wheel]
+universal = 1
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/setup.py 
new/pymediainfo-4.0/setup.py
--- old/pymediainfo-2.3.0/setup.py      2018-05-14 16:15:08.000000000 +0200
+++ new/pymediainfo-4.0/setup.py        2019-04-04 17:46:33.000000000 +0200
@@ -1,9 +1,36 @@
 #!/usr/bin/env python
+import os
 from setuptools import setup, find_packages
 
 with open("README.rst") as f:
     long_description = f.read()
 
+data_files = []
+bin_files = []
+cmdclass = {}
+
+bin_license = 'docs/License.html'
+if os.path.exists(bin_license):
+    data_files.append(('docs', [bin_license]))
+    bin_files.extend(['MediaInfo.dll', 'libmediainfo.*'])
+    try:
+        from wheel.bdist_wheel import bdist_wheel
+
+        class platform_bdist_wheel(bdist_wheel):
+            def finalize_options(self):
+                bdist_wheel.finalize_options(self)
+                # Force the wheel to be marked as platform-specific
+                self.root_is_pure = False
+            def get_tag(self):
+                python, abi, plat = bdist_wheel.get_tag(self)
+                # The python code works for any Python version,
+                # not just the one we are running to build the wheel
+                return 'py2.py3', 'none', plat
+
+        cmdclass['bdist_wheel'] = platform_bdist_wheel
+    except ImportError:
+        pass
+
 setup(
     name='pymediainfo',
     author='Louis Sautier',
@@ -16,17 +43,20 @@
     include_package_data=True,
     zip_safe=False,
     license='MIT',
+    data_files=data_files,
     use_scm_version=True,
     setup_requires=["setuptools_scm"],
     install_requires=["setuptools"],
     tests_require=["pytest", "pytest-runner"],
+    package_data={'pymediainfo': bin_files},
+    cmdclass=cmdclass,
     classifiers=[
         "Development Status :: 5 - Production/Stable",
-        "Programming Language :: Python :: 2.6",
         "Programming Language :: Python :: 2.7",
         "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
         "Operating System :: POSIX :: Linux",
Binary files old/pymediainfo-2.3.0/tests/data/aac_he_v2.aac and 
new/pymediainfo-4.0/tests/data/aac_he_v2.aac differ
Binary files old/pymediainfo-2.3.0/tests/data/issue55.flv and 
new/pymediainfo-4.0/tests/data/issue55.flv differ
Binary files old/pymediainfo-2.3.0/tests/data/vbr_requires_parsespeed_1.mp4 and 
new/pymediainfo-4.0/tests/data/vbr_requires_parsespeed_1.mp4 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymediainfo-2.3.0/tests/test_pymediainfo.py 
new/pymediainfo-4.0/tests/test_pymediainfo.py
--- old/pymediainfo-2.3.0/tests/test_pymediainfo.py     2018-05-14 
16:15:08.000000000 +0200
+++ new/pymediainfo-4.0/tests/test_pymediainfo.py       2019-04-04 
17:46:33.000000000 +0200
@@ -3,11 +3,20 @@
 import os
 import sys
 import unittest
+import xml
+import pickle
 
 import pytest
 
 from pymediainfo import MediaInfo
 
+os_is_nt = os.name in ("nt", "dos", "os2", "ce")
+
+if sys.version_info < (3, 3):
+    FileNotFoundError = IOError
+if sys.version_info < (3, 2):
+    unittest.TestCase.assertRegex = unittest.TestCase.assertRegexpMatches
+
 data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
 
 class MediaInfoTest(unittest.TestCase):
@@ -46,12 +55,12 @@
         with open(os.path.join(data_dir, 'invalid.xml'), 'r') as f:
             self.xml_data = f.read()
     def test_parse_invalid_xml(self):
-        mi = MediaInfo(MediaInfo._parse_xml_data_into_dom(self.xml_data))
-        self.assertEqual(len(mi.tracks), 0)
+        self.assertRaises(xml.etree.ElementTree.ParseError, MediaInfo, 
self.xml_data)
 
 class MediaInfoLibraryTest(unittest.TestCase):
     def setUp(self):
         self.mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"))
+        self.non_full_mi = MediaInfo.parse(os.path.join(data_dir, 
"sample.mp4"), full=False)
     def test_can_parse_true(self):
         self.assertTrue(MediaInfo.can_parse())
     def test_track_count(self):
@@ -60,10 +69,13 @@
         self.assertEqual(self.mi.tracks[1].track_type, "Video")
         self.assertEqual(self.mi.tracks[2].track_type, "Audio")
     def test_track_details(self):
-        self.assertEqual(self.mi.tracks[1].codec, "AVC")
-        self.assertEqual(self.mi.tracks[2].codec, "AAC LC")
+        self.assertEqual(self.mi.tracks[1].format, "AVC")
+        self.assertEqual(self.mi.tracks[2].format, "AAC")
         self.assertEqual(self.mi.tracks[1].duration, 958)
         self.assertEqual(self.mi.tracks[2].duration, 980)
+    def test_full_option(self):
+        self.assertEqual(self.mi.tracks[0].footersize, "59")
+        self.assertEqual(self.non_full_mi.tracks[0].footersize, None)
 
 class MediaInfoUnicodeXMLTest(unittest.TestCase):
     def setUp(self):
@@ -90,11 +102,21 @@
 
 class MediaInfoPathlibTest(unittest.TestCase):
     def setUp(self):
-        pathlib = pytest.importorskip("pathlib")
-        self.path = pathlib.Path(data_dir) / "sample.mp4"
+        self.pathlib = pytest.importorskip("pathlib")
     def test_parse_pathlib_path(self):
-        mi = MediaInfo.parse(self.path)
+        path = self.pathlib.Path(data_dir) / "sample.mp4"
+        mi = MediaInfo.parse(path)
         self.assertEqual(len(mi.tracks), 3)
+    @pytest.mark.skipif(os_is_nt, reason="Windows paths are URLs")
+    def test_parse_non_existent_path_pathlib(self):
+        path = self.pathlib.Path(data_dir) / "this file does not exist"
+        self.assertRaises(FileNotFoundError, MediaInfo.parse, path)
+
+class MediaInfoTestParseNonExistentFile(unittest.TestCase):
+    @pytest.mark.skipif(os_is_nt, reason="Windows paths are URLs")
+    def test_parse_non_existent_path(self):
+        path = os.path.join(data_dir, "this file does not exist")
+        self.assertRaises(FileNotFoundError, MediaInfo.parse, path)
 
 class MediaInfoCoverDataTest(unittest.TestCase):
     def setUp(self):
@@ -108,3 +130,54 @@
                 
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAAAAA"
                 
"AAAQCEeRdzAAAADUlEQVR4nGP4x8DwHwAE/AH+QSRCQgAAAABJRU5ErkJggg=="
         )
+
+class MediaInfoTrackParsingTest(unittest.TestCase):
+    def test_track_parsing(self):
+        mi = MediaInfo.parse(os.path.join(data_dir, "issue55.flv"))
+        self.assertEqual(len(mi.tracks), 2)
+
+class MediaInfoRuntimeErrorTest(unittest.TestCase):
+    def test_parse_invalid_url(self):
+        # This is the easiest way to cause a parsing error
+        # since non-existent files return a different exception
+        self.assertRaises(RuntimeError, MediaInfo.parse,
+                "unsupportedscheme://")
+
+class MediaInfoSlowParseTest(unittest.TestCase):
+    def setUp(self):
+        self.mi = MediaInfo.parse(
+                os.path.join(data_dir, "vbr_requires_parsespeed_1.mp4"),
+                parse_speed=1
+        )
+    def test_slow_parse_speed(self):
+        self.assertEqual(self.mi.tracks[2].stream_size, "3353 / 45")
+
+class MediaInfoEqTest(unittest.TestCase):
+    def setUp(self):
+        self.mp3_mi = MediaInfo.parse(os.path.join(data_dir, 
"sample_with_cover.mp3"))
+        self.mp3_other_mi = MediaInfo.parse(os.path.join(data_dir, 
"sample_with_cover.mp3"))
+        self.mp4_mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"))
+    def test_eq(self):
+        self.assertEqual(self.mp3_mi.tracks[0], self.mp3_other_mi.tracks[0])
+        self.assertEqual(self.mp3_mi, self.mp3_other_mi)
+        self.assertNotEqual(self.mp3_mi.tracks[0], self.mp4_mi.tracks[0])
+        self.assertNotEqual(self.mp3_mi, self.mp4_mi)
+    def test_pickle_unpickle(self):
+        pickled_track = pickle.dumps(self.mp4_mi.tracks[0])
+        self.assertEqual(self.mp4_mi.tracks[0], pickle.loads(pickled_track))
+        pickled_mi = pickle.dumps(self.mp4_mi)
+        self.assertEqual(self.mp4_mi, pickle.loads(pickled_mi))
+
+class MediaInfoTextOutputTest(unittest.TestCase):
+    def setUp(self):
+        self.mi = MediaInfo.parse(os.path.join(data_dir, "sample.mp4"), 
text=True)
+    def test_text_output(self):
+        self.assertRegex(self.mi, r"Stream size\s+: 373836\b")
+
+class MediaInfoLegacyStreamDisplayTest(unittest.TestCase):
+    def setUp(self):
+        self.mi = MediaInfo.parse(os.path.join(data_dir, "aac_he_v2.aac"))
+        self.legacy_mi = MediaInfo.parse(os.path.join(data_dir, 
"aac_he_v2.aac"), legacy_stream_display=True)
+    def test_legacy_stream_display(self):
+        self.assertEqual(self.mi.tracks[1].channel_s, 2)
+        self.assertEqual(self.legacy_mi.tracks[1].channel_s, "2 / 1 / 1")


Reply via email to