forked from sigmavirus24/github3.py
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreview_comment
More file actions
1 lines (1 loc) · 7.66 KB
/
Copy pathreview_comment
File metadata and controls
1 lines (1 loc) · 7.66 KB
1
{"body": "is the 31 chars limit in the PEP 8 recommendations?", "diff_hunk": "@@ -1020,6 +1025,267 @@ def python_3000_backticks(logical_line):\n \n \n ##############################################################################\n+# Checkers on AST\n+##############################################################################\n+class BaseAstCheck(object):\n+ \"\"\"Base class all ASTChecker should derive\"\"\"\n+\n+ def __init__(self, checker):\n+ self.checker = checker\n+ self.report_error = checker.report_error\n+\n+ def default_visit(self, node, parents):\n+ \"\"\"Function which is called if not appropiate vist_ method is found\"\"\"\n+ pass\n+\n+ def error_at_node(self, node, text):\n+ self.report_error(node.lineno, node.col_offset, text, self)\n+\n+ def get_parent_function(self, parents):\n+ for parent in reversed(parents):\n+ if isinstance(parent, ast.FunctionDef):\n+ return parent\n+ if isinstance(parent, ast.ClassDef):\n+ return None\n+ return None\n+\n+\n+class VisitorsRunner(object):\n+ def __init__(self, visitors):\n+ self.visitors = visitors\n+ self.parents = deque()\n+\n+ def run(self, node):\n+ self.visit_node(node)\n+ self.parents.append(node)\n+ for child in ast.iter_child_nodes(node):\n+ self.run(child)\n+ self.parents.pop()\n+\n+ def visit_node(self, node):\n+ if isinstance(node, ast.ClassDef):\n+ self.tag_class_functions(node)\n+\n+ if isinstance(node, ast.FunctionDef):\n+ self.find_global_defs(node)\n+\n+ method = 'visit_' + node.__class__.__name__\n+ # Dont break pep8 in a tool to check pep8\n+ method = method.lower()\n+ for visitor in self.visitors:\n+ meth = getattr(visitor, method, visitor.default_visit)\n+ meth(node, self.parents)\n+\n+ def tag_class_functions(self, cls_node):\n+ \"\"\"Tag functions if they are methods, classmethods, staticmethods\"\"\"\n+\n+ # tries to find all 'old style decorators' like\n+ # m = staticmethod(m)\n+ late_decoration = {}\n+ for node in ast.iter_child_nodes(cls_node):\n+ if not isinstance(node, ast.Assign):\n+ continue\n+\n+ if not isinstance(node.value, ast.Call):\n+ continue\n+\n+ if not isinstance(node.value.func, ast.Name):\n+ continue\n+\n+ func_name = node.value.func.id\n+ if func_name in ('classmethod', 'staticmethod'):\n+ if len(node.value.args) == 1:\n+ late_decoration[node.value.args[0].id] = func_name\n+\n+ # iterate over all functions and tag them\n+ for node in ast.iter_child_nodes(cls_node):\n+ if not isinstance(node, ast.FunctionDef):\n+ continue\n+\n+ if node.name in late_decoration:\n+ node.function_type = late_decoration[node.name]\n+\n+ elif node.decorator_list:\n+ decos = node.decorator_list\n+ decos = [d.id for d in decos if isinstance(d, ast.Name)]\n+\n+ if 'classmethod' in decos:\n+ node.function_type = 'classmethod'\n+ elif 'staticmethod' in decos:\n+ node.function_type = 'staticmethod'\n+ else:\n+ node.function_type = 'method'\n+\n+ else:\n+ node.function_type = 'method'\n+\n+\n+ def find_global_defs(self, func_def_node):\n+ global_names = set()\n+ nodes_to_check = deque(ast.iter_child_nodes(func_def_node))\n+ while nodes_to_check:\n+ node = nodes_to_check.pop()\n+ if isinstance(node, ast.Global):\n+ global_names.update(node.names)\n+\n+ if not isinstance(node, (ast.FunctionDef, ast.ClassDef)):\n+ nodes_to_check.extend(ast.iter_child_nodes(node))\n+ func_def_node.global_names = global_names\n+\n+\n+class ClassNameASTCheck(BaseAstCheck):\n+ \"\"\"\n+ Almost without exception, class names use the CapWords convention.\n+\n+ Classes for internal use have a leading underscore in addition.\n+ \"\"\"\n+ CLASS_NAME_RGX = re.compile('[_A-Z][a-zA-Z0-9]*$')\n+ text = \"E800 class names should use CapWords convention\"\n+\n+ def visit_classdef(self, node, parents):\n+ if not self.CLASS_NAME_RGX.match(node.name):\n+ self.error_at_node(node, self.text)\n+\n+\n+class FunctionNameASTCheck(BaseAstCheck):\n+ \"\"\"\n+ Function names should be lowercase, with words separated by underscores\n+ as necessary to improve readability.\n+ Functions *not* beeing methods '__' in front and back are not allowed.\n+\n+ mixedCase is allowed only in contexts where that's already the\n+ prevailing style (e.g. threading.py), to retain backwards compatibility.\n+ \"\"\"\n+ GOOD_FUNCTION_NAME = re.compile(r\"^[_a-z0-9][_a-z0-9]*$\")\n+ text = \"E801 function name does not follow PEP8 guidelines\"\n+\n+ def visit_functiondef(self, node, parents):\n+ function_type = getattr(node, 'function_type', 'function')\n+ if function_type == 'function':\n+ if node.name.startswith('__') or node.name.endswith('__'):\n+ self.error_at_node(node, self.text)\n+ elif not self.GOOD_FUNCTION_NAME.match(node.name):\n+ self.error_at_node(node, self.text)\n+ elif not self.GOOD_FUNCTION_NAME.match(node.name):\n+ self.error_at_node(node, self.text)\n+\n+\n+class FunctionArgNamesASTCheck(BaseAstCheck):\n+ \"\"\"\n+ The argument names of a function should be lowercase, with words separated\n+ by underscores.\n+\n+ A classmethod should have 'cls' as first argument.\n+ A method should have 'self' as first argument.\n+ \"\"\"\n+\n+ GOOD_ARG_NAME = re.compile('[a-z_][a-z0-9_]{0,30}$').match", "url": "https://api.github.com/repos/jcrocholl/pep8/pulls/comments/2504908", "created_at": "2012-12-26T19:16:17Z", "updated_at": "2012-12-26T19:16:17Z", "html_url": "https://github.com/jcrocholl/pep8/pull/121#discussion_r2504908", "original_position": 191, "pull_request_url": "https://api.github.com/repos/jcrocholl/pep8/pulls/121", "_links": {"self": {"href": "https://api.github.com/repos/jcrocholl/pep8/pulls/comments/2504908"}, "html": {"href": "https://github.com/jcrocholl/pep8/pull/121#discussion_r2504908"}, "pull_request": {"href": "https://api.github.com/repos/jcrocholl/pep8/pulls/121"}}, "commit_id": "0fd8a5b37b52cd8c499baa786e95a6609a200130", "user": {"following_url": "https://api.github.com/users/florentx/following{/other_user}", "events_url": "https://api.github.com/users/florentx/events{/privacy}", "organizations_url": "https://api.github.com/users/florentx/orgs", "url": "https://api.github.com/users/florentx", "gists_url": "https://api.github.com/users/florentx/gists{/gist_id}", "html_url": "https://github.com/florentx", "subscriptions_url": "https://api.github.com/users/florentx/subscriptions", "avatar_url": "https://secure.gravatar.com/avatar/df4a6858794ecf84eae5afb37bf276ba?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png", "repos_url": "https://api.github.com/users/florentx/repos", "received_events_url": "https://api.github.com/users/florentx/received_events", "gravatar_id": "df4a6858794ecf84eae5afb37bf276ba", "starred_url": "https://api.github.com/users/florentx/starred{/owner}{/repo}", "login": "florentx", "type": "User", "id": 142113, "followers_url": "https://api.github.com/users/florentx/followers"}, "position": 191, "path": "pep8.py", "original_commit_id": "0fd8a5b37b52cd8c499baa786e95a6609a200130", "id": 2504908}