In a typical pylint run, we get the following output:
Global evaluation
-----------------
Your code has been rated at 9.50/10 (previous run: 8.50/10)
Duplication
-----------
+-------------------------+------+---------+-----------+
| |now |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines |0 |0 |= |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000 |= |
+-------------------------+------+---------+-----------+
I wonder how pylint remembers scores from previous runs - In the example above, the score from previous run was 8.5.
I want to implement such a functionality in my own module, and I thought I should first find out how pylint implements the functionality.
I searched for hidden folders where this data could be stored, but found none.
The score is calculated using Pylint version 2.4. 3 To calculate the coding convention score, we will use the standard coding convention score calculated by Pylint. The formula for this score is as follows: 10.0 - ((float(5 * Frequency of convention errors) / Number of statement) * 10).
In python, the most consensual writing style is defined by the PEP-8 standard, which the popular pylint package enforces. It comes with a handy metric, the Pylint score: you get a 10/10 for perfectly conforming to the standard, less it you stray from it.
Pylint analyses your code without actually running it. It checks for errors, enforces a coding standard, looks for code smells, and can make suggestions about how the code could be refactored. Pylint can infer actual values from your code using its internal code representation (astroid).
Output optionsThe simplest way to output to a file is with the --output=<filename> option. The default format for the output is raw text. You can change this by passing pylint the --output-format=<value> option. Possible values are: text , json , parseable , colorized and msvs (for Visual Studio).
I have a .pylintrc
file in my home directory that includes the following line:
#pickle collected data for later comparisons.
persistent=yes
So it seems pylint
does use pickle for comparisons
In the lint.py
from the source code:
def make_options():
return (('ignore',
{'type' : 'csv', 'metavar' : '<file>[,<file>...]',
'dest' : 'black_list', 'default' : ('CVS',),
'help' : 'Add files or directories to the blacklist. '
'They should be base names, not paths.'}),
('persistent',
{'default': True, 'type' : 'yn', 'metavar' : '<y_or_n>',
'level': 1,
'help' : 'Pickle collected data for later comparisons.'})
The full lint.py
source is here
The bit that is most interesting is probably this method:
def close(self):
"""close the whole package /module, it's time to make reports !
if persistent run, pickle results for later comparison
"""
if self.file_state.base_name is not None:
# load previous results if any
previous_stats = config.load_results(self.file_state.base_name)
# XXX code below needs refactoring to be more reporter agnostic
self.reporter.on_close(self.stats, previous_stats)
if self.config.reports:
sect = self.make_reports(self.stats, previous_stats)
if self.config.files_output:
filename = 'pylint_global.' + self.reporter.extension
self.reporter.set_output(open(filename, 'w'))
else:
sect = Section()
if self.config.reports or self.config.output_format == 'html':
self.reporter.display_results(sect)
# save results if persistent run
if self.config.persistent:
config.save_results(self.stats, self.file_state.base_name)
else:
self.reporter.on_close(self.stats, {})
You will also want to look at the config.py
source
def load_results(base):
"""try to unpickle and return data from file if it exists and is not
corrupted
return an empty dictionary if it doesn't exists
"""
data_file = get_pdata_path(base, 1)
try:
with open(data_file, _PICK_LOAD) as stream:
return pickle.load(stream)
except:
return {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With