Skip to content

Commit d3bd89a

Browse files
author
kmalyshev
committed
Initial implementation
0 parents  commit d3bd89a

File tree

6 files changed

+281
-0
lines changed

6 files changed

+281
-0
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.idea/
2+
/venv/
3+
/build/
4+
/dist/
5+
/*.egg-info/
6+
*.pyc

LICENSE

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (C) 2019 Kirill Malyshev
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files
5+
(the "Software"), to deal in the Software without restriction,
6+
including without limitation the rights to use, copy, modify, merge,
7+
publish, distribute, sublicense, and/or sell copies of the Software,
8+
and to permit persons to whom the Software is furnished to do so,
9+
subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Pydiatra Code Analyzer Plugin for Flake8
2+
3+
[pydiatra](http://jwilk.net/software/pydiatra) ([github](https://github.com/jwilk/pydiatra)) is yet another static checker for Python code.
4+
5+
## Why another static checker
6+
7+
Among other checks pydiatra offers number of regexp checks which are hard to find
8+
within other analyzers:
9+
10+
* duplicate range (e.g. re.compile("[aa]"))
11+
* overlapping ranges (e.g. re.compile("[a-zA-z]"))
12+
* bad escape sequences (e.g. re.compile(r"\eggs"))
13+
* misplaced inline flags (e.g. re.compile("eggs(?i)"); Python 3.6+ only)
14+
* combining incompatible flags
15+
* redundant flags
16+
* misplaced flags arguments in re.split(), re.sub(), re.subn()
17+
18+
And some other nice to have checks:
19+
20+
* invalid escape sequences in strings (Python 3.6+ only)
21+
* hardcoded errno values (e.g. exc.errno == 2 instead of exc.errno == errno.ENOENT)
22+
23+
## Supported checks
24+
25+
For complete list of implemented checks consult pydiatra page.
26+
27+
Below is list of checks supported by this plugin:
28+
29+
* `PYD001` assertion always true
30+
* `PYD002` async await used as name
31+
* `PYD003` embedded code copy
32+
* `PYD004` except shadows builtin
33+
* `PYD005` bare except
34+
* `PYD006` hardcoded errno value
35+
* `PYD007` inconsistent indentation
36+
* `PYD008` mkstemp file descriptor leak
37+
* `PYD009` obsolete pil import
38+
* `PYD010` py3k compat warning
39+
* `PYD011` regexp bad escape
40+
* `PYD012` regexp duplicate range
41+
* `PYD013` regexp incompatible flags
42+
* `PYD014` regexp misplaced inline flags
43+
* `PYD015` regexp misplaced flags argument
44+
* `PYD016` regexp overlapping ranges
45+
* `PYD017` regexp redundant flag
46+
* `PYD018` regexp syntax error
47+
* `PYD019` regexp syntax warning
48+
* `PYD020` string exception
49+
* `PYD021` string formatting error
50+
* `PYD022` syntax error
51+
* `PYD023` syntax warning
52+
* `PYD024` sys.hexversion comparison
53+
* `PYD025` sys.version comparison
54+
55+
## Flake8 violation classes
56+
57+
This plugin uses `PYD0` as violation class. Add it to flake8's `select` to enable.
58+
59+
```bash
60+
flake8 --select PYD0 .
61+
```

development/copyright.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"author": "Kirill Malyshev",
3+
"back": false,
4+
"license": "mit",
5+
"include": "./flake8_pydiatra.py,./setup.py",
6+
"program": "flake8-pydiatra",
7+
"short": "Pydiatra plugin for flake8.",
8+
"single": true,
9+
"year": "2019"
10+
}

flake8_pydiatra.py

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Pydiatra plugin for flake8.
2+
# Copyright (C) 2019 Kirill Malyshev
3+
# The MIT License (MIT)
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining
6+
# a copy of this software and associated documentation files
7+
# (the "Software"), to deal in the Software without restriction,
8+
# including without limitation the rights to use, copy, modify, merge,
9+
# publish, distribute, sublicense, and/or sell copies of the Software,
10+
# and to permit persons to whom the Software is furnished to do so,
11+
# subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be
14+
# included in all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
24+
from sys import stderr
25+
26+
from pydiatra import checks
27+
28+
__version__ = '0.1.0'
29+
30+
31+
class PydiatraChecker():
32+
name = 'flake8-pydiatra'
33+
version = __version__
34+
35+
# @formatter:off
36+
messages = {
37+
'assertion-always-true': 'PYD001',
38+
'async-await-used-as-name': 'PYD002',
39+
'embedded-code-copy': 'PYD003',
40+
'except-shadows-builtin': 'PYD004',
41+
'bare-except': 'PYD005',
42+
'hardcoded-errno-value': 'PYD006',
43+
'inconsistent-indentation': 'PYD007',
44+
'mkstemp-file-descriptor-leak': 'PYD008',
45+
'obsolete-pil-import': 'PYD009',
46+
'py3k-compat-warning': 'PYD010',
47+
'regexp-bad-escape': 'PYD011',
48+
'regexp-duplicate-range': 'PYD012',
49+
'regexp-incompatible-flags': 'PYD013',
50+
'regexp-misplaced-inline-flags': 'PYD014',
51+
'regexp-misplaced-flags-argument': 'PYD015',
52+
'regexp-overlapping-ranges': 'PYD016 Overlapping regexp ranges: \'{1}\', \'{2}\'',
53+
'regexp-redundant-flag': 'PYD017',
54+
'regexp-syntax-error': 'PYD018',
55+
'regexp-syntax-warning': 'PYD019',
56+
'string-exception': 'PYD020',
57+
'string-formatting-error': 'PYD021',
58+
'syntax-error': 'PYD022',
59+
'syntax-warning': 'PYD023 {1}',
60+
'sys.hexversion-comparison': 'PYD024',
61+
'sys.version-comparison': 'PYD025',
62+
}
63+
# @formatter:on
64+
65+
def __init__(self, tree, filename, lines):
66+
self.filename = filename
67+
self.lines = lines
68+
checks.load_data()
69+
70+
def run(self):
71+
for tag in checks.check_file(self.filename):
72+
message_template = self.messages.get(tag.name, None)
73+
74+
if message_template is None:
75+
print(f'flake8_pydiatra warning: unsupported check: {tag}', file=stderr)
76+
else:
77+
if ' ' not in message_template:
78+
# PYD005 bare except
79+
message_template = '{0} {1}'.format(message_template, tag.name.replace('-', ' '))
80+
81+
if '{' in message_template and '}' in message_template:
82+
message = message_template.format(*tag.args)
83+
else:
84+
message = f'{message_template}'
85+
if len(tag.args) > 1:
86+
message += ': ' + ' '.join(str(arg) for arg in tag.args[1:])
87+
88+
yield (tag.lineno or 1, 0, message, type(self))

setup.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Pydiatra plugin for flake8.
2+
# Copyright (C) 2019 Kirill Malyshev
3+
# The MIT License (MIT)
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining
6+
# a copy of this software and associated documentation files
7+
# (the "Software"), to deal in the Software without restriction,
8+
# including without limitation the rights to use, copy, modify, merge,
9+
# publish, distribute, sublicense, and/or sell copies of the Software,
10+
# and to permit persons to whom the Software is furnished to do so,
11+
# subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be
14+
# included in all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
24+
import io
25+
import re
26+
from distutils.cmd import Command
27+
28+
import copyright
29+
import setuptools
30+
31+
32+
def get_version(filename):
33+
with open(filename, "r") as fp:
34+
contents = fp.read()
35+
return re.search(r"__version__ = ['\"]([^'\"]+)['\"]", contents).group(1)
36+
37+
38+
def get_readme():
39+
with io.open('README.md', encoding='ASCII') as file:
40+
return file.read()
41+
42+
43+
class UpdateCopyrightCommand(Command):
44+
"""
45+
Command to update source files copyright headers.
46+
"""
47+
description = 'update source files copyright headers'
48+
user_options = []
49+
50+
def initialize_options(self):
51+
pass
52+
53+
def finalize_options(self):
54+
pass
55+
56+
def run(self):
57+
copyright.App.main(['-c', 'development/copyright.json', '.'])
58+
59+
60+
if __name__ == '__main__':
61+
setuptools.setup(
62+
name='flake8-pydiatra',
63+
version=get_version('flake8_pydiatra.py'),
64+
description='flake8 integration for pydiatra code analyzer',
65+
long_description=get_readme(),
66+
long_description_content_type='text/markdown',
67+
url='https://github.com/Logicify/flake8-pydiatra',
68+
license='MIT',
69+
author='Kirill Malyshev',
70+
install_requires=[
71+
'flake8>3.0.0',
72+
'pydiatra<1',
73+
],
74+
extras_require={
75+
'dev': ['copyright'],
76+
},
77+
python_requires='>=3.5',
78+
py_modules=['flake8_pydiatra'],
79+
entry_points={
80+
"flake8.extension": ["PYD0 = flake8_pydiatra:PydiatraChecker"]
81+
},
82+
cmdclass={
83+
'copyright': UpdateCopyrightCommand,
84+
},
85+
classifiers=[
86+
"Framework :: Flake8",
87+
'Development Status :: 4 - Beta',
88+
'Environment :: Console',
89+
'Intended Audience :: Developers',
90+
'License :: OSI Approved :: MIT License',
91+
'Operating System :: OS Independent',
92+
'Programming Language :: Python',
93+
'Programming Language :: Python :: 3',
94+
'Topic :: Software Development :: Quality Assurance',
95+
],
96+
)

0 commit comments

Comments
 (0)