diff --git a/.gitignore b/.gitignore index c82d74f..dd9e851 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ build dist docs/_build +.pdm* diff --git a/README.rst b/README.rst index 3449f17..dd4b5c0 100644 --- a/README.rst +++ b/README.rst @@ -19,6 +19,6 @@ pymediainfo This small package is a wrapper around the MediaInfo library. -It works on Linux, Mac OS X and Windows and is tested with Python 3.7 to 3.12 and PyPy3. +It works on Linux, Mac OS X and Windows and is tested with Python 3.9 to 3.13 and PyPy3. See https://pymediainfo.readthedocs.io/ for more information. diff --git a/appveyor.yml b/appveyor.yml index 08a2cb1..c815f47 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,14 +1,12 @@ environment: LINUX_IMAGE: &linux_image Ubuntu2204 - MACOS_IMAGE: &macos_image macos-catalina + MACOS_IMAGE: &macos_image macos-monterey WINDOWS_IMAGE: &windows_image Visual Studio 2022 - LIBZEN_VERSION: 0.4.41 MEDIAINFO_VERSION: 24.11 - UBUNTU_VERSION: 22.04 + # Python 3.13 is not available everywhere yet, see https://github.com/appveyor/ci/issues/3927 + # Because of this, we can only deploy on 3.12 QA_PYTHON_VERSION: 3.12 - # Python 3.12 is not available everywhere yet, see https://github.com/appveyor/ci/issues/3879 - # Because of this, we can only deploy on 3.11 - DEPLOY_TOXENV: py311 + DEPLOY_TOXENV: py312 PYPY_URL: https://downloads.python.org/pypy/pypy3.10-v7.3.13-linux64.tar.bz2 # Work around https://github.com/tox-dev/tox/issues/1550 PYTHONIOENCODING: utf-8 @@ -21,10 +19,6 @@ environment: APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - TOXENV: pypy3 APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - - TOXENV: py37 - APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - - TOXENV: py38 - APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - TOXENV: py39 APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - TOXENV: py310 @@ -33,26 +27,16 @@ environment: APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - TOXENV: py312 APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - - TOXENV: py38 - APPVEYOR_BUILD_WORKER_IMAGE: *macos_image + - TOXENV: py313 + APPVEYOR_BUILD_WORKER_IMAGE: *linux_image - TOXENV: py39 APPVEYOR_BUILD_WORKER_IMAGE: *macos_image - TOXENV: py310 APPVEYOR_BUILD_WORKER_IMAGE: *macos_image - TOXENV: py311 APPVEYOR_BUILD_WORKER_IMAGE: *macos_image - - TOXENV: py37 - PYTHON: "C:/Python37" - APPVEYOR_BUILD_WORKER_IMAGE: *windows_image - - TOXENV: py37 - PYTHON: "C:/Python37-x64" - APPVEYOR_BUILD_WORKER_IMAGE: *windows_image - - TOXENV: py38 - PYTHON: "C:/Python38" - APPVEYOR_BUILD_WORKER_IMAGE: *windows_image - - TOXENV: py38 - PYTHON: "C:/Python38-x64" - APPVEYOR_BUILD_WORKER_IMAGE: *windows_image + - TOXENV: py312 + APPVEYOR_BUILD_WORKER_IMAGE: *macos_image - TOXENV: py39 PYTHON: "C:/Python39" APPVEYOR_BUILD_WORKER_IMAGE: *windows_image @@ -77,6 +61,12 @@ environment: - TOXENV: py312 PYTHON: "C:/Python312-x64" APPVEYOR_BUILD_WORKER_IMAGE: *windows_image + - TOXENV: py313 + PYTHON: "C:/Python313" + APPVEYOR_BUILD_WORKER_IMAGE: *windows_image + - TOXENV: py313 + PYTHON: "C:/Python313-x64" + APPVEYOR_BUILD_WORKER_IMAGE: *windows_image for: - matrix: @@ -86,6 +76,7 @@ for: - "SET PATH=%PYTHON%;%PYTHON%/Scripts;%PATH%" - "python --version" - "IF %PYTHON:~-4% == -x64 (SET ARCH=x64) ELSE (SET ARCH=i386)" + - "IF %PYTHON:~-4% == -x64 (SET PLATFORM_WHEEL=win_amd64) ELSE (SET PLATFORM_WHEEL=win32)" - 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" @@ -101,8 +92,9 @@ for: deploy_script: - ps: | If (($env:APPVEYOR_REPO_TAG -eq "true") -and ($env:TOXENV -eq $env:DEPLOY_TOXENV)) { - pip install twine wheel - python setup.py bdist_wheel + pip install twine wheel pdm + pdm build --no-sdist + wheel tags --remove --platform-tag=${Env:PLATFORM_WHEEL} dist/*-py3-none-any.whl Invoke-Expression "twine upload --skip-existing dist/*.whl" } - @@ -126,8 +118,9 @@ for: if [[ $APPVEYOR_REPO_TAG == "true" && $TOXENV == $DEPLOY_TOXENV ]]; then mv MediaInfoLib/libmediainfo.0.dylib pymediainfo mv MediaInfoLib/License.html docs - pip install twine wheel - python setup.py bdist_wheel + pip install twine wheel pdm + pdm build --no-sdist + wheel tags --remove --platform-tag=macosx-10.10-x86_64-macosx-11-universal2 dist/*-py3-none-any.whl twine upload --skip-existing dist/*.whl fi - @@ -152,20 +145,18 @@ for: fi # "python -m pip" will work with the unpacked PyPy too, "pip" won't python -m pip install tox - pushd /tmp - libzen_deb=libzen0v5_${LIBZEN_VERSION}-1_amd64.xUbuntu_${UBUNTU_VERSION}.deb - mediainfo_deb=libmediainfo0v5_${MEDIAINFO_VERSION}-1_amd64.xUbuntu_${UBUNTU_VERSION}.deb - curl -O "https://mediaarea.net/download/binary/libzen0/${LIBZEN_VERSION}/${libzen_deb}" - curl -O "https://mediaarea.net/download/binary/libmediainfo0/${MEDIAINFO_VERSION}/${mediainfo_deb}" - sudo apt-get -y install libmms0 - sudo dpkg -i "${libzen_deb}" "${mediainfo_deb}" - popd + curl -O https://mediaarea.net/download/binary/libmediainfo0/${MEDIAINFO_VERSION}/MediaInfo_DLL_${MEDIAINFO_VERSION}_Lambda_x86_64.zip + unzip MediaInfo_DLL_${MEDIAINFO_VERSION}_Lambda_x86_64.zip -d x86_64 + curl -O https://mediaarea.net/download/binary/libmediainfo0/${MEDIAINFO_VERSION}/MediaInfo_DLL_${MEDIAINFO_VERSION}_Lambda_arm64.zip + unzip MediaInfo_DLL_${MEDIAINFO_VERSION}_Lambda_arm64.zip -d arm64 fi build: off test_script: | if [[ $TOXENV =~ doc.* ]]; then tox -p else + # Use the previously downloaded library + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:x86_64/lib/" # We want to see the progression of the tests so we can't run # tox environments in parallel tox @@ -173,7 +164,21 @@ for: deploy_script: | set -eo pipefail if [[ $APPVEYOR_REPO_TAG == "true" && $TOXENV == $DEPLOY_TOXENV ]]; then - pip install twine - python setup.py sdist - twine upload --skip-existing dist/*.gz + pip install twine wheel pdm + # source distribution + pdm build --no-wheel + + # wheels + mv x86_64/LICENSE docs + # wheel x86_64 + cp x86_64/lib/libmediainfo.so.0 pymediainfo/libmediainfo.so.0 + pdm build --no-sdist + wheel tags --remove --platform-tag=manylinux_2_34-x86_64 dist/*-py3-none-any.whl + # wheel arm64 + mv -f arm64/lib/libmediainfo.so.0 pymediainfo/libmediainfo.so.0 + pdm build --no-sdist + wheel tags --remove --platform-tag=manylinux_2_34-arm64 dist/*-py3-none-any.whl + + # upload + twine upload --skip-existing dist/*.gz dist/*.whl fi diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e9e1c50 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,84 @@ +# https://packaging.python.org/en/latest/specifications/pyproject-toml/ +[build-system] +requires = ["pdm-backend", "wheel>=0.42"] +build-backend = "pdm.backend" + +[project] +name = "pymediainfo" +description = "A Python wrapper for the mediainfo library." +authors = [ + {name = "Louis Sautier", email = "sautier.louis@gmail.com"}, +] +readme = "README.rst" +license = {text = "MIT"} +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: MIT License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dynamic = ["version"] +requires-python = ">=3.9" +dependencies = [ +] + +[project.optional-dependencies] +tests = [ + "pytest>=6", + "pytest-cov", + "pytest-xdist", +] +docs = [ + "alabaster", + "setuptools_scm", + "sphinx", +] +dev = [ + "ipython", + "mypy>=1.0", + "black", + "isort", + "flake8", + "pylint", +] + +[project.urls] +Homepage = "https://github.com/sbraz/pymediainfo" +Documentation = "https://pymediainfo.readthedocs.io/" +Bugs = "https://github.com/sbraz/pymediainfo/issues" + + +# https://pdm-project.org/latest/ +[tool.pdm.version] +source = "scm" + +[tool.pdm.build] +source-includes = ["scripts/", "tests/"] + +[tool.pdm.scripts.types] +help = "Check type hints" +cmd = "mypy --install-types --non-interactive --config-file=pyproject.toml {args:src tests}" + + +# https://mypy.readthedocs.io/en/stable/config_file.html +[tool.mypy] +# global-only flags +pretty = true +show_error_codes = true + +[[tool.mypy.overrides]] +module = ["pymediainfo.*"] +strict = true + + +[tool.pytest.ini_options] +addopts = "-vv -r a" diff --git a/scripts/demo.py b/scripts/demo.py index a168a2f..0251145 100755 --- a/scripts/demo.py +++ b/scripts/demo.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# ruff: noqa: T201 """ a demo that shows how to call pymediainfo """ diff --git a/setup.cfg b/setup.cfg index 3ee1013..69c27e1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,16 +5,3 @@ all_files = 1 [upload_sphinx] upload-dir = docs/_build/html - -[metadata] -long_description = file: README.rst -long_description_content_type = text/x-rst; charset=UTF-8 - -[aliases] -test = pytest - -[tool:pytest] -addopts = -vv -r a - -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 46edd63..0000000 --- a/setup.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -import os - -from setuptools import find_packages, setup - -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 'py3', 'none', plat - - cmdclass['bdist_wheel'] = platform_bdist_wheel - except ImportError: - pass - -setup( - name='pymediainfo', - author='Louis Sautier', - author_email='sautier.louis@gmail.com', - url='https://github.com/sbraz/pymediainfo', - project_urls={ - "Documentation": "https://pymediainfo.readthedocs.io/", - "Bugs": "https://github.com/sbraz/pymediainfo/issues", - }, - description="""A Python wrapper for the mediainfo library.""", - long_description=long_description, - packages=find_packages(), - namespace_packages=[], - include_package_data=True, - zip_safe=False, - license='MIT', - data_files=data_files, - use_scm_version=True, - python_requires=">=3.7", - setup_requires=["setuptools_scm"], - install_requires=["importlib_metadata; python_version < '3.8'"], - package_data={'pymediainfo': bin_files}, - cmdclass=cmdclass, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Operating System :: POSIX :: Linux", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "License :: OSI Approved :: MIT License", - ] -) diff --git a/tox.ini b/tox.ini index 4dab504..ea1ec20 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,10 @@ [tox] envlist = - py37 - py38 py39 py310 py311 + py312 + py313 pypy3 black flake8 @@ -24,6 +24,7 @@ commands = deps = setuptools_scm sphinx + alabaster commands = sphinx-build -d "{toxworkdir}/docs_doctree" docs "{toxworkdir}/docs_out" --color -W {posargs} [testenv:black]