[Python-modules-commits] [pep8-naming] 01/03: Imported Upstream version 0.3.1

Daniel Stender danstender-guest at moszumanska.debian.org
Tue Jun 23 09:54:50 UTC 2015


This is an automated email from the git hooks/post-receive script.

danstender-guest pushed a commit to branch master
in repository pep8-naming.

commit ebfbc62ef89d54e6de2d01c5ce8a3b7044f15f5a
Author: Daniel Stender <debian at danielstender.com>
Date:   Tue Jun 23 11:49:25 2015 +0200

    Imported Upstream version 0.3.1
---
 .gitignore            |  10 ++
 .travis.yml           |  18 ++++
 LICENSE               |  23 ++++
 README.rst            | 116 ++++++++++++++++++++
 pep8ext_naming.py     | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++
 run_tests.py          |  81 ++++++++++++++
 setup.cfg             |   2 +
 setup.py              |  70 ++++++++++++
 testsuite/N801.py     |  11 ++
 testsuite/N802.py     |  72 +++++++++++++
 testsuite/N803.py     |  50 +++++++++
 testsuite/N803_py2.py |   7 ++
 testsuite/N803_py3.py |  13 +++
 testsuite/N804.py     |  13 +++
 testsuite/N805.py     |  16 +++
 testsuite/N806.py     |  48 +++++++++
 testsuite/N81x.py     |  12 +++
 tox.ini               |  13 +++
 18 files changed, 869 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6288ced
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+*.egg
+*.egg-info
+*.py[cod]
+.tox
+dist
+.project
+.pydevproject
+.settings/
+build/
+
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..d5e9258
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+language: python
+
+sudo: false
+
+install:
+    pip install tox
+
+script: tox
+
+env:
+  matrix:
+  - TOXENV=py26
+  - TOXENV=py27
+  - TOXENV=py32
+  - TOXENV=py33
+  - TOXENV=py34
+  - TOXENV=pypy
+  - TOXENV=pypy3
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a7621d3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Copyright © 2013 Florent Xicluna <florent.xicluna at gmail.com>
+
+Licensed under the terms of the Expat License
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..eb782aa
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,116 @@
+PEP-8 Naming Conventions
+========================
+
+.. image:: https://badge.fury.io/py/pep8-naming.png
+    :target: http://badge.fury.io/py/pep8-naming
+    
+.. image:: https://travis-ci.org/flintwork/pep8-naming.png?branch=master
+        :target: https://travis-ci.org/flintwork/pep8-naming
+
+.. image:: https://pypip.in/d/pep8-naming/badge.png
+        :target: https://crate.io/packages/pep8-naming?version=latest
+
+Check the PEP-8 naming conventions.
+
+This module provides a plugin for ``flake8``, the Python code checker.
+
+(It replaces the plugin ``flint-naming`` for the ``flint`` checker.)
+
+
+Installation
+------------
+
+You can install, upgrade, uninstall ``pep8-naming`` with these commands::
+
+  $ pip install pep8-naming
+  $ pip install --upgrade pep8-naming
+  $ pip uninstall pep8-naming
+
+
+Plugin for Flake8
+-----------------
+
+When both ``flake8`` and ``pep8-naming`` are installed, the plugin is
+available in ``flake8``::
+
+  $ flake8 --version
+  2.0 (pep8: 1.4.3, pyflakes: 0.6.1, naming: 0.2)
+
+By default the plugin is enabled.
+
+These error codes are emitted:
+
++------+-------------------------------------------------------+
+| code | sample message                                        |
++======+=======================================================+
+| N801 | class names should use CapWords convention            |
++------+-------------------------------------------------------+
+| N802 | function name should be lowercase                     |
++------+-------------------------------------------------------+
+| N803 | argument name should be lowercase                     |
++------+-------------------------------------------------------+
+| N804 | first argument of a classmethod should be named 'cls' |
++------+-------------------------------------------------------+
+| N805 | first argument of a method should be named 'self'     |
++------+-------------------------------------------------------+
+| N806 | variable in function should be lowercase              |
++------+-------------------------------------------------------+
++------+-------------------------------------------------------+
+| N811 | constant imported as non constant                     |
++------+-------------------------------------------------------+
+| N812 | lowercase imported as non lowercase                   |
++------+-------------------------------------------------------+
+| N813 | camelcase imported as lowercase                       |
++------+-------------------------------------------------------+
+| N814 | camelcase imported as constant                        |
++------+-------------------------------------------------------+
+
+
+Changes
+-------
+
+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
diff --git a/pep8ext_naming.py b/pep8ext_naming.py
new file mode 100644
index 0000000..d5ee9a2
--- /dev/null
+++ b/pep8ext_naming.py
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+"""Checker of PEP-8 Naming Conventions."""
+import re
+import sys
+from collections import deque
+
+try:
+    import ast
+    from ast import iter_child_nodes
+except ImportError:
+    from flake8.util import ast, iter_child_nodes
+
+__version__ = '0.3.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]*$')
+
+
+if sys.version_info[0] < 3:
+    def _unpack_args(args):
+        ret = []
+        for arg in args:
+            if isinstance(arg, ast.Tuple):
+                ret.extend(_unpack_args(arg.elts))
+            else:
+                ret.append(arg.id)
+        return ret
+
+    def get_arg_names(node):
+        return _unpack_args(node.args.args)
+else:
+    def get_arg_names(node):
+        pos_args = [arg.arg for arg in node.args.args]
+        kw_only = [arg.arg for arg in node.args.kwonlyargs]
+        return pos_args + kw_only
+
+
+class _ASTCheckMeta(type):
+    def __init__(self, class_name, bases, namespace):
+        try:
+            self._checks.append(self())
+        except AttributeError:
+            self._checks = []
+
+
+def _err(self, node, code):
+    lineno, col_offset = node.lineno, node.col_offset
+    if isinstance(node, ast.ClassDef):
+        lineno += len(node.decorator_list)
+        col_offset += 6
+    elif isinstance(node, ast.FunctionDef):
+        lineno += len(node.decorator_list)
+        col_offset += 4
+    return (lineno, col_offset, '%s %s' % (code, getattr(self, code)), self)
+BaseASTCheck = _ASTCheckMeta('BaseASTCheck', (object,),
+                             {'__doc__': "Base for AST Checks.", 'err': _err})
+
+
+class NamingChecker(object):
+    """Checker of PEP-8 Naming Conventions."""
+    name = 'naming'
+    version = __version__
+    ignore_names = ['setUp', 'tearDown', 'setUpClass', 'tearDownClass']
+
+    def __init__(self, tree, filename):
+        self.visitors = BaseASTCheck._checks
+        self.parents = deque()
+        self._node = tree
+
+    @classmethod
+    def add_options(cls, parser):
+        parser.add_option('--ignore-names', default=cls.ignore_names,
+                          action='store', type='string',
+                          help="Names that should be ignored.")
+        parser.config_options.append('ignore-names')
+
+    @classmethod
+    def parse_options(cls, options):
+        cls.ignore_names = options.ignore_names.split(' ')
+
+    def run(self):
+        return self.visit_tree(self._node) if self._node else ()
+
+    def visit_tree(self, node):
+        for error in self.visit_node(node):
+            yield error
+        self.parents.append(node)
+        for child in iter_child_nodes(node):
+            for error in self.visit_tree(child):
+                yield error
+        self.parents.pop()
+
+    def visit_node(self, node):
+        if isinstance(node, ast.ClassDef):
+            self.tag_class_functions(node)
+        elif isinstance(node, ast.FunctionDef):
+            self.find_global_defs(node)
+
+        method = 'visit_' + node.__class__.__name__.lower()
+        parents = self.parents
+        ignore_names = self.ignore_names
+        for visitor in self.visitors:
+            visitor_method = getattr(visitor, method, None)
+            if visitor_method is None:
+                continue
+            for error in visitor_method(node, parents, ignore_names):
+                yield error
+
+    def tag_class_functions(self, cls_node):
+        """Tag functions if they are methods, classmethods, staticmethods"""
+        # tries to find all 'old style decorators' like
+        # m = staticmethod(m)
+        late_decoration = {}
+        for node in iter_child_nodes(cls_node):
+            if not (isinstance(node, ast.Assign) and
+                    isinstance(node.value, ast.Call) and
+                    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
+
+        # 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'
+            if node.name == '__new__':
+                node.function_type = '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
+                         if isinstance(d, ast.Name) and
+                         d.id in ('classmethod', 'staticmethod')]
+                if names:
+                    node.function_type = names[0]
+
+    def find_global_defs(self, func_def_node):
+        global_names = set()
+        nodes_to_check = deque(iter_child_nodes(func_def_node))
+        while nodes_to_check:
+            node = nodes_to_check.pop()
+            if isinstance(node, ast.Global):
+                global_names.update(node.names)
+
+            if not isinstance(node, (ast.FunctionDef, ast.ClassDef)):
+                nodes_to_check.extend(iter_child_nodes(node))
+        func_def_node.global_names = global_names
+
+
+class ClassNameCheck(BaseASTCheck):
+    """
+    Almost without exception, class names use the CapWords convention.
+
+    Classes for internal use have a leading underscore in addition.
+    """
+    check = MIXEDCASE_REGEX.match
+    N801 = "class names should use CapWords convention"
+
+    def visit_classdef(self, node, parents, ignore=None):
+        if not self.check(node.name):
+            yield self.err(node, 'N801')
+
+
+class FunctionNameCheck(BaseASTCheck):
+    """
+    Function names should be lowercase, with words separated by underscores
+    as necessary to improve readability.
+    Functions *not* beeing methods '__' in front and back are not allowed.
+
+    mixedCase is allowed only in contexts where that's already the
+    prevailing style (e.g. threading.py), to retain backwards compatibility.
+    """
+    check = LOWERCASE_REGEX.match
+    N802 = "function name should be lowercase"
+
+    def visit_functiondef(self, node, parents, ignore=None):
+        function_type = getattr(node, 'function_type', 'function')
+        name = node.name
+        if ignore and name in ignore:
+            return
+        if ((function_type == 'function' and '__' in (name[:2], name[-2:])) or
+                not self.check(name)):
+            yield self.err(node, 'N802')
+
+
+class FunctionArgNamesCheck(BaseASTCheck):
+    """
+    The argument names of a function should be lowercase, with words separated
+    by underscores.
+
+    A classmethod should have 'cls' as first argument.
+    A method should have 'self' as first argument.
+    """
+    check = LOWERCASE_REGEX.match
+    N803 = "argument name should be lowercase"
+    N804 = "first argument of a classmethod should be named 'cls'"
+    N805 = "first argument of a method should be named 'self'"
+
+    def visit_functiondef(self, node, parents, ignore=None):
+
+        def arg_name(arg):
+            return getattr(arg, 'arg', arg)
+
+        kwarg = arg_name(node.args.kwarg)
+        if kwarg is not None:
+            if not self.check(kwarg):
+                yield self.err(node, 'N803')
+                return
+
+        vararg = arg_name(node.args.vararg)
+        if vararg is not None:
+            if not self.check(vararg):
+                yield self.err(node, 'N803')
+                return
+
+        arg_names = get_arg_names(node)
+        if not arg_names:
+            return
+        function_type = getattr(node, 'function_type', 'function')
+
+        if function_type == 'method':
+            if arg_names[0] != 'self':
+                yield self.err(node, 'N805')
+        elif function_type == 'classmethod':
+            if arg_names[0] != 'cls':
+                yield self.err(node, 'N804')
+        for arg in arg_names:
+            if not self.check(arg):
+                yield self.err(node, 'N803')
+                return
+
+
+class ImportAsCheck(BaseASTCheck):
+    """
+    Don't change the naming convention via an import
+    """
+    check_lower = LOWERCASE_REGEX.match
+    check_upper = UPPERCASE_REGEX.match
+    N811 = "constant imported as non constant"
+    N812 = "lowercase imported as non lowercase"
+    N813 = "camelcase imported as lowercase"
+    N814 = "camelcase imported as constant"
+
+    def visit_importfrom(self, node, parents, ignore=None):
+        for name in node.names:
+            if not name.asname:
+                continue
+            if self.check_upper(name.name):
+                if not self.check_upper(name.asname):
+                    yield self.err(node, 'N811')
+            elif self.check_lower(name.name):
+                if not self.check_lower(name.asname):
+                    yield self.err(node, 'N812')
+            elif self.check_lower(name.asname):
+                yield self.err(node, 'N813')
+            elif self.check_upper(name.asname):
+                yield self.err(node, 'N814')
+
+
+class VariablesInFunctionCheck(BaseASTCheck):
+    """
+    Local variables in functions should be lowercase
+    """
+    check = LOWERCASE_REGEX.match
+    N806 = "variable in function should be lowercase"
+
+    def visit_assign(self, node, parents, ignore=None):
+        for parent_func in reversed(parents):
+            if isinstance(parent_func, ast.ClassDef):
+                return
+            if isinstance(parent_func, ast.FunctionDef):
+                break
+        else:
+            return
+        for target in node.targets:
+            name = isinstance(target, ast.Name) and target.id
+            if not name or name in parent_func.global_names:
+                return
+            if not self.check(name) and name[:1] != '_':
+                if isinstance(node.value, ast.Call):
+                    if isinstance(node.value.func, ast.Attribute):
+                        if node.value.func.attr == 'namedtuple':
+                            return
+                    elif isinstance(node.value.func, ast.Name):
+                        if node.value.func.id == 'namedtuple':
+                            return
+                yield self.err(target, 'N806')
diff --git a/run_tests.py b/run_tests.py
new file mode 100644
index 0000000..b3d1b93
--- /dev/null
+++ b/run_tests.py
@@ -0,0 +1,81 @@
+import sys
+import os
+import pep8ext_naming
+import re
+
+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")
+
+
+def main():
+    print('Running pep8-naming tests')
+    test_count = 0
+    errors = 0
+    for filename in os.listdir('testsuite'):
+        with open(os.path.join('testsuite', filename)) as fd:
+            lines = list(fd)
+            if not is_test_allowed(lines):
+                continue
+
+            for testcase, codes in load_tests(lines):
+                test_count += 1
+                errors += test_file(filename, testcase, codes)
+
+    if errors == 0:
+        print("%s tests run successful" % test_count)
+        sys.exit(0)
+    else:
+        print("%i of %i tests failed" % (errors, test_count))
+        sys.exit(1)
+
+
+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
+
+    return True
+
+
+def load_tests(lines):
+    testcase = []
+    codes = []
+    for line in lines:
+        if line.startswith("#:"):
+            if testcase:
+                yield testcase, codes
+                del testcase[:]
+            codes = line.split()[1:]
+        else:
+            testcase.append(line)
+
+    if testcase and codes:
+        yield testcase, codes
+
+
+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])
+
+    if not found_errors and codes == ['Okay']:
+        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 __name__ == '__main__':
+    main()
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..5e40900
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,2 @@
+[wheel]
+universal = 1
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..dd4d0d0
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+from __future__ import with_statement
+from setuptools import setup
+from setuptools.command.test import test as TestCommand
+
+
+def get_version(fname='pep8ext_naming.py'):
+    with open(fname) as f:
+        for line in f:
+            if line.startswith('__version__'):
+                return eval(line.split('=')[-1])
+
+
+def get_long_description():
+    descr = []
+    for fname in ('README.rst',):
+        with open(fname) as f:
+            descr.append(f.read())
+    return '\n\n'.join(descr)
+
+
+class RunTests(TestCommand):
+    def finalize_options(self):
+        TestCommand.finalize_options(self)
+        self.test_args = []
+        self.test_suite = True
+
+    def run_tests(self):
+        import run_tests
+        import sys
+        errno = run_tests.main()
+        sys.exit(errno)
+
+
+setup(
+    name='pep8-naming',
+    version=get_version(),
+    description="Check PEP-8 naming conventions, plugin for flake8",
+    long_description=get_long_description(),
+    keywords='flake8 pep8 naming',
+    author='Florent Xicluna',
+    author_email='florent.xicluna at gmail.com',
+    url='https://github.com/flintwork/pep8-naming',
+    license='Expat license',
+    py_modules=['pep8ext_naming'],
+    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',
+        'Environment :: Console',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: MIT License',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 3',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'Topic :: Software Development :: Quality Assurance',
+    ],
+    cmdclass={'test': RunTests},
+)
diff --git a/testsuite/N801.py b/testsuite/N801.py
new file mode 100644
index 0000000..68b50d0
--- /dev/null
+++ b/testsuite/N801.py
@@ -0,0 +1,11 @@
+#: N801
+class notok(object):
+    pass
+#: N801
+class Good(object):
+    class notok(object):
+        pass
+    pass
+#: Okay
+class VeryGood(object):
+    pass
diff --git a/testsuite/N802.py b/testsuite/N802.py
new file mode 100644
index 0000000..9061def
--- /dev/null
+++ b/testsuite/N802.py
@@ -0,0 +1,72 @@
+#: Okay
+def ok():
+    pass
+#: N802
+def __bad():
+    pass
+#: N802
+def bad__():
+    pass
+#: N802
+def __bad__():
+    pass
+#: Okay
+def _ok():
+    pass
+#: Okay
+def ok_ok_ok_ok():
+    pass
+#: Okay
+def _somehow_good():
+    pass
+#: Okay
+def go_od_():
+    pass
+#: Okay
+def _go_od_():
+    pass
+#: N802
+def NotOK():
+    pass
+#: Okay
+def _():
+    pass
+#: Okay
+class Foo(object):
+    def __method(self):
+        pass
+#: Okay
+class Foo(object):
+    def __method__(self):
+        pass
+#: Okay
+class ClassName(object):
+    def __method__(self):
+        pass
+#: N802
+class ClassName(object):
+    def notOk(self):
+        pass
+#: N802
+class ClassName(object):
+    def method(self):
+        def __bad():
+            pass
+#: Okay
+def setUp():
+    pass
+
+#: Okay
+def tearDown():
+    pass
+
+#: Okay
+class TestCase:
+    def setUp(self):
+        pass
+    def tearDown(self):
+        pass
+    def setUpClass(self):
+        pass
+    def tearDownClass(self):
+        pass
diff --git a/testsuite/N803.py b/testsuite/N803.py
new file mode 100644
index 0000000..f619bd6
--- /dev/null
+++ b/testsuite/N803.py
@@ -0,0 +1,50 @@
+#: Okay
+def b1():
+    pass
+#: Okay
+def b2(a):
+    pass
+#: Okay
+def b3(a, b, c, d):
+    pass
+#: Okay
+def b4(a, b, c, *fuck):
+    pass
+#: Okay
+def b5(*fuck):
+    pass
+#: Okay
+def b6(a, b, c, **kwargs):
+    pass
+#: Okay
+def b7(**kwargs):
+    pass
+#: Okay
+def b8(*args, **kwargs):
+    pass
+#: Okay
+def b9(a, b, c, *args, **kwargs):
+    pass
+#: Okay
+def b10(a, b, c=3, d=4, *args, **kwargs):
+    pass
+#: N803
+def b11(**BAD):
+    pass
+#: N803
+def b12(*BAD):
+    pass
+#: N803
+def b13(BAD, *VERYBAD, **EXTRABAD):
+    pass
+#: N803
+def b14(BAD):
+    pass
+#: N803
+class Test(object):
+    def __init__(self, BAD):
+        pass
+
+    @classmethod
+    def test(cls, BAD):
+        pass
diff --git a/testsuite/N803_py2.py b/testsuite/N803_py2.py
new file mode 100644
index 0000000..58a6896
--- /dev/null
+++ b/testsuite/N803_py2.py
@@ -0,0 +1,7 @@
+# python2 only
+#: Okay
+def test(a, b, (good, verygood)):
+    pass
+#: N803
+def bad(a, b, (OHH, NOO)):
+    pass
diff --git a/testsuite/N803_py3.py b/testsuite/N803_py3.py
new file mode 100644
index 0000000..7fdaeec
--- /dev/null
+++ b/testsuite/N803_py3.py
@@ -0,0 +1,13 @@
+# python3 only
+#: Okay
+def compare(a, b, *, key=None):
+    pass
+#: N803
+def compare(a, b, *, BAD=None):
+    pass
+#: N803
+def compare(a, b, *VERY, bad=None):
+    pass
+#: N803
+def compare(a, b, *ok, fine=None, **BAD):
+    pass
diff --git a/testsuite/N804.py b/testsuite/N804.py
new file mode 100644
index 0000000..0fe6c06
--- /dev/null
+++ b/testsuite/N804.py
@@ -0,0 +1,13 @@
+#: N804
+class Foo(object):
+    @classmethod
+    def mmm(cls, ads):
+        pass
+
+    @classmethod
+    def bad(self, ads):
+        pass
+
+    @calling()
+    def test(self, ads):
+        pass
diff --git a/testsuite/N805.py b/testsuite/N805.py
new file mode 100644
index 0000000..2a19e1a
--- /dev/null
+++ b/testsuite/N805.py
@@ -0,0 +1,16 @@
+#: N805
+class Foo(object):
+    def good(self, ads):
+        pass
+
+    def bad(ads, self):
+        pass
+#: Okay
+class Foo(object):
+    def __new__(cls):
+        return object.__new__(Foo)
+#: Okay
+class Foo(object):
+    @classmethod
+    def __prepare__(cls):
+        pass
diff --git a/testsuite/N806.py b/testsuite/N806.py
new file mode 100644
index 0000000..53cb2d0
--- /dev/null
+++ b/testsuite/N806.py
@@ -0,0 +1,48 @@
+#: Okay
+def test():
+    good = 1
+#: Okay
+def test():
+    def test2():
+        good = 1
+#: Okay
+GOOD = 1
+#: Okay
+class Test(object):
+    GOOD = 1
+#: N806
+def test():
+    Bad = 1
+#: N806
+def test():
+    VERY = 2
+#: N806
+def test():
+    def test2():
+        class Foo(object):
+            def test3(self):
+                Bad = 3
+#: Okay
+def good():
+    global Bad
+    Bad = 1
+#: N806
+def bad():
+    global Bad
+
+    def foo():
+        Bad = 1
+
+#: Okay
+def test():
+    # namedtuples are often CamelCased since we treat them a bit like classes
+    import collections
+    Thing = collections.namedtuple('Thing', 'a b c')
+    from collections import namedtuple
+    ThingTwo = namedtuple('ThingTwo', 'a b c')
+
+#: N806
+def bad():
+    # Currently don't support aliased imports of namedtuple
+    from collections import namedtuple as nt
+    Thing = nt('Thing', 'a b c')
diff --git a/testsuite/N81x.py b/testsuite/N81x.py
new file mode 100644
index 0000000..826f331
--- /dev/null
+++ b/testsuite/N81x.py
@@ -0,0 +1,12 @@
+#: Okay
+import good as good
+#: Okay
+from mod import good as nice, NICE as GOOD, Camel as Memel
+#: N811
+from mod import GOOD as bad
+#: N812
+from mod import good as Bad
+#: N813
+from mod import CamelCase as noncamle
+#: N814
+from mod import CamelCase as CONSTANT
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..ef2173d
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,13 @@
+[tox]
+envlist = py26,py27,py32,py33,py34,pypy,pypy3
+
+[testenv]
+commands = python run_tests.py
+
+[testenv:release]
+deps =
+    twine >= 1.4.0
+    wheel
... 3 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pep8-naming.git



More information about the Python-modules-commits mailing list