Commit 08f77e12 authored by ChangZhuo Chen's avatar ChangZhuo Chen

New upstream version 0.8.2

parent 6b32d9a3
......@@ -9,21 +9,23 @@ script: tox
matrix:
include:
- env: TOXENV=py26
python: 2.6
- env: TOXENV=py27
python: 2.7
- env: TOXENV=py33
python: 3.3
- env: TOXENV=py34
python: 3.4
- env: TOXENV=py35
python: 3.5
- env: TOXENV=py36
python: 3.6
- env: TOXENV=py37
dist: xenial
sudo: required
python: 3.7
- env: TOXENV=pypy
python: pypy
- env: TOXENV=pypy3
python: pypy3
- env: TOXENV=py27-flake8
python: 2.7
- env: TOXENV=py34-flake8
python: 3.4
- env: TOXENV=py37-flake8
dist: xenial
sudo: required
python: 3.7
Changes
=======
0.8.2 - 2019-02-04
------------------
* Fix a problem with ``ignore-names`` option initialization.
0.8.1 - 2019-02-04
------------------
* ``ignore-names`` now also applies to the N806, N815, and N816 checks.
* ``failureException``, ``longMessage``, and ``maxDiff`` have been added to
the default ``ignore-names`` list.
* Allow lowercase names to be imported as just ``_``.
* Allow function arguments to be named just ``_``.
* Support Python 2's tuple syntax in ``except`` clauses.
0.8.0 - 2019-01-28
------------------
* Detect N806 errors within ``for`` loops and exception handlers.
* Improve support for non-ASCII characters.
* Detect mixedCased variable names at class (N815) and global (N816) scope.
* Ignore Django's ``setUpTestData`` method by default.
* Fix column offsets for N803, N804, and N805 under Python 3.
* Detect underscores within class names as N801 errors.
* Don't flag ``__getattr__`` and ``__dir__`` as N807 errors. (See
`PEP 562 <https://www.python.org/dev/peps/pep-0562/>`_).
* ``async`` function and method names are now checked.
* Detect N806 errors in generator expressions and comprehensions.
* Detect N81x errors in ``import x as y`` statements.
0.7.0 - 2018-05-17
------------------
* Detect N806 in ``with ... as ...:`` statements.
* Detect N806 in multiple assignment statements, e.g., ``Foo, Bar =
unpacking``.
* Allow class names to be properly ignored.
* Remove spurious 'xxx' from error message
* Detect N807 within conditional statements.
0.6.1 - 2018-05-06
------------------
* Fix N804 check for ``cls`` used in metaclass methods (See also
https://github.com/PyCQA/pep8-naming/issues/53)
0.6.0 - 2018-05-04
------------------
* Separate check for ``__`` in function names to its own code: N807
* Consider all metaclass methods to be class methods
0.5.0 - 2018-01-02
------------------
* Add configurable list of classmethod and staticmethod decorators
* Print the offending name as part of the error message
* Correct N804/N805 for __init_subclass__
0.4.1 - 2016-06-26
------------------
* Note to self: Never do releases before ~0600 or coffee on a Sunday.
* Fix option parsing for Flake8 3.0 (store parsed value on class)
0.4.0 - 2016-06-26
------------------
* Fix integration with Flake8 3.0.0b1
* Start testing against Python 3.5
0.3.3 - 2015-06-30
------------------
* Fix bug where ignored names were not properly split into a list.
0.3.2 - 2015-06-14
------------------
* Fix bug trying to call ``split`` on a list.
0.3.1 - 2015-06-14
------------------
* Fix optparse exception resulting from trying to register an option twice.
0.3.0 - 2015-06-14
------------------
* Relaxed N806 checking for use with namedtuples
* Add ``--ignore-names`` which allows the user to specify a list of names to
ignore. By default this includes ``setUp``, ``tearDown``, ``setUpClass``,
and ``tearDownClass``.
0.2.2 - 2014-04-19
------------------
* Do not require ``setuptools`` in setup.py. It works around an issue
with ``pip`` and Python 3.
* ``__new__`` is now considered as ``classmethod`` implicitly
* Run unit tests on travis-ci.org for python2.6, 2.7, 3.2, and 3.3
* Add unit tests and support running them with setup.py
* Support Python 3.4
0.2.1 - 2013-02-22
------------------
* Do not require ``flake8``
0.2 - 2013-02-22
----------------
* Rename project ``flint-naming`` to ``pep8-naming``
* Fix a crash when function argument is a tuple of tuples
0.1 - 2013-02-11
----------------
* First release
include LICENSE
include README.rst CHANGELOG.rst
include run_tests.py
recursive-include testsuite *.py
.. image:: https://travis-ci.org/PyCQA/pep8-naming.svg?branch=master
:target: https://travis-ci.org/PyCQA/pep8-naming
PEP-8 Naming Conventions
========================
......@@ -46,6 +49,8 @@ These error codes are emitted:
+------+-------------------------------------------------------+
| N806 | variable in function should be lowercase |
+------+-------------------------------------------------------+
| N807 | function name should not start or end with '__' |
+------+-------------------------------------------------------+
+------+-------------------------------------------------------+
| N811 | constant imported as non constant |
+------+-------------------------------------------------------+
......@@ -55,75 +60,30 @@ These error codes are emitted:
+------+-------------------------------------------------------+
| N814 | camelcase imported as constant |
+------+-------------------------------------------------------+
| N815 | mixedCase variable in class scope |
+------+-------------------------------------------------------+
| N816 | mixedCase variable in global scope |
+------+-------------------------------------------------------+
Changes
Options
-------
0.4.1 - 2016-06-26
``````````````````
* Note to self: Never do releases before ~0600 or coffee on a Sunday.
* Fix option parsing for Flake8 3.0 (store parsed value on class)
0.4.0 - 2016-06-26
``````````````````
* Fix integration with Flake8 3.0.0b1
* Start testing against Python 3.5
0.3.3 - 2015-06-30
``````````````````
* Fix bug where ignored names were not properly split into a list.
0.3.2 - 2015-06-14
``````````````````
* Fix bug trying to call ``split`` on a list.
0.3.1 - 2015-06-14
``````````````````
* Fix optparse exception resulting from trying to register an option twice.
0.3.0 - 2015-06-14
``````````````````
* Relaxed N806 checking for use with namedtuples
* Add ``--ignore-names`` which allows the user to specify a list of names to
ignore. By default this includes ``setUp``, ``tearDown``, ``setUpClass``,
and ``tearDownClass``.
0.2.2 - 2014-04-19
``````````````````
* Do not require ``setuptools`` in setup.py. It works around an issue
with ``pip`` and Python 3.
* ``__new__`` is now considered as ``classmethod`` implicitly
* Run unit tests on travis-ci.org for python2.6, 2.7, 3.2, and 3.3
The following flake8 options are added:
* Add unit tests and support running them with setup.py
--ignore-names Ignore errors for specific variable names.
* Support Python 3.4
Currently, this option can only be used for N802, N806, N815, and N816 errors.
Default: ``setUp,tearDown,setUpClass,tearDownClass,setUpTestData,failureException,longMessage,maxDiff``.
0.2.1 - 2013-02-22
``````````````````
* Do not require ``flake8``
--classmethod-decorators List of method decorators pep8-naming plugin should consider class method.
Used to prevent false N804 errors.
0.2 - 2013-02-22
````````````````
* Rename project ``flint-naming`` to ``pep8-naming``
Default: ``classmethod``.
* Fix a crash when function argument is a tuple of tuples
--staticmethod-decorators List of method decorators pep8-naming plugin should consider static method.
Used to prevent false N805 errors.
0.1 - 2013-02-11
````````````````
* First release
Default: ``staticmethod``.
import sys
import io
import optparse
import os
import pep8ext_naming
import platform
import re
import sys
import pep8ext_naming
PyCF_ONLY_AST = 1024
IS_PY3 = sys.version_info[0] == 3
IS_PY3_TEST = re.compile("^#\s*python3\s*only")
IS_PY2_TEST = re.compile("^#\s*python2\s*only")
TESTCASE_RE = re.compile(
r'#: '
r'(?P<code>\w+:?\d*:?\d*)'
r'(\((?P<options>.+)\))?'
r'$'
)
EVAL_LOCALS = {'python_version': platform.python_version()[:3]}
def main():
......@@ -15,14 +24,14 @@ def main():
test_count = 0
errors = 0
for filename in os.listdir('testsuite'):
with open(os.path.join('testsuite', filename)) as fd:
filepath = os.path.join('testsuite', filename)
with io.open(filepath, encoding='utf8') as fd:
lines = list(fd)
if not is_test_allowed(lines):
continue
for testcase, codes in load_tests(lines):
for testcase, code, options in load_tests(lines):
test_count += 1
errors += test_file(filename, testcase, codes)
errors += test_file(filename, testcase, code, options)
if errors == 0:
print("%s tests run successful" % test_count)
......@@ -33,48 +42,70 @@ def main():
def is_test_allowed(lines):
if IS_PY3 and any(IS_PY2_TEST.search(line) for line in lines[:3]):
return False
if not IS_PY3 and any(IS_PY3_TEST.search(line) for line in lines[:3]):
return False
for line in lines[:3]:
if 'python_version' in line:
return eval(line[1:], {}, EVAL_LOCALS)
return True
def load_tests(lines):
options = None
testcase = []
codes = []
code = None
for line in lines:
if line.startswith("#:"):
line_match = TESTCASE_RE.match(line)
if line_match:
if testcase:
yield testcase, codes
yield testcase, code, options
del testcase[:]
codes = line.split()[1:]
code = line_match.group('code')
if line_match.group('options'):
options = [line_match.group('options')]
else:
options = None
else:
testcase.append(line)
if testcase and codes:
yield testcase, codes
if testcase and code:
yield testcase, code, options
def test_file(filename, lines, codes):
tree = compile(''.join(lines), '', 'exec', PyCF_ONLY_AST)
checker = pep8ext_naming.NamingChecker(tree, filename)
found_errors = []
for lineno, col_offset, msg, instance in checker.run():
found_errors.append(msg.split()[0])
class OptionsManager(optparse.OptionParser):
"""A Flake8-2.x-compatible OptionsManager."""
def __init__(self, *args, **kwargs):
optparse.OptionParser.__init__(self, *args, **kwargs)
self.config_options = []
def parse_options(checker, options):
"""Parse the CLI-style flags from `options` and expose to `checker`"""
options_manager = OptionsManager('flake8')
checker.add_options(options_manager)
processed_options, _ = options_manager.parse_args(options)
checker.parse_options(processed_options)
if not found_errors and codes == ['Okay']:
def test_file(filename, lines, code, options):
if code is None: # Invalid test case
return 0
source = ''.join(lines)
tree = compile(source, '', 'exec', PyCF_ONLY_AST)
checker = pep8ext_naming.NamingChecker(tree, filename)
parse_options(checker, options)
error_format = (
'{0}:{lineno}:{col_offset}' if ':' in code else '{0}').format
errors = 0
for code in codes:
if code not in found_errors:
errors += 1
print("ERROR: %s not in %s" % (code, filename))
found_errors = set()
for lineno, col_offset, msg, instance in checker.run():
found_errors.add(error_format(msg.split()[0], **locals()))
return errors
if not found_errors and code == 'Okay': # Expected PASS
return 0
if code in found_errors: # Expected FAIL
return 0
print("ERROR: %s not in %s. found_errors: %s. Source:\n%s"
% (code, filename, found_errors, source))
return 1
if __name__ == '__main__':
......
......@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools.command.test import test as TestCommand
def get_version(fname='pep8ext_naming.py'):
def get_version(fname='src/pep8ext_naming.py'):
with open(fname) as f:
for line in f:
if line.startswith('__version__'):
......@@ -40,28 +40,27 @@ setup(
keywords='flake8 pep8 naming',
author='Florent Xicluna',
author_email='florent.xicluna@gmail.com',
url='https://github.com/flintwork/pep8-naming',
url='https://github.com/PyCQA/pep8-naming',
license='Expat license',
package_dir={'': 'src'},
py_modules=['pep8ext_naming'],
install_requires=['flake8_polyfill>=1.0.2,<2'],
zip_safe=False,
entry_points={
'flake8.extension': [
'N8 = pep8ext_naming:NamingChecker',
],
# Backward compatibility for Flint (now merged into Flake8)
'flint.extension': [
'N80 = pep8ext_naming:NamingChecker',
'N81 = pep8ext_naming:NamingChecker',
],
},
classifiers=[
'Development Status :: 3 - Alpha',
'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Framework :: Flake8',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Quality Assurance',
......
This diff is collapsed.
#: N801
class notok(object):
pass
#: Okay(--ignore-names=notok)
class notok(object):
pass
#: N801
......@@ -9,3 +12,40 @@ class Good(object):
#: Okay
class VeryGood(object):
pass
#: N801:1:7
class _:
pass
#: N801:1:7
class BAD_NAME:
pass
#: Okay
class Fine_:
pass
#: Okay
class Fine__:
pass
#: Okay
class G_:
pass
#: N801:1:7
class Not_Good:
pass
#: Okay
class __Fine:
pass
# The following cases are currently OK, but perhaps could be errors.
#: Okay
class MEHHHH:
pass
#: Okay
class __Meh__:
pass
#: Okay
class __MEH:
pass
#: Okay
class MEH__:
pass
#: Okay
class __MEH__:
pass
# python_version >= '3'
#: Okay
class Γ:
pass
#: Okay
class ΓγΓγ:
pass
#: Okay
class ΓγΓ6:
pass
#: Okay
class _Γ:
pass
#: N801:1:7
class γ:
pass
#: N801
class _γ:
pass
#: Okay
def ok():
pass
#: N802
def __bad():
pass
#: N802
def bad__():
pass
#: N802
def __bad__():
pass
#: Okay
def _ok():
pass
......@@ -25,7 +16,10 @@ def go_od_():
#: Okay
def _go_od_():
pass
#: N802
#: N802:1:5
def NotOK():
pass
#: Okay(--ignore-names=NotOK)
def NotOK():
pass
#: Okay
......@@ -47,11 +41,10 @@ class ClassName(object):
class ClassName(object):
def notOk(self):
pass
#: N802
#: Okay(--ignore-names=notOk)
class ClassName(object):
def method(self):
def __bad():
pass
def notOk(self):
pass
#: Okay
def setUp():
pass
......@@ -70,3 +63,5 @@ class TestCase:
pass
def tearDownClass(self):
pass
def setUpTestData(self):
pass
# python_version >= '3'
#: Okay
def γ(x):
pass
#: Okay
def γ6(x):
pass
# python_version >= '3.5'
#: Okay
async def func(param1, param2):
do_stuff()
await some_coroutine()
#: N802
async def Func(param1, param2):
do_stuff()
await some_coroutine()
......@@ -37,10 +37,25 @@ def b12(*BAD):
#: N803
def b13(BAD, *VERYBAD, **EXTRABAD):
pass
#: N803
#: N803:1:9
def b14(BAD):
pass
#: N803
#: Okay
def b15(_):
pass
#: Okay
def b16(_a):
pass
#: Okay
def b17(a, _):
pass
#: Okay
def b18(a, *_):
pass
#: Okay
def b19(a, **_):
pass
#: N803:2:24
class Test(object):
def __init__(self, BAD):
pass
......
# python2 only
# python_version < '3'
#: Okay
def test(a, b, (good, verygood)):
pass
......
# python3 only
# python_version >= '3'
#: Okay
def compare(a, b, *, key=None):
pass
......@@ -11,3 +11,21 @@ def compare(a, b, *VERY, bad=None):
#: N803
def compare(a, b, *ok, fine=None, **BAD):
pass
#: Okay
def foo(α, ß, γ):
pass
#: Okay
def foo(α, ß=''):
pass
#: Okay
def foo(**κ):
pass
#: Okay
def foo(*α):
pass
#: Okay
def foo(**κ2):
pass
#: Okay
def foo(*α2):
pass
# python_version >= '3.5'
#: Okay
async def compare(a, b, *, key=None):
pass
#: N803
async def compare(a, b, *, BAD=None):
pass
#: N804
#: N804:7:13
class Foo(object):
@classmethod
def mmm(cls, ads):
......@@ -11,3 +11,26 @@ class Foo(object):
@calling()
def test(self, ads):
pass
def __init_subclass(self, ads):
pass
#: N804:3:14(--classmethod-decorators=clazzy,cool)
class NewClassIsRequired(object):
@cool
def test(self, sy):
pass
#: N804
class Meta(type):
def __new__(self, name, bases, attrs):
pass
#: Okay
class MetaMethod(type):
def test(cls):
pass
#: Okay
class NotMeta(object):
otherclass = Foo
class AttributeParent(NotMeta.otherclass):
pass
class CallParent(type('_tmp', (), {})):
pass
# python_version >= '3.5'
#: N804:7:19
class Foo(object):
@classmethod
async def mmm(cls, ads):
pass
@classmethod
async def bad(self, ads):
pass
@calling()
async def test(self, ads):
pass
async def __init_subclass(self, ads):
pass
#: N804:3:20(--classmethod-decorators=clazzy,cool)
class NewClassIsRequired(object):
@cool
async def test(self, sy):
pass
#: N804
class Meta(type):
async def __new__(self, name, bases, attrs):