Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pycqa/pep8-naming
1 result
Show changes
Commits on Source (3)
Changes
=======
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
Loading
Loading
@@ -55,75 +55,3 @@ These error codes are emitted:
+------+-------------------------------------------------------+
| N814 | camelcase imported as constant |
+------+-------------------------------------------------------+
Changes
-------
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
# -*- coding: utf-8 -*-
"""Checker of PEP-8 Naming Conventions."""
import optparse
import re
import sys
from collections import deque
 
from flake8_polyfill import options
try:
import ast
from ast import iter_child_nodes
Loading
Loading
@@ -16,7 +17,6 @@ __version__ = '0.4.1'
LOWERCASE_REGEX = re.compile(r'[_a-z][_a-z0-9]*$')
UPPERCASE_REGEX = re.compile(r'[_A-Z][_A-Z0-9]*$')
MIXEDCASE_REGEX = re.compile(r'_?[A-Z][a-zA-Z0-9]*$')
SPLIT_IGNORED_RE = re.compile(r'[,\s]')
 
 
if sys.version_info[0] < 3:
Loading
Loading
@@ -64,18 +64,24 @@ BaseASTCheck = _ASTCheckMeta('BaseASTCheck', (object,),
{'__doc__': "Base for AST Checks.", 'err': _err})
 
 
def register_opt(parser, *args, **kwargs):
try:
# Flake8 3.x registration
parser.add_option(*args, **kwargs)
except (optparse.OptionError, TypeError):
# Flake8 2.x registration
parse_from_config = kwargs.pop('parse_from_config', False)
kwargs.pop('comma_separated_list', False)
kwargs.pop('normalize_paths', False)
parser.add_option(*args, **kwargs)
if parse_from_config:
parser.config_options.append(args[-1].lstrip('-'))
class _FunctionType(object):
CLASSMETHOD = 'classmethod'
STATICMETHOD = 'staticmethod'
FUNCTION = 'function'
METHOD = 'method'
_default_classmethod_decorators = ['classmethod']
_default_staticmethod_decorators = ['staticmethod']
def _build_decorator_to_type(classmethod_decorators, staticmethod_decorators):
decorator_to_type = {}
for decorator in classmethod_decorators:
decorator_to_type[decorator] = _FunctionType.CLASSMETHOD
for decorator in staticmethod_decorators:
decorator_to_type[decorator] = _FunctionType.STATICMETHOD
return decorator_to_type
 
 
class NamingChecker(object):
Loading
Loading
@@ -83,6 +89,8 @@ class NamingChecker(object):
name = 'naming'
version = __version__
ignore_names = ['setUp', 'tearDown', 'setUpClass', 'tearDownClass']
decorator_to_type = _build_decorator_to_type(
_default_classmethod_decorators, _default_staticmethod_decorators)
 
def __init__(self, tree, filename):
self.visitors = BaseASTCheck._checks
Loading
Loading
@@ -91,21 +99,41 @@ class NamingChecker(object):
 
@classmethod
def add_options(cls, parser):
ignored = ','.join(cls.ignore_names)
register_opt(parser, '--ignore-names',
default=ignored,
action='store',
type='string',
parse_from_config=True,
comma_separated_list=True,
help='List of names the pep8-naming plugin should '
'ignore. (Defaults to %default)')
options.register(parser, '--ignore-names',
default=cls.ignore_names,
action='store',
type='string',
parse_from_config=True,
comma_separated_list=True,
help='List of names the pep8-naming plugin should '
'ignore. (Defaults to %default)')
options.register(parser, '--classmethod-decorators',
default=_default_classmethod_decorators,
action='store',
type='string',
parse_from_config=True,
comma_separated_list=True,
help='List of method decorators pep8-naming plugin '
'should consider classmethods (Defaults to '
'%default)')
options.register(parser, '--staticmethod-decorators',
default=_default_staticmethod_decorators,
action='store',
type='string',
parse_from_config=True,
comma_separated_list=True,
help='List of method decorators pep8-naming plugin '
'should consider staticmethods (Defaults to '
'%default)')
 
@classmethod
def parse_options(cls, options):
cls.ignore_names = options.ignore_names
if not isinstance(cls.ignore_names, list):
cls.ignore_names = SPLIT_IGNORED_RE.split(options.ignore_names)
cls.decorator_to_type = _build_decorator_to_type(
options.classmethod_decorators,
options.staticmethod_decorators)
 
def run(self):
return self.visit_tree(self._node) if self._node else ()
Loading
Loading
@@ -146,26 +174,27 @@ class NamingChecker(object):
isinstance(node.value.func, ast.Name)):
continue
func_name = node.value.func.id
if func_name in ('classmethod', 'staticmethod'):
meth = (len(node.value.args) == 1 and node.value.args[0])
if isinstance(meth, ast.Name):
late_decoration[meth.id] = func_name
if func_name not in self.decorator_to_type:
continue
meth = (len(node.value.args) == 1 and node.value.args[0])
if isinstance(meth, ast.Name):
late_decoration[meth.id] = self.decorator_to_type[func_name]
 
# iterate over all functions and tag them
for node in iter_child_nodes(cls_node):
if not isinstance(node, ast.FunctionDef):
continue
 
