Skip to content

Commit 764940d

Browse files
committed
Changes name-related rules
Changes: 1. Now we are using the same errors for every name violation 2. We now forbid private names, closes #45 3. Restricts `file` and `klass` as variable names, closes #42 4. Checks `flake --version` output, closes #41 5. Adds checks for errors to be correctly defined
1 parent 2291cc1 commit 764940d

File tree

17 files changed

+288
-242
lines changed

17 files changed

+288
-242
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ addopts =
4242
--cov=wemake_python_styleguide
4343
--cov-report=term:skip-covered
4444
--cov-report=html
45-
--cov-fail-under=95
45+
--cov-fail-under=100
4646

4747

4848
[isort]

tests/fixtures/wrong_variable.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class Fixture(object):
4545
def __init__(self, value): # error here
4646
self.var = value # error here only for `var`, not for `value`
4747
self.x = value # error here only for `x`, not for `value`
48+
self.__private = value # error here for `__private`, not for `value`
4849

4950

5051
val = Fixture() # error here

tests/test_checkers/test_wrong_variable.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ def test_wrong_variables_in_fixture(absolute_path):
1313
)
1414
stdout, _ = process.communicate()
1515

16-
assert stdout.count(b'WPS120') == 8
17-
assert stdout.count(b'WPS121') == 3
18-
assert stdout.count(b'WPS122') == 3
19-
assert stdout.count(b'WPS123') == 2
20-
assert stdout.count(b'WPS124') == 1
21-
assert stdout.count(b'WPS125') == 1
22-
assert stdout.count(b'WPS126') == 1
16+
assert stdout.count(b'WPS120') == 12
17+
assert stdout.count(b'WPS121') == 6
18+
assert stdout.count(b'WPS122') == 1
19+
assert stdout.count(b'WPS123') == 1

tests/test_errors.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import inspect
4+
from operator import itemgetter
5+
6+
import pytest
7+
8+
from wemake_python_styleguide import errors
9+
10+
11+
def _is_error_class(cls) -> bool:
12+
return (
13+
inspect.isclass(cls) and
14+
issubclass(cls, errors.BaseStyleViolation) and
15+
cls is not errors.BaseStyleViolation
16+
)
17+
18+
19+
@pytest.fixture(scope='module')
20+
def all_errors():
21+
"""Loads all errors from the package."""
22+
return list(
23+
map(itemgetter(1), inspect.getmembers(errors, _is_error_class)),
24+
)
25+
26+
27+
def test_all_unique_error_codes(all_errors):
28+
"""Ensures that all errors have unique error codes."""
29+
codes = []
30+
for error in all_errors:
31+
codes.append(error._code)
32+
33+
assert len(set(codes)) == len(all_errors)
34+
35+
36+
def test_all_errors_have_description_with_code(all_errors):
37+
"""Ensures that all errors have description with error code."""
38+
for error in all_errors:
39+
assert error._code in error.__doc__

tests/test_version.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import subprocess
4+
5+
6+
def test_call_flake8_version():
7+
"""Checks that module is registered and visible in the meta data."""
8+
output = subprocess.check_output(
9+
['flake8', '--version'],
10+
stderr=subprocess.STDOUT,
11+
)
12+
assert b'wemake-python-styleguide' in output

tests/test_visitors/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def assert_errors():
2929
"""Helper function to assert visitor errors."""
3030
def factory(visiter: BaseNodeVisitor, errors: Sequence[str]):
3131
for index, error in enumerate(visiter.errors):
32+
assert len(errors) > index, error._code
3233
assert error._code == errors[index]._code
3334

3435
assert len(visiter.errors) == len(errors)

tests/test_visitors/test_wrong_import/test_nested_imports.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
WrongImportVisitor,
88
)
99

10+
# Incorrect imports:
11+
1012
nested_function_import = """
1113
def function():
1214
import os
@@ -17,6 +19,11 @@ def function():
1719
from os import path
1820
"""
1921

22+
nested_conditional_import = """
23+
if True:
24+
import os
25+
"""
26+
2027
nested_method_import = """
2128
class Test:
2229
def with_import(self):
@@ -29,12 +36,31 @@ def with_import(self):
2936
from os import path
3037
"""
3138

