PK!uh$wemake_python_styleguide/__init__.py# -*- coding: utf-8 -*- PK!""#wemake_python_styleguide/checker.py# -*- coding: utf-8 -*- from ast import Module from typing import Generator, Tuple from wemake_python_styleguide.version import __version__ from wemake_python_styleguide.visitors.high_complexity import ComplexityVisitor from wemake_python_styleguide.visitors.wrong_function_call import ( WrongFunctionCallVisitor, ) from wemake_python_styleguide.visitors.wrong_import import WrongImportVisitor from wemake_python_styleguide.visitors.wrong_keyword import ( WrongKeywordVisitor, WrongRaiseVisitor, ) from wemake_python_styleguide.visitors.wrong_name import ( WrongModuleMetadataVisitor, WrongNameVisitor, ) from wemake_python_styleguide.visitors.wrong_nested import WrongNestedVisitor CheckResult = Tuple[int, int, str, type] class Checker(object): """ Main checker class. Runs all possible checks. """ name = 'wemake-python-styleguide' version = __version__ def __init__(self, tree: Module, filename: str = '-') -> None: """Creates new checker instance.""" self.tree = tree self.filename = filename self._visitors = ( WrongRaiseVisitor, WrongFunctionCallVisitor, WrongImportVisitor, WrongKeywordVisitor, WrongNestedVisitor, ComplexityVisitor, WrongNameVisitor, WrongModuleMetadataVisitor, ) def run(self) -> Generator[CheckResult, None, None]: """ Runs the checker. This method is used by `flake8` API. """ for visitor_class in self._visitors: visiter = visitor_class() visiter.visit(self.tree) for error in visiter.errors: lineno, col_offset, message = error.node_items() yield lineno, col_offset, message, type(self) PK!%wemake_python_styleguide/constants.py# -*- coding: utf-8 -*- """ This module contains list of white- and black-listed ``python`` members. It contains lists of keywords and built-in functions we discourage to use. It also contains some exceptions that we allow to use in our codebase. """ #: List of functions we forbid to use. BAD_FUNCTIONS = frozenset(( # Code generation: 'eval', 'exec', 'compile', # Magic: 'globals', 'locals', 'vars', 'dir', # IO: 'input', 'help', # Attribute access: 'hasattr', 'delattr', # Misc: 'copyright', )) #: List of module metadata we forbid to use. BAD_MODULE_METADATA_VARIABLES = frozenset(( '__author__', '__all__', '__version__', '__about__', )) #: List of variable names we forbid to use. BAD_VARIABLE_NAMES = frozenset(( 'data', 'result', 'results', 'item', 'items', 'value', 'values', 'val', 'vals', 'var', 'vars', 'content', 'contents', 'info', 'handle', 'handler', )) #: List of nested classes' names we allow to use. NESTED_CLASSES_WHITELIST = frozenset(( 'Meta', )) #: List of nested functions' names we allow to use. NESTED_FUNCTIONS_WHITELIST = frozenset(( 'decorator', 'factory', )) PK!jdN--"wemake_python_styleguide/errors.py# -*- coding: utf-8 -*- # TODO(@sobolevn): write docs for each error, remove ignore from setup.cfg """ All style errors are defined here. They should be sorted by ``_code``. """ from ast import AST from typing import Tuple class BaseStyleViolation(object): """ This is a base class for all style errors. It basically just defines how to create any error and how to format this error later on. """ _error_tmpl: str _code: str def __init__(self, node: AST, text: str = None) -> None: """Creates new instance of style error.""" self.node = node if text is None: self._text = node.__class__.__name__.lower() else: self._text = text def message(self) -> str: """ Returns error's formated message. >>> import ast >>> error = WrongKeywordViolation(ast.Pass()) >>> error.message() 'WPS100 Found wrong keyword "pass"' >>> error = WrongKeywordViolation(ast.Delete(), text='del') >>> error.message() 'WPS100 Found wrong keyword "del"' """ return self._error_tmpl.format(self._code, self._text) def node_items(self) -> Tuple[int, int, str]: """Returns `Tuple` to match `flake8` API format.""" lineno = getattr(self.node, 'lineno', 0) col_offset = getattr(self.node, 'col_offset', 0) return lineno, col_offset, self.message() class WrongKeywordViolation(BaseStyleViolation): """ This rule forbids to use some keywords from ``python``. We do this, since some keywords are anti-patterns. Example:: # Wrong: pass exec eval Note: Returns WPS100 as error code """ _error_tmpl = '{0} Found wrong keyword "{1}"' _code = 'WPS100' class BareRiseViolation(BaseStyleViolation): """ This rule forbids using bare `raise` keyword outside of `except` block. This may be a serious error in your application, so we should prevent that. Example:: # Correct: raise ValueError('Value is to low') # Wrong: raise Note: Returns WPS101 as error code """ _error_tmpl = '{0} Found bare raise outside of except "{1}"' _code = 'WPS101' class RaiseNotImplementedViolation(BaseStyleViolation): """ This rule forbids to use `NotImplemented` error. These two errors have different use cases. Use cases of `NotImplemented` is too limited to be generally available. Example:: # Correct: raise NotImplementedError('To be done') # Wrong: raise NotImplemented See Also: https://stackoverflow.com/a/44575926/4842742 Note: Returns WPS102 as error code """ _error_tmpl = '{0} Found raise NotImplemented "{1}"' _code = 'WPS102' class WrongFunctionCallViolation(BaseStyleViolation): """ This rule forbids to call some built-in functions. Since some functions are only suitable for very specific usecases, we forbid to use them in a free manner. Note: Returns WPS110 as error code """ _error_tmpl = '{0} Found wrong function call "{1}"' _code = 'WPS110' class WrongVariableNameViolation(BaseStyleViolation): """ This rule forbids to have blacklisted variable names. Example:: # Correct: html_node = None # Wrong: item = None Note: Returns WPS120 as error code """ _error_tmpl = '{0} Found wrong variable name "{1}"' _code = 'WPS120' class TooShortVariableNameViolation(BaseStyleViolation): """ This rule forbids to have too short variable names. Example:: # Correct: x_coord = 1 # Wrong: x = 1 Note: Returns WPS121 as error code """ _error_tmpl = '{0} Found too short variable name "{1}"' _code = 'WPS121' class WrongArgumentNameViolation(BaseStyleViolation): """ This rule forbids to have blacklisted function argument names. Example:: # Correct: def parse(xml_tree): ... # Wrong: def parse(value): ... Note: Returns WPS122 as error code """ _error_tmpl = '{0} Found wrong argument name "{1}"' _code = 'WPS122' class TooShortArgumentNameViolation(BaseStyleViolation): """ This rule forbids to have short argument names. Example:: # Correct: def test(username): ... # Wrong: def test(a): ... Note: Returns WPS123 as error code """ _error_tmpl = '{0} Found too short argument name "{1}"' _code = 'WPS123' class WrongAttributeNameViolation(BaseStyleViolation): """ This rule forbids to have attributes with blacklisted names. Example:: # Correct: class NormalClass: request_payload = None # Wrong: class WithBlacklisted: data = None Note: Returns WPS124 as error code """ _error_tmpl = '{0} Found wrong attribute name "{1}"' _code = 'WPS124' class TooShortAttributeNameViolation(BaseStyleViolation): """ This rule forbids to have attributes with short names. Example:: # Correct: class WithAttributes: def __init__(self): self.room_number = 1 # Wrong: class WithAttributes: def __init__(self): self.a = 1 Note: Returns WPS125 as error code """ _error_tmpl = '{0} Found too short attribute name "{1}"' _code = 'WPS125' class WrongFunctionNameViolation(BaseStyleViolation): """ This rule forbids to have functions with blacklisted names. Example:: # Correct: def request_dispatcher(): ... # Wrong: def handler(): ... Note: Returns WPS126 as error code """ _error_tmpl = '{0} Found wrong function name "{1}"' _code = 'WPS126' class TooShortFunctionNameViolation(BaseStyleViolation): """ This rule forbids to have functions with short names. Example:: # Correct: def collect_coverage(): ... # Wrong: def c(): ... Note: Returns WPS127 as error code """ _error_tmpl = '{0} Found too short function name "{1}"' _code = 'WPS127' class WrongModuleMetadataViolation(BaseStyleViolation): """ This rule forbids to have some module level variables. We discourage using module variables like ``__author__``, because there's no need in them. Use proper docstrings and classifiers. Example:: # Wrong: __author__ = 'Nikita Sobolev' Note: Returns WPS126 as error code """ _error_tmpl = '{0} Found wrong metadata variable {1}' _code = 'WPS126' class LocalFolderImportViolation(BaseStyleViolation): """ This rule forbids to have imports relative to the current folder. Example:: # Correct: from my_package.version import get_version # Wrong: from .version import get_version from ..drivers import MySQLDriver Note: Returns WPS130 as error code """ _error_tmpl = '{0} Found local folder import "{1}"' _code = 'WPS130' class NestedImportViolation(BaseStyleViolation): """ This rule forbids to have nested imports in functions. Nested imports show that there's an issue with you design. So, you don't need nested imports, you need to refactor your code. Example:: # Wrong: def some(): from my_module import some_function Note: Returns WPS131 as error code """ _error_tmpl = '{0} Found nested import "{1}"' _code = 'WPS131' class DynamicImportViolation(BaseStyleViolation): """ This rule forbids importing your code with ``__import__()`` function. This is almost never a good idea. So, it is an error by default. Use regular imports instead. Or use ``importlib.import_module()`` in case you know what you are doing. Example:: # Wrong: my_module = __import__('my_module') See Also: https://docs.python.org/3/library/functions.html#__import__ Note: Returns WPS132 as error code """ _error_tmpl = '{0} Found dynamic import "{1}"' _code = 'WPS132' class NestedFunctionViolation(BaseStyleViolation): """ This rule forbids to have nested functions. Just write flat functions, there's no need to nest them. However, there are some whitelisted names like: ``decorator``. Example:: # Wrong: def do_some(): def inner(): ... Note: Returns WPS140 as error code """ _error_tmpl = '{0} Found nested function "{1}"' _code = 'WPS140' class NestedClassViolation(BaseStyleViolation): """ This rule forbids to have nested classes. Just write flat classes, there's no need nest them. However, there are some whitelisted class names like: ``Meta``. Example:: # Wrong: class Some: class Inner: ... Note: Returns WPS141 as error code """ _error_tmpl = '{0} Found nested class "{1}"' _code = 'WPS141' class TooManyLocalsViolation(BaseStyleViolation): """ This rule forbids to have too many local variables in the unit of code. If you have too many variables in a function, you have to refactor it. Note: Returns WPS150 as error code """ _error_tmpl = '{0} Found too many local variables "{1}"' _code = 'WPS150' class TooManyArgumentsViolation(BaseStyleViolation): """ This rule forbids to have too many arguments for a function or method. This is an indecator of a bad desing. When function requires many arguments it shows that it is required to refactor this piece of code. Note: Returns WPS10 as error code """ _error_tmpl = '{0} Found too many arguments "{1}"' _code = 'WPS151' class TooManyBranchesViolation(BaseStyleViolation): """ This rule forbids to have to many branches in a function. When there are too many branches, functions are hard to test. They are also hard to read and hard to change and read. Note: Returns WPS152 as error code """ _error_tmpl = '{0} Found too many branches "{1}"' _code = 'WPS152' class TooManyReturnsViolation(BaseStyleViolation): """ This rule forbids placing too many ``return`` statements into the function. When there are too many ``return`` keywords, functions are hard to test. They are also hard to read and hard to change and read. Note: Returns WPS153 as error code """ _error_tmpl = '{0} Found too many return statements "{1}"' _code = 'WPS153' class TooManyExpressionsViolation(BaseStyleViolation): """ This rule forbids putting to many expression is a unit of code. Because when there are too many expression, it means, that code has some logical or structural problems. We only have to identify them. Note: Returns WPS154 as error code """ _error_tmpl = '{0} Found too many expressions "{1}"' _code = 'WPS154' class TooDeepNestingViolation(BaseStyleViolation): """ This rule forbids nesting blocks too deep. If nesting is too deep that indicates of another problem, that there's to many things going on at the same time. So, we need to check these cases before they have made their way to production. Note: Returns WPS155 as error code """ _error_tmpl = '{0} Found too deep nesting "{1}"' _code = 'WPS155' PK!uh,wemake_python_styleguide/helpers/__init__.py# -*- coding: utf-8 -*- PK!gbuu-wemake_python_styleguide/helpers/functions.py# -*- coding: utf-8 -*- from ast import Call from typing import Iterable def given_function_called(node: Call, to_check: Iterable[str]) -> str: """ Returns function name if it is called and contained in the `to_check`. >>> import ast >>> module = ast.parse('print("some value")') >>> given_function_called(module.body[0].value, ['print']) 'print' """ function_name = getattr(node.func, 'id', None) function_value = getattr(node.func, 'value', None) function_inner_id = getattr(function_value, 'id', None) function_attr = getattr(node.func, 'attr', None) is_restricted_function = function_name in to_check is_restricted_function_attribute = ( function_inner_id in to_check and function_attr in to_check ) if is_restricted_function or is_restricted_function_attribute: return function_name return '' PK!fa-wemake_python_styleguide/helpers/variables.py# -*- coding: utf-8 -*- from typing import Iterable, Optional def is_wrong_variable_name(name: str, to_check: Iterable[str]) -> bool: """ Checks that variable is not prohibited by explicitly listing it's name. >>> is_wrong_variable_name('wrong', ['wrong']) True >>> is_wrong_variable_name('correct', ['wrong']) False """ return name in to_check def is_too_short_variable_name( name: Optional[str], min_length: int = 2, # TODO: config ) -> bool: """ Checks for too short variable names. >>> is_too_short_variable_name('test') False >>> is_too_short_variable_name(None) False >>> is_too_short_variable_name('o') True >>> is_too_short_variable_name('_') False >>> is_too_short_variable_name('z1') False >>> is_too_short_variable_name('z', min_length=1) False """ return name is not None and name != '_' and len(name) < min_length PK!^ ||#wemake_python_styleguide/version.py# -*- coding: utf-8 -*- __version__ = '0.0.2' # noqa # TODO: resolve after https://github.com/sdispater/poetry/issues/273 PK!uh-wemake_python_styleguide/visitors/__init__.py# -*- coding: utf-8 -*- PK!uh2wemake_python_styleguide/visitors/base/__init__.py# -*- coding: utf-8 -*- PK!(*1wemake_python_styleguide/visitors/base/visitor.py# -*- coding: utf-8 -*- from ast import NodeVisitor from typing import List from wemake_python_styleguide.errors import BaseStyleViolation class BaseNodeVisitor(NodeVisitor): """This class allows to store errors while traversing node tree.""" def __init__(self) -> None: """Creates new visitor instance.""" super().__init__() self._errors: List[BaseStyleViolation] = [] @property def errors(self) -> List[BaseStyleViolation]: """Return errors collected by this visitor.""" return self._errors def add_error(self, error: BaseStyleViolation) -> None: """Adds error to the visitor.""" self._errors.append(error) PK! 4wemake_python_styleguide/visitors/high_complexity.py# -*- coding: utf-8 -*- import ast from collections import defaultdict from typing import DefaultDict, Optional from wemake_python_styleguide.errors import ( TooManyArgumentsViolation, TooManyExpressionsViolation, TooManyLocalsViolation, TooManyReturnsViolation, ) from wemake_python_styleguide.visitors.base.visitor import BaseNodeVisitor # TODO: implement TooDeepNestingViolation, TooManyBranchesViolation class ComplexityVisitor(BaseNodeVisitor): """This class checks for code with high complexity.""" def __init__(self) -> None: """Creates counters for tracked metrics.""" super().__init__() self.expressions: DefaultDict[str, int] = defaultdict(int) self.variables: DefaultDict[str, int] = defaultdict(int) self.returns: DefaultDict[str, int] = defaultdict(int) def _is_method(self, function_type: Optional[str]) -> bool: """ Returns either or not given function type belongs to a class. >>> ComplexityVisitor()._is_method('function') False >>> ComplexityVisitor()._is_method(None) False >>> ComplexityVisitor()._is_method('method') True >>> ComplexityVisitor()._is_method('classmethod') True """ return function_type in ['method', 'classmethod'] def _check_arguments_count(self, node: ast.FunctionDef): counter = 0 has_extra_self_or_cls = 0 if self._is_method(getattr(node, 'function_type', None)): has_extra_self_or_cls = 1 counter += len(node.args.args) counter += len(node.args.kwonlyargs) if node.args.vararg: counter += 1 if node.args.kwarg: counter += 1 if counter > 5 + has_extra_self_or_cls: # TODO: config self.add_error( TooManyArgumentsViolation(node, text=node.name), ) def _update_variables(self, function: ast.FunctionDef): self.variables[function.name] += 1 if self.variables[function.name] == 9 + 1: # TODO: config self.add_error( TooManyLocalsViolation(function, text=function.name), ) def _update_returns(self, function: ast.FunctionDef): self.returns[function.name] += 1 if self.returns[function.name] == 5 + 1: # TODO: config self.add_error( TooManyReturnsViolation(function, text=function.name), ) def _update_expression(self, function: ast.FunctionDef): self.expressions[function.name] += 1 if self.expressions[function.name] == 10: # TODO: config self.add_error( TooManyExpressionsViolation(function, text=function.name), ) def visit_FunctionDef(self, node: ast.FunctionDef): """Checks function internal complexity.""" self._check_arguments_count(node) for body_item in node.body: for sub_node in ast.walk(body_item): is_variable = isinstance(sub_node, ast.Name) context = getattr(sub_node, 'ctx', None) if is_variable and isinstance(context, ast.Store): self._update_variables(node) if isinstance(sub_node, ast.Return): self._update_returns(node) if isinstance(sub_node, ast.Expr): self._update_expression(node) self.generic_visit(node) PK!fVV8wemake_python_styleguide/visitors/wrong_function_call.py# -*- coding: utf-8 -*- import ast from wemake_python_styleguide.constants import BAD_FUNCTIONS from wemake_python_styleguide.errors import WrongFunctionCallViolation from wemake_python_styleguide.helpers.functions import given_function_called from wemake_python_styleguide.visitors.base.visitor import BaseNodeVisitor class WrongFunctionCallVisitor(BaseNodeVisitor): """ This class is responsible for restricting some dangerous function calls. All these functions are defined in `BAD_FUNCTIONS`. """ def visit_Call(self, node: ast.Call): """Used to find `BAD_FUNCTIONS` calls.""" function_name = given_function_called(node, BAD_FUNCTIONS) if function_name: self.add_error(WrongFunctionCallViolation( node, text=function_name, )) self.generic_visit(node) PK!ԏ1wemake_python_styleguide/visitors/wrong_import.py# -*- coding: utf-8 -*- import ast from wemake_python_styleguide.errors import ( DynamicImportViolation, LocalFolderImportViolation, NestedImportViolation, ) from wemake_python_styleguide.helpers.functions import given_function_called from wemake_python_styleguide.visitors.base.visitor import BaseNodeVisitor class WrongImportVisitor(BaseNodeVisitor): """This class is responsible for finding wrong imports.""" def _get_error_text(self, node: ast.AST) -> str: module = getattr(node, 'module', None) if module is not None: return module if isinstance(node, ast.Import): return node.names[0].name return '.' def _check_nested_import(self, node: ast.AST, text: str): parent = getattr(node, 'parent', None) if isinstance(parent, ast.FunctionDef): self.add_error(NestedImportViolation(node, text=text)) def visit_Call(self, node: ast.Call): """Used to find `__import__` function calls.""" function_name = given_function_called(node, ['__import__']) if function_name: self.add_error(DynamicImportViolation(node, text=function_name)) self.generic_visit(node) def visit_Import(self, node: ast.Import): """Used to find nested `import` statements.""" text = self._get_error_text(node) self._check_nested_import(node, text) self.generic_visit(node) def visit_ImportFrom(self, node: ast.ImportFrom): """Used to find nested `from import` statements and local imports.""" text = self._get_error_text(node) if node.level != 0: self.add_error( LocalFolderImportViolation(node, text=text), ) if isinstance(getattr(node, 'parent', None), ast.FunctionDef): self.add_error(NestedImportViolation(node, text=text)) self.generic_visit(node) PK!U2wemake_python_styleguide/visitors/wrong_keyword.py# -*- coding: utf-8 -*- import ast from wemake_python_styleguide.errors import ( BareRiseViolation, RaiseNotImplementedViolation, WrongKeywordViolation, ) from wemake_python_styleguide.visitors.base.visitor import BaseNodeVisitor class WrongRaiseVisitor(BaseNodeVisitor): """This class finds wrong `raise` keywords.""" def _check_exception_type(self, node: ast.Raise, exception) -> None: exception_func = getattr(exception, 'func', None) if exception_func: exception = exception_func exception_name = getattr(exception, 'id', None) if exception_name == 'NotImplemented': self.add_error( RaiseNotImplementedViolation(node, text=exception_name), ) def visit_Raise(self, node: ast.Raise) -> None: """Checks how `raise` keyword is used.""" exception = getattr(node, 'exc', None) if not exception: parent = getattr(node, 'parent', None) if not isinstance(parent, ast.ExceptHandler): self.add_error(BareRiseViolation(node)) else: self._check_exception_type(node, exception) self.generic_visit(node) class WrongKeywordVisitor(BaseNodeVisitor): """This class is responsible for finding wrong keywords.""" def visit_Global(self, node: ast.Global): """Used to find `global` keyword.""" self.add_error(WrongKeywordViolation(node)) self.generic_visit(node) def visit_Nonlocal(self, node: ast.Nonlocal): """Used to find `nonlocal` keyword.""" self.add_error(WrongKeywordViolation(node)) self.generic_visit(node) def visit_Delete(self, node: ast.Delete): """Used to find `del` keyword.""" self.add_error(WrongKeywordViolation(node, text='del')) self.generic_visit(node) def visit_Pass(self, node: ast.Pass): """Used to find `pass` keyword.""" self.add_error(WrongKeywordViolation(node)) self.generic_visit(node) PK!ɜbYY/wemake_python_styleguide/visitors/wrong_name.py# -*- coding: utf-8 -*- import ast from wemake_python_styleguide.constants import ( BAD_MODULE_METADATA_VARIABLES, BAD_VARIABLE_NAMES, ) from wemake_python_styleguide.errors import ( TooShortArgumentNameViolation, TooShortAttributeNameViolation, TooShortFunctionNameViolation, TooShortVariableNameViolation, WrongArgumentNameViolation, WrongAttributeNameViolation, WrongFunctionNameViolation, WrongModuleMetadataViolation, WrongVariableNameViolation, ) from wemake_python_styleguide.helpers.variables import ( is_too_short_variable_name, is_wrong_variable_name, ) from wemake_python_styleguide.visitors.base.visitor import BaseNodeVisitor class WrongNameVisitor(BaseNodeVisitor): """ This class performs checks based on variable names. It is responsible for finding short and blacklisted variables, functions, and arguments. """ def _check_argument(self, node: ast.FunctionDef, arg: str) -> None: if is_wrong_variable_name(arg, BAD_VARIABLE_NAMES): self.add_error(WrongArgumentNameViolation(node, text=arg)) if is_too_short_variable_name(arg): self.add_error(TooShortArgumentNameViolation(node, text=arg)) def _check_function_signature(self, node: ast.FunctionDef) -> None: for arg in node.args.args: self._check_argument(node, arg.arg) for arg in node.args.kwonlyargs: self._check_argument(node, arg.arg) if node.args.vararg: self._check_argument(node, node.args.vararg.arg) if node.args.kwarg: self._check_argument(node, node.args.kwarg.arg) def visit_Attribute(self, node: ast.Attribute): """Used to find wrong attribute names inside classes.""" context = getattr(node, 'ctx', None) if isinstance(context, ast.Store): if is_wrong_variable_name(node.attr, BAD_VARIABLE_NAMES): self.add_error( WrongAttributeNameViolation(node, text=node.attr), ) if is_too_short_variable_name(node.attr): self.add_error( TooShortAttributeNameViolation(node, text=node.attr), ) self.generic_visit(node) def visit_FunctionDef(self, node: ast.FunctionDef): """Used to find wrong function and method parameters.""" if is_too_short_variable_name(node.name): self.add_error(TooShortFunctionNameViolation(node, text=node.name)) if is_wrong_variable_name(node.name, BAD_VARIABLE_NAMES): self.add_error(WrongFunctionNameViolation(node, text=node.name)) self._check_function_signature(node) self.generic_visit(node) def visit_ExceptHandler(self, node: ast.ExceptHandler): """Used to find wrong exception instances in `try/except`.""" name = getattr(node, 'name', '_') if is_wrong_variable_name(name, BAD_VARIABLE_NAMES): self.add_error( WrongVariableNameViolation(node, text=name), ) if is_too_short_variable_name(name): self.add_error( TooShortVariableNameViolation(node, text=name), ) def visit_Name(self, node: ast.Name): """Used to find wrong regular variables.""" context = getattr(node, 'ctx', None) if isinstance(context, ast.Store): if is_wrong_variable_name(node.id, BAD_VARIABLE_NAMES): self.add_error( WrongVariableNameViolation(node, text=node.id), ) if is_too_short_variable_name(node.id): self.add_error( TooShortVariableNameViolation(node, text=node.id), ) self.generic_visit(node) class WrongModuleMetadataVisitor(BaseNodeVisitor): """This class finds wrong metadata information of a module.""" def visit_Assign(self, node: ast.Assign): """Used to find the bad metadata variable names.""" node_parent = getattr(node, 'parent') if not isinstance(node_parent, ast.Module): return for target_node in node.targets: target_node_id = getattr(target_node, 'id') if target_node_id in BAD_MODULE_METADATA_VARIABLES: self.add_error( WrongModuleMetadataViolation(node, text=target_node_id), ) PK!hH??1wemake_python_styleguide/visitors/wrong_nested.py# -*- coding: utf-8 -*- import ast from wemake_python_styleguide.constants import ( NESTED_CLASSES_WHITELIST, NESTED_FUNCTIONS_WHITELIST, ) from wemake_python_styleguide.errors import ( NestedClassViolation, NestedFunctionViolation, ) from wemake_python_styleguide.visitors.base.visitor import BaseNodeVisitor class WrongNestedVisitor(BaseNodeVisitor): """This class checks that structures are not nested.""" def visit_ClassDef(self, node: ast.ClassDef): """ Used to find nested classes in other classes and functions. Uses `NESTED_CLASSES_WHITELIST` to respect some nested classes. """ parent = getattr(node, 'parent', None) is_inside_class = isinstance(parent, ast.ClassDef) is_inside_function = isinstance(parent, ast.FunctionDef) if is_inside_class and node.name not in NESTED_CLASSES_WHITELIST: self.add_error(NestedClassViolation(node, text=node.name)) elif is_inside_function: self.add_error(NestedClassViolation(node, text=node.name)) self.generic_visit(node) def visit_FunctionDef(self, node: ast.FunctionDef): """ Used to find nested functions. Uses `NESTED_FUNCTIONS_WHITELIST` to respect some nested functions. """ parent = getattr(node, 'parent', None) is_inside_function = isinstance(parent, ast.FunctionDef) if is_inside_function and node.name not in NESTED_FUNCTIONS_WHITELIST: self.add_error(NestedFunctionViolation(node, text=node.name)) self.generic_visit(node) PK!HFYb=A9wemake_python_styleguide-0.0.2.dist-info/entry_points.txtNINK(I+ϋ -O TdT椦f%g&gY9Ch..PK!f000wemake_python_styleguide-0.0.2.dist-info/LICENSEMIT License Copyright (c) 2018 wemake.services 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. PK!H,ST.wemake_python_styleguide-0.0.2.dist-info/WHEEL A н#J;/"d&F]xzw>@Zpy3F ].MRi튒hv=0(0PK!HvG= 1wemake_python_styleguide-0.0.2.dist-info/METADATAVs6:a&4*!U kf8I_S(8gXUWo RX!pj,ŭ&}, ] g~q, MLIIf< Tir[ClrJ`1܋_n۽?.ώfnja~TqSxT~nt>ZA'5~d4ʂ(zӚ⻐Ҹ`jUNX/ҺPZSEB?_2UI*=E:ԠF|4q:'p v-#Sek˛+VY6gEp" (AqeQp@8]~{n]5.Ymg %Kւ ~PK!uh$wemake_python_styleguide/__init__.pyPK!""#Zwemake_python_styleguide/checker.pyPK!%wemake_python_styleguide/constants.pyPK!jdN--" wemake_python_styleguide/errors.pyPK!uh,$;wemake_python_styleguide/helpers/__init__.pyPK!gbuu-;wemake_python_styleguide/helpers/functions.pyPK!fa-F?wemake_python_styleguide/helpers/variables.pyPK!^ ||#DCwemake_python_styleguide/version.pyPK!uh-Dwemake_python_styleguide/visitors/__init__.pyPK!uh2dDwemake_python_styleguide/visitors/base/__init__.pyPK!(*1Dwemake_python_styleguide/visitors/base/visitor.pyPK! 4Gwemake_python_styleguide/visitors/high_complexity.pyPK!fVV8Uwemake_python_styleguide/visitors/wrong_function_call.pyPK!ԏ1_Ywemake_python_styleguide/visitors/wrong_import.pyPK!U2-awemake_python_styleguide/visitors/wrong_keyword.pyPK!ɜbYY/iiwemake_python_styleguide/visitors/wrong_name.pyPK!hH??1{wemake_python_styleguide/visitors/wrong_nested.pyPK!HFYb=A9wemake_python_styleguide-0.0.2.dist-info/entry_points.txtPK!f0001wemake_python_styleguide-0.0.2.dist-info/LICENSEPK!H,ST.wemake_python_styleguide-0.0.2.dist-info/WHEELPK!HvG= 1Nwemake_python_styleguide-0.0.2.dist-info/METADATAPK!Hg/:wemake_python_styleguide-0.0.2.dist-info/RECORDPKJ