node.function_type = 'method'
node.function_type = _FunctionType.METHOD
if node.name in ('__new__', '__init_subclass__'):
node.function_type = 'classmethod'
node.function_type = _FunctionType.CLASSMETHOD
if node.name in late_decoration:
node.function_type = late_decoration[node.name]
elif node.decorator_list:
names = [d.id for d in node.decorator_list
names = [self.decorator_to_type[d.id]
for d in node.decorator_list
if isinstance(d, ast.Name) and
d.id in ('classmethod', 'staticmethod')]
d.id in self.decorator_to_type]
if names:
node.function_type = names[0]
 
Loading
Loading
@@ -209,7 +238,7 @@ class FunctionNameCheck(BaseASTCheck):
N802 = "function name '{name}' should be lowercase xxx"
 
def visit_functiondef(self, node, parents, ignore=None):
function_type = getattr(node, 'function_type', 'function')
function_type = getattr(node, 'function_type', _FunctionType.FUNCTION)
name = node.name
if ignore and name in ignore:
return
Loading
Loading
@@ -253,10 +282,10 @@ class FunctionArgNamesCheck(BaseASTCheck):
return
function_type = getattr(node, 'function_type', 'function')
 
if function_type == 'method':
if function_type == _FunctionType.METHOD:
if arg_names[0] != 'self':
yield self.err(node, 'N805')
elif function_type == 'classmethod':
elif function_type == _FunctionType.CLASSMETHOD:
if arg_names[0] != 'cls':
yield self.err(node, 'N804')
for arg in arg_names:
Loading
Loading
import sys
import optparse
import os
import pep8ext_naming
import re
import sys
import pep8ext_naming
 
PyCF_ONLY_AST = 1024
 
Loading
Loading
@@ -9,6 +12,8 @@ IS_PY3 = sys.version_info[0] == 3
IS_PY3_TEST = re.compile(r"^#\s*python3\s*only")
IS_PY2_TEST = re.compile(r"^#\s*python2\s*only")
 
TESTCASE_RE = re.compile("^#: (?P<code>\w+)(\((?P<options>.+)\))?$")
 
def main():
print('Running pep8-naming tests')
Loading
Loading
@@ -19,10 +24,9 @@ def main():
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)
Loading
Loading
@@ -43,38 +47,59 @@ def is_test_allowed(lines):
 
 
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
 
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 test_file(filename, lines, codes):
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)
def test_file(filename, lines, code, options):
tree = compile(''.join(lines), '', 'exec', PyCF_ONLY_AST)
checker = pep8ext_naming.NamingChecker(tree, filename)
parse_options(checker, options)
found_errors = []
for lineno, col_offset, msg, instance in checker.run():
found_errors.append(msg.split()[0])
 
if not found_errors and codes == ['Okay']:
if code is None: # Invalid test case
return 0
errors = 0
for code in codes:
if code not in found_errors:
errors += 1
print("ERROR: %s not in %s" % (code, filename))
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" % (code, filename))
return 1
 
 
if __name__ == '__main__':
Loading
Loading
Loading
Loading
@@ -43,6 +43,7 @@ setup(
url='https://github.com/flintwork/pep8-naming',
license='Expat license',
py_modules=['pep8ext_naming'],
install_requires=['flake8_polyfill>=1.0.2,<2'],
zip_safe=False,
entry_points={
'flake8.extension': [
Loading
Loading
Loading
Loading
@@ -14,3 +14,8 @@ class Foo(object):
 
def __init_subclass(self, ads):
pass
#: N804(--classmethod-decorators=clazzy,cool)
class NewClassIsRequired(object):
@cool
def test(self, sy):
pass
Loading
Loading
@@ -15,7 +15,72 @@ class Foo(object):
def __prepare__(cls):
pass
 
@staticmethod
def test(so, exciting):
pass
def test1(cls):
pass
test1 = classmethod(test1)
def test2(so, exciting):
pass
test2 = staticmethod(test2)
#: Okay
class Foo(object):
def __init_subclass__(cls):
pass
#: Okay(--classmethod-decorators=clazzy,cool)
class NewClassmethodDecorators(object):
@clazzy
def test1(cls, sy):
pass
@cool
def test2(cls, sy):
pass
def test3(cls, sy):
pass
test3 = clazzy(test3)
def test4(cls, sy):
pass
test4 = cool(test4)
#: N805(--classmethod-decorators=clazzy,cool)
class ButWeLostTheOriginalClassMethodDecorator(object):
@classmethod
def test(cls, sy):
pass
#: N805(--classmethod-decorators=clazzy,cool)
class ButWeLostTheOriginalClassMethodLateDecorator(object):
def test(cls, sy):
pass
test = classmethod(test)
#: Okay(--staticmethod-decorators=ecstatik,stcmthd)
class NewStaticMethodDecorators(object):
@ecstatik
def test1(so, exciting):
pass
@stcmthd
def test2(so, exciting):
pass
def test3(so, exciting):
pass
test3 = ecstatik(test3)
def test4(so, exciting):
pass
test4 = stcmthd(test4)
#: N805(--staticmethod-decorators=exstatik,stcmthd)
class ButWeLostTheOriginalStaticMethodDecorator(object):
@staticmethod
def test(so, exciting):
pass
#: N805(--staticmethod-decorators=exstatik,stcmthd)
class ButWeLostTheOriginalStaticMethodLateDecorator(object):
def test(so, exciting):
pass
test = staticmethod(test)