From d56ca0ee4fde7fa4ad82a532f9ea387f9f33d389 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 16 Mar 2021 17:52:49 +0000 Subject: [PATCH] Migrate to setup.cfg (cherry picked from commit b167bef82c3bf2739707f062b35fcabbb9cc11ad) setup.cfg seems to be mandatory since (at least) setuptools 67.8.0 otherwise gpiozero dependencies are not properly detected File "/builds/buildroot.org/buildroot/test-output/TestPythonPy3Gpiozero/host/lib/python3.11/site-packages/pkg_resources/__init__.py", line 868, in _resolve_dist raise DistributionNotFound(req, requirers) pkg_resources.DistributionNotFound: The 'colorzero' distribution was not found and is required by the application Upstream: https://github.com/gpiozero/gpiozero/commit/b167bef82c3bf2739707f062b35fcabbb9cc11ad See: http://lists.busybox.net/pipermail/buildroot/2023-June/669207.html [Romain: rebase on 1.6.2] Signed-off-by: Romain Naour --- MANIFEST.in | 4 -- Makefile | 88 +++++--------------------------- copyrights | 56 +++++++++++--------- copyrights.cfg | 11 ---- coverage.cfg | 18 ------- docs/conf.py | 99 +++++++++++++++-------------------- setup.cfg | 98 +++++++++++++++++++++++++++++++++++ setup.py | 136 +++++-------------------------------------------- 8 files changed, 196 insertions(+), 314 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 copyrights.cfg delete mode 100644 coverage.cfg create mode 100644 setup.cfg diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index bb562ea..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -include README.rst -recursive-include gpiozero/fonts *.txt -recursive-include tests *.py -include LICENSE.rst diff --git a/Makefile b/Makefile index c9ddd90..264a73c 100644 --- a/Makefile +++ b/Makefile @@ -4,44 +4,18 @@ PYTHON=python PIP=pip PYTEST=py.test -COVERAGE=coverage TWINE=twine PYFLAGS= DEST_DIR=/ -# Horrid hack to ensure setuptools is installed in our python environment. This -# is necessary with Python 3.3's venvs which don't install it by default. -ifeq ($(shell python -c "import setuptools" 2>&1),) -SETUPTOOLS:= -else -SETUPTOOLS:=$(shell wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | $(PYTHON)) -endif - # Calculate the base names of the distribution, the location of all source, # documentation, packaging, icon, and executable script files NAME:=$(shell $(PYTHON) $(PYFLAGS) setup.py --name) VER:=$(shell $(PYTHON) $(PYFLAGS) setup.py --version) -ifeq ($(shell lsb_release -si),Ubuntu) -DEB_SUFFIX:=ubuntu1 -else -DEB_SUFFIX:= -endif -DEB_ARCH:=$(shell dpkg --print-architecture) PYVER:=$(shell $(PYTHON) $(PYFLAGS) -c "import sys; print('py%d.%d' % sys.version_info[:2])") PY_SOURCES:=$(shell \ $(PYTHON) $(PYFLAGS) setup.py egg_info >/dev/null 2>&1 && \ grep -v "\.egg-info" $(NAME).egg-info/SOURCES.txt) -DEB_SOURCES:=debian/changelog \ - debian/control \ - debian/copyright \ - debian/rules \ - debian/docs \ - $(wildcard debian/*.init) \ - $(wildcard debian/*.default) \ - $(wildcard debian/*.manpages) \ - $(wildcard debian/*.docs) \ - $(wildcard debian/*.doc-base) \ - $(wildcard debian/*.desktop) DOC_SOURCES:=docs/conf.py \ $(wildcard docs/*.png) \ $(wildcard docs/*.svg) \ @@ -56,17 +30,6 @@ SUBDIRS:= DIST_WHEEL=dist/$(NAME)-$(VER)-py2.py3-none-any.whl DIST_TAR=dist/$(NAME)-$(VER).tar.gz DIST_ZIP=dist/$(NAME)-$(VER).zip -DIST_DEB=dist/python-$(NAME)_$(VER)$(DEB_SUFFIX)_all.deb \ - dist/python3-$(NAME)_$(VER)$(DEB_SUFFIX)_all.deb \ - dist/python-$(NAME)-doc_$(VER)$(DEB_SUFFIX)_all.deb \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX)_$(DEB_ARCH).build \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX)_$(DEB_ARCH).buildinfo \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX)_$(DEB_ARCH).changes -DIST_DSC=dist/$(NAME)_$(VER)$(DEB_SUFFIX).tar.xz \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX).dsc \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX)_source.build \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX)_source.buildinfo \ - dist/$(NAME)_$(VER)$(DEB_SUFFIX)_source.changes # Default target @@ -76,10 +39,9 @@ all: @echo "make test - Run tests" @echo "make doc - Generate HTML and PDF documentation" @echo "make source - Create source package" - @echo "make egg - Generate a PyPI egg package" + @echo "make wheel - Generate a PyPI wheel package" @echo "make zip - Generate a source zip package" @echo "make tar - Generate a source tar package" - @echo "make deb - Generate Debian packages" @echo "make dist - Generate all packages" @echo "make clean - Get rid of all generated files" @echo "make release - Create and tag a new release" @@ -102,9 +64,7 @@ zip: $(DIST_ZIP) tar: $(DIST_TAR) -deb: $(DIST_DEB) $(DIST_DSC) - -dist: $(DIST_WHEEL) $(DIST_DEB) $(DIST_DSC) $(DIST_TAR) $(DIST_ZIP) +dist: $(DIST_WHEEL) $(DIST_TAR) $(DIST_ZIP) develop: @# These have to be done separately to avoid a cockup... @@ -113,18 +73,17 @@ develop: $(PIP) install -e .[doc,test] test: - $(COVERAGE) run --rcfile coverage.cfg -m $(PYTEST) tests -v -r sx - $(COVERAGE) report --rcfile coverage.cfg + $(PYTEST) tests clean: - dh_clean - rm -fr dist/ $(NAME).egg-info/ tags + rm -fr dist/ build/ .pytest_cache/ .mypy_cache/ $(NAME).egg-info/ tags .coverage for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir clean; \ done + find $(CURDIR) -name "*.pyc" -delete tags: $(PY_SOURCES) - ctags -R --exclude="build/*" --exclude="debian/*" --exclude="docs/*" --languages="Python" + ctags -R --exclude="build/*" --exclude="docs/*" --languages="Python" $(SUBDIRS): $(MAKE) -C $@ @@ -138,37 +97,14 @@ $(DIST_ZIP): $(PY_SOURCES) $(SUBDIRS) $(DIST_WHEEL): $(PY_SOURCES) $(SUBDIRS) $(PYTHON) $(PYFLAGS) setup.py bdist_wheel --universal -$(DIST_DEB): $(PY_SOURCES) $(SUBDIRS) $(DEB_SOURCES) $(DIST_TAR) - cp $(DIST_TAR) ../$(NAME)_$(VER).orig.tar.gz - debuild -b - mkdir -p dist/ - for f in $(DIST_DEB); do cp ../$${f##*/} dist/; done - -$(DIST_DSC): $(PY_SOURCES) $(SUBDIRS) $(DEB_SOURCES) $(DIST_TAR) - cp $(DIST_TAR) ../$(NAME)_$(VER).orig.tar.gz - debuild -S - mkdir -p dist/ - for f in $(DIST_DSC); do cp ../$${f##*/} dist/; done - -copyrights: $(PY_SOURCES) $(DOC_SOURCES) - ./copyrights - -changelog: $(PY_SOURCES) $(DOC_SOURCES) $(DEB_SOURCES) +release: $(MAKE) clean - # ensure there are no current uncommitted changes test -z "$(shell git status --porcelain)" - # update the debian changelog with new release information - dch --newversion $(VER)$(DEB_SUFFIX) - # commit the changes and add a new tag - git commit debian/changelog -m "Updated changelog for release $(VER)" - -release: $(DIST_DEB) $(DIST_DSC) $(DIST_TAR) $(DIST_WHEEL) git tag -s v$(VER) -m "Release v$(VER)" - git push --tags - # build a source archive and upload to PyPI + git push origin v$(VER) + +upload: $(DIST_TAR) $(DIST_WHEEL) + $(TWINE) check $(DIST_TAR) $(DIST_WHEEL) $(TWINE) upload $(DIST_TAR) $(DIST_WHEEL) - # build the deb source archive and upload to Raspbian - dput raspberrypi dist/$(NAME)_$(VER)$(DEB_SUFFIX)_source.changes - dput raspberrypi dist/$(NAME)_$(VER)$(DEB_SUFFIX)_$(DEB_ARCH).changes -.PHONY: all install develop test doc source egg wheel zip tar deb dist clean tags release upload $(SUBDIRS) +.PHONY: all install develop test doc source wheel zip tar dist clean tags release upload $(SUBDIRS) diff --git a/copyrights b/copyrights index b709fc8..2f14e78 100755 --- a/copyrights +++ b/copyrights @@ -6,10 +6,13 @@ derives the authorship and copyright years information from the git history of the project; hence, this script must be run within a git repository. """ +from __future__ import annotations + import os import sys assert sys.version_info >= (3, 6), 'Script requires Python 3.6+' import tempfile +import typing as t from argparse import ArgumentParser, Namespace from configparser import ConfigParser from operator import attrgetter @@ -18,14 +21,13 @@ from datetime import datetime from subprocess import Popen, PIPE, DEVNULL from pathlib import Path from fnmatch import fnmatch -from typing import NamedTuple, Iterator, List, Tuple, Set, Union, Optional SPDX_PREFIX = 'SPDX-License-Identifier:' COPYRIGHT_PREFIX = 'Copyright (c)' -def main(args: List[str] = None): +def main(args: t.List[str] = None): if args is None: args = sys.argv[1:] config = get_config(args) @@ -41,7 +43,7 @@ def main(args: List[str] = None): target.write(chunk) -def get_config(args: List[str]) -> Namespace: +def get_config(args: t.List[str]) -> Namespace: config = ConfigParser( defaults={ 'include': '**/*', @@ -52,10 +54,10 @@ def get_config(args: List[str]) -> Namespace: 'spdx_prefix': SPDX_PREFIX, 'copy_prefix': COPYRIGHT_PREFIX, }, - delimiters=('=',), default_section='settings', + delimiters=('=',), default_section='copyrights:settings', empty_lines_in_values=False, interpolation=None, converters={'list': lambda s: s.strip().splitlines() }) - config.read('copyrights.cfg') + config.read('setup.cfg') sect = config[config.default_section] parser = ArgumentParser(description=__doc__) @@ -113,10 +115,10 @@ def get_config(args: List[str]) -> Namespace: return ns -class Copyright(NamedTuple): +class Copyright(t.NamedTuple): author: str email: str - years: Set[int] + years: t.Set[int] def __str__(self): if len(self.years) > 1: @@ -126,8 +128,8 @@ class Copyright(NamedTuple): return f'{years} {self.author} <{self.email}>' -def get_copyrights(include: Set[str], exclude: Set[str])\ - -> Iterator[Tuple[Path, List[Copyright]]]: +def get_copyrights(include: t.Set[str], exclude: t.Set[str])\ + -> t.Iterator[t.Tuple[Path, t.Container[Copyright]]]: sorted_blame = sorted( get_contributions(include, exclude), key=lambda c: (c.path, c.author, c.email) @@ -147,15 +149,15 @@ def get_copyrights(include: Set[str], exclude: Set[str])\ yield path, copyrights -class Contribution(NamedTuple): +class Contribution(t.NamedTuple): author: str email: str year: int path: Path -def get_contributions(include: Set[str], exclude: Set[str])\ - -> Iterator[Contribution]: +def get_contributions(include: t.Set[str], exclude: t.Set[str])\ + -> t.Iterator[Contribution]: for path in get_source_paths(include, exclude): blame = Popen( ['git', 'blame', '--line-porcelain', 'HEAD', '--', str(path)], @@ -186,7 +188,8 @@ def get_contributions(include: Set[str], exclude: Set[str])\ assert blame.returncode == 0 -def get_source_paths(include: Set[str], exclude: Set[str]) -> Iterator[Path]: +def get_source_paths(include: t.Set[str], exclude: t.Set[str])\ + -> t.Iterator[Path]: ls_tree = Popen( ['git', 'ls-tree', '-r', '--name-only', 'HEAD'], stdout=PIPE, stderr=DEVNULL, universal_newlines=True) @@ -203,9 +206,9 @@ def get_source_paths(include: Set[str], exclude: Set[str]) -> Iterator[Path]: assert ls_tree.returncode == 0 -class License(NamedTuple): - ident: Optional[str] - text: List[str] +class License(t.NamedTuple): + ident: t.Optional[str] + text: t.List[str] def get_license(path: Path, *, spdx_prefix: str = SPDX_PREFIX) -> License: @@ -253,20 +256,26 @@ class CopyWriter: '.sql': '--', } - def __init__(self, license='LICENSE.txt', preamble=(), - spdx_prefix=SPDX_PREFIX, copy_prefix=COPYRIGHT_PREFIX): + def __init__(self, license: Path=Path('LICENSE.txt'), + preamble: t.List[str]=None, + spdx_prefix: str=SPDX_PREFIX, + copy_prefix: str=COPYRIGHT_PREFIX): + if preamble is None: + preamble = [] self.license = get_license(license, spdx_prefix=spdx_prefix) self.preamble = preamble self.spdx_prefix = spdx_prefix self.copy_prefix = copy_prefix @classmethod - def from_config(cls, config): + def from_config(cls, config: Namespace) -> CopyWriter: return cls( config.license, config.preamble, config.spdx_prefix, config.copy_prefix) - def transform(self, source, copyrights, *, comment_prefix=None): + def transform(self, source: t.TextIO, + copyrights: t.List[Copyright], *, + comment_prefix: str=None) -> t.Iterator[str]: if comment_prefix is None: comment_prefix = self.COMMENTS[Path(source.name).suffix] license_start = self.license.text[0] @@ -279,7 +288,7 @@ class CopyWriter: yield line empty = False elif linenum < 3 and ( - 'set fileencoding=' in line or '-*- coding:' in line): + 'fileencoding=' in line or '-*- coding:' in line): yield line empty = False elif line.rstrip() == comment_prefix: @@ -313,7 +322,8 @@ class CopyWriter: elif state == 'body': yield line - def _generate_header(self, copyrights, comment_prefix, empty): + def _generate_header(self, copyrights: t.Iterable[Copyright], + comment_prefix: str, empty: bool) -> t.Iterator[str]: if not empty: yield comment_prefix + '\n' for line in self.preamble: @@ -356,7 +366,7 @@ class AtomicReplaceFile: If ``None`` (the default), the temporary file will be opened in binary mode. Otherwise, this specifies the encoding to use with text mode. """ - def __init__(self, path: Union[str, Path], encoding: str = None): + def __init__(self, path: t.Union[str, Path], encoding: str = None): if isinstance(path, str): path = Path(path) self._path = path diff --git a/copyrights.cfg b/copyrights.cfg deleted file mode 100644 index de68dbe..0000000 --- a/copyrights.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[settings] -include= - **/*.py - **/*.rst -exclude= - docs/examples/*.py - docs/license.rst -license=LICENSE.rst -preamble= - GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins -strip-preamble=no diff --git a/coverage.cfg b/coverage.cfg deleted file mode 100644 index e3f3349..0000000 --- a/coverage.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[run] -branch = True -include = gpiozero/* -;omit = */bar.py,*/baz.py - -[report] -ignore_errors = True -show_missing = True -exclude_lines = - pragma: no cover - assert False - raise AssertionError - raise NotImplementedError - pass - if __name__ == .__main__.: - -[html] -directory = coverage diff --git a/docs/conf.py b/docs/conf.py index 998ae91..626ae29 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,62 +11,34 @@ import sys import os +from pathlib import Path from datetime import datetime -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -import setup as _setup - -# Mock out certain modules while building documentation -class Mock(object): - __all__ = [] - - def __init__(self, *args, **kw): - pass - - def __call__(self, *args, **kw): - return Mock() - - def __mul__(self, other): - return Mock() - - def __and__(self, other): - return Mock() +from setuptools.config import read_configuration - def __bool__(self): - return False - - def __nonzero__(self): - return False - - @classmethod - def __getattr__(cls, name): - if name in ('__file__', '__path__'): - return '/dev/null' - else: - return Mock() - -sys.modules['RPi'] = Mock() -sys.modules['RPi.GPIO'] = sys.modules['RPi'].GPIO -sys.modules['lgpio'] = Mock() -sys.modules['RPIO'] = Mock() -sys.modules['RPIO.PWM'] = sys.modules['RPIO'].PWM -sys.modules['RPIO.Exceptions'] = sys.modules['RPIO'].Exceptions -sys.modules['pigpio'] = Mock() -sys.modules['w1thermsensor'] = Mock() -sys.modules['spidev'] = Mock() -sys.modules['colorzero'] = Mock() +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +config = read_configuration(str(Path(__file__).parent / '..' / 'setup.cfg')) +info = config['metadata'] # -- General configuration ------------------------------------------------ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx'] +if on_rtd: + needs_sphinx = '1.4.0' + extensions.append('sphinx.ext.imgmath') + imgmath_image_format = 'svg' + tags.add('rtd') +else: + extensions.append('sphinx.ext.mathjax') + mathjax_path = '/usr/share/javascript/mathjax/MathJax.js?config=TeX-AMS_HTML' + templates_path = ['_templates'] source_suffix = '.rst' #source_encoding = 'utf-8-sig' master_doc = 'index' -project = 'GPIO Zero' -copyright = '2015-%s %s' % (datetime.now().year, _setup.__author__) -version = _setup.__version__ -release = _setup.__version__ +project = info['name'] +copyright = '2015-{now:%Y} {info[author]}'.format(now=datetime.now(), info=info) +version = info['version'] +#release = None #language = None #today_fmt = '%B %d, %Y' exclude_patterns = ['_build'] @@ -82,6 +54,15 @@ pygments_style = 'sphinx' # -- Autodoc configuration ------------------------------------------------ autodoc_member_order = 'groupwise' +autodoc_mock_imports = [ + 'RPi', + 'lgpio', + 'RPIO', + 'pigpio', + 'w1thermsensor', + 'spidev', + 'colorzero', +] # -- Intersphinx configuration -------------------------------------------- @@ -94,7 +75,7 @@ intersphinx_mapping = { # -- Options for HTML output ---------------------------------------------- html_theme = 'sphinx_rtd_theme' -html_title = '%s %s Documentation' % (project, version) +html_title = '{info[name]} {info[version]} Documentation'.format(info=info) #html_theme_path = [] #html_short_title = None #html_logo = None @@ -112,7 +93,7 @@ html_static_path = ['_static'] #html_show_copyright = True #html_use_opensearch = '' #html_file_suffix = None -htmlhelp_basename = '%sdoc' % _setup.__project__ +htmlhelp_basename = '{info[name]}doc'.format(info=info) # Hack to make wide tables work properly in RTD # See https://github.com/snide/sphinx_rtd_theme/issues/117 for details @@ -131,12 +112,12 @@ latex_elements = { latex_documents = [ ( - 'index', # source start file - '%s.tex' % _setup.__project__, # target filename - '%s Documentation' % project, # title - _setup.__author__, # author - 'manual', # documentclass - True, # documents ref'd from toctree only + 'index', # source start file + project + '.tex', # target filename + html_title, # title + info['author'], # author + 'manual', # documentclass + True, # documents ref'd from toctree only ), ] @@ -149,11 +130,11 @@ latex_show_urls = 'footnote' # -- Options for epub output ---------------------------------------------- -epub_basename = _setup.__project__ +epub_basename = project #epub_theme = 'epub' #epub_title = html_title -epub_author = _setup.__author__ -epub_identifier = 'https://gpiozero.readthedocs.io/' +epub_author = info['author'] +epub_identifier = 'https://{info[name]}.readthedocs.io/'.format(info=info) #epub_tocdepth = 3 epub_show_urls = 'no' #epub_use_index = True @@ -161,8 +142,8 @@ epub_show_urls = 'no' # -- Options for manual page output --------------------------------------- man_pages = [ - ('cli_pinout', 'pinout', 'GPIO Zero pinout tool', [_setup.__author__], 1), - ('remote_gpio', 'remote-gpio', 'GPIO Zero remote GPIO guide', [_setup.__author__], 7), + ('cli_pinout', 'pinout', 'GPIO Zero pinout tool', [info['author']], 1), + ('remote_gpio', 'remote-gpio', 'GPIO Zero remote GPIO guide', [info['author']], 7), ] man_show_urls = True diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..db0cfa4 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,98 @@ +[metadata] +name = gpiozero +version = 1.6.2 +description = A simple interface to GPIO devices with Raspberry Pi +long_description = file:README.rst +author = Ben Nuttall +author_email = ben@bennuttall.com +url = https://gpiozero.readthedocs.io/ +project_urls = + Documentation = https://gpiozero.readthedocs.io/ + Source Code = https://github.com/gpiozero/gpiozero + Issue Tracker = https://github.com/gpiozero/gpiozero/issues +keywords = raspberrypi gpio +license = BSD-3-Clause +classifiers = + Development Status :: 5 - Production/Stable + Intended Audience :: Education + Intended Audience :: Developers + Topic :: Education + Topic :: System :: Hardware + License :: OSI Approved :: BSD License + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + 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 :: Implementation :: PyPy + +[options] +packages = find: +install_requires = + colorzero + +[options.package_data] +gpiozero = + fonts/*.txt + +[options.extras_require] +test = + pytest + pytest-cov +doc = + sphinx + sphinx-rtd-theme + +[options.entry_points] +console_scripts = + pinout = gpiozerocli.pinout:main +gpiozero_pin_factories = + pigpio = gpiozero.pins.pigpio:PiGPIOFactory + lgpio = gpiozero.pins.lgpio:LGPIOFactory + rpigpio = gpiozero.pins.rpigpio:RPiGPIOFactory + rpio = gpiozero.pins.rpio:RPIOFactory + native = gpiozero.pins.native:NativeFactory + mock = gpiozero.pins.mock:MockFactory + PiGPIOPin = gpiozero.pins.pigpio:PiGPIOFactory + RPiGPIOPin = gpiozero.pins.rpigpio:RPiGPIOFactory + RPIOPin = gpiozero.pins.rpio:RPIOFactory + NativePin = gpiozero.pins.native:NativeFactory +gpiozero_mock_pin_classes = + mockpin = gpiozero.pins.mock:MockPin + mockpwmpin = gpiozero.pins.mock:MockPWMPin + mockchargingpin = gpiozero.pins.mock:MockChargingPin + mocktriggerpin = gpiozero.pins.mock:MockTriggerPin + +[tools:pytest] +addopts = -rsx --cov --tb=short +testpaths = tests + +[coverage:run] +source = gpiozero +branch = true + +[coverage:report] +ignore_errors = true +show_missing = true +exclude_lines = + pragma: no cover + assert False + raise AssertionError + raise NotImplementedError + pass + if __name__ == .__main__.: + +[copyrights:settings] +include = + **/*.py + **/*.rst +exclude = + docs/examples/*.py + docs/license.rst +license = LICENSE.rst +preamble = + GPIO Zero: a library for controlling the Raspberry Pi's GPIO pins +strip-preamble = false diff --git a/setup.py b/setup.py index 621398a..fc644b6 100644 --- a/setup.py +++ b/setup.py @@ -1,139 +1,29 @@ -"A simple interface to GPIO devices with Raspberry Pi." +from __future__ import ( + unicode_literals, + absolute_import, +) +str = type('') import io import os -import sys import errno -from setuptools import setup, find_packages +from setuptools import setup, config -if sys.version_info[0] == 2: - 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') -else: - raise ValueError('Unrecognized major version of Python') - -HERE = os.path.abspath(os.path.dirname(__file__)) - -# Workaround -try: - import multiprocessing -except ImportError: - pass - -__project__ = 'gpiozero' -__version__ = '1.6.2' -__author__ = 'Ben Nuttall' -__author_email__ = 'ben@bennuttall.com' -__url__ = 'https://github.com/gpiozero/gpiozero' -__platforms__ = 'ALL' - -__classifiers__ = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Education", - "Intended Audience :: Developers", - "Topic :: Education", - "Topic :: System :: Hardware", - "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "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 :: Implementation :: PyPy", -] - -__keywords__ = [ - 'raspberrypi', - 'gpio', -] - -__requires__ = [ - 'colorzero', -] - -__extra_requires__ = { - 'doc': ['sphinx', 'sphinx_rtd_theme'], - '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' +cfg = config.read_configuration( + os.path.join(os.path.dirname(__file__), 'setup.cfg')) 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) with io.open('/proc/device-tree/model', 'r') as f: if f.read().startswith('Raspberry Pi'): - __extra_requires__['test'].append('RPi.GPIO') - __extra_requires__['test'].append('pigpio') + cfg['options']['extras_require']['test'].append('RPI.GPIO') + cfg['options']['extras_require']['test'].append('pigpio') except IOError as e: if e.errno != errno.ENOENT: raise -__entry_points__ = { - 'gpiozero_pin_factories': [ - 'pigpio = gpiozero.pins.pigpio:PiGPIOFactory', - 'lgpio = gpiozero.pins.lgpio:LGPIOFactory', - 'rpigpio = gpiozero.pins.rpigpio:RPiGPIOFactory', - 'rpio = gpiozero.pins.rpio:RPIOFactory', - 'native = gpiozero.pins.native:NativeFactory', - 'mock = gpiozero.pins.mock:MockFactory', - # Backwards compatible names - 'PiGPIOPin = gpiozero.pins.pigpio:PiGPIOFactory', - 'RPiGPIOPin = gpiozero.pins.rpigpio:RPiGPIOFactory', - 'RPIOPin = gpiozero.pins.rpio:RPIOFactory', - 'NativePin = gpiozero.pins.native:NativeFactory', - ], - 'gpiozero_mock_pin_classes': [ - 'mockpin = gpiozero.pins.mock:MockPin', - 'mockpwmpin = gpiozero.pins.mock:MockPWMPin', - 'mockchargingpin = gpiozero.pins.mock:MockChargingPin', - 'mocktriggerpin = gpiozero.pins.mock:MockTriggerPin', - ], - 'console_scripts': [ - 'pinout = gpiozerocli.pinout:main', - ] -} - - -def main(): - import io - with io.open(os.path.join(HERE, 'README.rst'), 'r') as readme: - setup( - name = __project__, - version = __version__, - description = __doc__, - long_description = readme.read(), - classifiers = __classifiers__, - author = __author__, - author_email = __author_email__, - url = __url__, - license = 'BSD-3-Clause', - keywords = __keywords__, - packages = find_packages(), - include_package_data = True, - platforms = __platforms__, - install_requires = __requires__, - extras_require = __extra_requires__, - entry_points = __entry_points__, - ) - +opts = cfg['metadata'] +opts.update(cfg['options']) -if __name__ == '__main__': - main() +setup(**opts) -- 2.41.0