summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--example.py10
-rw-r--r--flake8/__init__.py1
-rw-r--r--flake8/_trie.py74
-rw-r--r--flake8/notifier.py22
-rw-r--r--flake8/style_guide.py0
-rw-r--r--setup.py75
-rw-r--r--tests/test_trie.py14
-rw-r--r--tox.ini8
9 files changed, 209 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a41da07
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.cache/*
+.tox/*
+*.pyc
+*.sw*
+*.egg-info
diff --git a/example.py b/example.py
new file mode 100644
index 0000000..a201782
--- /dev/null
+++ b/example.py
@@ -0,0 +1,10 @@
+from flake8 import _trie as trie
+
+
+tree = trie.Trie()
+for i in range(5):
+ tree.add('E103', 'E103-listener-{0}'.format(i))
+ j = i + 1
+ tree.add('E1{0}3'.format(j), 'E1{0}3-listener'.format(j))
+for i in range(10):
+ tree.add('W1{0:02d}'.format(i), 'W1{0:02d}-listener'.format(i))
diff --git a/flake8/__init__.py b/flake8/__init__.py
new file mode 100644
index 0000000..6e648d3
--- /dev/null
+++ b/flake8/__init__.py
@@ -0,0 +1 @@
+__version__ = '3.0.0a1'
diff --git a/flake8/_trie.py b/flake8/_trie.py
new file mode 100644
index 0000000..ddd3c19
--- /dev/null
+++ b/flake8/_trie.py
@@ -0,0 +1,74 @@
+"""Independent implementation of a Trie tree."""
+
+__all__ = ('Trie', 'TrieNode')
+
+
+def _iterate_stringlike_objects(string):
+ for i in range(len(string)):
+ yield string[i:i+1]
+
+
+class Trie(object):
+ """The object that manages the trie nodes."""
+
+ def __init__(self):
+ """Initialize an empty trie."""
+ self.root = TrieNode(None, None)
+
+ def add(self, path, node_data):
+ """Add the node data to the path described."""
+ node = self.root
+ for prefix in _iterate_stringlike_objects(path):
+ child = node.find_prefix(prefix)
+ if child is None:
+ child = node.add_child(prefix, [])
+ node = child
+ node.data.append(node_data)
+
+ def find(self, path):
+ """Find a node based on the path provided."""
+ node = self.root
+ for prefix in _iterate_stringlike_objects(path):
+ child = node.find_prefix(prefix)
+ if child is None:
+ return None
+ node = child
+ return node
+
+
+class TrieNode(object):
+ """The majority of the implementation details of a Trie."""
+
+ def __init__(self, prefix, data, children=None):
+ """Initialize a TrieNode with data and children."""
+ self.children = children or {}
+ self.data = data
+ self.prefix = prefix
+
+ def __repr__(self):
+ """Generate an easy to read representation of the node."""
+ return 'TrieNode(prefix={0}, data={1}, children={2})'.format(
+ self.prefix, self.data, dict(self.children)
+ )
+
+ def find_prefix(self, prefix):
+ """Find the prefix in the children of this node.
+
+ :returns: A child matching the prefix or None.
+ :rtype: :class:`~TrieNode` or None
+ """
+ return self.children.get(prefix, None)
+
+ def add_child(self, prefix, data, children=None):
+ """Create and add a new child node.
+
+ :returns: The newly created node
+ :rtype: :class:`~TrieNode`
+ """
+ new_node = TrieNode(prefix, data, children)
+ self.children[prefix] = new_node
+ return new_node
+
+ def traverse(self):
+ """Traverse children of this node in order."""
+ raise NotImplementedError()
diff --git a/flake8/notifier.py b/flake8/notifier.py
new file mode 100644
index 0000000..7b24b2f
--- /dev/null
+++ b/flake8/notifier.py
@@ -0,0 +1,22 @@
+from flake8 import _trie
+
+
+class Notifier(object):
+ def __init__(self):
+ self.listeners = _trie.Trie()
+
+ def listeners_for(self, error_code):
+ node = self.listeners.find(error_code)
+ for listener in node.data:
+ yield listener
+ if node.children:
+ for child in node.traverse():
+ for listener in child.data:
+ yield listener
+
+ def notify(self, error_code, *args, **kwargs):
+ for listener in self.listeners_for(error_code):
+ listener.notify(*args, **kwargs)
+
+ def register_listener(self, error_code, listener):
+ self.listeners.add(error_code, listener)
diff --git a/flake8/style_guide.py b/flake8/style_guide.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/flake8/style_guide.py
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..fb0585e
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+from __future__ import with_statement
+from setuptools import setup
+try:
+ # Work around a traceback with Nose on Python 2.6
+ # http://bugs.python.org/issue15881#msg170215
+ __import__('multiprocessing')
+except ImportError:
+ pass
+
+try:
+ # Use https://docs.python.org/3/library/unittest.mock.html
+ from unittest import mock
+except ImportError:
+ # < Python 3.3
+ mock = None
+
+
+tests_require = ['nose']
+if mock is None:
+ tests_require += ['mock']
+
+
+def get_version(fname='flake8/__init__.py'):
+ with open(fname) as f:
+ for line in f:
+ if line.startswith('__version__'):
+ return eval(line.split('=')[-1])
+
+
+def get_long_description():
+ descr = []
+ for fname in ('README.rst', 'CHANGES.rst'):
+ with open(fname) as f:
+ descr.append(f.read())
+ return '\n\n'.join(descr)
+
+
+setup(
+ name="flake8",
+ license="MIT",
+ version=get_version(),
+ description="the modular source code checker: pep8, pyflakes and co",
+ # long_description=get_long_description(),
+ author="Tarek Ziade",
+ author_email="tarek@ziade.org",
+ maintainer="Ian Cordasco",
+ maintainer_email="graffatcolmingov@gmail.com",
+ url="https://gitlab.com/pycqa/flake8",
+ packages=["flake8"],
+ install_requires=[
+ "pyflakes >= 0.8.1, < 1.1",
+ "pep8 >= 1.5.7, != 1.6.0, != 1.6.1, != 1.6.2",
+ "mccabe >= 0.2.1, < 0.4",
+ ],
+ entry_points={
+ 'distutils.commands': ['flake8 = flake8.main:Flake8Command'],
+ 'console_scripts': ['flake8 = flake8.main:main'],
+ 'flake8.extension': [
+ 'F = flake8._pyflakes:FlakesChecker',
+ ],
+ },
+ classifiers=[
+ "Environment :: Console",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 3",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Topic :: Software Development :: Quality Assurance",
+ ],
+ tests_require=tests_require,
+ test_suite='nose.collector',
+)
diff --git a/tests/test_trie.py b/tests/test_trie.py
new file mode 100644
index 0000000..10a10aa
--- /dev/null
+++ b/tests/test_trie.py
@@ -0,0 +1,14 @@
+from flake8 import _trie as trie
+
+
+def test_build_tree():
+ tree = trie.Trie()
+ for i in range(5):
+ tree.add('E103', 'E103-listener-{0}'.format(i))
+ j = i + 1
+ tree.add('E1{0}3'.format(j), 'E1{0}3-listener'.format(j))
+ for i in range(10):
+ tree.add('W1{0:02d}'.format(i), 'W1{0:02d}-listener'.format(i))
+
+ assert tree.find('E103') is not None
+ assert tree.find('E200') is None
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..de47800
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,8 @@
+[tox]
+envlist = py26,py27,py32,py33,py34,py35
+
+[testenv]
+deps =
+ pytest
+commands =
+ py.test