GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

PylintLinter   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 21
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 10
c 0
b 0
f 0
wmc 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A extra_processing() 0 5 2
1
# -*- coding: utf-8 -*-
2
# -----------------------------------------------------------------------------
3
# Copyright (c) 2016 Continuum Analytics, Inc.
4
#
5
# Licensed under the terms of the MIT License
6
# (see LICENSE.txt for details)
7
# -----------------------------------------------------------------------------
8
"""Generic and custom code linters."""
9
10
# Standard library imports
11
import json
12
import os
13
import re
14
15
# Local imports
16
from ciocheck.tools import Tool
17
from ciocheck.utils import run_command
18
19
20
class Linter(Tool):
21
    """Generic linter with json and regex output support."""
22
23
    # Regex matching
24
    pattern = None
25
26
    # Json matching
27
    json_keys = []  # ((old_key, new_key), ...)
28
    output_on_stderr = False
29
30
    def __init__(self, cmd_root):
31
        """Generic linter with json and regex output support."""
32
        super(Linter, self).__init__(cmd_root)
33
        self.paths = None
34
        self.regex = None
35
36
    def _parse_regex(self, string):
37
        """Parse output with grouped regex."""
38
        results = []
39
        self.regex = re.compile(self.pattern, re.VERBOSE)
40
        for matches in self.regex.finditer(string):
41
            results.append(matches.groupdict())
42
        return results
43
44
    def _parse_json(self, string):
45
        """Parse output with json keys."""
46
        data = json.loads(string)
47
        results = []
48
        for item in data:
49
            new_item = {}
50
            for (old_key, new_key) in self.json_keys:
51
                new_item[new_key] = item.pop(old_key)
52
            new_item.update(item)
53
            results.append(new_item)
54
        return results
55
56
    def _parse(self, string):
57
        """Parse linter output."""
58
        if self.json_keys:
59
            results = self._parse_json(string)
60
        elif self.pattern:
61
            results = self._parse_regex(string)
62
        else:
63
            raise Exception('Either a pattern or a json key mapping has to '
64
                            'be defined.')
65
        return results
66
67
    def extra_processing(self, results):
68
        """Override in case extra processing on results is needed."""
69
        return results
70
71
    def run(self, paths):
72
        """Run linter and return a list of dicts."""
73
        self.paths = list(paths.keys()) if isinstance(paths, dict) else paths
74
        if self.paths:
75
            args = list(self.command)
76
            args += self.paths
77
            out, err = run_command(args)
78
            if self.output_on_stderr:
79
                string = err
80
            else:
81
                string = out
82
            results = self._parse(string)
83
            results = self.extra_processing(results)
84
        else:
85
            results = []
86
87
        return results
88
89
90
class Flake8Linter(Linter):
91
    """Flake8 python tool runner."""
92
93
    language = 'python'
94
    name = 'flake8'
95
    extensions = ('py', )
96
    command = ('flake8', )
97
    config_file = '.flake8'
98
    config_sections = [('flake8', 'flake8')]
99
100
    # Match lines of the form:
101
    # path/to/file.py:328: undefined name '_thing'
102
    pattern = r'''
103
        (?P<path>.*?):(?P<line>\d{1,1000}):
104
        (?P<column>\d{1,1000}):\s
105
        (?P<type>[EWFCNTIBDSQ]\d{3})\s
106
        (?P<message>.*)
107
        '''
108
109
110
class Pep8Linter(Linter):
111
    """Pep8 python tool runner."""
112
113
    language = 'python'
114
    name = 'pep8'
115
    extensions = ('py', )
116
    command = ('pep8', )
117
    config_file = '.pep8'
118
    config_sections = [('pep8', 'pep8')]
119
120
    # Match lines of the form:
121
    pattern = r'''
122
        (?P<path>.*?):(?P<line>\d{1,1000}):
123
        (?P<column>\d{1,1000}):\s
124
        (?P<type>[EWFCNTIBDSQ]\d{3})\s
125
        (?P<message>.*)
126
        '''
127
128
129
class PydocstyleLinter(Linter):
130
    """Pydocstyle python tool runner."""
131
132
    language = 'python'
133
    name = 'pydocstyle'
134
    extensions = ('py', )
135
    command = ('pydocstyle', )
136
    config_file = '.pydocstyle'
137
    config_sections = [('pydocstyle', 'pydocstyle')]
138
    output_on_stderr = True
139
140
    # Match lines of the form:
141
    # ./bootstrap.py:1 at module level:
142
    #    D400: First line should end with a period (not 't')
143
    pattern = r'''
144
        (?P<path>.*?):
145
        (?P<line>\d{1,1000000})\  # 1 million lines of code :-p ?
146
        (?P<symbol>.*):\n.*?
147
        (?P<type>D\d{3}):\s
148
        (?P<message>.*)
149
        '''
150
151
152
class PylintLinter(Linter):
153
    """Pylint python tool runner."""
154
155
    language = 'python'
156
    name = 'pylint'
157
    extensions = ('py', )
158
    command = ('pylint', '--output-format', 'json', '-j', '0')
159
    config_file = '.pydocstyle'
160
    config_sections = [('pydocstyle', 'pydocstyle')]
161
    json_keys = (
162
        ('message', 'message'),
163
        ('line', 'line'),
164
        ('column', 'column'),
165
        ('type', 'type'),
166
        ('path', 'path'), )
167
168
    def extra_processing(self, results):
169
        """Make path an absolute path."""
170
        for item in results:
171
            item['path'] = os.path.join(self.cmd_root, item['path'])
172
        return results
173
174
175
LINTERS = [
176
    Pep8Linter,
177
    PydocstyleLinter,
178
    Flake8Linter,
179
    PylintLinter,
180
]
181
182
183
def test():
184
    """Main local test."""
185
    here = os.path.dirname(os.path.realpath(__file__))
186
    paths = [here]
187
    linter = PylintLinter(here)
188
    results = linter.run(paths)
189
    for result in results:
190
        print(result)
191
192
193
if __name__ == '__main__':
194
    test()
195