Skip to content

Commit

Permalink
Drop Python 3.2, 3.3, 3.4 gpiozero#799
Browse files Browse the repository at this point in the history
  • Loading branch information
fangchenli committed Oct 12, 2020
1 parent 3b9b785 commit ca3bbae
Show file tree
Hide file tree
Showing 20 changed files with 23 additions and 574 deletions.
12 changes: 1 addition & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
language: python
dist: trusty
python:
- "3.6"
- "3.5"
- "3.4"
- "3.3"
- "3.2"
- "2.7"
- "pypy"
- "pypy3"
matrix:
include:
- python: 3.7
dist: xenial
sudo: true

install: "pip install -e .[test]"
script: make test
before_install:
# Coverage 4.0 no longer supports py3.2 and codecov depends on latest coverage
- if [[ $TRAVIS_PYTHON_VERSION == '3.2' ]]; then pip install "coverage<4.0dev"; fi
- pip install codecov
after_success:
- codecov
Expand Down
109 changes: 2 additions & 107 deletions gpiozero/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,64 +38,14 @@
print_function,
division,
)
str = type('')

import math
import cmath
import weakref
import operator
import functools

# Handles pre 3.3 versions of Python without collections.abc
try:
from collections.abc import Mapping
except ImportError:
from collections import Mapping

# Back-ported from python 3.5; see
# github.com/PythonCHB/close_pep/blob/master/is_close.py for original
# implementation
def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
if rel_tol < 0.0 or abs_tol < 0.0:
raise ValueError('error tolerances must be non-negative')
if a == b: # fast-path for exact equality
return True
if cmath.isinf(a) or cmath.isinf(b):
return False
diff = abs(b - a)
return (
(diff <= abs(rel_tol * b)) or
(diff <= abs(rel_tol * a)) or
(diff <= abs_tol)
)


# Backported from py3.4
def mean(data):
if iter(data) is data:
data = list(data)
n = len(data)
if not n:
raise ValueError('cannot calculate mean of empty data')
return sum(data) / n
from collections.abc import Mapping


