Created
May 29, 2020 22:26
-
-
Save sprytnyk/8b05f5ffbf27225c36274d78b9cb930d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import subprocess | |
from collections import defaultdict | |
from dataclasses import dataclass, field | |
from pprint import pprint | |
TEMPLATE = """## {code} ({text_code}) | |
### :x: Problematic code: | |
```python | |
# to be addded | |
``` | |
### :heavy_check_mark: Correct code: | |
```python | |
# to be added | |
``` | |
### Rationale: | |
{description} | |
### Related resources: | |
- [Testcases](#) | |
- [Issue Tracker](https://github.com/PyCQA/pylint/issues?q=is%3Aissue+%22{text_code}%22+OR+%22{code}%22) | |
""" | |
CHECKS_TO_DIRS = { | |
'Async Checker Messages': 'async', | |
'Basic Checker Messages': 'basic', | |
'Broad Try Clause Checker Messages': 'broad-try-clause', | |
'Classes Checker Messages': 'classes', | |
'Compare-To-Empty-String Checker Messages': 'compare-to-empty-string', | |
'Compare-To-Zero Checker Messages': 'compare-to-zero', | |
'Deprecated Builtins Checker Messages': 'deprecated-builtins', | |
'Design Checker Messages': 'design', | |
'Docstyle Checker Messages': 'docstyle', | |
'Else If Used Checker Messages': 'else-if-used', | |
'Exceptions Checker Messages': 'exceptions', | |
'Format Checker Messages': 'format', | |
'Imports Checker Messages': 'imports', | |
'Logging Checker Messages': 'logging', | |
'Miscellaneous Checker Messages': 'miscellaneous', | |
'Multiple Types Checker Messages': 'multiple-types', | |
'Newstyle Checker Messages': 'newstyle', | |
'Overlap-Except Checker Messages': 'overlap-except', | |
'Parameter Documentation Checker Messages': 'parameter-documentation', | |
'Python3 Checker Messages': 'python3', | |
'Refactoring Checker Messages': 'refactoring', | |
'Similarities Checker Messages': 'similarities', | |
'Spelling Checker Messages': 'spelling', | |
'Stdlib Checker Messages': 'stdlib', | |
'String Checker Messages': 'string', | |
'Typecheck Checker Messages': 'typecheck', | |
'Variables Checker Messages': 'variables' | |
} | |
CHECK = re.compile(r'^\#\#\# .* checker Messages$') | |
ERROR = re.compile(r'^[a-z-]+ \([\w]+\)$') | |
@dataclass | |
class PylintError: | |
code: str | |
text_code: str | |
description: list = field(repr=False, default=None) | |
def capitalise_key(words): | |
"""Capitalises a key and preserves dashes.""" | |
capitalised_key = [] | |
for word in words: | |
sub_words = [] | |
for sub_word in word.split('-'): | |
sub_words.append(sub_word.capitalize()) | |
capitalised_key.append('-'.join(sub_words)) | |
return ' '.join(capitalised_key) | |
def extract_errors(): | |
check = None | |
checks_to_errors = defaultdict(list) | |
with open('pylint.md', 'r') as fh: | |
for line in fh.readlines(): | |
if CHECK.search(line): | |
# [1:] to skip ### | |
check = capitalise_key(line.split()[1:]) | |
# Add an error to check's array | |
if ERROR.search(line): | |
checks_to_errors[check].append(line[:-1]) | |
return checks_to_errors | |
def parse_errors(mapping): | |
errors = defaultdict(list) | |
for key, values in mapping.items(): | |
for error in values: | |
text_error = error.split(' ') | |
error_code = text_error[-1].split('(') | |
error_code = error_code[-1].split(')') | |
errors[key].append(PylintError(error_code[0], text_error[0])) | |
return errors | |
def sort_errors(mapping): | |
sorted_errors = {} | |
for key, errors in mapping.items(): | |
sorted_errors[key] = sorted(errors, key=lambda e: e.code) | |
return sorted_errors | |
def set_errors_description(mapping): | |
for key, errors in mapping.items(): | |
for error in errors: | |
p = subprocess.Popen( | |
['pylint', '--help-msg', error.code], | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE | |
) | |
stdout, stderr = p.communicate() | |
stdout = stdout.decode().split(':')[2:] | |
error.description = ''.join(stdout) | |
def write_errors(mapping): | |
for key, errors in mapping.items(): | |
for error in errors: | |
path = '{}/{}.md'.format(CHECKS_TO_DIRS[key], error.code) | |
with open(path, 'w') as fh: | |
fh.write( | |
TEMPLATE.format( | |
code=error.code, | |
text_code=error.text_code, | |
description=error.description | |
) | |
) | |
def render_tree(mapping): | |
for key, errors in mapping.items(): | |
print(f'### {key}') | |
print() | |
for error in errors: | |
print( | |
'- [{} ({})](errors/{}/{}.md)'.format( | |
error.code, error.text_code, CHECKS_TO_DIRS[key], error.code | |
) | |
) | |
print() | |
if __name__ == '__main__': | |
# Get errors from a .md doc | |
raw_errors = extract_errors() | |
# Parse errors | |
parsed_errors = parse_errors(raw_errors) | |
# Sort errors | |
sorted_errors = sort_errors(parsed_errors) | |
render_tree(sorted_errors) | |
#set_errors_description(sorted_errors) | |
# Write errors | |
#write_errors(sorted_errors) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment