Merge pull request #400 from waveform80/pin-entry-points

Fix #359, close #396
This commit is contained in:
Dave Jones
2016-08-14 13:58:35 +01:00
committed by GitHub
3 changed files with 42 additions and 19 deletions

View File

@@ -7,6 +7,7 @@ from __future__ import (
nstr = str
str = type('')
import os
import atexit
import weakref
from collections import namedtuple
@@ -14,12 +15,16 @@ from itertools import chain
from types import FunctionType
from threading import RLock
import pkg_resources
from .threads import _threads_shutdown
from .pins import _pins_shutdown
from .mixins import (
ValuesMixin,
SharedMixin,
)
from .exc import (
BadPinFactory,
DeviceClosed,
CompositeDeviceBadName,
CompositeDeviceBadOrder,
@@ -30,25 +35,32 @@ from .exc import (
)
from .compat import frozendict
# Get a pin implementation to use as the default; we prefer RPi.GPIO's here
# as it supports PWM, and all Pi revisions. If no third-party libraries are
# available, however, we fall back to a pure Python implementation which
# supports platforms like PyPy
from .pins import _pins_shutdown
try:
from .pins.rpigpio import RPiGPIOPin
pin_factory = RPiGPIOPin
except ImportError:
try:
from .pins.rpio import RPIOPin
pin_factory = RPIOPin
except ImportError:
try:
from .pins.pigpiod import PiGPIOPin
pin_factory = PiGPIOPin
except ImportError:
from .pins.native import NativePin
pin_factory = NativePin
def _default_pin_factory(name=os.getenv('GPIOZERO_PIN_FACTORY', None)):
group = 'gpiozero_pin_factories'
if name is None:
# If no factory is explicitly specified, try various names in
# "preferred" order. Note that in this case we only select from
# gpiozero distribution so without explicitly specifying a name (via
# the environment) it's impossible to auto-select a factory from
# outside the base distribution
#
# We prefer RPi.GPIO here as it supports PWM, and all Pi revisions. If
# no third-party libraries are available, however, we fall back to a
# pure Python implementation which supports platforms like PyPy
dist = pkg_resources.get_distribution('gpiozero')
for name in ('RPiGPIOPin', 'RPIOPin', 'PiGPIOPin', 'NativePin'):
try:
return pkg_resources.load_entry_point(dist, group, name)
except ImportError:
pass
raise BadPinFactory('Unable to locate any default pin factory!')
else:
for factory in pkg_resources.iter_entry_points(group, name):
return factory.load()
raise BadPinFactory('Unable to locate pin factory "%s"' % name)
pin_factory = _default_pin_factory()
_PINS = set()

View File

@@ -22,6 +22,9 @@ class BadWaitTime(GPIOZeroError, ValueError):
class BadQueueLen(GPIOZeroError, ValueError):
"Error raised when non-positive queue length is specified"
class BadPinFactory(GPIOZeroError, ImportError):
"Error raised when an unknown pin factory name is specified"
class CompositeDeviceError(GPIOZeroError):
"Base class for errors specific to the CompositeDevice hierarchy"

View File

@@ -61,6 +61,14 @@ if sys.version_info[:2] == (3, 2):
__extra_requires__['test'][1] = 'coverage<4.0dev'
__entry_points__ = {
'gpiozero_pin_factories': [
'PiGPIOPin = gpiozero.pins.pigpiod:PiGPIOPin',
'RPiGPIOPin = gpiozero.pins.rpigpio:RPiGPIOPin',
'RPIOPin = gpiozero.pins.rpio:RPIOPin',
'NativePin = gpiozero.pins.native:NativePin',
'MockPin = gpiozero.pins.mock:MockPin',
'MockPWMPin = gpiozero.pins.mock:MockPWMPin',
],
}