Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions easybuild/framework/easyconfig/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,25 @@

EB_CHECK = '_eb_check_'

COMMENT_REGEX = re.compile(r'^\s*#')
PARAM_DEF_REGEX = re.compile(r"^(?P<key>[a-z_]+)\s*=\s*")

# any function starting with _eb_check_ (see EB_CHECK variable) will be

# Any function starting with _eb_check_ (see EB_CHECK variable) will be
# added to the tests if the test number is added to the select list.
#
# Note: only functions that have a first argument named 'physical_line' or 'logical_line'
# will actually be used!
#
# The test number is definied as WXXX and EXXX (for warnings and errors)
# where XXX is a 3 digit number.
#
# It should be mentioned in the docstring as a single word.
# Read the pep8 docs to understand the arguments of these functions:
# https://pep8.readthedocs.org or more specifically:
# https://pep8.readthedocs.org/en/latest/developer.html#contribute
def _eb_check_trailing_whitespace(physical_line, lines, line_number, total_lines): # pylint:disable=unused-argument

def _eb_check_trailing_whitespace(physical_line, lines, line_number, checker_state): # pylint:disable=unused-argument
"""
W299
Warn about trailing whitespace, except for the description and comments.
Expand All @@ -62,27 +70,25 @@ def _eb_check_trailing_whitespace(physical_line, lines, line_number, total_lines
The arguments are explained at
https://pep8.readthedocs.org/en/latest/developer.html#contribute
"""
comment_re = re.compile(r'^\s*#')
if comment_re.match(physical_line):
# apparently this is not the same as physical_line line?!
line = lines[line_number-1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why switch?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because apparently this is not the same as physical_line... I noticed that for the description = line, only the part after the = was included in physical_line...


if COMMENT_REGEX.match(line):
return None

result = pep8.trailing_whitespace(physical_line)
result = pep8.trailing_whitespace(line)
if result:
result = (result[0], result[1].replace("W291", "W299"))
result = (result[0], result[1].replace('W291', 'W299'))

# keep track of name of last parameter that was defined
param_def = PARAM_DEF_REGEX.search(line)
if param_def:
checker_state['eb_last_key'] = param_def.group('key')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is nice!


# if the warning is about the multiline string of description
# we will not issue a warning
keys_re = re.compile(r"^(?P<key>[a-z_]+)\s*=\s*")

# starting from the current line and going to the top,
# check that if the first `key = value` that is found, has
# key == description, then let the test pass, else return
# the result of the general pep8 check.
for line in reversed(lines[:line_number]):
res = keys_re.match(line)
if res and res.group("key") == "description":
result = None
break
if checker_state.get('eb_last_key') == 'description':
result = None

return result

Expand Down Expand Up @@ -112,7 +118,7 @@ def check_easyconfigs_style(easyconfigs, verbose=False):
# on a line: the default of 79 is too narrow.
options.max_line_length = 120
# we ignore some tests
# note that W291 has be replaced by our custom W299
# note that W291 has been replaced by our custom W299
options.ignore = (
'W291', # replaced by W299
)
Expand Down
30 changes: 29 additions & 1 deletion test/framework/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered
from unittest import TextTestRunner
from vsc.utils import fancylogger
from easybuild.framework.easyconfig.style import check_easyconfigs_style
from easybuild.framework.easyconfig.style import _eb_check_trailing_whitespace, check_easyconfigs_style

try:
import pep8
Expand All @@ -60,6 +60,34 @@ def test_style_conformance(self):

self.assertEqual(result, 0, "No code style errors (and/or warnings) found.")

def test_check_trailing_whitespace(self):
"""Test for trailing whitespace check."""
lines = [
"name = 'foo'", # no trailing whitespace
"version = '1.2.3' ", # trailing whitespace
" ", # blank line with whitespace included
'''description = """start of long description, ''', # trailing whitespace, but allowed in description
''' continuation of long description ''', # trailing whitespace, but allowed in continued description
''' end of long description"""''',
"moduleclass = 'tools' ", # trailing whitespace
'',
]
line_numbers = range(1, len(lines) + 1)
state = {}
test_cases = [
None,
(17, "W299 trailing whitespace"),
(0, "W293 blank line contains whitespace"),
None,
None,
None,
(21, "W299 trailing whitespace"),
]

for (line, line_number, expected_result) in zip(lines, line_numbers, test_cases):
result = _eb_check_trailing_whitespace(line, lines, line_number, state)
self.assertEqual(result, expected_result)


def suite():
"""Return all style tests for easyconfigs."""
Expand Down