From 8c8d54b3705489006c7d0e6d81a993eeed6ddc2b Mon Sep 17 00:00:00 2001 From: Stefano Palazzo Date: Thu, 3 Aug 2017 16:25:17 +0200 Subject: [PATCH] Initial commit --- .coveragerc | 6 ++++ .gitignore | 15 +++++++++ .travis.yml | 11 +++++++ COPYING | 13 ++++++++ DESCRIPTION.rst | 6 ++++ MANIFEST.in | 9 ++++++ Makefile | 25 +++++++++++++++ README.md | 18 +++++++++++ flake8_import_style/__init__.py | 24 +++++++++++++++ flake8_import_style/tests/__init__.py | 44 +++++++++++++++++++++++++++ pip.conf | 4 +++ requirements-dev.txt | 19 ++++++++++++ setup.cfg | 8 +++++ setup.py | 37 ++++++++++++++++++++++ tox.ini | 12 ++++++++ 15 files changed, 251 insertions(+) create mode 100644 .coveragerc create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 COPYING create mode 100644 DESCRIPTION.rst create mode 100644 MANIFEST.in create mode 100644 Makefile create mode 100644 README.md create mode 100644 flake8_import_style/__init__.py create mode 100644 flake8_import_style/tests/__init__.py create mode 100644 pip.conf create mode 100644 requirements-dev.txt create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tox.ini diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..fc19f9a --- /dev/null +++ b/.coveragerc @@ -0,0 +1,6 @@ +[run] +branch = True +source = flake8_import_style + +[report] +show_missing = True diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93f7395 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.egg-info +*.pyc +__pycache__ +/dist +/build +/bin +/lib +/lib64 +/include +/share +/pip-selfcheck.json +/pyvenv.cfg +/htmlcov +/.coverage +/.tox diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..77afb77 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: python +sudo: false +python: + - "2.7" + - "3.4" + - "3.5" + - "3.6" +install: pip install tox tox-travis coveralls +script: tox +after_success: + coveralls diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4c04412 --- /dev/null +++ b/COPYING @@ -0,0 +1,13 @@ +Copyright (c) 2016-2017, Stefano Palazzo + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/DESCRIPTION.rst b/DESCRIPTION.rst new file mode 100644 index 0000000..241d402 --- /dev/null +++ b/DESCRIPTION.rst @@ -0,0 +1,6 @@ +flake8-import-style +=================== + +A flake8 plugin to ensure explicit module imports. + +For more information, see `github.com/sfstpala/flake8-import-style `_. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..2a23af5 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,9 @@ +include README.md +include DESCRIPTION.rst +include COPYING +include Makefile +include requirements-dev.txt +include .coveragerc +include pip.conf +include tox.ini +include .travis.yml diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1ccbc74 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +python ?= python3.6 +package = flake8_import_style + +all: $(package).egg-info +$(package).egg-info: setup.py requirements-dev.txt bin/pip + bin/pip install -r requirements-dev.txt && touch $@ +bin/pip: bin/python + bin/python -m pip install -I pip wheel +bin/python: + $(python) -m venv . + +test: all + bin/coverage run setup.py test + bin/coverage html + bin/coverage report --fail-under=100 + bin/flake8 setup.py $(package) + bin/check-manifest + bin/python setup.py check -mrs + bin/pip list --outdated + +clean: + rm -rf *.egg-info $(shell find $(package) -name "__pycache__") + rm -rf *.pyc $(shell find $(package) -name "*.pyc") + rm -rf bin lib lib64 include pip-selfcheck.json pyvenv.cfg + rm -rf share build dist .tox .coverage htmlcov diff --git a/README.md b/README.md new file mode 100644 index 0000000..c1aed01 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# flake8-import-style + +[![Build](https://img.shields.io/travis/sfstpala/flake8-import-style.svg?style=flat-square)](https://travis-ci.org/sfstpala/flake8-import-style) +[![Coverage](https://img.shields.io/coveralls/sfstpala/flake8-import-style.svg?style=flat-square)](https://coveralls.io/r/sfstpala/flake8-import-style) +[![PyPI](https://img.shields.io/pypi/v/flake8-import-style.svg?style=flat-square)](https://pypi.python.org/pypi/flake8-import-style) + +A [flake8](http://flake8.pycqa.org/en/latest/) plugin to ensure explicit module imports. + + pip install flake8_import_style + flake8 *.py + +Errors (enabled by default): + + - `I801 use 'import ...' instead of 'from ... import ...'` + +Tested with Python 2.7, 3.4, 3.5, and 3.6. + +Type `make test` or `tox` to run the test suite in a virtual environment. diff --git a/flake8_import_style/__init__.py b/flake8_import_style/__init__.py new file mode 100644 index 0000000..05055fe --- /dev/null +++ b/flake8_import_style/__init__.py @@ -0,0 +1,24 @@ +import ast + +import pkg_resources + + +I801 = "I801 use 'import {module}' instead of 'from {module} import {names}'" + + +class I8(object): + """Complain about all "from x import y" style imports.""" + + name = "import-style" + version = pkg_resources.get_distribution(__package__).version + + def __init__(self, tree): + self.tree = tree + + def run(self): + for i in ast.walk(self.tree): + if isinstance(i, ast.ImportFrom): + message = I801.format( + module=(i.module or "..."), + names=", ".join(i.name for i in i.names)) + yield (i.lineno, i.col_offset, message, "I801") diff --git a/flake8_import_style/tests/__init__.py b/flake8_import_style/tests/__init__.py new file mode 100644 index 0000000..0925697 --- /dev/null +++ b/flake8_import_style/tests/__init__.py @@ -0,0 +1,44 @@ +import ast +import unittest + +import flake8_import_style + + +class I8Test(unittest.TestCase): + + def test_run(self): + + tree = ast.parse("import mod") + i8 = flake8_import_style.I8(tree) + self.assertEqual(list(i8.run()), []) + + tree = ast.parse("import mod as mod1") + i8 = flake8_import_style.I8(tree) + self.assertEqual(list(i8.run()), []) + + tree = ast.parse("from . import obj") + i8 = flake8_import_style.I8(tree) + self.assertEqual(list(i8.run()), [( + 1, + 0, + "I801 use 'import ...' instead of 'from ... import obj'", + "I801", + )]) + + tree = ast.parse("from .. import obj") + i8 = flake8_import_style.I8(tree) + self.assertEqual(list(i8.run()), [( + 1, + 0, + "I801 use 'import ...' instead of 'from ... import obj'", + "I801", + )]) + + tree = ast.parse("from mod import obj") + i8 = flake8_import_style.I8(tree) + self.assertEqual(list(i8.run()), [( + 1, + 0, + "I801 use 'import mod' instead of 'from mod import obj'", + "I801", + )]) diff --git a/pip.conf b/pip.conf new file mode 100644 index 0000000..3cdc986 --- /dev/null +++ b/pip.conf @@ -0,0 +1,4 @@ +[install] +upgrade = true +[list] +format = legacy diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..f897722 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,19 @@ +--editable . +setuptools +wheel +coverage +flake8 +flake8-docstrings +flake8-import-order +flake8-quotes +flake8-commas +flake8-blind-except +flake8-comprehensions +flake8-mutable +flake8-print +flake8-logging-format +flake8-mock +flake8-builtins +pep8-naming +check-manifest +docutils diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..e0d1abb --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[bdist_wheel] +python-tag=py36 +[flake8] +max-complexity=10 +ignore=D100,D101,D102,D103,D104,D105 +import-order-style=cryptography +application-import-names=flake8_import_style +inline-quotes=double diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f2da930 --- /dev/null +++ b/setup.py @@ -0,0 +1,37 @@ +import os.path +import setuptools + + +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, "DESCRIPTION.rst")) as f: + long_description = f.read() + +setuptools.setup( + name="flake8-import-style", version="0.1.0", + description="A flake8 plugin to ensure explicit module imports", + long_description=long_description, + packages=setuptools.find_packages(), + author="Stefano Palazzo", + author_email="stefano.palazzo@gmail.com", + url="https://github.com/sfstpala/flake8-import-style", + license="ISC", + test_suite="flake8_import_style.tests", + entry_points={ + "flake8.extension": [ + "I8 = flake8_import_style:I8", + ], + }, + classifiers=[ + "Framework :: Flake8", + "License :: OSI Approved :: ISC License (ISCL)", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Quality Assurance", + ], +) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..b76836f --- /dev/null +++ b/tox.ini @@ -0,0 +1,12 @@ +[tox] +envlist = py27,py34,py35,py36 + +[testenv] +deps= + -rrequirements-dev.txt +commands = + coverage run setup.py test + coverage report --fail-under=100 + flake8 setup.py flake8_import_style + check-manifest + python setup.py check -mrs