39+
nested_try_import = """
40+
try:
41+
from missing import some
42+
except ImportError:
43+
some = None
44+
"""
45+
46+
# Correct imports:
47+
48+
regular_import = """
49+
import os
50+
"""
51+
52+
regular_from_import = """
53+
from os import path
54+
"""
55+
3256

3357
@pytest.mark.parametrize('code', [
3458
nested_function_import,
3559
nested_function_from_import,
3660
nested_method_import,
3761
nested_method_from_import,
62+
nested_conditional_import,
63+
nested_try_import,
3864
])
3965
def test_nested_import(assert_errors, parse_ast_tree, code):
4066
"""Testing that nested imports are restricted."""
@@ -46,19 +72,13 @@ def test_nested_import(assert_errors, parse_ast_tree, code):
4672
assert_errors(visiter, [NestedImportViolation])
4773

4874

49-
def test_regular_import(assert_errors, parse_ast_tree):
75+
@pytest.mark.parametrize('code', [
76+
regular_import,
77+
regular_from_import,
78+
])
79+
def test_regular_imports(assert_errors, parse_ast_tree, code):
5080
"""Testing that regular imports are allowed."""
51-
tree = parse_ast_tree('import os')
52-
53-
visiter = WrongImportVisitor()
54-
visiter.visit(tree)
55-
56-
assert_errors(visiter, [])
57-
58-
59-
def test_regular_from_import(assert_errors, parse_ast_tree):
60-
"""Testing that regular from imports are allowed."""
61-
tree = parse_ast_tree('from os import path')
81+
tree = parse_ast_tree(code)
6282

6383
visiter = WrongImportVisitor()
6484
visiter.visit(tree)

tests/test_visitors/test_wrong_name/test_class_attributes.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66

77
from wemake_python_styleguide.visitors.wrong_name import (
88
BAD_VARIABLE_NAMES,
9-
TooShortAttributeNameViolation,
9+
PrivateNameViolation,
1010
TooShortVariableNameViolation,
11-
WrongAttributeNameViolation,
1211
WrongNameVisitor,
1312
WrongVariableNameViolation,
1413
)
@@ -26,45 +25,61 @@ def __init__(self):
2625

2726

