summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Cordasco <graffatcolmingov@gmail.com>2016-07-11 20:13:41 -0500
committerIan Cordasco <graffatcolmingov@gmail.com>2016-07-11 20:13:41 -0500
commit6cfb292b1b0e4f956b53e76b83f567b77cd1525e (patch)
treea98505eaeb35c8f03d05b8b5d73559d7edb4833a /src
parent58e67634cd24122e1961ac2e223d38465e2ab4c8 (diff)
downloadflake8-6cfb292b1b0e4f956b53e76b83f567b77cd1525e.tar.gz
Add the statistics module
Diffstat (limited to 'src')
-rw-r--r--src/flake8/statistics.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/flake8/statistics.py b/src/flake8/statistics.py
new file mode 100644
index 0000000..2ae6c64
--- /dev/null
+++ b/src/flake8/statistics.py
@@ -0,0 +1,101 @@
+"""Statistic collection logic for Flake8."""
+import collections
+
+
+class Statistics(object):
+ """Manager of aggregated statistics for a run of Flake8."""
+
+ def __init__(self):
+ """Initialize the underlying dictionary for our statistics."""
+ self._store = {}
+
+ def record(self, error):
+ """Add the fact that the error was seen in the file.
+
+ :param error:
+ The Error instance containing the information about the violation.
+ :type error:
+ flake8.style_guide.Error
+ """
+ key = Key.create_from(error)
+ if key in self._store:
+ statistic = self._store[key]
+ else:
+ statistic = Statistic.create_from(error)
+ self._store[key] = statistic.increment()
+
+ def statistics_for(self, prefix, filename=None):
+ """Generate statistics for the prefix and filename.
+
+ If you have a :class:`Statistics` object that has recorded errors,
+ you can generate the statistics for a prefix (e.g., ``E``, ``E1``,
+ ``W50``, ``W503``) with the optional filter of a filename as well.
+
+ .. code-block:: python
+
+ >>> stats = Statistics()
+ >>> stats.statistics_for('E12',
+ filename='src/flake8/statistics.py')
+ <generator ...>
+ >>> stats.statistics_for('W')
+ <generator ...>
+
+ :param str prefix:
+ The error class or specific error code to find statistics for.
+ :param str filename:
+ (Optional) The filename to further filter results by.
+ :returns:
+ Generator of instances of :class:`Statistic`
+ """
+ matching_errors = sorted(key for key in self._store.keys()
+ if key.matches(prefix, filename))
+ for error_code in matching_errors:
+ yield self._store[error_code]
+
+
+class Key(collections.namedtuple('Key', ['filename', 'code'])):
+ __slots__ = ()
+
+ @classmethod
+ def create_from(cls, error):
+ return cls(
+ filename=error.filename,
+ code=error.code,
+ )
+
+ def matches(self, prefix, filename):
+ return (self.code.startswith(prefix) and
+ (filename is None or
+ self.filename == filename))
+
+
+_Statistic = collections.namedtuple('Statistic', [
+ 'error_code',
+ 'filename',
+ 'message',
+ 'count',
+])
+
+
+class Statistic(_Statistic):
+ __slots__ = ()
+
+ @classmethod
+ def create_from(cls, error):
+ return cls(
+ error_code=error.code,
+ filename=error.filename,
+ message=error.message,
+ count=0,
+ )
+
+ def increment(self):
+ return Statistic(
+ error_code=self.error_code,
+ filename=self.filename,
+ message=self.message,
+ count=self.count + 1,
+ )
+
+
+del _Statistic