]>
crepu.dev Git - config.git/blob - djavu-asus/emacs/elpy/rpc-venv/lib/python3.11/site-packages/flake8/statistics.py
a33e6a642b1eeca77684db827ce53eed6a905d62
1 """Statistic collection logic for Flake8."""
2 from __future__
import annotations
4 from typing
import Generator
5 from typing
import NamedTuple
7 from flake8
.violation
import Violation
11 """Manager of aggregated statistics for a run of Flake8."""
13 def __init__(self
) -> None:
14 """Initialize the underlying dictionary for our statistics."""
15 self
._store
: dict[Key
, Statistic
] = {}
17 def error_codes(self
) -> list[str]:
18 """Return all unique error codes stored.
21 Sorted list of error codes.
23 return sorted({key
.code
for key
in self
._store
})
25 def record(self
, error
: Violation
) -> None:
26 """Add the fact that the error was seen in the file.
29 The Violation instance containing the information about the
32 key
= Key
.create_from(error
)
33 if key
not in self
._store
:
34 self
._store
[key
] = Statistic
.create_from(error
)
35 self
._store
[key
].increment()
38 self
, prefix
: str, filename
: str |
None = None
39 ) -> Generator
[Statistic
, None, None]:
40 """Generate statistics for the prefix and filename.
42 If you have a :class:`Statistics` object that has recorded errors,
43 you can generate the statistics for a prefix (e.g., ``E``, ``E1``,
44 ``W50``, ``W503``) with the optional filter of a filename as well.
46 .. code-block:: python
48 >>> stats = Statistics()
49 >>> stats.statistics_for('E12',
50 filename='src/flake8/statistics.py')
52 >>> stats.statistics_for('W')
56 The error class or specific error code to find statistics for.
58 (Optional) The filename to further filter results by.
60 Generator of instances of :class:`Statistic`
62 matching_errors
= sorted(
63 key
for key
in self
._store
if key
.matches(prefix
, filename
)
65 for error_code
in matching_errors
:
66 yield self
._store
[error_code
]
69 class Key(NamedTuple
):
70 """Simple key structure for the Statistics dictionary.
72 To make things clearer, easier to read, and more understandable, we use a
73 namedtuple here for all Keys in the underlying dictionary for the
81 def create_from(cls
, error
: Violation
) -> Key
:
82 """Create a Key from :class:`flake8.violation.Violation`."""
83 return cls(filename
=error
.filename
, code
=error
.code
)
85 def matches(self
, prefix
: str, filename
: str |
None) -> bool:
86 """Determine if this key matches some constraints.
89 The error code prefix that this key's error code should start with.
91 The filename that we potentially want to match on. This can be
92 None to only match on error prefix.
94 True if the Key's code starts with the prefix and either filename
95 is None, or the Key's filename matches the value passed in.
97 return self
.code
.startswith(prefix
) and (
98 filename
is None or self
.filename
== filename
103 """Simple wrapper around the logic of each statistic.
105 Instead of maintaining a simple but potentially hard to reason about
106 tuple, we create a class which has attributes and a couple
107 convenience methods on it.
111 self
, error_code
: str, filename
: str, message
: str, count
: int
113 """Initialize our Statistic."""
114 self
.error_code
= error_code
115 self
.filename
= filename
116 self
.message
= message
120 def create_from(cls
, error
: Violation
) -> Statistic
:
121 """Create a Statistic from a :class:`flake8.violation.Violation`."""
123 error_code
=error
.code
,
124 filename
=error
.filename
,
129 def increment(self
) -> None:
130 """Increment the number of times we've seen this error in this file."""