Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove support for Python 2 and require > 3.6 #114

Merged
merged 11 commits into from
Nov 30, 2021
25 changes: 25 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Python Tests

on: [push]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.6", "3.7", "3.8", "3.9"]

steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
- name: Install ffmpeg
run: sudo apt install -y ffmpeg
- name: Install tox and any other packages
run: pip install tox
- name: Run tox
# Run tox using the version of Python in `PATH`
run: tox -e py
20 changes: 0 additions & 20 deletions .travis.yml

This file was deleted.

3 changes: 1 addition & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ A second optional parameter to ``audio_open`` specifies which backends to try
``available_backends`` function to get a list backends that are usable on the
current system.

Audioread is "universal" and supports both Python 2 (2.6+) and Python 3
(3.2+).
Audioread supports Python 3 (3.6+).

Example
-------
Expand Down
17 changes: 7 additions & 10 deletions audioread/ffdec.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@
output.
"""

import sys
import subprocess
import os
import queue
import re
import subprocess
import sys
import threading
import time
import os
try:
import queue
except ImportError:
import Queue as queue

from .exceptions import DecodeError

Expand Down Expand Up @@ -62,7 +59,7 @@ class QueueReaderThread(threading.Thread):
over a Queue.
"""
def __init__(self, fh, blocksize=1024, discard=False):
super(QueueReaderThread, self).__init__()
super().__init__()
self.fh = fh
self.blocksize = blocksize
self.daemon = True
Expand Down Expand Up @@ -121,7 +118,7 @@ def available():
windows_error_mode_lock = threading.Lock()


class FFmpegAudioFile(object):
class FFmpegAudioFile:
"""An audio file decoded by the ffmpeg command-line utility."""
def __init__(self, filename, block_size=4096):
# On Windows, we need to disable the subprocess's crash dialog
Expand Down Expand Up @@ -227,7 +224,7 @@ def _get_info(self):
line = line.strip().lower()

