diff --git a/gpiozero/input_devices.py b/gpiozero/input_devices.py index adb035b..c8a25d1 100644 --- a/gpiozero/input_devices.py +++ b/gpiozero/input_devices.py @@ -1,6 +1,7 @@ from __future__ import division import inspect +import warnings from functools import wraps from time import sleep, time from threading import Event @@ -27,6 +28,10 @@ class InputDevice(GPIODevice): Generic GPIO Input Device. """ def __init__(self, pin=None, pull_up=False): + if pin in (2, 3) and not pull_up: + raise InputDeviceError( + 'GPIO pins 2 and 3 are fitted with physical pull up ' + 'resistors; you cannot initialize them with pull_up=False') super(InputDevice, self).__init__(pin) self._pull_up = pull_up self._active_edge = GPIO.FALLING if pull_up else GPIO.RISING @@ -34,7 +39,19 @@ class InputDevice(GPIODevice): self._active_state = GPIO.LOW if pull_up else GPIO.HIGH self._inactive_state = GPIO.HIGH if pull_up else GPIO.LOW pull = GPIO.PUD_UP if pull_up else GPIO.PUD_DOWN - GPIO.setup(pin, GPIO.IN, pull) + + # NOTE: catch_warnings isn't thread-safe but hopefully no-one's messing + # around with GPIO init within background threads... + with warnings.catch_warnings(record=True) as w: + GPIO.setup(pin, GPIO.IN, pull) + # The only warning we want to squash is a RuntimeWarning that is thrown + # when setting pins 2 or 3. Anything else should be replayed + for warning in w: + if warning.category != RuntimeWarning or pin not in (2, 3): + warnings.showwarning( + warning.message, warning.category, warning.filename, + warning.lineno, warning.file, warning.line + ) @property def pull_up(self): @@ -217,7 +234,7 @@ class Button(DigitalInputDevice): def __init__(self, pin=None, pull_up=True, bouncetime=None): super(Button, self).__init__(pin, pull_up, bouncetime) - is_pressed = alias('is_active') + is_pressed = _alias('is_active') when_pressed = _alias('when_activated') when_released = _alias('when_deactivated') diff --git a/gpiozero/output_devices.py b/gpiozero/output_devices.py index 3a87b8a..096ff2c 100644 --- a/gpiozero/output_devices.py +++ b/gpiozero/output_devices.py @@ -1,3 +1,4 @@ +import warnings from time import sleep from threading import Lock from itertools import repeat @@ -17,7 +18,17 @@ class OutputDevice(GPIODevice): """ def __init__(self, pin=None): super(OutputDevice, self).__init__(pin) - GPIO.setup(pin, GPIO.OUT) + # NOTE: catch_warnings isn't thread-safe but hopefully no-one's messing + # around with GPIO init within background threads... + with warnings.catch_warnings(record=True) as w: + GPIO.setup(pin, GPIO.OUT) + # The only warning we want to squash is a RuntimeWarning that is thrown + # when setting pins 2 or 3. Anything else should be replayed + for warning in w: + if warning.category != RuntimeWarning or pin not in (2, 3): + warnings.showwarning( + warning.message, warning.category, warning.filename, + warning.lineno, warning.file, warning.line) def on(self): """