2827
@pytest.mark.parametrize('bad_name', BAD_VARIABLE_NAMES)
29-
@pytest.mark.parametrize('code,error', [
30-
(static_attribute, WrongVariableNameViolation),
31-
(instance_attribute, WrongAttributeNameViolation),
28+
@pytest.mark.parametrize('code', [
29+
static_attribute,
30+
instance_attribute,
3231
])
3332
def test_wrong_attributes_names(
34-
assert_errors, parse_ast_tree, bad_name, code, error,
33+
assert_errors, parse_ast_tree, bad_name, code,
3534
):
3635
"""Testing that attribute can not have blacklisted names."""
3736
tree = parse_ast_tree(code.format(bad_name))
3837

3938
visiter = WrongNameVisitor()
4039
visiter.visit(tree)
4140

42-
assert_errors(visiter, [error])
41+
assert_errors(visiter, [WrongVariableNameViolation])
4342

4443

4544
@pytest.mark.parametrize('short_name', string.ascii_letters)
46-
@pytest.mark.parametrize('code,error', [
47-
(static_attribute, TooShortVariableNameViolation),
48-
(instance_attribute, TooShortAttributeNameViolation),
45+
@pytest.mark.parametrize('code', [
46+
static_attribute,
47+
instance_attribute,
4948
])
5049
def test_too_short_attribute_names(
51-
assert_errors, parse_ast_tree, short_name, code, error,
50+
assert_errors, parse_ast_tree, short_name, code,
5251
):
5352
"""Testing that attribute can not have too short names."""
5453
tree = parse_ast_tree(code.format(short_name))
5554

5655
visiter = WrongNameVisitor()
5756
visiter.visit(tree)
5857

59-
assert_errors(visiter, [error])
58+
assert_errors(visiter, [TooShortVariableNameViolation])
59+
60+
61+
@pytest.mark.parametrize('code', [
62+
static_attribute,
63+
instance_attribute,
64+
])
65+
def test_private_attribute_names(
66+
assert_errors, parse_ast_tree, code,
67+
):
68+
"""Testing that attribute can not have private names."""
69+
tree = parse_ast_tree(code.format('__private_name'))
70+
71+
visiter = WrongNameVisitor()
72+
visiter.visit(tree)
73+
74+
assert_errors(visiter, [PrivateNameViolation])
6075

6176

6277
@pytest.mark.parametrize('correct_name', [
6378
'correct_name',
6479
'xy',
6580
'test1',
66-
'__private',
6781
'_protected',
82+
'__magic__',
6883
])
6984
@pytest.mark.parametrize('code', [
7085
static_attribute,

tests/test_visitors/test_wrong_name/test_function_args_names.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77
from wemake_python_styleguide.visitors.wrong_name import (
88
BAD_VARIABLE_NAMES,
9-
TooShortArgumentNameViolation,
10-
WrongArgumentNameViolation,
9+
PrivateNameViolation,
10+
TooShortVariableNameViolation,
1111
WrongNameVisitor,
12+
WrongVariableNameViolation,
1213
)
1314

1415
function_test = """
@@ -58,8 +59,8 @@ def test_wrong_function_arguments(
5859
visiter.visit(tree)
5960

6061
assert_errors(visiter, [
61-
TooShortArgumentNameViolation,
62-
WrongArgumentNameViolation,
62+
TooShortVariableNameViolation,
63+
WrongVariableNameViolation,
6364
])
6465

6566

@@ -82,8 +83,31 @@ def test_too_short_function_arguments(
8283
visiter.visit(tree)
8384

8485
assert_errors(visiter, [
85-
TooShortArgumentNameViolation,
86-
WrongArgumentNameViolation,
86+
TooShortVariableNameViolation,
87+
WrongVariableNameViolation,
88+
])
89+
90+
91+
@pytest.mark.parametrize('code', [
92+
function_test,
93+
method_test,
94+
function_kwargs_test,
95+
method_kwargs_test,
96+
function_args_kwargs_test,
97+
method_args_kwargs_test,
98+
])
99+
def test_private_function_arguments(
100+
assert_errors, parse_ast_tree, code,
101+
):
102+
"""Testing that function can not have private arguments."""
103+
tree = parse_ast_tree(code.format('__private', '__name'))
104+
105+
visiter = WrongNameVisitor()
106+
visiter.visit(tree)
107+
108+
assert_errors(visiter, [
109+
PrivateNameViolation,
110+
PrivateNameViolation,
87111
])
88112

89113

tests/test_visitors/test_wrong_name/test_function_names.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77
from wemake_python_styleguide.visitors.wrong_name import (
88
BAD_VARIABLE_NAMES,
9-
TooShortFunctionNameViolation,
10-
WrongFunctionNameViolation,
9+
PrivateNameViolation,
10+
TooShortVariableNameViolation,
1111
WrongNameVisitor,
12+
WrongVariableNameViolation,
1213
)
1314

1415
function_bad_name = """
@@ -35,7 +36,7 @@ def test_wrong_function_names(
3536
visiter = WrongNameVisitor()
3637
visiter.visit(tree)
3738

38-
assert_errors(visiter, [WrongFunctionNameViolation])
39+
assert_errors(visiter, [WrongVariableNameViolation])
3940

4041

4142
@pytest.mark.parametrize('short_name', string.ascii_letters)
@@ -52,10 +53,32 @@ def test_too_short_function_names(
5253
visiter = WrongNameVisitor()
5354
visiter.visit(tree)
5455

55-
assert_errors(visiter, [TooShortFunctionNameViolation])
56+
assert_errors(visiter, [TooShortVariableNameViolation])
5657

5758

58-
@pytest.mark.parametrize('correct_name', ['my_function', 'xy', 'test'])
59+
@pytest.mark.parametrize('code', [
60+
function_bad_name,
61+
method_bad_name,
62+
])
63+
def test_private_function_names(
64+
assert_errors, parse_ast_tree, code,
65+
):
66+
"""Testing that function can not have too short names."""
67+
tree = parse_ast_tree(code.format('__hidden'))
68+
69+
visiter = WrongNameVisitor()
70+
visiter.visit(tree)
71+
72+
assert_errors(visiter, [PrivateNameViolation])
73+
74+
75+
@pytest.mark.parametrize('correct_name', [
76+
'my_function',
77+
'xy',
78+
'test',
79+
'_protected',
80+
'__magic__',
81+
])
5982
@pytest.mark.parametrize('code', [
6083
function_bad_name,
6184
method_bad_name,

0 commit comments

Comments
 (0)