/usr/lib/python2.7/dist-packages/flake8/statistics.py is in python-flake8 3.5.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | """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 error_codes(self):
"""Return all unique error codes stored.
:returns:
Sorted list of error codes.
:rtype:
list(str)
"""
return sorted({key.code for key in self._store})
def record(self, error):
"""Add the fact that the error was seen in the file.
:param error:
The Violation instance containing the information about the
violation.
:type error:
flake8.style_guide.Violation
"""
key = Key.create_from(error)
if key not in self._store:
self._store[key] = Statistic.create_from(error)
self._store[key].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
if key.matches(prefix, filename))
for error_code in matching_errors:
yield self._store[error_code]
class Key(collections.namedtuple('Key', ['filename', 'code'])):
"""Simple key structure for the Statistics dictionary.
To make things clearer, easier to read, and more understandable, we use a
namedtuple here for all Keys in the underlying dictionary for the
Statistics object.
"""
__slots__ = ()
@classmethod
def create_from(cls, error):
"""Create a Key from :class:`flake8.style_guide.Violation`."""
return cls(
filename=error.filename,
code=error.code,
)
def matches(self, prefix, filename):
"""Determine if this key matches some constraints.
:param str prefix:
The error code prefix that this key's error code should start with.
:param str filename:
The filename that we potentially want to match on. This can be
None to only match on error prefix.
:returns:
True if the Key's code starts with the prefix and either filename
is None, or the Key's filename matches the value passed in.
:rtype:
bool
"""
return (self.code.startswith(prefix) and
(filename is None or
self.filename == filename))
class Statistic(object):
"""Simple wrapper around the logic of each statistic.
Instead of maintaining a simple but potentially hard to reason about
tuple, we create a namedtuple which has attributes and a couple
convenience methods on it.
"""
def __init__(self, error_code, filename, message, count):
"""Initialize our Statistic."""
self.error_code = error_code
self.filename = filename
self.message = message
self.count = count
@classmethod
def create_from(cls, error):
"""Create a Statistic from a :class:`flake8.style_guide.Violation`."""
return cls(
error_code=error.code,
filename=error.filename,
message=error.text,
count=0,
)
def increment(self):
"""Increment the number of times we've seen this error in this file."""
self.count += 1
|