if 'no such file' in line:
raise IOError('file not found')
raise OSError('file not found')
elif 'invalid data found' in line:
raise UnsupportedError()
elif 'duration:' in line:
Expand Down
35 changes: 8 additions & 27 deletions audioread/gstdec.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@
>>> print f.channels
>>> print f.duration
"""
from __future__ import with_statement
from __future__ import division

import gi
gi.require_version('Gst', '1.0')
Expand All @@ -55,20 +53,11 @@
import sys
import threading
import os
import queue
from urllib.parse import quote

from .exceptions import DecodeError

try:
import queue
except ImportError:
import Queue as queue

try:
from urllib.parse import quote
except ImportError:
from urllib import quote


QUEUE_SIZE = 10
BUFFER_SIZE = 10
SENTINEL = '__GSTDEC_SENTINEL__'
Expand All @@ -83,7 +72,7 @@ class GStreamerError(DecodeError):
class UnknownTypeError(GStreamerError):
"""Raised when Gstreamer can't decode the given file type."""
def __init__(self, streaminfo):
super(UnknownTypeError, self).__init__(
super().__init__(
"can't decode stream: " + streaminfo
)
self.streaminfo = streaminfo
Expand All @@ -99,7 +88,7 @@ class NoStreamError(GStreamerError):
were found.
"""
def __init__(self):
super(NoStreamError, self).__init__('no audio streams found')
super().__init__('no audio streams found')


class MetadataMissingError(GStreamerError):
Expand All @@ -114,7 +103,7 @@ class IncompleteGStreamerError(GStreamerError):
principal plugin packages) are missing.
"""
def __init__(self):
super(IncompleteGStreamerError, self).__init__(
super().__init__(
'missing GStreamer base plugins'
)

Expand Down Expand Up @@ -142,7 +131,7 @@ class MainLoopThread(threading.Thread):
"""A daemon thread encapsulating a Gobject main loop.
"""
def __init__(self):
super(MainLoopThread, self).__init__()
super().__init__()
self.loop = GLib.MainLoop.new(None, False)
self.daemon = True

Expand All @@ -152,7 +141,7 @@ def run(self):

# The decoder.

class GstAudioFile(object):
class GstAudioFile:
"""Reads raw audio data from any audio file that Gstreamer
knows how to decode.

Expand Down Expand Up @@ -373,17 +362,14 @@ def _message(self, bus, message):

# Iteration.

def next(self):
def __next__(self):
# Wait for data from the Gstreamer callbacks.
val = self.queue.get()
if val == SENTINEL:
# End of stream.
raise StopIteration
return val

# For Python 3 compatibility.
__next__ = next

def __iter__(self):
return self

Expand Down Expand Up @@ -418,11 +404,6 @@ def close(self, force=False):
# Halt the pipeline (closing file).
self.pipeline.set_state(Gst.State.NULL)

# Delete the pipeline object. This seems to be necessary on Python
# 2, but not Python 3 for some reason: on 3.5, at least, the
# pipeline gets dereferenced automatically.
del self.pipeline

def __del__(self):
self.close()

Expand Down
16 changes: 8 additions & 8 deletions audioread/macca.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
# included in all copies or substantial portions of the Software.

"""Read audio files using CoreAudio on Mac OS X."""
import os
import sys
import copy
import ctypes
import ctypes.util
import copy
import os
import sys

from .exceptions import DecodeError

Expand Down Expand Up @@ -110,20 +110,20 @@ def __init__(self, code):
msg = 'unsupported format'
else:
msg = 'error %i' % code
super(MacError, self).__init__(msg)
super().__init__(msg)


def check(err):
"""If err is nonzero, raise a MacError exception."""
if err == ERROR_NOT_FOUND:
raise IOError('file not found')
raise OSError('file not found')
elif err != 0:
raise MacError(err)


# CoreFoundation objects.

class CFObject(object):
class CFObject:
def __init__(self, obj):
if obj == 0:
raise ValueError('object is zero')
Expand All @@ -142,7 +142,7 @@ def __init__(self, filename):
url = _corefoundation.CFURLCreateFromFileSystemRepresentation(
0, filename, len(filename), False
)
super(CFURL, self).__init__(url)
super().__init__(url)

def __str__(self):
cfstr = _corefoundation.CFURLGetString(self._obj)
Expand Down Expand Up @@ -184,7 +184,7 @@ class AudioBufferList(ctypes.Structure):

# Main functionality.

class ExtAudioFile(object):
class ExtAudioFile:
"""A CoreAudio "extended audio file". Reads information and raw PCM
audio data from any file that CoreAudio knows how to decode.

Expand Down
3 changes: 2 additions & 1 deletion audioread/maddec.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@

"""Decode MPEG audio files with MAD (via pymad)."""
import mad

from . import DecodeError


class UnsupportedError(DecodeError):
"""The file is not readable by MAD."""


class MadAudioFile(object):
class MadAudioFile:
"""MPEG audio file decoder using the MAD library."""
def __init__(self, filename):
self.fp = open(filename, 'rb')
Expand Down
12 changes: 4 additions & 8 deletions audioread/rawread.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,19 @@
# included in all copies or substantial portions of the Software.

"""Uses standard-library modules to read AIFF, AIFF-C, and WAV files."""
import wave
import aifc
import sunau
import audioop
import struct
import sys
import sunau
import wave

from .exceptions import DecodeError

# Produce two-byte (16-bit) output samples.
TARGET_WIDTH = 2

# Python 3.4 added support for 24-bit (3-byte) samples.
if sys.version_info > (3, 4, 0):
SUPPORTED_WIDTHS = (1, 2, 3, 4)
else:
SUPPORTED_WIDTHS = (1, 2, 4)
SUPPORTED_WIDTHS = (1, 2, 3, 4)


class UnsupportedError(DecodeError):
Expand All @@ -54,7 +50,7 @@ def byteswap(s):
return b''.join(parts)


class RawAudioFile(object):
class RawAudioFile:
"""An AIFF, WAV, or Au file that can be read by the Python standard
library modules ``wave``, ``aifc``, and ``sunau``.
"""
Expand Down
1 change: 0 additions & 1 deletion decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# included in all copies or substantial portions of the Software.

"""Command-line tool to decode audio files to WAV files."""
from __future__ import print_function
import audioread
import sys
import os
Expand Down
2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

17 changes: 5 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,15 @@ def _read(fn):

packages=['audioread'],

tests_require=[
'pytest-runner',
'pytest'
],

classifiers=[
'Topic :: Multimedia :: Sound/Audio :: Conversion',
'Intended Audience :: Developers',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
],
python_requires='>=3.6',
)
2 changes: 1 addition & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
def audiofile(request):
"""Fixture that provides an AudiofileSpec instance."""
spec_path = os.path.join(DATADIR, request.param + '.json')
with open(spec_path, 'r') as f:
with open(spec_path) as f:
spec = json.load(f)
result = AudiofileSpec(**spec)
return result
Expand Down
6 changes: 0 additions & 6 deletions test/test_audioread.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@
# included in all copies or substantial portions of the Software.


import json
import os
import sys

import pytest

import audioread


Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py27,py36
envlist = py36,py37,py38,py39,py310

[testenv]
deps = pytest
Expand Down