Skip to content

Instantly share code, notes, and snippets.

@britonad
Created May 29, 2020 22:26
Show Gist options
  • Save britonad/8b05f5ffbf27225c36274d78b9cb930d to your computer and use it in GitHub Desktop.
Save britonad/8b05f5ffbf27225c36274d78b9cb930d to your computer and use it in GitHub Desktop.
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