flake8-author 2.0.0__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flake8-author-2.0.0/flake8_author.egg-info → flake8_author-2.2.0}/PKG-INFO +20 -97
- {flake8-author-2.0.0 → flake8_author-2.2.0}/README.rst +4 -1
- flake8_author-2.2.0/pyproject.toml +51 -0
- flake8_author-2.2.0/setup.cfg +9 -0
- {flake8-author-2.0.0 → flake8_author-2.2.0/src/flake8_author.egg-info}/PKG-INFO +20 -97
- flake8_author-2.2.0/src/flake8_author.egg-info/SOURCES.txt +12 -0
- {flake8-author-2.0.0 → flake8_author-2.2.0/src}/flake8_author.egg-info/entry_points.txt +0 -1
- flake8_author-2.2.0/src/flake8_author.py +106 -0
- flake8_author-2.2.0/tests/test_checker.py +197 -0
- flake8-author-2.0.0/CHANGES.rst +0 -59
- flake8-author-2.0.0/MANIFEST.in +0 -6
- flake8-author-2.0.0/flake8_author.egg-info/SOURCES.txt +0 -16
- flake8-author-2.0.0/flake8_author.egg-info/zip-safe +0 -1
- flake8-author-2.0.0/flake8_author.py +0 -90
- flake8-author-2.0.0/setup.cfg +0 -44
- flake8-author-2.0.0/setup.py +0 -10
- flake8-author-2.0.0/tests/__init__.py +0 -0
- flake8-author-2.0.0/tests/test_checker.py +0 -76
- {flake8-author-2.0.0 → flake8_author-2.2.0}/LICENSE +0 -0
- {flake8-author-2.0.0 → flake8_author-2.2.0/src}/flake8_author.egg-info/dependency_links.txt +0 -0
- {flake8-author-2.0.0 → flake8_author-2.2.0/src}/flake8_author.egg-info/requires.txt +0 -0
- {flake8-author-2.0.0 → flake8_author-2.2.0/src}/flake8_author.egg-info/top_level.txt +0 -0
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: flake8-author
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Flake8 __author__ checker
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Project-URL:
|
|
10
|
-
Project-URL:
|
|
11
|
-
Keywords: flake8
|
|
12
|
-
Platform: UNKNOWN
|
|
5
|
+
Author-email: Jon Parise <jon@indelible.org>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jparise/flake8-author
|
|
8
|
+
Project-URL: Repository, https://github.com/jparise/flake8-author
|
|
9
|
+
Project-URL: Issues, https://github.com/jparise/flake8-author/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/jparise/flake8-author/blob/main/CHANGELOG.rst
|
|
11
|
+
Keywords: flake8,__author__
|
|
13
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
13
|
Classifier: Environment :: Console
|
|
15
14
|
Classifier: Framework :: Flake8
|
|
16
15
|
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
18
16
|
Classifier: Programming Language :: Python
|
|
19
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
22
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
23
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
24
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
26
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Description-Content-Type: text/x-rst
|
|
27
27
|
License-File: LICENSE
|
|
28
|
+
Requires-Dist: flake8>=3.0.0
|
|
29
|
+
Dynamic: license-file
|
|
28
30
|
|
|
29
31
|
=========================
|
|
30
32
|
Flake8 __author__ Checker
|
|
@@ -51,6 +53,9 @@ This extension can therefore be configured to explicitly require or forbid
|
|
|
51
53
|
If the ``__author__`` attribute is allowed, its value can also be validated
|
|
52
54
|
using a configurable regular expression pattern.
|
|
53
55
|
|
|
56
|
+
The ``__author__`` attribute is generally assigned to a string, but multiple
|
|
57
|
+
authors can be listed using a list (or tuple or set) of strings.
|
|
58
|
+
|
|
54
59
|
.. |PyPI Version| image:: https://img.shields.io/pypi/v/flake8-author.svg
|
|
55
60
|
:target: https://pypi.python.org/pypi/flake8-author
|
|
56
61
|
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/flake8-author.svg
|
|
@@ -72,7 +77,7 @@ that it has been loaded by inspecting the ``flake8 --version`` string.
|
|
|
72
77
|
.. code-block:: sh
|
|
73
78
|
|
|
74
79
|
$ flake8 --version
|
|
75
|
-
|
|
80
|
+
6.1.0 (author: 2.1.0, ...) CPython 3.11.5 on Darwin
|
|
76
81
|
|
|
77
82
|
|
|
78
83
|
Error Codes
|
|
@@ -97,85 +102,3 @@ file`_ or as command line arguments (e.g. ``--author-attribute=required``).
|
|
|
97
102
|
|
|
98
103
|
.. _config file: http://flake8.pycqa.org/en/latest/user/configuration.html
|
|
99
104
|
.. _re: https://docs.python.org/library/re.html
|
|
100
|
-
|
|
101
|
-
Copyright (c) 2016 Jon Parise
|
|
102
|
-
|
|
103
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
104
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
105
|
-
in the Software without restriction, including without limitation the rights
|
|
106
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
107
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
108
|
-
furnished to do so, subject to the following conditions:
|
|
109
|
-
|
|
110
|
-
The above copyright notice and this permission notice shall be included in all
|
|
111
|
-
copies or substantial portions of the Software.
|
|
112
|
-
|
|
113
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
114
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
115
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
116
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
117
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
118
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
119
|
-
SOFTWARE.
|
|
120
|
-
|
|
121
|
-
Changes
|
|
122
|
-
=======
|
|
123
|
-
|
|
124
|
-
2.0.0 (2021-12-30)
|
|
125
|
-
------------------
|
|
126
|
-
|
|
127
|
-
* Drop support for Python 2.7 and 3.6, and add 3.10.
|
|
128
|
-
* Drop support for flake8 2.x versions.
|
|
129
|
-
|
|
130
|
-
1.2.0 (2020-10-12)
|
|
131
|
-
------------------
|
|
132
|
-
|
|
133
|
-
* Drop Python 3.5 support and add versions 3.8 and 3.9.
|
|
134
|
-
* Minor documentation improvements.
|
|
135
|
-
|
|
136
|
-
1.1.4 (2017-07-29)
|
|
137
|
-
------------------
|
|
138
|
-
|
|
139
|
-
* Minor code and packaging cleanup.
|
|
140
|
-
|
|
141
|
-
1.1.3 (2017-07-28)
|
|
142
|
-
------------------
|
|
143
|
-
|
|
144
|
-
* Drop the ``setup_requires`` dependency on flake8.
|
|
145
|
-
|
|
146
|
-
1.1.2 (2017-01-12)
|
|
147
|
-
------------------
|
|
148
|
-
|
|
149
|
-
* Only apply the author regular expression pattern check when a pattern has
|
|
150
|
-
actually been configured.
|
|
151
|
-
|
|
152
|
-
1.1.1 (2016-11-06)
|
|
153
|
-
------------------
|
|
154
|
-
|
|
155
|
-
* Fix configuration file parsing for flake8 3.0+.
|
|
156
|
-
|
|
157
|
-
1.1.0 (2016-08-15)
|
|
158
|
-
------------------
|
|
159
|
-
|
|
160
|
-
* Support flake8 3.0.0 (required for development)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
1.0.2 (2016-06-02)
|
|
164
|
-
------------------
|
|
165
|
-
|
|
166
|
-
* Support flake8 version 2.6.0
|
|
167
|
-
* Drop test dependency on pytest (development only)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
1.0.1 (2016-05-11)
|
|
171
|
-
------------------
|
|
172
|
-
|
|
173
|
-
* Fixed parser validation for configuration-based options
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
1.0.0 (2016-04-30)
|
|
177
|
-
------------------
|
|
178
|
-
|
|
179
|
-
* Initial release
|
|
180
|
-
|
|
181
|
-
|
|
@@ -23,6 +23,9 @@ This extension can therefore be configured to explicitly require or forbid
|
|
|
23
23
|
If the ``__author__`` attribute is allowed, its value can also be validated
|
|
24
24
|
using a configurable regular expression pattern.
|
|
25
25
|
|
|
26
|
+
The ``__author__`` attribute is generally assigned to a string, but multiple
|
|
27
|
+
authors can be listed using a list (or tuple or set) of strings.
|
|
28
|
+
|
|
26
29
|
.. |PyPI Version| image:: https://img.shields.io/pypi/v/flake8-author.svg
|
|
27
30
|
:target: https://pypi.python.org/pypi/flake8-author
|
|
28
31
|
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/flake8-author.svg
|
|
@@ -44,7 +47,7 @@ that it has been loaded by inspecting the ``flake8 --version`` string.
|
|
|
44
47
|
.. code-block:: sh
|
|
45
48
|
|
|
46
49
|
$ flake8 --version
|
|
47
|
-
|
|
50
|
+
6.1.0 (author: 2.1.0, ...) CPython 3.11.5 on Darwin
|
|
48
51
|
|
|
49
52
|
|
|
50
53
|
Error Codes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "flake8-author"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Flake8 __author__ checker"
|
|
9
|
+
authors = [
|
|
10
|
+
{name = "Jon Parise", email = "jon@indelible.org"},
|
|
11
|
+
]
|
|
12
|
+
readme = "README.rst"
|
|
13
|
+
license = "MIT"
|
|
14
|
+
keywords = ["flake8", "__author__"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 5 - Production/Stable",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Framework :: Flake8",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Programming Language :: Python",
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
29
|
+
]
|
|
30
|
+
requires-python = ">= 3.9"
|
|
31
|
+
dependencies = [
|
|
32
|
+
"flake8>=3.0.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=8",
|
|
38
|
+
"ruff==0.12.0",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.entry-points."flake8.extension"]
|
|
42
|
+
A40 = "flake8_author:Checker"
|
|
43
|
+
|
|
44
|
+
[project.urls]
|
|
45
|
+
Homepage = "https://github.com/jparise/flake8-author"
|
|
46
|
+
Repository = "https://github.com/jparise/flake8-author"
|
|
47
|
+
Issues = "https://github.com/jparise/flake8-author/issues"
|
|
48
|
+
Changelog = "https://github.com/jparise/flake8-author/blob/main/CHANGELOG.rst"
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.dynamic]
|
|
51
|
+
version = {attr = "flake8_author.__version__"}
|
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: flake8-author
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Flake8 __author__ checker
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Project-URL:
|
|
10
|
-
Project-URL:
|
|
11
|
-
Keywords: flake8
|
|
12
|
-
Platform: UNKNOWN
|
|
5
|
+
Author-email: Jon Parise <jon@indelible.org>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jparise/flake8-author
|
|
8
|
+
Project-URL: Repository, https://github.com/jparise/flake8-author
|
|
9
|
+
Project-URL: Issues, https://github.com/jparise/flake8-author/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/jparise/flake8-author/blob/main/CHANGELOG.rst
|
|
11
|
+
Keywords: flake8,__author__
|
|
13
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
13
|
Classifier: Environment :: Console
|
|
15
14
|
Classifier: Framework :: Flake8
|
|
16
15
|
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
18
16
|
Classifier: Programming Language :: Python
|
|
19
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
22
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
23
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
24
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
26
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Description-Content-Type: text/x-rst
|
|
27
27
|
License-File: LICENSE
|
|
28
|
+
Requires-Dist: flake8>=3.0.0
|
|
29
|
+
Dynamic: license-file
|
|
28
30
|
|
|
29
31
|
=========================
|
|
30
32
|
Flake8 __author__ Checker
|
|
@@ -51,6 +53,9 @@ This extension can therefore be configured to explicitly require or forbid
|
|
|
51
53
|
If the ``__author__`` attribute is allowed, its value can also be validated
|
|
52
54
|
using a configurable regular expression pattern.
|
|
53
55
|
|
|
56
|
+
The ``__author__`` attribute is generally assigned to a string, but multiple
|
|
57
|
+
authors can be listed using a list (or tuple or set) of strings.
|
|
58
|
+
|
|
54
59
|
.. |PyPI Version| image:: https://img.shields.io/pypi/v/flake8-author.svg
|
|
55
60
|
:target: https://pypi.python.org/pypi/flake8-author
|
|
56
61
|
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/flake8-author.svg
|
|
@@ -72,7 +77,7 @@ that it has been loaded by inspecting the ``flake8 --version`` string.
|
|
|
72
77
|
.. code-block:: sh
|
|
73
78
|
|
|
74
79
|
$ flake8 --version
|
|
75
|
-
|
|
80
|
+
6.1.0 (author: 2.1.0, ...) CPython 3.11.5 on Darwin
|
|
76
81
|
|
|
77
82
|
|
|
78
83
|
Error Codes
|
|
@@ -97,85 +102,3 @@ file`_ or as command line arguments (e.g. ``--author-attribute=required``).
|
|
|
97
102
|
|
|
98
103
|
.. _config file: http://flake8.pycqa.org/en/latest/user/configuration.html
|
|
99
104
|
.. _re: https://docs.python.org/library/re.html
|
|
100
|
-
|
|
101
|
-
Copyright (c) 2016 Jon Parise
|
|
102
|
-
|
|
103
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
104
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
105
|
-
in the Software without restriction, including without limitation the rights
|
|
106
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
107
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
108
|
-
furnished to do so, subject to the following conditions:
|
|
109
|
-
|
|
110
|
-
The above copyright notice and this permission notice shall be included in all
|
|
111
|
-
copies or substantial portions of the Software.
|
|
112
|
-
|
|
113
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
114
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
115
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
116
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
117
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
118
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
119
|
-
SOFTWARE.
|
|
120
|
-
|
|
121
|
-
Changes
|
|
122
|
-
=======
|
|
123
|
-
|
|
124
|
-
2.0.0 (2021-12-30)
|
|
125
|
-
------------------
|
|
126
|
-
|
|
127
|
-
* Drop support for Python 2.7 and 3.6, and add 3.10.
|
|
128
|
-
* Drop support for flake8 2.x versions.
|
|
129
|
-
|
|
130
|
-
1.2.0 (2020-10-12)
|
|
131
|
-
------------------
|
|
132
|
-
|
|
133
|
-
* Drop Python 3.5 support and add versions 3.8 and 3.9.
|
|
134
|
-
* Minor documentation improvements.
|
|
135
|
-
|
|
136
|
-
1.1.4 (2017-07-29)
|
|
137
|
-
------------------
|
|
138
|
-
|
|
139
|
-
* Minor code and packaging cleanup.
|
|
140
|
-
|
|
141
|
-
1.1.3 (2017-07-28)
|
|
142
|
-
------------------
|
|
143
|
-
|
|
144
|
-
* Drop the ``setup_requires`` dependency on flake8.
|
|
145
|
-
|
|
146
|
-
1.1.2 (2017-01-12)
|
|
147
|
-
------------------
|
|
148
|
-
|
|
149
|
-
* Only apply the author regular expression pattern check when a pattern has
|
|
150
|
-
actually been configured.
|
|
151
|
-
|
|
152
|
-
1.1.1 (2016-11-06)
|
|
153
|
-
------------------
|
|
154
|
-
|
|
155
|
-
* Fix configuration file parsing for flake8 3.0+.
|
|
156
|
-
|
|
157
|
-
1.1.0 (2016-08-15)
|
|
158
|
-
------------------
|
|
159
|
-
|
|
160
|
-
* Support flake8 3.0.0 (required for development)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
1.0.2 (2016-06-02)
|
|
164
|
-
------------------
|
|
165
|
-
|
|
166
|
-
* Support flake8 version 2.6.0
|
|
167
|
-
* Drop test dependency on pytest (development only)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
1.0.1 (2016-05-11)
|
|
171
|
-
------------------
|
|
172
|
-
|
|
173
|
-
* Fixed parser validation for configuration-based options
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
1.0.0 (2016-04-30)
|
|
177
|
-
------------------
|
|
178
|
-
|
|
179
|
-
* Initial release
|
|
180
|
-
|
|
181
|
-
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.rst
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.cfg
|
|
5
|
+
src/flake8_author.py
|
|
6
|
+
src/flake8_author.egg-info/PKG-INFO
|
|
7
|
+
src/flake8_author.egg-info/SOURCES.txt
|
|
8
|
+
src/flake8_author.egg-info/dependency_links.txt
|
|
9
|
+
src/flake8_author.egg-info/entry_points.txt
|
|
10
|
+
src/flake8_author.egg-info/requires.txt
|
|
11
|
+
src/flake8_author.egg-info/top_level.txt
|
|
12
|
+
tests/test_checker.py
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Flake8 extension that checks Python modules for an __author__ attribute.
|
|
2
|
+
|
|
3
|
+
This extension can be configured to explicitly require or forbid __author__
|
|
4
|
+
attributes. By default, __author__ is optional.
|
|
5
|
+
|
|
6
|
+
If the __author__ attribute is allowed, its value will be validated against a
|
|
7
|
+
configurable regular expression pattern (defaults to '.*').
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import ast
|
|
11
|
+
import re
|
|
12
|
+
from typing import Literal, Optional, get_args
|
|
13
|
+
|
|
14
|
+
__author__ = "Jon Parise"
|
|
15
|
+
__version__ = "2.2.0"
|
|
16
|
+
|
|
17
|
+
AttributePolicy = Literal["optional", "required", "forbidden"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Checker(object):
|
|
21
|
+
"""flake8 __author__ checker"""
|
|
22
|
+
|
|
23
|
+
name = "author"
|
|
24
|
+
version = __version__
|
|
25
|
+
|
|
26
|
+
# Options
|
|
27
|
+
attribute: AttributePolicy = "optional"
|
|
28
|
+
pattern: Optional[re.Pattern] = None
|
|
29
|
+
|
|
30
|
+
def __init__(self, tree, filename):
|
|
31
|
+
self.tree = tree
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def add_options(cls, parser):
|
|
35
|
+
extra_kwargs = {"parse_from_config": True}
|
|
36
|
+
|
|
37
|
+
parser.add_option(
|
|
38
|
+
"--author-attribute",
|
|
39
|
+
default=cls.attribute,
|
|
40
|
+
help="__author__ attribute: {0}".format(
|
|
41
|
+
", ".join(get_args(AttributePolicy))
|
|
42
|
+
),
|
|
43
|
+
**extra_kwargs,
|
|
44
|
+
)
|
|
45
|
+
parser.add_option(
|
|
46
|
+
"--author-pattern",
|
|
47
|
+
default=r"",
|
|
48
|
+
help="__author__ attribute validation pattern (regex)",
|
|
49
|
+
**extra_kwargs,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def parse_options(cls, options):
|
|
54
|
+
if options.author_attribute in get_args(AttributePolicy):
|
|
55
|
+
cls.attribute = options.author_attribute
|
|
56
|
+
else:
|
|
57
|
+
raise ValueError(
|
|
58
|
+
"author-attribute: '{0}' must be one of: {1}".format(
|
|
59
|
+
options.author_attribute, ", ".join(get_args(AttributePolicy))
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Only build a regular expression object when we've been configured
|
|
64
|
+
# with a pattern that doesn't match all strings. This naively just
|
|
65
|
+
# checks for the default empty pattern string as well as `.*`.
|
|
66
|
+
if options.author_pattern and options.author_pattern != ".*":
|
|
67
|
+
try:
|
|
68
|
+
cls.pattern = re.compile(options.author_pattern)
|
|
69
|
+
except re.error as e:
|
|
70
|
+
raise ValueError(
|
|
71
|
+
"author-pattern: '{0}': {1}".format(options.author_pattern, e)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def find_author_node(self, tree):
|
|
75
|
+
for node in tree.body:
|
|
76
|
+
if not isinstance(node, ast.Assign):
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
for target in node.targets:
|
|
80
|
+
if isinstance(target, ast.Name) and target.id == "__author__":
|
|
81
|
+
return node
|
|
82
|
+
|
|
83
|
+
def _match_author_pattern(self, author, node):
|
|
84
|
+
if self.pattern is not None and not self.pattern.match(author):
|
|
85
|
+
message = 'A402 __author__ value "{0}" does not match "{1}"'.format(
|
|
86
|
+
author, self.pattern.pattern
|
|
87
|
+
)
|
|
88
|
+
yield (node.lineno, node.col_offset, message, type(self))
|
|
89
|
+
|
|
90
|
+
def run(self):
|
|
91
|
+
node = self.find_author_node(self.tree)
|
|
92
|
+
|
|
93
|
+
if node is None and self.attribute == "required":
|
|
94
|
+
message = "A400 module-level __author__ attribute required"
|
|
95
|
+
yield 0, 0, message, type(self)
|
|
96
|
+
|
|
97
|
+
elif node and self.attribute == "forbidden":
|
|
98
|
+
message = "A401 __author__ attributes are not allowed"
|
|
99
|
+
yield node.lineno, node.col_offset, message, type(self)
|
|
100
|
+
|
|
101
|
+
elif node and self.pattern is not None:
|
|
102
|
+
if isinstance(node.value, (ast.List, ast.Tuple, ast.Set)):
|
|
103
|
+
for author in ast.literal_eval(node.value):
|
|
104
|
+
yield from self._match_author_pattern(author, node)
|
|
105
|
+
elif isinstance(node.value, ast.Constant):
|
|
106
|
+
yield from self._match_author_pattern(node.value.value, node)
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
from flake8.main.application import Application
|
|
5
|
+
from flake8_author import Checker
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def make_linter(code, path="example.py", argv=None):
|
|
9
|
+
app = Application()
|
|
10
|
+
app.initialize(argv)
|
|
11
|
+
Checker.parse_options(app.options)
|
|
12
|
+
tree = ast.parse(code, path)
|
|
13
|
+
return Checker(tree, path)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def check(author, attribute=None, pattern=None):
|
|
17
|
+
code = ""
|
|
18
|
+
if isinstance(author, (list, tuple, set)):
|
|
19
|
+
code = "__author__ = {0}".format(author)
|
|
20
|
+
elif author:
|
|
21
|
+
code = '__author__ = "{0}"'.format(author)
|
|
22
|
+
|
|
23
|
+
argv = []
|
|
24
|
+
if attribute:
|
|
25
|
+
argv.append("--author-attribute={0}".format(attribute))
|
|
26
|
+
if pattern:
|
|
27
|
+
argv.append("--author-pattern={0}".format(pattern))
|
|
28
|
+
|
|
29
|
+
linter = make_linter(code, argv=argv)
|
|
30
|
+
if isinstance(author, (list, tuple, set)):
|
|
31
|
+
result = list(linter.run())
|
|
32
|
+
return result if len(result) else None
|
|
33
|
+
return next(linter.run(), None)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestChecker(unittest.TestCase):
|
|
37
|
+
def tearDown(self):
|
|
38
|
+
Checker.attribute = "optional"
|
|
39
|
+
Checker.pattern = None
|
|
40
|
+
|
|
41
|
+
def test_author_optional(self):
|
|
42
|
+
self.assertIsNone(check("", attribute="optional"))
|
|
43
|
+
self.assertIsNone(check("Jon Parise", attribute="optional"))
|
|
44
|
+
|
|
45
|
+
def test_author_required(self):
|
|
46
|
+
self.assertIsNone(check("Jon Parise", attribute="required"))
|
|
47
|
+
|
|
48
|
+
def test_author_required_but_missing(self):
|
|
49
|
+
lineno, offset, message, _ = check("", attribute="required")
|
|
50
|
+
self.assertEqual(lineno, 0)
|
|
51
|
+
self.assertEqual(offset, 0)
|
|
52
|
+
self.assertTrue(message.startswith("A400"))
|
|
53
|
+
|
|
54
|
+
def test_author_forbidden(self):
|
|
55
|
+
self.assertIsNone(check("", attribute="forbidden"))
|
|
56
|
+
|
|
57
|
+
def test_author_forbidden_but_present(self):
|
|
58
|
+
lineno, offset, message, _ = check("Jon Parise", attribute="forbidden")
|
|
59
|
+
self.assertEqual(lineno, 1)
|
|
60
|
+
self.assertEqual(offset, 0)
|
|
61
|
+
self.assertTrue(message.startswith("A401"))
|
|
62
|
+
|
|
63
|
+
def test_author_invalid_attribute(self):
|
|
64
|
+
with self.assertRaises(ValueError):
|
|
65
|
+
check("Jon Parise", attribute="invalid")
|
|
66
|
+
|
|
67
|
+
def test_author_pattern(self):
|
|
68
|
+
author = "Jon Parise <jon@example.com>"
|
|
69
|
+
self.assertIsNone(check(author))
|
|
70
|
+
self.assertIsNone(check(author, pattern=r""))
|
|
71
|
+
self.assertIsNone(check(author, pattern=r".*"))
|
|
72
|
+
|
|
73
|
+
def test_author_pattern_not_matched(self):
|
|
74
|
+
author = "Jon Parise <jon@example.com>"
|
|
75
|
+
lineno, offset, message, _ = check(author, pattern=r"^[\w\s]+$")
|
|
76
|
+
self.assertEqual(lineno, 1)
|
|
77
|
+
self.assertEqual(offset, 0)
|
|
78
|
+
self.assertTrue(message.startswith("A402"))
|
|
79
|
+
|
|
80
|
+
def test_multi_author_list_pattern(self):
|
|
81
|
+
author = [
|
|
82
|
+
"Jon Parise <jon@example.com>",
|
|
83
|
+
"Jesse Boswell <jesse@example.com>",
|
|
84
|
+
]
|
|
85
|
+
self.assertIsNone(check(author))
|
|
86
|
+
self.assertIsNone(check(author, pattern=r""))
|
|
87
|
+
self.assertIsNone(check(author, pattern=r".*"))
|
|
88
|
+
|
|
89
|
+
def test_multi_author_list_pattern_partial_match(self):
|
|
90
|
+
author = [
|
|
91
|
+
"Jon Parise <jon@example.com>",
|
|
92
|
+
"Jesse Boswell <jesse@badexample.com>",
|
|
93
|
+
]
|
|
94
|
+
results = check(author, pattern=r"^.+?@example.com>$")
|
|
95
|
+
self.assertIsNotNone(results)
|
|
96
|
+
self.assertEqual(len(results), 1)
|
|
97
|
+
for result in results:
|
|
98
|
+
lineno, offset, message, _ = result
|
|
99
|
+
self.assertEqual(lineno, 1)
|
|
100
|
+
self.assertEqual(offset, 0)
|
|
101
|
+
self.assertTrue(message.startswith("A402"))
|
|
102
|
+
|
|
103
|
+
def test_multi_author_list_pattern_not_matched(self):
|
|
104
|
+
author = [
|
|
105
|
+
"Jon Parise <jon@example.com>",
|
|
106
|
+
"Jesse Boswell <jesse@example.com>",
|
|
107
|
+
]
|
|
108
|
+
results = check(author, pattern=r"^[\w\s]+$")
|
|
109
|
+
self.assertIsNotNone(results)
|
|
110
|
+
self.assertEqual(len(results), 2)
|
|
111
|
+
for result in results:
|
|
112
|
+
lineno, offset, message, _ = result
|
|
113
|
+
self.assertEqual(lineno, 1)
|
|
114
|
+
self.assertEqual(offset, 0)
|
|
115
|
+
self.assertTrue(message.startswith("A402"))
|
|
116
|
+
|
|
117
|
+
def test_multi_author_tuple_pattern(self):
|
|
118
|
+
author = (
|
|
119
|
+
"Jon Parise <jon@example.com>",
|
|
120
|
+
"Jesse Boswell <jesse@example.com>",
|
|
121
|
+
)
|
|
122
|
+
self.assertIsNone(check(author))
|
|
123
|
+
self.assertIsNone(check(author, pattern=r""))
|
|
124
|
+
self.assertIsNone(check(author, pattern=r".*"))
|
|
125
|
+
|
|
126
|
+
def test_multi_author_tuple_pattern_partial_match(self):
|
|
127
|
+
author = (
|
|
128
|
+
"Jon Parise <jon@example.com>",
|
|
129
|
+
"Jesse Boswell <jesse@badexample.com>",
|
|
130
|
+
)
|
|
131
|
+
results = check(author, pattern=r"^.+?@example.com>$")
|
|
132
|
+
self.assertIsNotNone(results)
|
|
133
|
+
self.assertEqual(len(results), 1)
|
|
134
|
+
for result in results:
|
|
135
|
+
lineno, offset, message, _ = result
|
|
136
|
+
self.assertEqual(lineno, 1)
|
|
137
|
+
self.assertEqual(offset, 0)
|
|
138
|
+
self.assertTrue(message.startswith("A402"))
|
|
139
|
+
|
|
140
|
+
def test_multi_author_tuple_pattern_not_matched(self):
|
|
141
|
+
author = (
|
|
142
|
+
"Jon Parise <jon@example.com>",
|
|
143
|
+
"Jesse Boswell <jesse@example.com>",
|
|
144
|
+
)
|
|
145
|
+
results = check(author, pattern=r"^[\w\s]+$")
|
|
146
|
+
self.assertIsNotNone(results)
|
|
147
|
+
self.assertEqual(len(results), 2)
|
|
148
|
+
for result in results:
|
|
149
|
+
lineno, offset, message, _ = result
|
|
150
|
+
self.assertEqual(lineno, 1)
|
|
151
|
+
self.assertEqual(offset, 0)
|
|
152
|
+
self.assertTrue(message.startswith("A402"))
|
|
153
|
+
|
|
154
|
+
def test_multi_author_set_pattern(self):
|
|
155
|
+
author = {
|
|
156
|
+
"Jon Parise <jon@example.com>",
|
|
157
|
+
"Jesse Boswell <jesse@example.com>",
|
|
158
|
+
}
|
|
159
|
+
self.assertIsNone(check(author))
|
|
160
|
+
self.assertIsNone(check(author, pattern=r""))
|
|
161
|
+
self.assertIsNone(check(author, pattern=r".*"))
|
|
162
|
+
|
|
163
|
+
def test_multi_author_set_pattern_partial_match(self):
|
|
164
|
+
author = {
|
|
165
|
+
"Jon Parise <jon@example.com>",
|
|
166
|
+
"Jesse Boswell <jesse@badexample.com>",
|
|
167
|
+
}
|
|
168
|
+
results = check(author, pattern=r"^.+?@example.com>$")
|
|
169
|
+
self.assertIsNotNone(results)
|
|
170
|
+
self.assertEqual(len(results), 1)
|
|
171
|
+
for result in results:
|
|
172
|
+
lineno, offset, message, _ = result
|
|
173
|
+
self.assertEqual(lineno, 1)
|
|
174
|
+
self.assertEqual(offset, 0)
|
|
175
|
+
self.assertTrue(message.startswith("A402"))
|
|
176
|
+
|
|
177
|
+
def test_multi_author_set_pattern_not_matched(self):
|
|
178
|
+
author = {
|
|
179
|
+
"Jon Parise <jon@example.com>",
|
|
180
|
+
"Jesse Boswell <jesse@example.com>",
|
|
181
|
+
}
|
|
182
|
+
results = check(author, pattern=r"^[\w\s]+$")
|
|
183
|
+
self.assertIsNotNone(results)
|
|
184
|
+
self.assertEqual(len(results), 2)
|
|
185
|
+
for result in results:
|
|
186
|
+
lineno, offset, message, _ = result
|
|
187
|
+
self.assertEqual(lineno, 1)
|
|
188
|
+
self.assertEqual(offset, 0)
|
|
189
|
+
self.assertTrue(message.startswith("A402"))
|
|
190
|
+
|
|
191
|
+
def test_author_pattern_invalid_regex(self):
|
|
192
|
+
with self.assertRaises(ValueError):
|
|
193
|
+
check("Jon Parise", pattern=r"\[[")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
if __name__ == "__main__":
|
|
197
|
+
unittest.main()
|
flake8-author-2.0.0/CHANGES.rst
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
Changes
|
|
2
|
-
=======
|
|
3
|
-
|
|
4
|
-
2.0.0 (2021-12-30)
|
|
5
|
-
------------------
|
|
6
|
-
|
|
7
|
-
* Drop support for Python 2.7 and 3.6, and add 3.10.
|
|
8
|
-
* Drop support for flake8 2.x versions.
|
|
9
|
-
|
|
10
|
-
1.2.0 (2020-10-12)
|
|
11
|
-
------------------
|
|
12
|
-
|
|
13
|
-
* Drop Python 3.5 support and add versions 3.8 and 3.9.
|
|
14
|
-
* Minor documentation improvements.
|
|
15
|
-
|
|
16
|
-
1.1.4 (2017-07-29)
|
|
17
|
-
------------------
|
|
18
|
-
|
|
19
|
-
* Minor code and packaging cleanup.
|
|
20
|
-
|
|
21
|
-
1.1.3 (2017-07-28)
|
|
22
|
-
------------------
|
|
23
|
-
|
|
24
|
-
* Drop the ``setup_requires`` dependency on flake8.
|
|
25
|
-
|
|
26
|
-
1.1.2 (2017-01-12)
|
|
27
|
-
------------------
|
|
28
|
-
|
|
29
|
-
* Only apply the author regular expression pattern check when a pattern has
|
|
30
|
-
actually been configured.
|
|
31
|
-
|
|
32
|
-
1.1.1 (2016-11-06)
|
|
33
|
-
------------------
|
|
34
|
-
|
|
35
|
-
* Fix configuration file parsing for flake8 3.0+.
|
|
36
|
-
|
|
37
|
-
1.1.0 (2016-08-15)
|
|
38
|
-
------------------
|
|
39
|
-
|
|
40
|
-
* Support flake8 3.0.0 (required for development)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
1.0.2 (2016-06-02)
|
|
44
|
-
------------------
|
|
45
|
-
|
|
46
|
-
* Support flake8 version 2.6.0
|
|
47
|
-
* Drop test dependency on pytest (development only)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
1.0.1 (2016-05-11)
|
|
51
|
-
------------------
|
|
52
|
-
|
|
53
|
-
* Fixed parser validation for configuration-based options
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
1.0.0 (2016-04-30)
|
|
57
|
-
------------------
|
|
58
|
-
|
|
59
|
-
* Initial release
|
flake8-author-2.0.0/MANIFEST.in
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
CHANGES.rst
|
|
2
|
-
LICENSE
|
|
3
|
-
MANIFEST.in
|
|
4
|
-
README.rst
|
|
5
|
-
flake8_author.py
|
|
6
|
-
setup.cfg
|
|
7
|
-
setup.py
|
|
8
|
-
flake8_author.egg-info/PKG-INFO
|
|
9
|
-
flake8_author.egg-info/SOURCES.txt
|
|
10
|
-
flake8_author.egg-info/dependency_links.txt
|
|
11
|
-
flake8_author.egg-info/entry_points.txt
|
|
12
|
-
flake8_author.egg-info/requires.txt
|
|
13
|
-
flake8_author.egg-info/top_level.txt
|
|
14
|
-
flake8_author.egg-info/zip-safe
|
|
15
|
-
tests/__init__.py
|
|
16
|
-
tests/test_checker.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"""Flake8 extension that checks Python modules for an __author__ attribute.
|
|
2
|
-
|
|
3
|
-
This extension can be configured to explicitly require or forbid __author__
|
|
4
|
-
attributes. By default, __author__ is optional.
|
|
5
|
-
|
|
6
|
-
If the __author__ attribute is allowed, its value will be validated against a
|
|
7
|
-
configurable regular expression pattern (defaults to '.*').
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import ast
|
|
11
|
-
import re
|
|
12
|
-
|
|
13
|
-
__author__ = 'Jon Parise'
|
|
14
|
-
__version__ = '2.0.0'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Checker(object):
|
|
18
|
-
"""flake8 __author__ checker"""
|
|
19
|
-
|
|
20
|
-
name = 'author'
|
|
21
|
-
options = {}
|
|
22
|
-
version = __version__
|
|
23
|
-
|
|
24
|
-
# Attribute existence choices
|
|
25
|
-
attribute_choices = ('optional', 'required', 'forbidden')
|
|
26
|
-
|
|
27
|
-
def __init__(self, tree, filename):
|
|
28
|
-
self.tree = tree
|
|
29
|
-
|
|
30
|
-
@classmethod
|
|
31
|
-
def add_options(cls, parser):
|
|
32
|
-
extra_kwargs = {'parse_from_config': True}
|
|
33
|
-
|
|
34
|
-
parser.add_option(
|
|
35
|
-
'--author-attribute',
|
|
36
|
-
default='optional',
|
|
37
|
-
help="__author__ attribute: {0}".format(
|
|
38
|
-
', '.join(cls.attribute_choices)),
|
|
39
|
-
**extra_kwargs)
|
|
40
|
-
parser.add_option(
|
|
41
|
-
'--author-pattern',
|
|
42
|
-
default=r'',
|
|
43
|
-
help="__author__ attribute validation pattern (regex)",
|
|
44
|
-
**extra_kwargs)
|
|
45
|
-
|
|
46
|
-
@classmethod
|
|
47
|
-
def parse_options(cls, options):
|
|
48
|
-
if options.author_attribute in cls.attribute_choices:
|
|
49
|
-
cls.options['attribute'] = options.author_attribute
|
|
50
|
-
else:
|
|
51
|
-
raise ValueError(
|
|
52
|
-
"author-attribute: '{0}' must be one of: {1}".format(
|
|
53
|
-
options.author_attribute,
|
|
54
|
-
', '.join(cls.attribute_choices)))
|
|
55
|
-
|
|
56
|
-
# Only build a regular expression object when we've been configured
|
|
57
|
-
# with a pattern that doesn't match all strings. This naively just
|
|
58
|
-
# checks for the default empty pattern string as well as `.*`.
|
|
59
|
-
if options.author_pattern and options.author_pattern != '.*':
|
|
60
|
-
try:
|
|
61
|
-
cls.options['pattern'] = re.compile(options.author_pattern)
|
|
62
|
-
except re.error as e:
|
|
63
|
-
raise ValueError("author-pattern: '{0}': {1}".format(
|
|
64
|
-
options.author_pattern, e))
|
|
65
|
-
|
|
66
|
-
def find_author_node(self, tree):
|
|
67
|
-
for node in tree.body:
|
|
68
|
-
if not isinstance(node, ast.Assign):
|
|
69
|
-
continue
|
|
70
|
-
|
|
71
|
-
for target in node.targets:
|
|
72
|
-
if isinstance(target, ast.Name) and target.id == '__author__':
|
|
73
|
-
return node
|
|
74
|
-
|
|
75
|
-
def run(self):
|
|
76
|
-
node = self.find_author_node(self.tree)
|
|
77
|
-
|
|
78
|
-
if node is None and self.options['attribute'] == 'required':
|
|
79
|
-
message = 'A400 module-level __author__ attribute required'
|
|
80
|
-
yield 0, 0, message, type(self)
|
|
81
|
-
|
|
82
|
-
elif node and self.options['attribute'] == 'forbidden':
|
|
83
|
-
message = 'A401 __author__ attributes are not allowed'
|
|
84
|
-
yield node.lineno, node.col_offset, message, type(self)
|
|
85
|
-
|
|
86
|
-
elif (node and 'pattern' in self.options and
|
|
87
|
-
not self.options['pattern'].match(node.value.s)):
|
|
88
|
-
message = ('A402 __author__ value "{0}" does not match "{1}"'
|
|
89
|
-
.format(node.value.s, self.options['pattern'].pattern))
|
|
90
|
-
yield node.lineno, node.col_offset, message, type(self)
|
flake8-author-2.0.0/setup.cfg
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
[metadata]
|
|
2
|
-
name = flake8-author
|
|
3
|
-
version = attr: flake8_author.__version__
|
|
4
|
-
author = Jon Parise
|
|
5
|
-
author_email = jon@indelible.org
|
|
6
|
-
description = Flake8 __author__ checker
|
|
7
|
-
long_description = file: README.rst, LICENSE, CHANGES.rst
|
|
8
|
-
license = MIT
|
|
9
|
-
url = https://github.com/jparise/flake8-author
|
|
10
|
-
project_urls =
|
|
11
|
-
Source Code = https://github.com/jparise/flake8-author
|
|
12
|
-
Issue Tracker = https://github.com/jparise/flake8-author/issues
|
|
13
|
-
keywords = flake8 __author__
|
|
14
|
-
classifiers =
|
|
15
|
-
Development Status :: 5 - Production/Stable
|
|
16
|
-
Environment :: Console
|
|
17
|
-
Framework :: Flake8
|
|
18
|
-
Intended Audience :: Developers
|
|
19
|
-
License :: OSI Approved :: MIT License
|
|
20
|
-
Programming Language :: Python
|
|
21
|
-
Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Programming Language :: Python :: 3.7
|
|
23
|
-
Programming Language :: Python :: 3.8
|
|
24
|
-
Programming Language :: Python :: 3.9
|
|
25
|
-
Programming Language :: Python :: 3.10
|
|
26
|
-
Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
-
Topic :: Software Development :: Quality Assurance
|
|
28
|
-
|
|
29
|
-
[options]
|
|
30
|
-
py_modules = flake8_author
|
|
31
|
-
python_requires = >= 3.7
|
|
32
|
-
zip_safe = True
|
|
33
|
-
|
|
34
|
-
[options.entry_points]
|
|
35
|
-
flake8.extension =
|
|
36
|
-
A40 = flake8_author:Checker
|
|
37
|
-
|
|
38
|
-
[flake8]
|
|
39
|
-
exclude = .eggs/,.git/,.venv/,build/,dist/
|
|
40
|
-
|
|
41
|
-
[egg_info]
|
|
42
|
-
tag_build =
|
|
43
|
-
tag_date = 0
|
|
44
|
-
|
flake8-author-2.0.0/setup.py
DELETED
|
File without changes
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import ast
|
|
2
|
-
import unittest
|
|
3
|
-
|
|
4
|
-
from flake8.main.application import Application
|
|
5
|
-
from flake8_author import Checker
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def make_linter(code, path='example.py', argv=None):
|
|
9
|
-
app = Application()
|
|
10
|
-
app.initialize(argv)
|
|
11
|
-
Checker.parse_options(app.options)
|
|
12
|
-
tree = ast.parse(code, path)
|
|
13
|
-
return Checker(tree, path)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def check(author, attribute=None, pattern=None):
|
|
17
|
-
code = '__author__ = "{0}"'.format(author) if author else ''
|
|
18
|
-
|
|
19
|
-
argv = []
|
|
20
|
-
if attribute:
|
|
21
|
-
argv.append('--author-attribute={0}'.format(attribute))
|
|
22
|
-
if pattern:
|
|
23
|
-
argv.append('--author-pattern={0}'.format(pattern))
|
|
24
|
-
|
|
25
|
-
linter = make_linter(code, argv=argv)
|
|
26
|
-
return next(linter.run(), None)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class TestChecker(unittest.TestCase):
|
|
30
|
-
|
|
31
|
-
def test_author_optional(self):
|
|
32
|
-
self.assertIsNone(check('', attribute='optional'))
|
|
33
|
-
self.assertIsNone(check('Jon Parise', attribute='optional'))
|
|
34
|
-
|
|
35
|
-
def test_author_required(self):
|
|
36
|
-
self.assertIsNone(check('Jon Parise', attribute='required'))
|
|
37
|
-
|
|
38
|
-
def test_author_required_but_missing(self):
|
|
39
|
-
lineno, offset, message, _ = check('', attribute='required')
|
|
40
|
-
self.assertEqual(lineno, 0)
|
|
41
|
-
self.assertEqual(offset, 0)
|
|
42
|
-
self.assertTrue(message.startswith('A400'))
|
|
43
|
-
|
|
44
|
-
def test_author_forbidden(self):
|
|
45
|
-
self.assertIsNone(check('', attribute='forbidden'))
|
|
46
|
-
|
|
47
|
-
def test_author_forbidden_but_present(self):
|
|
48
|
-
lineno, offset, message, _ = check('Jon Parise', attribute='forbidden')
|
|
49
|
-
self.assertEqual(lineno, 1)
|
|
50
|
-
self.assertEqual(offset, 0)
|
|
51
|
-
self.assertTrue(message.startswith('A401'))
|
|
52
|
-
|
|
53
|
-
def test_author_invalid_attribute(self):
|
|
54
|
-
with self.assertRaises(ValueError):
|
|
55
|
-
check('Jon Parise', attribute='invalid')
|
|
56
|
-
|
|
57
|
-
def test_author_pattern(self):
|
|
58
|
-
author = 'Jon Parise <jon@example.com>'
|
|
59
|
-
self.assertIsNone(check(author))
|
|
60
|
-
self.assertIsNone(check(author, pattern=r''))
|
|
61
|
-
self.assertIsNone(check(author, pattern=r'.*'))
|
|
62
|
-
|
|
63
|
-
def test_author_pattern_not_matched(self):
|
|
64
|
-
author = 'Jon Parise <jon@example.com>'
|
|
65
|
-
lineno, offset, message, _ = check(author, pattern=r'^[\w\s]+$')
|
|
66
|
-
self.assertEqual(lineno, 1)
|
|
67
|
-
self.assertEqual(offset, 0)
|
|
68
|
-
self.assertTrue(message.startswith('A402'))
|
|
69
|
-
|
|
70
|
-
def test_author_pattern_invalid_regex(self):
|
|
71
|
-
with self.assertRaises(ValueError):
|
|
72
|
-
check('Jon Parise', pattern=r'\[[')
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if __name__ == '__main__':
|
|
76
|
-
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|