Search code examples
pythonflake8

Unable to Create Flake8 Plugin to Check Function Name


I'm writing a simple flake8 plugins to check the function name conventions that they need to start with one of these verbs: "is, set, get, validate", but it did not success.

My custom flake8 plugin is as so:

setup.py

import setuptools

setuptools.setup(
   name='flake8-var',
   license='MIT',
   version='0.0.1',
   description='Plugin to check coding convention',
   author='QA',
   author_email='qa@gmail.com',
   url='https://example.com',
   py_modules=['flake8_var'],
   entry_points={
       'flake8.extension': [
           'PCK01 = flake8_var:Checker',
       ],
   },
   install_requires=['flake8'],
   classifiers=[
       'Topic :: Software Development :: Quality Assurance',
   ],
)

flake8_var.py

import ast


class Analyzer(ast.NodeVisitor):

    def __init__(self, *args, **kwargs):
        super(ast.NodeVisitor,self).__init__(*args, **kwargs)
        self.stats = []
        self.rule = Rule()

    def visit_FunctionDef(self, node):
        if not self.rule.isValidFunction(node.name):
            verb = ", ".join(str(x) for x in self.rule.verbs)
            msg = "PCK012 Function or Method name must start with one of the ", verb
            self.stats.append((node.lineno, node.col_offset, msg))



class Checker(object):
    options = None
    name = 'flake8_var'
    version = '0.1'

    def __init__(self, tree, filename):
        self.tree = tree
        self.filename = filename

    def run(self):
        parser = Analyzer()
        parser.visit(self.tree)

        for lineno, column, msg in parser.stats:
            yield (lineno, column, msg, Checker)

class Rule(object):
    def __init__(self):
        self.verbs = ['is', 'del', 'set', 'get', 'to']

    def is_camel_case(self, s):
        return s[0].isupper() \
        and s != s.lower() \
        and s != s.upper() \
        and "_" not in s

    def isValidFunction(self, FunName):
        for verb in self.verbs:
            if not FunName.startswith(verb):
                return False
            return True

test.py

def myFun():

    return ''

def setNewValue():

    return ''

After I setup plugins successfully and test the plugin by commend $ flake8 test.py, it gave me an error:

    error_code, text = text.split(" ", 1)
AttributeError: 'tuple' object has no attribute 'split'

What was wrong? How can I fix that? Thanks


Solution

  • (unrelated but the first thing I noticed) -- your visitor has a bug for nested functions:

    def f():
        def g(): ...
    

    you'll want to add self.generic_visit(node) to the end of your visit_FunctionDef


    as for the actual problem, it is saying that the error text is a tuple instead of a string

    this is due to this line:

    msg = "PCK012 Function or Method name must start with one of the ", verb
    

    you probably mean to use + or some sort of string formatting instead such as:

    msg = f"PCK012 Function or Method name must start with one of the {verb}"