Skip to content

Commit

Permalink
Version 0.5.0 release, closes #312
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Nov 10, 2018
1 parent edf198b commit 889080f
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 62 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@
We follow Semantic Versions since the `0.1.0` release.
We used to have incremental versioning before `0.1.0`.

## WIP
## 0.5.0

### Features

- Adds `TooLongNameViolation`
- **Breaking**: removes `--max-conditions` and `--max-elifs` options
- **Breaking**: removes `--max-offset-blocks`
- **Breaking**: changes default `TooManyConditionsViolation` threshold from `3` to `4`
- **Breaking**: changes `TooManyBaseClassesViolation` code from ``225`` to ``215``
- Forbids to use `lambda` inside loops
- Reserving names `self`, `cls`, and `mcs` for first arguments only
- Forbids to use `self`, `cls`, and `mcs` except for first arguments only
- Forbids to use too many decorators
- Now `RedundantLoopElseViolation` also checks `while` loops
- Forbids to have unreachable code
- Forbids to have statements that have no effect
- Forbids to have too long names for modules and variables
- Forbids to have names with unicode for modules and variables
- Add `variable` to the blacklisted names
- Now `RedundantLoopElseViolation` also checks `while` loops


## Bugfixes

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "wemake-python-styleguide"
version = "0.4.0"
version = "0.5.0"
description = "The strictest and most opinionated python linter ever"

license = "MIT"
Expand Down
7 changes: 5 additions & 2 deletions tests/test_checker/test_module_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
('123py.py', naming.WrongModuleNamePatternViolation),
('version_1.py', naming.UnderscoredNumberNameViolation),
('__private.py', naming.PrivateNameViolation),
('oh_no_not_an_extremely_super_duper_unreasonably_long_name.py',
naming.TooLongNameViolation),
(
'oh_no_not_an_extremely_super_duper_unreasonably_long_name.py',
naming.TooLongNameViolation,
),
('привет', naming.UnicodeNameViolation),
])
def test_module_names(filename, error, default_options):
"""Ensures that checker works with module names."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ def first(): ...
def second(): ...
"""

module_without_methods_with_async_functions = """
module_with_async_functions = """
async def first(): ...
async def second(): ...
"""

module_without_methods_with_async_and_usual_functions = """
module_async_and_usual_functions = """
def first(): ...
async def second(): ...
Expand Down Expand Up @@ -76,8 +76,8 @@ async def method2(cls): ...

@pytest.mark.parametrize('code', [
module_without_methods,
module_without_methods_with_async_functions,
module_without_methods_with_async_and_usual_functions,
module_with_async_functions,
module_async_and_usual_functions,
class_with_methods,
class_with_async_methods,
class_with_async_and_usual_methods,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ class Second(object):
def method(self): ...
"""