# Backported from py3.4
def median(data):
data = sorted(data)
n = len(data)
if not n:
raise ValueError('cannot calculate median of empty data')
elif n % 2:
return data[n // 2]
else:
i = n // 2
return (data[i - 1] + data[i]) / 2


# Backported from py3.3
def log2(x):
return math.log(x, 2)
str = type('')


# Copied from the MIT-licensed https://github.com/slezica/python-frozendict
Expand Down Expand Up @@ -124,58 +74,3 @@ def __hash__(self):
hashes = map(hash, self.items())
self.__hash = functools.reduce(operator.xor, hashes, 0)
return self.__hash


# Backported from py3.4
class WeakMethod(weakref.ref):
"""
A custom `weakref.ref` subclass which simulates a weak reference to
a bound method, working around the lifetime problem of bound methods.
"""

__slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__"

def __new__(cls, meth, callback=None):
try:
obj = meth.__self__
func = meth.__func__
except AttributeError:
raise TypeError("argument should be a bound method, not {0}"
.format(type(meth)))
def _cb(arg):
# The self-weakref trick is needed to avoid creating a reference
# cycle.
self = self_wr()
if self._alive:
self._alive = False
if callback is not None:
callback(self)
self = weakref.ref.__new__(cls, obj, _cb)
self._func_ref = weakref.ref(func, _cb)
self._meth_type = type(meth)
self._alive = True
self_wr = weakref.ref(self)
return self

def __call__(self):
obj = super(WeakMethod, self).__call__()
func = self._func_ref()
if obj is None or func is None:
return None
return self._meth_type(func, obj)

def __eq__(self, other):
if isinstance(other, WeakMethod):
if not self._alive or not other._alive:
return self is other
return weakref.ref.__eq__(self, other) and self._func_ref == other._func_ref
return False

def __ne__(self, other):
if isinstance(other, WeakMethod):
if not self._alive or not other._alive:
return self is not other
return weakref.ref.__ne__(self, other) or self._func_ref != other._func_ref
return True

__hash__ = weakref.ref.__hash__
3 changes: 0 additions & 3 deletions gpiozero/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
from collections import namedtuple, OrderedDict
from itertools import chain
from types import FunctionType
from threading import Lock

from .pins import Pin
from .threads import _threads_shutdown
from .mixins import (
ValuesMixin,
Expand Down
5 changes: 1 addition & 4 deletions gpiozero/input_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@
import warnings
from time import sleep, time
from threading import Event, Lock
try:
from statistics import median
except ImportError:
from .compat import median
from statistics import median

from .exc import InputDeviceError, DeviceClosed, DistanceSensorNoEcho, \
PinInvalidState, PWMSoftwareFallback
Expand Down
5 changes: 1 addition & 4 deletions gpiozero/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@
from functools import wraps, partial
from threading import Event
from collections import deque
try:
from statistics import median
except ImportError:
from .compat import median
from statistics import median
import warnings

from .threads import GPIOThread
Expand Down
5 changes: 1 addition & 4 deletions gpiozero/output_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@
from itertools import repeat, cycle, chain
from colorzero import Color
from collections import OrderedDict
try:
from math import log2
except ImportError:
from .compat import log2
from math import log2
import warnings

from .exc import OutputDeviceBadValue, GPIOPinMissing, PWMSoftwareFallback
Expand Down
1 change: 0 additions & 1 deletion gpiozero/pins/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import io
import errno
import struct
import warnings
from collections import defaultdict
from threading import Lock
try:
Expand Down
5 changes: 1 addition & 4 deletions gpiozero/pins/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@
from collections import namedtuple
from time import time, sleep
from threading import Thread, Event
try:
from math import isclose
except ImportError:
from ..compat import isclose
from math import isclose

import pkg_resources

Expand Down
2 changes: 0 additions & 2 deletions gpiozero/pins/native.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@
import errno
import struct
import select
import warnings
from time import sleep
from threading import Thread, Event, RLock
from collections import Counter
try:
from queue import Queue, Empty
except ImportError:
Expand Down
12 changes: 3 additions & 9 deletions gpiozero/pins/pi.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,10 @@
)
str = type('')

import io
from threading import RLock, Lock
from types import MethodType
from collections import defaultdict
try:
from weakref import ref, WeakMethod
except ImportError:

from ..compat import WeakMethod
from threading import RLock
from types import MethodType
from weakref import ref, WeakMethod
import warnings

try:
Expand All @@ -56,7 +51,6 @@
from ..exc import (
PinNoPins,
PinNonPhysical,
PinInvalidPin,
SPIBadArgs,
SPISoftwareFallback,
)
Expand Down
6 changes: 1 addition & 5 deletions gpiozero/tones.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@

import re
import warnings
from collections import namedtuple
try:
from math import log2
except ImportError:
from .compat import log2
from math import log2

from .exc import AmbiguousTone

Expand Down
11 changes: 2 additions & 9 deletions gpiozero/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,8 @@
except ImportError:
pass
from itertools import cycle
from math import sin, cos, pi
try:
from statistics import mean
except ImportError:
from .compat import mean
try:
from math import isclose
except ImportError:
from .compat import isclose
from math import sin, cos, pi, isclose
from statistics import mean


def _normalize(values):
Expand Down
22 changes: 3 additions & 19 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"A simple interface to GPIO devices with Raspberry Pi."
"""A simple interface to GPIO devices with Raspberry Pi."""

import io
import os
Expand All @@ -10,8 +10,8 @@
if not sys.version_info >= (2, 7):
raise ValueError('This package requires Python 2.7 or above')
elif sys.version_info[0] == 3:
if not sys.version_info >= (3, 2):
raise ValueError('This package requires Python 3.2 or above')
if not sys.version_info >= (3, 5):
raise ValueError('This package requires Python 3.5 or above')
else:
raise ValueError('Unrecognized major version of Python')

Expand Down Expand Up @@ -40,9 +40,6 @@
"Programming Language :: Python :: 2",
"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",
Expand All @@ -63,19 +60,6 @@
'test': ['pytest', 'coverage', 'mock'],
}

if sys.version_info[:2] == (3, 2):
# Particular versions are required for Python 3.2 compatibility
__extra_requires__['doc'].extend([
'Jinja2<2.7',
'MarkupSafe<0.16',
])
__extra_requires__['test'][0] = 'pytest<3.0dev'
__extra_requires__['test'][1] = 'coverage<4.0dev'
elif sys.version_info[:2] == (3, 3):
__extra_requires__['test'][0] = 'pytest<3.3dev'
elif sys.version_info[:2] == (3, 4):
__extra_requires__['test'][0] = 'pytest<5.0dev'

try:
# If we're executing on a Raspberry Pi, install all GPIO libraries for
# testing (except RPIO which doesn't work on the multi-core models yet)
Expand Down
Loading

0 comments on commit ca3bbae

Please sign in to comment.