Skip to content

Commit

Permalink
Make styles able to be extended by users
Browse files Browse the repository at this point in the history
  • Loading branch information
dahlia committed Jan 30, 2017
1 parent 65796b2 commit 3bc1a6f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 19 deletions.
43 changes: 43 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ the code being developed. This option is only supported if using the
* ``edited`` - style as ``smarkets`` only with `import` statements for packages local to your company or organisation coming after `import` statements for third-party packages, see an `example <https://github.com/PyCQA/flake8-import-order/blob/master/tests/test_cases/complete_edited.py>`__
* ``pep8`` - style that only enforces groups without enforcing the order within the groups

You can also `add your own style <#extending-styles>`_ by extending ``Style``
class.

Limitations
-----------

Expand All @@ -82,5 +85,45 @@ is also the same for all Python versions because otherwise it would
be impossible to write programs that work under both Python 2 and 3
*and* pass the import order check.

Extending styles
----------------

You can add your own style by extending ``flake8_import_order.styles.Style``
class. Here's an example:

.. code-block:: python
from flake8_import_order.styles import Cryptography
class ReversedCryptography(Cryptography):
# Note that Cryptography is a subclass of Style.
@staticmethod
def sorted_names(names):
return reversed(Cryptography.sorted_names(names))
To make flake8-import-order able to discover your extended style, you need to
register it as ``flake8_import_order.styles`` using setuptools' `entry points
<https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points>`__
mechanism:

.. code-block:: python
# setup.py of your style package
setup(
name='flake8-import-order-reversed-cryptography',
...,
entry_points={
'flake8_import_order.styles': [
'reversed = reversedcryptography:ReversedCryptography',
# 'reversed' is a style name. You can pass it to
# --import-order-style option
# 'reversedcryptography:ReversedCryptography' is an import path
# of your extended style class.
]
}
)
.. |Build Status| image:: https://travis-ci.org/PyCQA/flake8-import-order.png?branch=master
:target: https://travis-ci.org/PyCQA/flake8-import-order
29 changes: 13 additions & 16 deletions flake8_import_order/checker.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import ast

import pkg_resources

import pycodestyle

from flake8_import_order import ImportVisitor
from flake8_import_order.styles import (
AppNexus, Cryptography, Edited, Google, PEP8, Smarkets,
)

DEFAULT_IMPORT_ORDER_STYLE = 'cryptography'

Expand Down Expand Up @@ -59,20 +58,18 @@ def check_order(self):
if not pycodestyle.noqa(self.lines[import_.lineno - 1]):
imports.append(import_)

if style_option == 'cryptography':
style = Cryptography(imports)
elif style_option == 'google':
style = Google(imports)
elif style_option == 'pep8':
style = PEP8(imports)
elif style_option == 'smarkets':
style = Smarkets(imports)
elif style_option == 'appnexus':
style = AppNexus(imports)
elif style_option == 'edited':
style = Edited(imports)
else:
try:
style_entry_point = next(
pkg_resources.iter_entry_points(
'flake8_import_order.styles',
name=style_option
)
)
except StopIteration:
raise AssertionError("Unknown style {}".format(style_option))
else:
style_cls = style_entry_point.load()
style = style_cls(imports)

for error in style.check():
yield self.error(error)
14 changes: 12 additions & 2 deletions flake8_import_order/flake8_linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import optparse

import pkg_resources

from flake8_import_order import __version__
from flake8_import_order.checker import (
DEFAULT_IMPORT_ORDER_STYLE, ImportOrderChecker,
Expand Down Expand Up @@ -46,11 +48,19 @@ def add_options(cls, parser):
default=DEFAULT_IMPORT_ORDER_STYLE,
action="store",
type="string",
help=("Style to follow. Available: "
"cryptography, google, smarkets, appnexus, pep8"),
help=("Style to follow. Available: " +
", ".join(cls.list_available_styles())),
parse_from_config=True,
)

@staticmethod
def list_available_styles():
entry_points = pkg_resources.iter_entry_points(
'flake8_import_order.styles'
)
for entry_point in entry_points:
yield entry_point.name

@classmethod
def parse_options(cls, options):
optdict = {}
Expand Down
11 changes: 10 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
zip_safe=False,

install_requires=[
"pycodestyle"
"pycodestyle",
"setuptools",
],

tests_require=[
Expand All @@ -41,6 +42,14 @@

py_modules=['flake8_import_order'],
entry_points={
'flake8_import_order.styles': [
'cryptography = flake8_import_order.styles:Cryptography',
'google = flake8_import_order.styles:Google',
'pep8 = flake8_import_order.styles:PEP8',
'smarkets = flake8_import_order.styles:Smarkets',
'appnexus = flake8_import_order.styles:AppNexus',
'edited = flake8_import_order.styles:Edited',
],
'flake8.extension': [
'I10 = flake8_import_order.flake8_linter:Linter',
],
Expand Down

0 comments on commit 3bc1a6f

Please sign in to comment.