module_with_function_and_class_and_async_method = """
module_with_function_and_async_method = """
def first(): ...
class Second(object):
async def method(self): ...
"""

module_with_function_and_class_and_classmethod = """
module_with_function_and_classmethod = """
def first(): ...
class Second(object):
Expand Down Expand Up @@ -98,8 +98,8 @@ def other(self): ...
empty_module,
module_with_function_and_class,
module_with_function_and_class_and_method,
module_with_function_and_class_and_async_method,
module_with_function_and_class_and_classmethod,
module_with_function_and_async_method,
module_with_function_and_classmethod,
module_with_async_function_and_class,
module_with_methods,
module_with_async_methods,
Expand All @@ -124,8 +124,8 @@ def test_module_counts_normal(
@pytest.mark.parametrize('code', [
module_with_function_and_class,
module_with_function_and_class_and_method,
module_with_function_and_class_and_async_method,
module_with_function_and_class_and_classmethod,
module_with_function_and_async_method,
module_with_function_and_classmethod,
module_with_async_function_and_class,
module_with_methods,
module_with_async_methods,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def test_multiple_for_keywords_in_comprehension(
@pytest.mark.parametrize('code', [
complex_nested_list_comprehension,
])
def test_multiple_for_keywords_in_async_comprehension(
def test_multiple_fors_in_async_comprehension(
assert_errors,
parse_ast_tree,
code,
Expand All @@ -120,7 +120,7 @@ def test_multiple_for_keywords_in_async_comprehension(
regular_dict_comprehension,
regular_gen_expression,
])
def test_regular_for_keywords_in_comprehension(
def test_regular_fors_in_comprehension(
assert_errors,
parse_ast_tree,
code,
Expand All @@ -137,7 +137,7 @@ def test_regular_for_keywords_in_comprehension(
@pytest.mark.parametrize('code', [
regular_nested_list_comprehension,
])
def test_regular_for_keywords_in_async_comprehension(
def test_regular_fors_in_async_comprehension(
assert_errors,
parse_ast_tree,
code,
Expand Down
27 changes: 0 additions & 27 deletions tests/test_visitors/test_ast/test_naming/test_length_config.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-

import pytest

from wemake_python_styleguide.violations.naming import TooShortNameViolation
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor

Expand All @@ -21,3 +23,25 @@ def test_short_variable_name(

assert_errors(visitor, [TooShortNameViolation])
assert_error_text(visitor, short_name)


@pytest.mark.parametrize('correct_name', [
'snake_case',
'_protected_or_unused',
'with_number5',
])
def test_naming_correct(
assert_errors,
parse_ast_tree,
naming_template,
options,
correct_name,
):
"""Ensures that correct names are allowed."""
tree = parse_ast_tree(naming_template.format(correct_name))

option_values = options(min_name_length=3)
visitor = WrongNameVisitor(option_values, tree=tree)
visitor.run()

assert_errors(visitor, [])
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_missing_space(
multiline_correct_function,
multiline_correct_statement,
])
def test_fine_when_space_in_between_keyword_and_parens(
def test_space_between_keyword_and_parens(
parse_tokens,
assert_errors,
default_options,
Expand Down
37 changes: 31 additions & 6 deletions wemake_python_styleguide/logics/naming/logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ def is_wrong_name(name: str, to_check: Iterable[str]) -> bool:
"""
for name_to_check in to_check:
choices_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
Expand Down Expand Up @@ -74,7 +74,7 @@ def is_too_short_name(
min_length: int = defaults.MIN_NAME_LENGTH,
) -> bool:
"""
Checks for too short variable names.
Checks for too short names.
>>> is_too_short_name('test')
False
Expand All @@ -100,7 +100,7 @@ def is_too_long_name(
max_length: int = defaults.MAX_NAME_LENGTH,
) -> bool:
"""
Checks for too long variable names.
Checks for too long names.
>>> is_too_long_name('test')
False
Expand All @@ -123,7 +123,7 @@ def is_too_long_name(

def does_contain_underscored_number(name: str) -> bool:
"""
Checks for variable names with underscored number.
Checks for names with underscored number.
>>> does_contain_underscored_number('star_wars_episode2')
False
Expand Down Expand Up @@ -158,7 +158,7 @@ def does_contain_underscored_number(name: str) -> bool:

def does_contain_consecutive_underscores(name: str) -> bool:
"""
Checks if variable contains consecutive underscores in middle of name.
Checks if name contains consecutive underscores in middle of name.
>>> does_contain_consecutive_underscores('name')
False
Expand Down Expand Up @@ -186,3 +186,28 @@ def does_contain_consecutive_underscores(name: str) -> bool:
return True

return False


def does_contain_unicode(name: str) -> bool:
"""
Check if name contains unicode characters.
>>> does_contain_unicode('hello_world1')
False
>>> does_contain_unicode('')
False
>>> does_contain_unicode('привет_мир1')
True
>>> does_contain_unicode('russian_техт')
True
"""
try:
name.encode('ascii')
except UnicodeEncodeError:
return True
else:
return False
2 changes: 1 addition & 1 deletion wemake_python_styleguide/options/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
MIN_NAME_LENGTH: Final = 2

#: Maximum variable and module name length:
MAX_NAME_LENGTH: Final = 55
MAX_NAME_LENGTH: Final = 45

#: Whether you control ones who use your code.
I_CONTROL_CODE: Final = True
Expand Down
5 changes: 4 additions & 1 deletion wemake_python_styleguide/violations/naming.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ class TooLongNameViolation(MaybeASTViolation):


@final
class UnicodeNameViolation(ASTViolation):
class UnicodeNameViolation(MaybeASTViolation):
"""
Restrict unicode names.
Expand All @@ -571,6 +571,9 @@ class UnicodeNameViolation(ASTViolation):
Solution:
Rename your entities so that they contain only ASCII symbols.
This rule checks: modules, variables, attributes,
functions, methods, and classes.
Example::
# Correct:
Expand Down
9 changes: 3 additions & 6 deletions wemake_python_styleguide/visitors/ast/naming.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,9 @@ def check_name(
self._error_callback(
naming.ReservedArgumentNameViolation(node, text=name),
)
try:
name.encode('ascii')
except UnicodeEncodeError:
self._error_callback(
naming.UnicodeNameViolation(node, text=name),
)

if logical.does_contain_unicode(name):
self._error_callback(naming.UnicodeNameViolation(node, text=name))

self._ensure_length(node, name)
self._ensure_underscores(node, name)
Expand Down
4 changes: 4 additions & 0 deletions wemake_python_styleguide/visitors/filenames/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
TooLongNameViolation,
TooShortNameViolation,
UnderscoredNumberNameViolation,
UnicodeNameViolation,
WrongModuleMagicNameViolation,
WrongModuleNamePatternViolation,
WrongModuleNameViolation,
Expand All @@ -31,6 +32,9 @@ def _check_module_name(self) -> None:
if access.is_private(self.stem):
self.add_violation(PrivateNameViolation(text=self.stem))

if logical.does_contain_unicode(self.stem):
self.add_violation(UnicodeNameViolation(text=self.stem))

def _check_module_name_length(self) -> None:
min_length = self.options.min_name_length
if logical.is_too_short_name(self.stem, min_length=min_length):
Expand Down

0 comments on commit 889080f

Please sign in to comment.