PK!uh$wemake_python_styleguide/__init__.py# -*- coding: utf-8 -*- PK!B7  #wemake_python_styleguide/checker.py# -*- coding: utf-8 -*- from ast import Module from typing import Generator, Tuple from wemake_python_styleguide.compat import maybe_set_parent from wemake_python_styleguide.options.config import Configuration 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 config = Configuration() options = None # So that mypy could detect the attribute def __init__(self, tree: Module, filename: str = '-') -> None: """Creates new checker instance.""" self.tree = maybe_set_parent(tree) self.filename = filename self._visitors = ( WrongRaiseVisitor, WrongFunctionCallVisitor, WrongImportVisitor, WrongKeywordVisitor, WrongNestedVisitor, ComplexityVisitor, WrongNameVisitor, WrongModuleMetadataVisitor, ) @classmethod def add_options(cls, parser): """Calls Configuration instance method for registering options.""" cls.config.register_options(parser) @classmethod def parse_options(cls, options): """Parses registered options for providing to the visiter.""" cls.options = options 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.provide_options(self.options) visiter.visit(self.tree) for error in visiter.errors: lineno, col_offset, message = error.node_items() yield lineno, col_offset, message, type(self) PK!I"wemake_python_styleguide/compat.py# -*- coding: utf-8 -*- """ This module contains ugly hacks and fixes for version compat issues. Do not be over-exited to add anything here. """ import ast def maybe_set_parent(tree: ast.AST) -> ast.AST: """Sets parents for all nodes that do not have this prop.""" for statement in ast.walk(tree): for child in ast.iter_child_nodes(statement): if not hasattr(child, 'parent'): # noqa: Z105 setattr(child, 'parent', statement) # noqa: Z105 return tree PK!9- 00%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', # Dynamic imports: '__import__', )) #: 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', 'file', 'klass', )) #: 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!n##"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() 'Z102 Found wrong keyword "pass"' >>> error = WrongKeywordViolation(ast.Delete(), text='del') >>> error.message() 'Z102 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 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 Z100 as error code """ _error_tmpl = '{0} Found local folder import "{1}"' _code = 'Z100' 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 Z101 as error code """ _error_tmpl = '{0} Found nested import "{1}"' _code = 'Z101' 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 Z102 as error code """ _error_tmpl = '{0} Found wrong keyword "{1}"' _code = 'Z102' 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 Z103 as error code """ _error_tmpl = '{0} Found bare raise outside of except "{1}"' _code = 'Z103' 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 Z104 as error code """ _error_tmpl = '{0} Found raise NotImplemented "{1}"' _code = 'Z104' 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 Z105 as error code """ _error_tmpl = '{0} Found wrong function call "{1}"' _code = 'Z105' class WrongVariableNameViolation(BaseStyleViolation): """ This rule forbids to have blacklisted variable names. Example:: # Correct: html_node = None # Wrong: item = None Note: Returns Z106 as error code """ _error_tmpl = '{0} Found wrong variable name "{1}"' _code = 'Z106' class TooShortVariableNameViolation(BaseStyleViolation): """ This rule forbids to have too short variable names. Example:: # Correct: x_coord = 1 # Wrong: x = 1 Note: Returns Z107 as error code """ _error_tmpl = '{0} Found too short name "{1}"' _code = 'Z107' class PrivateNameViolation(BaseStyleViolation): """ This rule forbids to have private name pattern. It includes: variables, attributes, functions, and methods. Example:: # Correct: def _collect_coverage(self): ... # Wrong: def __collect_coverage(self): ... Note: Returns Z108 as error code """ _error_tmpl = '{0} Found private name pattern "{1}"' _code = 'Z108' 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 Z109 as error code """ _error_tmpl = '{0} Found wrong metadata variable {1}' _code = 'Z109' # Design: # These errors finds flaws in your application design and reports them. 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 Z200 as error code """ _error_tmpl = '{0} Found nested function "{1}"' _code = 'Z200' 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 Z201 as error code """ _error_tmpl = '{0} Found nested class "{1}"' _code = 'Z201' 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 Z202 as error code """ _error_tmpl = '{0} Found too many local variables "{1}"' _code = 'Z202' 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 Z203 as error code """ _error_tmpl = '{0} Found too many arguments "{1}"' _code = 'Z203' 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 Z204 as error code """ _error_tmpl = '{0} Found too many branches "{1}"' _code = 'Z204' 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 Z205 as error code """ _error_tmpl = '{0} Found too many return statements "{1}"' _code = 'Z205' 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 Z206 as error code """ _error_tmpl = '{0} Found too many expressions "{1}"' _code = 'Z206' 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 Z207 as error code """ _error_tmpl = '{0} Found too deep nesting "{1}"' _code = 'Z207' 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!-,cc-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 >>> is_wrong_variable_name('_wrong', ['wrong']) True >>> is_wrong_variable_name('wrong_', ['wrong']) True >>> is_wrong_variable_name('wrong__', ['wrong']) False >>> is_wrong_variable_name('__wrong', ['wrong']) False """ for name_to_check in to_check: choices_to_check = [ name_to_check, '_{0}'.format(name_to_check), '{0}_'.format(name_to_check), ] if name in choices_to_check: return True return False 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 def is_private_variable(name: Optional[str]) -> bool: """ Checks if variable has private name pattern. >>> is_private_variable(None) False >>> is_private_variable('regular') False >>> is_private_variable('__private') True >>> is_private_variable('_protected') False >>> is_private_variable('__magic__') False """ return ( name is not None and name.startswith('__') and not name.endswith('__') ) PK!uh,wemake_python_styleguide/options/__init__.py# -*- coding: utf-8 -*- PK!X%*wemake_python_styleguide/options/config.py# -*- coding: utf-8 -*- from wemake_python_styleguide.options import defaults class Configuration(object): """Provides method for registering options for Z flake8 plugin.""" def register_options(self, parser): """Registers options for Z plugin.""" parser.add_option( '--max-returns', parse_from_config=True, type='int', default=defaults.MAX_RETURNS, help='Maximum allowed number of return statements in one function.', ) parser.add_option( '--max-local-variables', parse_from_config=True, type='int', default=defaults.MAX_LOCAL_VARIABLES, help='Maximum allowed number of local variables in one function.', ) parser.add_option( '--max-expressions', parse_from_config=True, type='int', default=defaults.MAX_EXPRESSIONS, help='Maximum allowed number of expressions in one function.', ) parser.add_option( '--max-arguments', parse_from_config=True, type='int', default=defaults.MAX_ARGUMENTS, help='Maximum allowed number of arguments in one function.', ) PK!k4 ,wemake_python_styleguide/options/defaults.py# -*- coding: utf-8 -*- """Constants with default values for configuration.""" MAX_RETURNS = 6 MAX_LOCAL_VARIABLES = 10 MAX_EXPRESSIONS = 10 MAX_ARGUMENTS = 5 PK!ժh||#wemake_python_styleguide/version.py# -*- coding: utf-8 -*- import pkg_resources version = pkg_resources.get_distribution('wemake-python-styleguide').version PK!uh-wemake_python_styleguide/visitors/__init__.py# -*- coding: utf-8 -*- PK!uh2wemake_python_styleguide/visitors/base/__init__.py# -*- coding: utf-8 -*- PK!{ɴ111wemake_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) def provide_options(self, options) -> None: """Provides options for checking.""" self.options = options PK!tʢ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 config parser instance and 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 max_arguments_count = self.options.max_arguments 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 > max_arguments_count + has_extra_self_or_cls: self.add_error( TooManyArgumentsViolation(node, text=node.name), ) def _update_variables(self, function: ast.FunctionDef): max_local_variables_count = self.options.max_local_variables self.variables[function.name] += 1 if self.variables[function.name] == max_local_variables_count: self.add_error( TooManyLocalsViolation(function, text=function.name), ) def _update_returns(self, function: ast.FunctionDef): max_returns_count = self.options.max_returns self.returns[function.name] += 1 if self.returns[function.name] == max_returns_count: self.add_error( TooManyReturnsViolation(function, text=function.name), ) def _update_expression(self, function: ast.FunctionDef): max_expressions_count = self.options.max_expressions self.expressions[function.name] += 1 if self.expressions[function.name] == max_expressions_count: 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!F1wemake_python_styleguide/visitors/wrong_import.py# -*- coding: utf-8 -*- import ast from wemake_python_styleguide.errors import ( LocalFolderImportViolation, NestedImportViolation, ) 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 not isinstance(parent, ast.Module): self.add_error(NestedImportViolation(node, text=text)) def _check_local_import(self, node: ast.ImportFrom, text: str): if node.level != 0: self.add_error(LocalFolderImportViolation(node, text=text)) 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) self._check_local_import(node, text) self._check_nested_import(node, 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!N /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 ( PrivateNameViolation, TooShortVariableNameViolation, WrongModuleMetadataViolation, WrongVariableNameViolation, ) from wemake_python_styleguide.helpers.variables import ( is_private_variable, 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_name(self, node: ast.AST, arg: str) -> None: if is_wrong_variable_name(arg, BAD_VARIABLE_NAMES): self.add_error(WrongVariableNameViolation(node, text=arg)) if is_too_short_variable_name(arg): self.add_error(TooShortVariableNameViolation(node, text=arg)) if is_private_variable(arg): self.add_error(PrivateNameViolation(node, text=arg)) def _check_function_signature(self, node: ast.FunctionDef) -> None: for arg in node.args.args: self._check_name(node, arg.arg) for arg in node.args.kwonlyargs: self._check_name(node, arg.arg) if node.args.vararg: self._check_name(node, node.args.vararg.arg) if node.args.kwarg: self._check_name(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): self._check_name(node, node.attr) self.generic_visit(node) def visit_FunctionDef(self, node: ast.FunctionDef): """Used to find wrong function and method parameters.""" name = getattr(node, 'name', None) self._check_name(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', None) self._check_name(node, name) self.generic_visit(node) def visit_Name(self, node: ast.Name): """Used to find wrong regular variables.""" context = getattr(node, 'ctx', None) if isinstance(context, ast.Store): self._check_name(node, 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', None) 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!H";?9wemake_python_styleguide-0.0.3.dist-info/entry_points.txtNINK(I+ϋ劲-O TdT椦f%g&gY9Ch..PK!f000wemake_python_styleguide-0.0.3.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_zTT.wemake_python_styleguide-0.0.3.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]n0H*J>mlcAPK!H5v 1wemake_python_styleguide-0.0.3.dist-info/METADATAVS8n:ܕP(sBvnVYr%9뻲 o}zwoؾ'RQygupDhA"<#v)#aBbαsj (2-nL9cM#=Puse]4NUT &㋨TB4 \mkhݐt!dh(fIHў-y7FYF:#9KW܉'*{Aes~{ت2P52'L 4։B2:E6rY<;:S)xPUpv g\ܹoqMxip+l`DwBnK1rHH ?tlK=%Uh? ^c%uO: &˖>f+&˲>vAPQhPAۓ߼4+Ѳ14v{1 ; QX#ǀ9"z"T ; fRO'YR-dz6i e:>2&RDhZT 4,޿lQoceB',aulX=1}Dž50@l$J㴈<߶"@wo uo ڨ"f4IPDф,RY$!oќbTmVc.V1l;K[HEnr$6yktƥ'B 6%q8%2/A Ϝ"jh%:5iDPc$s8+lP4SVҁ`Ssg 3{`x^[FkӚ@ǻa0' /pc[a~` {)PK!HDO /wemake_python_styleguide-0.0.3.dist-info/RECORDIF-fY Bbp 1A~}$택cwmx$fWʰB8+i)Gfj5#n-s.o/ ;QCMNA5ZRT$YN;v@GI M &ǙvgjA΍~ C4jdĵ9z<"@&R{z(_CaQ֐̞K<” q; "iٍmF9E~[gΪ͠`)e1L7@8eYԈL!{~Ɖ`_#c]f֊`WZ_8gkjpFV wPteen~U:zpwp( VNҏDӔN|ٹ]u??nn $ DW/cC*LN/S%+xvBqkʼn#g4Ճq9'+{?`XYnux=k$@T׵By>. ~+[f8.x.LsCXoض[n/R4~aao[ôA_1|[׭uڿ|hmm\ T]Nwk1C~Ex>0H؁ :gy bALKK赗pA"IF%\ԋ8E25a(GNۖ!˶2/Sp? tQlXY,Mg˙qDSL+=y7qI4-PK!uh$wemake_python_styleguide/__init__.pyPK!B7  #Zwemake_python_styleguide/checker.pyPK!I" wemake_python_styleguide/compat.pyPK!9- 00%U wemake_python_styleguide/constants.pyPK!n##"wemake_python_styleguide/errors.pyPK!uh,5wemake_python_styleguide/helpers/__init__.pyPK!gbuu-66wemake_python_styleguide/helpers/functions.pyPK!-,cc-9wemake_python_styleguide/helpers/variables.pyPK!uh,Awemake_python_styleguide/options/__init__.pyPK!X%*Bwemake_python_styleguide/options/config.pyPK!k4 ,MGwemake_python_styleguide/options/defaults.pyPK!ժh||#;Hwemake_python_styleguide/version.pyPK!uh-Hwemake_python_styleguide/visitors/__init__.pyPK!uh2[Iwemake_python_styleguide/visitors/base/__init__.pyPK!{ɴ111Iwemake_python_styleguide/visitors/base/visitor.pyPK!tʢ4CMwemake_python_styleguide/visitors/high_complexity.pyPK!fVV87\wemake_python_styleguide/visitors/wrong_function_call.pyPK!F1_wemake_python_styleguide/visitors/wrong_import.pyPK!U2 fwemake_python_styleguide/visitors/wrong_keyword.pyPK!N /Inwemake_python_styleguide/visitors/wrong_name.pyPK!hH??1o{wemake_python_styleguide/visitors/wrong_nested.pyPK!H";?9wemake_python_styleguide-0.0.3.dist-info/entry_points.txtPK!f000wemake_python_styleguide-0.0.3.dist-info/LICENSEPK!H_zTT. wemake_python_styleguide-0.0.3.dist-info/WHEELPK!H5v 1wemake_python_styleguide-0.0.3.dist-info/METADATAPK!HDO /rwemake_python_styleguide-0.0.3.dist-info/RECORDPK=