mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	Move exceptions to their own sub-module
This removes the circular dependency introduced in PR#137. This also fixes up an issue in the base meta-class which meant it wasn't working in Python 3 (only Python 2), and adds a bit to the meta-class to allow docstrings to be inherited (taken from the rest-docs branch).
This commit is contained in:
		| @@ -4,15 +4,18 @@ from __future__ import ( | ||||
|     absolute_import, | ||||
|     division, | ||||
|     ) | ||||
| nstr = str | ||||
| str = type('') | ||||
|  | ||||
| import atexit | ||||
| import weakref | ||||
| from threading import Thread, Event, RLock | ||||
| from collections import deque | ||||
| from types import FunctionType | ||||
|  | ||||
| from RPi import GPIO | ||||
|  | ||||
| from .input_devices import InputDeviceError | ||||
| from .exc import GPIODeviceError, GPIODeviceClosed, InputDeviceError | ||||
|  | ||||
| _GPIO_THREADS = set() | ||||
| _GPIO_PINS = set() | ||||
| @@ -35,21 +38,28 @@ GPIO.setmode(GPIO.BCM) | ||||
| GPIO.setwarnings(False) | ||||
|  | ||||
|  | ||||
| class GPIODeviceError(Exception): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class GPIODeviceClosed(GPIODeviceError): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class GPIOFixedAttrs(type): | ||||
| class GPIOMeta(type): | ||||
|     # NOTE Yes, this is a metaclass. Don't be scared - it's a simple one. | ||||
|  | ||||
|     def __call__(cls, *args, **kwargs): | ||||
|         # Construct the class as normal and ensure it's a subclass of GPIOBase | ||||
|         # (defined below with a custom __setattrs__) | ||||
|         result = super(GPIOFixedAttrs, cls).__call__(*args, **kwargs) | ||||
|     def __new__(mcls, name, bases, cls_dict): | ||||
|         # Construct the class as normal | ||||
|         cls = super(GPIOMeta, mcls).__new__(mcls, name, bases, cls_dict) | ||||
|         for attr_name, attr in cls_dict.items(): | ||||
|             # If there's a method in the class which has no docstring, search | ||||
|             # the base classes recursively for a docstring to copy | ||||
|             if isinstance(attr, FunctionType) and not attr.__doc__: | ||||
|                 for base_cls in cls.__mro__: | ||||
|                     if hasattr(base_cls, attr_name): | ||||
|                         base_fn = getattr(base_cls, attr_name) | ||||
|                         if base_fn.__doc__: | ||||
|                             attr.__doc__ = base_fn.__doc__ | ||||
|                             break | ||||
|         return cls | ||||
|  | ||||
|     def __call__(mcls, *args, **kwargs): | ||||
|         # Construct the instance as normal and ensure it's an instance of | ||||
|         # GPIOBase (defined below with a custom __setattrs__) | ||||
|         result = super(GPIOMeta, mcls).__call__(*args, **kwargs) | ||||
|         assert isinstance(result, GPIOBase) | ||||
|         # At this point __new__ and __init__ have all been run. We now fix the | ||||
|         # set of attributes on the class by dir'ing the instance and creating a | ||||
| @@ -59,9 +69,8 @@ class GPIOFixedAttrs(type): | ||||
|         return result | ||||
|  | ||||
|  | ||||
| class GPIOBase(object): | ||||
|     __metaclass__ = GPIOFixedAttrs | ||||
|  | ||||
| # Cross-version compatible method of using a metaclass | ||||
| class GPIOBase(GPIOMeta(nstr('GPIOBase'), (), {})): | ||||
|     def __setattr__(self, name, value): | ||||
|         # This overridden __setattr__ simply ensures that additional attributes | ||||
|         # cannot be set on the class after construction (it manages this in | ||||
|   | ||||
		Reference in New Issue
	
	Block a user