From d16e566143e2737a97a72a61bb30daa9a9033ea5 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 6 Jan 2020 23:14:24 +0200 Subject: [PATCH 01/69] CI: Unify tests cases --- ci/code_checks.sh | 4 +- scripts/validate_string_concatenation.py | 129 ------------ scripts/validate_unwanted_patterns.py | 256 +++++++++++++++++++++++ 3 files changed, 258 insertions(+), 131 deletions(-) delete mode 100755 scripts/validate_string_concatenation.py create mode 100755 scripts/validate_unwanted_patterns.py diff --git a/ci/code_checks.sh b/ci/code_checks.sh index a90774d2e8ff1..1eaae74f488ca 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -102,9 +102,9 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for use of not concatenated strings' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_string_concatenation.py --format="[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_unwanted_patterns.py --id="STC" --format="[error]{source_path}:{line_number}:{msg}" . else - $BASE_DIR/scripts/validate_string_concatenation.py . + $BASE_DIR/scripts/validate_unwanted_patterns.py --id="STC" . fi RET=$(($RET + $?)) ; echo $MSG "DONE" diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py deleted file mode 100755 index 3feeddaabe8d2..0000000000000 --- a/scripts/validate_string_concatenation.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env python -""" -GH #30454 - -Check where there is a string that needs to be concatenated. - -This is necessary after black formating, -where for example black transforms this: - ->>> foo = ( -... "bar " -... "baz" -... ) - -into this: - ->>> foo = ("bar " "baz") - -Black is not considering this as an -issue (see issue https://github.com/psf/black/issues/1051), -so we are checking it here. -""" - -import argparse -import os -import sys -import token -import tokenize -from typing import Generator, List, Tuple - -FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") - - -def main(source_path: str, output_format: str) -> bool: - """ - Main entry point of the script. - - Parameters - ---------- - source_path : str - Source path representing path to a file/directory. - output_format : str - Output format of the script. - - Returns - ------- - bool - True if found any strings that needs to be concatenated. - - Raises - ------ - ValueError - If the `source_path` is not pointing to existing file/directory. - """ - if not os.path.exists(source_path): - raise ValueError( - "Please enter a valid path, pointing to a valid file/directory." - ) - - is_failed: bool = False - - msg = "String unnecessarily split in two by black. Please merge them manually." - - if os.path.isfile(source_path): - for source_path, line_number in strings_to_concatenate(source_path): - is_failed = True - print( - output_format.format( - source_path=source_path, line_number=line_number, msg=msg - ) - ) - - for subdir, _, files in os.walk(source_path): - for file_name in files: - if any( - file_name.endswith(extension) for extension in FILE_EXTENSIONS_TO_CHECK - ): - for source_path, line_number in strings_to_concatenate( - os.path.join(subdir, file_name) - ): - is_failed = True - print( - output_format.format( - source_path=source_path, line_number=line_number, msg=msg - ) - ) - return is_failed - - -def strings_to_concatenate(source_path: str) -> Generator[Tuple[str, int], None, None]: - """ - Yielding the strings that needs to be concatenated in a given file. - - Parameters - ---------- - source_path : str - File path pointing to a single file. - - Yields - ------ - source_path : str - Source file path. - line_number : int - Line number of unconcatenated string. - """ - with open(source_path, "r") as file_name: - tokens: List = list(tokenize.generate_tokens(file_name.readline)) - - for current_token, next_token in zip(tokens, tokens[1:]): - if current_token[0] == next_token[0] == token.STRING: - yield source_path, current_token[2][0] - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Validate concatenated strings") - - parser.add_argument( - "path", nargs="?", default=".", help="Source path of file/directory to check." - ) - parser.add_argument( - "--format", - "-f", - default="{source_path}:{line_number}:{msg}", - help="Output format of the unconcatenated strings.", - ) - - args = parser.parse_args() - - sys.exit(main(source_path=args.path, output_format=args.format)) diff --git a/scripts/validate_unwanted_patterns.py b/scripts/validate_unwanted_patterns.py new file mode 100755 index 0000000000000..0b4ed8c28256f --- /dev/null +++ b/scripts/validate_unwanted_patterns.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python +""" +Unwanted patterns test cases. +""" + +import argparse +import os +import sys +import token +import tokenize +from typing import Callable, Generator, List, Tuple + +FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") + + +def main( + function: Callable[[str], Generator[Tuple[str, int, str], None, None]], + source_path: str, + output_format: str, +) -> bool: + """ + Main entry point of the script. + + Parameters + ---------- + function : Callable + Function to execute for the test case. + source_path : str + Source path representing path to a file/directory. + output_format : str + Output format of the error message. + + Returns + ------- + bool + True if found any patterns are found related to the given function. + + Raises + ------ + ValueError + If the `source_path` is not pointing to existing file/directory. + """ + if not os.path.exists(source_path): + raise ValueError( + "Please enter a valid path, pointing to a valid file/directory." + ) + + is_failed: bool = False + + if os.path.isfile(source_path): + for source_path, line_number, msg in function(source_path): + is_failed = True + print( + output_format.format( + source_path=source_path, line_number=line_number, msg=msg + ) + ) + + for subdir, _, files in os.walk(source_path): + for file_name in files: + if any( + file_name.endswith(extension) for extension in FILE_EXTENSIONS_TO_CHECK + ): + for source_path, line_number, msg in function( + os.path.join(subdir, file_name) + ): + is_failed = True + print( + output_format.format( + source_path=source_path, line_number=line_number, msg=msg + ) + ) + return is_failed + + +def STC(source_path: str) -> Generator[Tuple[str, int, str], None, None]: + """ + Strings To Concatenate. + + This test case is necessary after 'Black' (https://github.com/psf/black), + is formating strings over multiple lines. + + For example, when this: + + >>> foo = ( + ... "bar " + ... "baz" + ... ) + + Is becoming this: + + >>> foo = ("bar " "baz") + + 'Black' is not considering this as an + issue (see https://github.com/psf/black/issues/1051), + so we are checking it here instead. + + Parameters + ---------- + source_path : str + File path pointing to a single file. + + Yields + ------ + source_path : str + Source file path. + line_number : int + Line number of unconcatenated string. + MSG : str + Explenation of the error. + + Notes + ----- + GH #30454 + """ + MSG: str = ( + "String unnecessarily split in two by black. Please merge them manually." + ) + + with open(source_path, "r") as file_name: + tokens: List = list(tokenize.generate_tokens(file_name.readline)) + + for current_token, next_token in zip(tokens, tokens[1:]): + if current_token[0] == next_token[0] == token.STRING: + yield source_path, current_token[2][0], MSG + + +def SWWPS(source_path: str) -> Generator[Tuple[str, int, str], None, None]: + """ + Strings With Wrong Placed Space. + + Test case for leading spaces in concated strings. + + For example: + + >>> foo = ( + ... "bar " + ... "baz" + ... ) + + Instead of: + + >>> foo = ( + ... "bar" + ... " baz" + ... ) + + Parameters + ---------- + source_path : str + File path pointing to a single file. + + Yields + ------ + source_path : str + Source file path. + line_number : int + Line number of unconcatenated string. + MSG : str + Explenation of the error. + """ + MSG: str = ( + "String has a space at the beginning " + "instead of the end of the previous string." + ) + with open(source_path, "r") as file_name: + tokens: List = list(tokenize.generate_tokens(file_name.readline)) + + for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]): + if ( + first_token[0] == third_token[0] == token.STRING + and second_token[0] == token.NL + ): + # Means we are in a block of concated string + + # Striping the quotes + first_string = first_token[1][1:-1] + second_string = third_token[1][1:-1] + + if (not first_string.endswith(" ")) and (second_string.startswith(" ")): + yield source_path, third_token[2][0], MSG + + +def BPR(source_path: str) -> Generator[Tuple[str, int, str], None, None]: + """ + Test Case for bare pytest raise. + + For example: + + >>> with pytest.raise(ValueError): + ... # Some code that raises ValueError + + Instead of: + + >>> with pytest.raise(ValueError, match="foo"): + ... # Some code that raises ValueError + + Parameters + ---------- + source_path : str + File path pointing to a single file. + + Yields + ------ + source_path : str + Source file path. + line_number : int + Line number of unconcatenated string. + MSG : str + Explenation of the error. + + Notes + ----- + GH #23922 + """ + MSG: str = "Bare pytests raise have been found." + with open(source_path, "r") as file_name: + tokens: List = list(tokenize.generate_tokens(file_name.readline)) + + for counter, current_token in enumerate(tokens, start=1): + if current_token[0] == token.NAME and current_token[1] == "raises": + for next_token in tokens[counter:]: + if next_token[0] == token.NAME and next_token[1] == "match": + break + if next_token[0] == token.NEWLINE: + yield source_path, current_token[2][0], MSG + break + + +if __name__ == "__main__": + FUNCTIONS_MAP = {"STC": STC, "SWWPS": SWWPS, "BPR": BPR} + + parser = argparse.ArgumentParser(description="Unwanted patterns checker.") + + parser.add_argument( + "path", nargs="?", default=".", help="Source path of file/directory to check." + ) + parser.add_argument( + "--format", + "-f", + default="{source_path}:{line_number}:{msg}.", + help="Output format of the error message.", + ) + parser.add_argument( + "--id", "-i", choices=FUNCTIONS_MAP.keys(), help="Test case to check." + ) + + args = parser.parse_args() + + sys.exit( + main( + function=FUNCTIONS_MAP[args.id], + source_path=args.path, + output_format=args.format, + ) + ) From 6e6bb6686a8df9a6e90a8a305df5cad9ef73b754 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 01:40:04 +0200 Subject: [PATCH 02/69] Changed functions name --- scripts/validate_unwanted_patterns.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/scripts/validate_unwanted_patterns.py b/scripts/validate_unwanted_patterns.py index 0b4ed8c28256f..77b0b956f034a 100755 --- a/scripts/validate_unwanted_patterns.py +++ b/scripts/validate_unwanted_patterns.py @@ -73,10 +73,10 @@ def main( return is_failed -def STC(source_path: str) -> Generator[Tuple[str, int, str], None, None]: +def strings_to_concatenate( + source_path: str, +) -> Generator[Tuple[str, int, str], None, None]: """ - Strings To Concatenate. - This test case is necessary after 'Black' (https://github.com/psf/black), is formating strings over multiple lines. @@ -125,10 +125,10 @@ def STC(source_path: str) -> Generator[Tuple[str, int, str], None, None]: yield source_path, current_token[2][0], MSG -def SWWPS(source_path: str) -> Generator[Tuple[str, int, str], None, None]: +def strings_with_wrong_placed_space( + source_path: str, +) -> Generator[Tuple[str, int, str], None, None]: """ - Strings With Wrong Placed Space. - Test case for leading spaces in concated strings. For example: @@ -181,9 +181,9 @@ def SWWPS(source_path: str) -> Generator[Tuple[str, int, str], None, None]: yield source_path, third_token[2][0], MSG -def BPR(source_path: str) -> Generator[Tuple[str, int, str], None, None]: +def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None, None]: """ - Test Case for bare pytest raise. + Test Case for bare pytest raises. For example: @@ -228,7 +228,11 @@ def BPR(source_path: str) -> Generator[Tuple[str, int, str], None, None]: if __name__ == "__main__": - FUNCTIONS_MAP = {"STC": STC, "SWWPS": SWWPS, "BPR": BPR} + FUNCTIONS_MAP = { + "STC": strings_to_concatenate, + "SWWPS": strings_with_wrong_placed_space, + "BPR": bare_pytest_raises, + } parser = argparse.ArgumentParser(description="Unwanted patterns checker.") From 48f3e86905295a46a510536e73ffbc2bae038a8d Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 16:51:34 +0200 Subject: [PATCH 03/69] Renamed file name, back to the original --- ci/code_checks.sh | 4 ++-- ..._unwanted_patterns.py => validate_string_concatenation.py} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename scripts/{validate_unwanted_patterns.py => validate_string_concatenation.py} (100%) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 1eaae74f488ca..4e8f4eb20a5a0 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -102,9 +102,9 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for use of not concatenated strings' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_unwanted_patterns.py --id="STC" --format="[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_string_concatenation --id="STC" --format="[error]{source_path}:{line_number}:{msg}" . else - $BASE_DIR/scripts/validate_unwanted_patterns.py --id="STC" . + $BASE_DIR/scripts/validate_string_concatenation --id="STC" . fi RET=$(($RET + $?)) ; echo $MSG "DONE" diff --git a/scripts/validate_unwanted_patterns.py b/scripts/validate_string_concatenation.py similarity index 100% rename from scripts/validate_unwanted_patterns.py rename to scripts/validate_string_concatenation.py From 2e249a8e799c9028d0d11b68ebf3e451d7d977d6 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 17:03:43 +0200 Subject: [PATCH 04/69] STY: inconsistent linebreaks --- scripts/validate_string_concatenation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 77b0b956f034a..fe11cd91521b7 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -163,6 +163,7 @@ def strings_with_wrong_placed_space( "String has a space at the beginning " "instead of the end of the previous string." ) + with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) @@ -214,6 +215,7 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None GH #23922 """ MSG: str = "Bare pytests raise have been found." + with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) From 4ec704c6802c6847389525d5b676fbe05944c5f9 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 17:07:42 +0200 Subject: [PATCH 05/69] Made the code check "ID" to be more verbose as @datapythonista suggested in https://github.com/pandas-dev/pandas/pull/30755#issuecomment-571533520 --- ci/code_checks.sh | 4 ++-- scripts/validate_string_concatenation.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 4e8f4eb20a5a0..9abd6f918184b 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -102,9 +102,9 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for use of not concatenated strings' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_string_concatenation --id="STC" --format="[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_string_concatenation --id="strings_to_concatenate" --format="[error]{source_path}:{line_number}:{msg}" . else - $BASE_DIR/scripts/validate_string_concatenation --id="STC" . + $BASE_DIR/scripts/validate_string_concatenation --id="strings_to_concatenate" . fi RET=$(($RET + $?)) ; echo $MSG "DONE" diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index fe11cd91521b7..220dad645ff79 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -231,9 +231,9 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None if __name__ == "__main__": FUNCTIONS_MAP = { - "STC": strings_to_concatenate, - "SWWPS": strings_with_wrong_placed_space, - "BPR": bare_pytest_raises, + "strings_to_concatenate": strings_to_concatenate, + "strings_with_wrong_placed_space": strings_with_wrong_placed_space, + "bare_pytest_raises": bare_pytest_raises, } parser = argparse.ArgumentParser(description="Unwanted patterns checker.") From 8b2f603af47423e148d903fbc94f9ef154a7ba70 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 17:21:22 +0200 Subject: [PATCH 06/69] Added ".py" in ci/code_check.sh to the script call --- ci/code_checks.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 9abd6f918184b..8987458690304 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -102,9 +102,9 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for use of not concatenated strings' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_string_concatenation --id="strings_to_concatenate" --format="[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_string_concatenation.py --id="strings_to_concatenate" --format="[error]{source_path}:{line_number}:{msg}" . else - $BASE_DIR/scripts/validate_string_concatenation --id="strings_to_concatenate" . + $BASE_DIR/scripts/validate_string_concatenation.py --id="strings_to_concatenate" . fi RET=$(($RET + $?)) ; echo $MSG "DONE" From bb5b9051357f07caf117a056f2ca38bc90202149 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 20:28:15 +0200 Subject: [PATCH 07/69] Replaced the dictonary with 'globals()' --- scripts/validate_string_concatenation.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 220dad645ff79..a49d45c585d7c 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -230,11 +230,11 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None if __name__ == "__main__": - FUNCTIONS_MAP = { - "strings_to_concatenate": strings_to_concatenate, - "strings_with_wrong_placed_space": strings_with_wrong_placed_space, - "bare_pytest_raises": bare_pytest_raises, - } + available_tests = [ + f.__name__ + for f in globals().values() + if type(f) == type(main) and f.__name__ != "main" + ] parser = argparse.ArgumentParser(description="Unwanted patterns checker.") @@ -248,14 +248,14 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None help="Output format of the error message.", ) parser.add_argument( - "--id", "-i", choices=FUNCTIONS_MAP.keys(), help="Test case to check." + "--id", "-i", choices=available_tests, help="Test case to check." ) args = parser.parse_args() sys.exit( main( - function=FUNCTIONS_MAP[args.id], + function=globals().get(args.id), source_path=args.path, output_format=args.format, ) From 22251759a9d050d110aa5590b90ec6c3a689603c Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 20:41:59 +0200 Subject: [PATCH 08/69] Changed from "id" to "validation-type" --- ci/code_checks.sh | 4 ++-- scripts/validate_string_concatenation.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 8987458690304..3570453606e05 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -102,9 +102,9 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for use of not concatenated strings' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_string_concatenation.py --id="strings_to_concatenate" --format="[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_to_concatenate" --format="[error]{source_path}:{line_number}:{msg}" . else - $BASE_DIR/scripts/validate_string_concatenation.py --id="strings_to_concatenate" . + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_to_concatenate" . fi RET=$(($RET + $?)) ; echo $MSG "DONE" diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index a49d45c585d7c..fbee96d65a376 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -230,7 +230,7 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None if __name__ == "__main__": - available_tests = [ + available_validation_types = [ f.__name__ for f in globals().values() if type(f) == type(main) and f.__name__ != "main" @@ -248,14 +248,17 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None help="Output format of the error message.", ) parser.add_argument( - "--id", "-i", choices=available_tests, help="Test case to check." + "--validation-type", + "-vt", + choices=available_validation_types, + help="Validation test case to check.", ) args = parser.parse_args() sys.exit( main( - function=globals().get(args.id), + function=globals().get(args.validation_type), source_path=args.path, output_format=args.format, ) From a2b60c5ecbf4b5b8183bce20d35153902ac197f1 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 20:47:05 +0200 Subject: [PATCH 09/69] Better explained (I hope) why this file exists --- scripts/validate_string_concatenation.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index fbee96d65a376..b75953ba9c38e 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -1,6 +1,13 @@ #!/usr/bin/env python """ Unwanted patterns test cases. + +The reason this file exist despite the fact we already have +`ci/code_checks.sh`, +(see https://github.com/pandas-dev/pandas/blob/master/ci/code_checks.sh) + +is that some of the test cases are more complex/imposible to validate via regex. +So this file is somewhat an extensions to `ci/code_checks.sh` """ import argparse From 590ca48c5617f67c08156911fa96d633e6e8b14f Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 20:56:20 +0200 Subject: [PATCH 10/69] Yielding the string directly instead of assigning it to a variable --- scripts/validate_string_concatenation.py | 35 ++++++++++++++---------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index b75953ba9c38e..ff1ad8c87203f 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -120,16 +120,19 @@ def strings_to_concatenate( ----- GH #30454 """ - MSG: str = ( - "String unnecessarily split in two by black. Please merge them manually." - ) - with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) for current_token, next_token in zip(tokens, tokens[1:]): if current_token[0] == next_token[0] == token.STRING: - yield source_path, current_token[2][0], MSG + yield ( + source_path, + current_token[2][0], + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ) def strings_with_wrong_placed_space( @@ -166,11 +169,6 @@ def strings_with_wrong_placed_space( MSG : str Explenation of the error. """ - MSG: str = ( - "String has a space at the beginning " - "instead of the end of the previous string." - ) - with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) @@ -186,7 +184,14 @@ def strings_with_wrong_placed_space( second_string = third_token[1][1:-1] if (not first_string.endswith(" ")) and (second_string.startswith(" ")): - yield source_path, third_token[2][0], MSG + yield ( + source_path, + third_token[2][0], + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None, None]: @@ -221,8 +226,6 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None ----- GH #23922 """ - MSG: str = "Bare pytests raise have been found." - with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) @@ -232,7 +235,11 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None if next_token[0] == token.NAME and next_token[1] == "match": break if next_token[0] == token.NEWLINE: - yield source_path, current_token[2][0], MSG + yield ( + source_path, + current_token[2][0], + "Bare pytests raise have been found.", + ) break From ef00c686bffe2c05f37e7d8d6c43a20d296fa93b Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 20:58:40 +0200 Subject: [PATCH 11/69] Fixed indentation in docs --- scripts/validate_string_concatenation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index ff1ad8c87203f..25ff2e2441cf7 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -90,8 +90,8 @@ def strings_to_concatenate( For example, when this: >>> foo = ( - ... "bar " - ... "baz" + ... "bar " + ... "baz" ... ) Is becoming this: @@ -151,8 +151,8 @@ def strings_with_wrong_placed_space( Instead of: >>> foo = ( - ... "bar" - ... " baz" + ... "bar" + ... " baz" ... ) Parameters From 9341623560f56ca1034e461a20a299655f566465 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 21:36:23 +0200 Subject: [PATCH 12/69] Imporved docstring for spaces test case, as datapythonista suggested --- scripts/validate_string_concatenation.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 25ff2e2441cf7..c4baa1c23343d 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -143,16 +143,16 @@ def strings_with_wrong_placed_space( For example: - >>> foo = ( - ... "bar " - ... "baz" + >>> rule = ( + ... "We want the space at the end of the line, " + ... "not at the beginning" ... ) Instead of: - >>> foo = ( - ... "bar" - ... " baz" + >>> rule = ( + ... "We want the space at the end of the line," + ... " not at the beginning" ... ) Parameters From c0f800d15b67a71d5fdc735b520b07e8c9371334 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 21:37:22 +0200 Subject: [PATCH 13/69] Removed uppercase "MSG" from docs and replaced it with lowercase "msg" --- scripts/validate_string_concatenation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index c4baa1c23343d..3a5d45e9d7b54 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -113,7 +113,7 @@ def strings_to_concatenate( Source file path. line_number : int Line number of unconcatenated string. - MSG : str + msg : str Explenation of the error. Notes @@ -166,7 +166,7 @@ def strings_with_wrong_placed_space( Source file path. line_number : int Line number of unconcatenated string. - MSG : str + msg : str Explenation of the error. """ with open(source_path, "r") as file_name: @@ -219,7 +219,7 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None Source file path. line_number : int Line number of unconcatenated string. - MSG : str + msg : str Explenation of the error. Notes From 63b39dda4e54ac027c2c501fdc881c79a1a13c05 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 21:38:56 +0200 Subject: [PATCH 14/69] Fixed comment placement --- scripts/validate_string_concatenation.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 3a5d45e9d7b54..27f99f3a410eb 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -173,12 +173,11 @@ def strings_with_wrong_placed_space( tokens: List = list(tokenize.generate_tokens(file_name.readline)) for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]): + # Checking if we are in a block of concated string if ( first_token[0] == third_token[0] == token.STRING and second_token[0] == token.NL ): - # Means we are in a block of concated string - # Striping the quotes first_string = first_token[1][1:-1] second_string = third_token[1][1:-1] From 2b61e53c385918ba02fd540234834d30571c7a5d Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 21:41:13 +0200 Subject: [PATCH 15/69] Applied datapythonista suggestions --- scripts/validate_string_concatenation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 27f99f3a410eb..285e09c2eb4ef 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -197,12 +197,12 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None """ Test Case for bare pytest raises. - For example: + For example, this is wrong: >>> with pytest.raise(ValueError): ... # Some code that raises ValueError - Instead of: + And this is what we want instead: >>> with pytest.raise(ValueError, match="foo"): ... # Some code that raises ValueError From e18efbb277c09cddb9970ae33ac5b401a1662e90 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 8 Jan 2020 21:42:44 +0200 Subject: [PATCH 16/69] Moved "main" function to the bottom (Above 'if __name__ == "__main__"') --- scripts/validate_string_concatenation.py | 120 +++++++++++------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 285e09c2eb4ef..2c5591da5667f 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -20,66 +20,6 @@ FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") -def main( - function: Callable[[str], Generator[Tuple[str, int, str], None, None]], - source_path: str, - output_format: str, -) -> bool: - """ - Main entry point of the script. - - Parameters - ---------- - function : Callable - Function to execute for the test case. - source_path : str - Source path representing path to a file/directory. - output_format : str - Output format of the error message. - - Returns - ------- - bool - True if found any patterns are found related to the given function. - - Raises - ------ - ValueError - If the `source_path` is not pointing to existing file/directory. - """ - if not os.path.exists(source_path): - raise ValueError( - "Please enter a valid path, pointing to a valid file/directory." - ) - - is_failed: bool = False - - if os.path.isfile(source_path): - for source_path, line_number, msg in function(source_path): - is_failed = True - print( - output_format.format( - source_path=source_path, line_number=line_number, msg=msg - ) - ) - - for subdir, _, files in os.walk(source_path): - for file_name in files: - if any( - file_name.endswith(extension) for extension in FILE_EXTENSIONS_TO_CHECK - ): - for source_path, line_number, msg in function( - os.path.join(subdir, file_name) - ): - is_failed = True - print( - output_format.format( - source_path=source_path, line_number=line_number, msg=msg - ) - ) - return is_failed - - def strings_to_concatenate( source_path: str, ) -> Generator[Tuple[str, int, str], None, None]: @@ -242,6 +182,66 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None break +def main( + function: Callable[[str], Generator[Tuple[str, int, str], None, None]], + source_path: str, + output_format: str, +) -> bool: + """ + Main entry point of the script. + + Parameters + ---------- + function : Callable + Function to execute for the test case. + source_path : str + Source path representing path to a file/directory. + output_format : str + Output format of the error message. + + Returns + ------- + bool + True if found any patterns are found related to the given function. + + Raises + ------ + ValueError + If the `source_path` is not pointing to existing file/directory. + """ + if not os.path.exists(source_path): + raise ValueError( + "Please enter a valid path, pointing to a valid file/directory." + ) + + is_failed: bool = False + + if os.path.isfile(source_path): + for source_path, line_number, msg in function(source_path): + is_failed = True + print( + output_format.format( + source_path=source_path, line_number=line_number, msg=msg + ) + ) + + for subdir, _, files in os.walk(source_path): + for file_name in files: + if any( + file_name.endswith(extension) for extension in FILE_EXTENSIONS_TO_CHECK + ): + for source_path, line_number, msg in function( + os.path.join(subdir, file_name) + ): + is_failed = True + print( + output_format.format( + source_path=source_path, line_number=line_number, msg=msg + ) + ) + return is_failed + + if __name__ == "__main__": available_validation_types = [ f.__name__ From b60f5ee63857211f59f6966090a4f786bee709ed Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 9 Jan 2020 01:38:42 +0200 Subject: [PATCH 17/69] Imporved test case in 'strings_with_wrong_placed_space' validation type --- scripts/validate_string_concatenation.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 2c5591da5667f..38c5310535ef0 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -122,7 +122,9 @@ def strings_with_wrong_placed_space( first_string = first_token[1][1:-1] second_string = third_token[1][1:-1] - if (not first_string.endswith(" ")) and (second_string.startswith(" ")): + if ((not first_string.endswith(" ")) and second_string.startswith(" ")) and ( + not second_string.startswith(" ") + ): yield ( source_path, third_token[2][0], From a4ec49ee2022319eaac9602be61d4e40eabf105e Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 9 Jan 2020 02:25:28 +0200 Subject: [PATCH 18/69] Added more logic to 'strings_with_wrong_placed_space' --- scripts/validate_string_concatenation.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 38c5310535ef0..607a45139d65a 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -122,9 +122,16 @@ def strings_with_wrong_placed_space( first_string = first_token[1][1:-1] second_string = third_token[1][1:-1] - if ((not first_string.endswith(" ")) and second_string.startswith(" ")) and ( - not second_string.startswith(" ") - ): + is_first_ends_single: bool = first_string.endswith(" ") + is_first_ends_newline: bool = first_string.endswith("\n") + is_second_starts_single: bool = second_string.startswith(" ") + is_second_starts_double: bool = second_string.startswith(" ") + + if ( + (not is_first_ends_single) + and is_second_starts_single + and (not is_second_starts_double) + ) and (not is_first_ends_newline): yield ( source_path, third_token[2][0], From 8dccf052ac44be37f4c9dd264c9b613e1dc7982a Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:16:55 +0200 Subject: [PATCH 19/69] Added some typings --- scripts/validate_string_concatenation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 607a45139d65a..a2501afb77e4d 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -119,8 +119,8 @@ def strings_with_wrong_placed_space( and second_token[0] == token.NL ): # Striping the quotes - first_string = first_token[1][1:-1] - second_string = third_token[1][1:-1] + first_string: str = first_token[1][1:-1] + second_string: str = third_token[1][1:-1] is_first_ends_single: bool = first_string.endswith(" ") is_first_ends_newline: bool = first_string.endswith("\n") @@ -252,7 +252,7 @@ def main( if __name__ == "__main__": - available_validation_types = [ + available_validation_types: List[str] = [ f.__name__ for f in globals().values() if type(f) == type(main) and f.__name__ != "main" From 84c71259bdd1cb5c97eb5b5b077ff5ead9d6dd09 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:21:03 +0200 Subject: [PATCH 20/69] Defining 'TYPE' as constant --- scripts/validate_string_concatenation.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index a2501afb77e4d..58e92668b89f1 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -18,6 +18,7 @@ from typing import Callable, Generator, List, Tuple FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") +TYPE: int = 0 def strings_to_concatenate( @@ -64,7 +65,7 @@ def strings_to_concatenate( tokens: List = list(tokenize.generate_tokens(file_name.readline)) for current_token, next_token in zip(tokens, tokens[1:]): - if current_token[0] == next_token[0] == token.STRING: + if current_token[TYPE] == next_token[TYPE] == token.STRING: yield ( source_path, current_token[2][0], @@ -115,7 +116,7 @@ def strings_with_wrong_placed_space( for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]): # Checking if we are in a block of concated string if ( - first_token[0] == third_token[0] == token.STRING + first_token[TYPE] == third_token[TYPE] == token.STRING and second_token[0] == token.NL ): # Striping the quotes @@ -178,11 +179,11 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None tokens: List = list(tokenize.generate_tokens(file_name.readline)) for counter, current_token in enumerate(tokens, start=1): - if current_token[0] == token.NAME and current_token[1] == "raises": + if current_token[TYPE] == token.NAME and current_token[1] == "raises": for next_token in tokens[counter:]: - if next_token[0] == token.NAME and next_token[1] == "match": + if next_token[TYPE] == token.NAME and next_token[1] == "match": break - if next_token[0] == token.NEWLINE: + if next_token[TYPE] == token.NEWLINE: yield ( source_path, current_token[2][0], From b623c2f81c7a638ce4dc054e217afd703e9f9e67 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:33:40 +0200 Subject: [PATCH 21/69] Added 'continue' for code block --- scripts/validate_string_concatenation.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 58e92668b89f1..453bdf6ab61df 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -179,17 +179,18 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None tokens: List = list(tokenize.generate_tokens(file_name.readline)) for counter, current_token in enumerate(tokens, start=1): - if current_token[TYPE] == token.NAME and current_token[1] == "raises": - for next_token in tokens[counter:]: - if next_token[TYPE] == token.NAME and next_token[1] == "match": - break - if next_token[TYPE] == token.NEWLINE: - yield ( - source_path, - current_token[2][0], - "Bare pytests raise have been found.", - ) - break + if not (current_token[TYPE] == token.NAME and current_token[1] == "raises"): + continue + for next_token in tokens[counter:]: + if next_token[TYPE] == token.NAME and next_token[1] == "match": + break + if next_token[TYPE] == token.NEWLINE: + yield ( + source_path, + current_token[2][0], + "Bare pytests raise have been found.", + ) + break def main( From 74c1abb27fd582c15bb26feafb79f59ee936bc8a Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:35:29 +0200 Subject: [PATCH 22/69] Added comment about token.NEWLINE --- scripts/validate_string_concatenation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 453bdf6ab61df..5f78a5c5fda21 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -184,6 +184,8 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None for next_token in tokens[counter:]: if next_token[TYPE] == token.NAME and next_token[1] == "match": break + # token.NEWLINE refers to end of a logical line + # unlike token.NL or "\n" which represents a newline if next_token[TYPE] == token.NEWLINE: yield ( source_path, From a1e18330dbc871e022df5eb118128db1640bba84 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:36:32 +0200 Subject: [PATCH 23/69] Applied datapythonsita code suggestion --- ci/code_checks.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index c8322b79690bd..6bd1d2f466e92 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -102,7 +102,7 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for use of not concatenated strings' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_to_concatenate" --format="[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_to_concatenate" --format="##[error]{source_path}:{line_number}:{msg}" . else $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_to_concatenate" . fi From 052102e3f3816a57972a34465e152488d056dbc6 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:40:17 +0200 Subject: [PATCH 24/69] Replaced available_validation_types with predefined list of available validation types --- scripts/validate_string_concatenation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 5f78a5c5fda21..55ba0a62083ff 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -257,9 +257,9 @@ def main( if __name__ == "__main__": available_validation_types: List[str] = [ - f.__name__ - for f in globals().values() - if type(f) == type(main) and f.__name__ != "main" + "strings_to_concatenate", + "strings_with_wrong_placed_space", + "bare_pytest_raises", ] parser = argparse.ArgumentParser(description="Unwanted patterns checker.") From b7849857822b76e90603b72fe9bac93a2909ea05 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:44:26 +0200 Subject: [PATCH 25/69] Make the validation type parameter to be required --- scripts/validate_string_concatenation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 55ba0a62083ff..2100327d56f63 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -277,6 +277,7 @@ def main( "--validation-type", "-vt", choices=available_validation_types, + required=True, help="Validation test case to check.", ) From 09ec060c1ba16d62c96aa947907f41fe43ef427f Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:49:38 +0200 Subject: [PATCH 26/69] Added 'VALUE' constant --- scripts/validate_string_concatenation.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 2100327d56f63..0357744031659 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -19,6 +19,7 @@ FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") TYPE: int = 0 +VALUE: int = 1 def strings_to_concatenate( @@ -179,10 +180,10 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None tokens: List = list(tokenize.generate_tokens(file_name.readline)) for counter, current_token in enumerate(tokens, start=1): - if not (current_token[TYPE] == token.NAME and current_token[1] == "raises"): + if not (current_token[TYPE] == token.NAME and current_token[VALUE] == "raises"): continue for next_token in tokens[counter:]: - if next_token[TYPE] == token.NAME and next_token[1] == "match": + if next_token[TYPE] == token.NAME and next_token[VALUE] == "match": break # token.NEWLINE refers to end of a logical line # unlike token.NL or "\n" which represents a newline From 479352601f0d45bceec0c5fcbc79ad32f8a42d79 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 17:57:43 +0200 Subject: [PATCH 27/69] Fixed grammer mistake (I think) --- scripts/validate_string_concatenation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 0357744031659..3ed3cc9f29848 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -185,7 +185,7 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None for next_token in tokens[counter:]: if next_token[TYPE] == token.NAME and next_token[VALUE] == "match": break - # token.NEWLINE refers to end of a logical line + # token.NEWLINE refers to the end of a logical line # unlike token.NL or "\n" which represents a newline if next_token[TYPE] == token.NEWLINE: yield ( From 60614c7bc505c3c45421f277852dc1a8fadef541 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 10 Jan 2020 19:53:16 +0200 Subject: [PATCH 28/69] Removed complex if statement, Replaced with a function --- scripts/validate_string_concatenation.py | 35 +++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 3ed3cc9f29848..e8152267c4645 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -111,6 +111,30 @@ def strings_with_wrong_placed_space( msg : str Explenation of the error. """ + + def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: + """ + Checking if the two lines are mattching the unwanted pattern. + + Parameters + ---------- + first_line : str + First line to check. + second_line : str + Second line to check. + + Returns + ------- + bool + True if the two recived string match, an unwanted pattern. + """ + return ( + (not first_line.endswith(" ")) + and second_line.startswith(" ") + and (not second_line.startswith(" ")) + and (not first_line.endswith("\n")) + ) or ((first_line.endswith(" ") and second_line.startswith(" "))) + with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) @@ -124,16 +148,7 @@ def strings_with_wrong_placed_space( first_string: str = first_token[1][1:-1] second_string: str = third_token[1][1:-1] - is_first_ends_single: bool = first_string.endswith(" ") - is_first_ends_newline: bool = first_string.endswith("\n") - is_second_starts_single: bool = second_string.startswith(" ") - is_second_starts_double: bool = second_string.startswith(" ") - - if ( - (not is_first_ends_single) - and is_second_starts_single - and (not is_second_starts_double) - ) and (not is_first_ends_newline): + if idk_how_to_call_this_function(first_string, second_string): yield ( source_path, third_token[2][0], From 39048883cc68df4467a6a2255feb6589c926f80d Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 12 Jan 2020 11:50:29 +0200 Subject: [PATCH 29/69] Removed useless parenthasis --- scripts/validate_string_concatenation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index e8152267c4645..8bbd9dbf28352 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -133,7 +133,7 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: and second_line.startswith(" ") and (not second_line.startswith(" ")) and (not first_line.endswith("\n")) - ) or ((first_line.endswith(" ") and second_line.startswith(" "))) + ) or (first_line.endswith(" ") and second_line.startswith(" ")) with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) From 48762f9e2756c16d8ab24dd24f971df684fce6b8 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 12 Jan 2020 12:01:43 +0200 Subject: [PATCH 30/69] Fix tests case for 'strings_with_wrong_placed_space' --- scripts/validate_string_concatenation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 8bbd9dbf28352..d81e1a19d77e6 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -132,7 +132,7 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: (not first_line.endswith(" ")) and second_line.startswith(" ") and (not second_line.startswith(" ")) - and (not first_line.endswith("\n")) + and (not first_line.endswith("\\n")) ) or (first_line.endswith(" ") and second_line.startswith(" ")) with open(source_path, "r") as file_name: From b1ac49e17b98c448277dfd81a186e90691ae26db Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 12 Jan 2020 13:35:33 +0200 Subject: [PATCH 31/69] Removed constants and replaced with values from the generated named tuple --- scripts/validate_string_concatenation.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index d81e1a19d77e6..d9d25e470230e 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -18,8 +18,6 @@ from typing import Callable, Generator, List, Tuple FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") -TYPE: int = 0 -VALUE: int = 1 def strings_to_concatenate( @@ -66,10 +64,10 @@ def strings_to_concatenate( tokens: List = list(tokenize.generate_tokens(file_name.readline)) for current_token, next_token in zip(tokens, tokens[1:]): - if current_token[TYPE] == next_token[TYPE] == token.STRING: + if current_token.type == next_token.type == token.STRING: yield ( source_path, - current_token[2][0], + current_token.start[0], ( "String unnecessarily split in two by black. " "Please merge them manually." @@ -141,17 +139,17 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]): # Checking if we are in a block of concated string if ( - first_token[TYPE] == third_token[TYPE] == token.STRING - and second_token[0] == token.NL + first_token.type == third_token.type == token.STRING + and second_token.type == token.NL ): # Striping the quotes - first_string: str = first_token[1][1:-1] - second_string: str = third_token[1][1:-1] + first_string: str = first_token.string[1:-1] + second_string: str = third_token.string[1:-1] if idk_how_to_call_this_function(first_string, second_string): yield ( source_path, - third_token[2][0], + third_token.start[0], ( "String has a space at the beginning instead " "of the end of the previous string." @@ -195,17 +193,17 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None tokens: List = list(tokenize.generate_tokens(file_name.readline)) for counter, current_token in enumerate(tokens, start=1): - if not (current_token[TYPE] == token.NAME and current_token[VALUE] == "raises"): + if not (current_token.type == token.NAME and current_token.string == "raises"): continue for next_token in tokens[counter:]: - if next_token[TYPE] == token.NAME and next_token[VALUE] == "match": + if next_token.type == token.NAME and next_token.string == "match": break # token.NEWLINE refers to the end of a logical line # unlike token.NL or "\n" which represents a newline - if next_token[TYPE] == token.NEWLINE: + if next_token.type == token.NEWLINE: yield ( source_path, - current_token[2][0], + current_token.start[0], "Bare pytests raise have been found.", ) break From eef10620df3c445bda88fbcf47758d6ee0b47aa3 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 13 Jan 2020 16:44:23 +0200 Subject: [PATCH 32/69] Fixed CI-test for 'strings_with_wrong_placed_space' --- scripts/validate_string_concatenation.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index d9d25e470230e..4a386f2557662 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -126,12 +126,11 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: bool True if the two recived string match, an unwanted pattern. """ - return ( - (not first_line.endswith(" ")) - and second_line.startswith(" ") + return ((not first_line.endswith(" ")) and second_line.startswith(" ")) and ( + (not first_line.endswith(" ")) and (not second_line.startswith(" ")) and (not first_line.endswith("\\n")) - ) or (first_line.endswith(" ") and second_line.startswith(" ")) + ) with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) From b66705e87b01bd01c48983ef807eaa60c38fce8e Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 13 Jan 2020 16:51:14 +0200 Subject: [PATCH 33/69] Activating "strings_with_wrong_placed_space" in the CI --- ci/code_checks.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 6bd1d2f466e92..141fb830e1618 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -108,6 +108,14 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then fi RET=$(($RET + $?)) ; echo $MSG "DONE" + MSG='Check for strings with wrong placed spaces' ; echo $MSG + if [[ "$GITHUB_ACTIONS" == "true" ]]; then + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_with_wrong_placed_space" --format="##[error]{source_path}:{line_number}:{msg}" . + else + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_with_wrong_placed_space" . + fi + RET=$(($RET + $?)) ; echo $MSG "DONE" + echo "isort --version-number" isort --version-number From f77ed82d1ac1198c65ccb1f874d20791b5236865 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 13 Jan 2020 19:15:14 +0200 Subject: [PATCH 34/69] Refactored the function that check the unwanted patterns of the wrong placed spaces --- scripts/validate_string_concatenation.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 4a386f2557662..3fb61d1d2ee44 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -126,11 +126,15 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: bool True if the two recived string match, an unwanted pattern. """ - return ((not first_line.endswith(" ")) and second_line.startswith(" ")) and ( - (not first_line.endswith(" ")) - and (not second_line.startswith(" ")) - and (not first_line.endswith("\\n")) - ) + if first_line.endswith(r"\n"): + return False + elif first_line.startswith(" ") or second_line.startswith(" "): + return False + elif first_line.endswith(" ") or second_line.endswith(" "): + return False + elif (not first_line.endswith(" ")) and second_line.startswith(" "): + return True + return False with open(source_path, "r") as file_name: tokens: List = list(tokenize.generate_tokens(file_name.readline)) From 93c6543b8cf4c54cb528441396175a7c4f5eee47 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 13 Jan 2020 19:37:03 +0200 Subject: [PATCH 35/69] Added docs --- scripts/validate_string_concatenation.py | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 3fb61d1d2ee44..67baa4d25728c 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -125,6 +125,46 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: ------- bool True if the two recived string match, an unwanted pattern. + + Notes + ----- + The unwanted pattern that we are trying to catch is if the spaces in + a string that is concatenated over multiple lines are placed at the + end of each string, unless this string is ending with a + newline character (\n). + + For example, this is bad: + + >>> rule = ( + ... "We want the space at the end of the line," + ... " not at the beginning" + ... ) + + And what we want is: + + >>> rule = ( + ... "We want the space at the end of the line, " + ... "not at the beginning" + ... ) + + And if the string is ending with a new line character (\n) we + do not want any trailing whitespaces after it. + + For example, this is bad: + + >>> rule = ( + ... "We want the space at the begging of " + ... "the line if the previous line is ending with a \n " + ... "not at the end, like always" + ... ) + + And what we do want is: + + >>> rule = ( + ... "We want the space at the begging of " + ... "the line if the previous line is ending with a \n" + ... " not at the end, like always" + ... ) """ if first_line.endswith(r"\n"): return False From 256ae10a7aee22bb47a502333a4cd566b79cb6ed Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 13 Jan 2020 19:38:18 +0200 Subject: [PATCH 36/69] Changed function name --- scripts/validate_string_concatenation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 67baa4d25728c..f288a92201b1d 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -110,7 +110,7 @@ def strings_with_wrong_placed_space( Explenation of the error. """ - def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: + def whitespace_validation(first_line: str, second_line: str) -> bool: """ Checking if the two lines are mattching the unwanted pattern. @@ -189,7 +189,7 @@ def idk_how_to_call_this_function(first_line: str, second_line: str) -> bool: first_string: str = first_token.string[1:-1] second_string: str = third_token.string[1:-1] - if idk_how_to_call_this_function(first_string, second_string): + if whitespace_validation(first_string, second_string): yield ( source_path, third_token.start[0], From 7f4a5799ca84976368954acf89947ade4d4aec6c Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 10:40:47 +0200 Subject: [PATCH 37/69] Rearanged functions in alphabetical order --- scripts/validate_string_concatenation.py | 106 +++++++++++------------ 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index f288a92201b1d..e59261a0c89d3 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -20,6 +20,58 @@ FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") +def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None, None]: + """ + Test Case for bare pytest raises. + + For example, this is wrong: + + >>> with pytest.raise(ValueError): + ... # Some code that raises ValueError + + And this is what we want instead: + + >>> with pytest.raise(ValueError, match="foo"): + ... # Some code that raises ValueError + + Parameters + ---------- + source_path : str + File path pointing to a single file. + + Yields + ------ + source_path : str + Source file path. + line_number : int + Line number of unconcatenated string. + msg : str + Explenation of the error. + + Notes + ----- + GH #23922 + """ + with open(source_path, "r") as file_name: + tokens: List = list(tokenize.generate_tokens(file_name.readline)) + + for counter, current_token in enumerate(tokens, start=1): + if not (current_token.type == token.NAME and current_token.string == "raises"): + continue + for next_token in tokens[counter:]: + if next_token.type == token.NAME and next_token.string == "match": + break + # token.NEWLINE refers to the end of a logical line + # unlike token.NL or "\n" which represents a newline + if next_token.type == token.NEWLINE: + yield ( + source_path, + current_token.start[0], + "Bare pytests raise have been found.", + ) + break + + def strings_to_concatenate( source_path: str, ) -> Generator[Tuple[str, int, str], None, None]: @@ -200,58 +252,6 @@ def whitespace_validation(first_line: str, second_line: str) -> bool: ) -def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None, None]: - """ - Test Case for bare pytest raises. - - For example, this is wrong: - - >>> with pytest.raise(ValueError): - ... # Some code that raises ValueError - - And this is what we want instead: - - >>> with pytest.raise(ValueError, match="foo"): - ... # Some code that raises ValueError - - Parameters - ---------- - source_path : str - File path pointing to a single file. - - Yields - ------ - source_path : str - Source file path. - line_number : int - Line number of unconcatenated string. - msg : str - Explenation of the error. - - Notes - ----- - GH #23922 - """ - with open(source_path, "r") as file_name: - tokens: List = list(tokenize.generate_tokens(file_name.readline)) - - for counter, current_token in enumerate(tokens, start=1): - if not (current_token.type == token.NAME and current_token.string == "raises"): - continue - for next_token in tokens[counter:]: - if next_token.type == token.NAME and next_token.string == "match": - break - # token.NEWLINE refers to the end of a logical line - # unlike token.NL or "\n" which represents a newline - if next_token.type == token.NEWLINE: - yield ( - source_path, - current_token.start[0], - "Bare pytests raise have been found.", - ) - break - - def main( function: Callable[[str], Generator[Tuple[str, int, str], None, None]], source_path: str, @@ -314,9 +314,9 @@ def main( if __name__ == "__main__": available_validation_types: List[str] = [ + "bare_pytest_raises", "strings_to_concatenate", "strings_with_wrong_placed_space", - "bare_pytest_raises", ] parser = argparse.ArgumentParser(description="Unwanted patterns checker.") From 88e09d16072b2bf9036f5d28eb10e233dd7ac6d7 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 10:45:27 +0200 Subject: [PATCH 38/69] Renamed strings_with_wrong_placed_space --> strings_with_wrong_placed_whitespace --- scripts/validate_string_concatenation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index e59261a0c89d3..66c83fd9aa62e 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -127,7 +127,7 @@ def strings_to_concatenate( ) -def strings_with_wrong_placed_space( +def strings_with_wrong_placed_whitespace( source_path: str, ) -> Generator[Tuple[str, int, str], None, None]: """ @@ -316,7 +316,7 @@ def main( available_validation_types: List[str] = [ "bare_pytest_raises", "strings_to_concatenate", - "strings_with_wrong_placed_space", + "strings_with_wrong_placed_whitespace", ] parser = argparse.ArgumentParser(description="Unwanted patterns checker.") From fc24720058f297804a00585a69c8265d193fa1e7 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 11:38:01 +0200 Subject: [PATCH 39/69] Fixed bug where not report wrong placed whitespace if string had a prefix of a string literal --- scripts/validate_string_concatenation.py | 39 ++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 66c83fd9aa62e..11c606eb2c024 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -162,6 +162,37 @@ def strings_with_wrong_placed_whitespace( Explenation of the error. """ + def get_prefix_len(line: str) -> int: + """ + Get the prefix length from a string literal. + + Parameters + ---------- + line : str + Line to check. + + Returns + ------- + int + Length of the prefix of the string literal. + + Examples + -------- + + >>> get_prefix_len('"Hello world"') + 0 + + >>> get_prefix_len('f"Hello world"') + 1 + + >>> get_prefix_len('rf"Hello world"') + 2 + """ + for counter, character in enumerate(line): + if character == r'"' or character == r"'": + return counter + return 0 + def whitespace_validation(first_line: str, second_line: str) -> bool: """ Checking if the two lines are mattching the unwanted pattern. @@ -238,8 +269,12 @@ def whitespace_validation(first_line: str, second_line: str) -> bool: and second_token.type == token.NL ): # Striping the quotes - first_string: str = first_token.string[1:-1] - second_string: str = third_token.string[1:-1] + first_string: str = first_token.string[ + get_prefix_len(first_token.string) + 1 : -1 + ] + second_string: str = third_token.string[ + get_prefix_len(third_token.string) + 1 : -1 + ] if whitespace_validation(first_string, second_string): yield ( From e4957dbc6a00086f694b536de1acd334692358b8 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 12:05:49 +0200 Subject: [PATCH 40/69] Changed validation-type call name in the CI as well --- ci/code_checks.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 141fb830e1618..e020eb63ce6e2 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -110,9 +110,9 @@ if [[ -z "$CHECK" || "$CHECK" == "lint" ]]; then MSG='Check for strings with wrong placed spaces' ; echo $MSG if [[ "$GITHUB_ACTIONS" == "true" ]]; then - $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_with_wrong_placed_space" --format="##[error]{source_path}:{line_number}:{msg}" . + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_with_wrong_placed_whitespace" --format="##[error]{source_path}:{line_number}:{msg}" . else - $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_with_wrong_placed_space" . + $BASE_DIR/scripts/validate_string_concatenation.py --validation-type="strings_with_wrong_placed_whitespace" . fi RET=$(($RET + $?)) ; echo $MSG "DONE" From b206569870df42dc0f611ec2a70da8a89424a706 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 20:17:40 +0200 Subject: [PATCH 41/69] Eleborate more about bare_pytest_raises error message --- scripts/validate_string_concatenation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 11c606eb2c024..801f695d7a722 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -67,7 +67,8 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None yield ( source_path, current_token.start[0], - "Bare pytests raise have been found.", + "Bare pytests raise have been found. " + "Please pass in the argument 'match' as well the exception.", ) break From 9feac861c31450890d3f976537bb004a6d36be60 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 20:18:15 +0200 Subject: [PATCH 42/69] Removed empty line below 'Examples' --- scripts/validate_string_concatenation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 801f695d7a722..f3008a54a4f82 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -179,7 +179,6 @@ def get_prefix_len(line: str) -> int: Examples -------- - >>> get_prefix_len('"Hello world"') 0 From 11b0a3be1d7238738046f67c0ff1b07e35c8e8a0 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 20:19:40 +0200 Subject: [PATCH 43/69] Renamed "whitespace_validation" function to --> "has_wrong_whitespaces" --- scripts/validate_string_concatenation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index f3008a54a4f82..a51e4daaa1dc7 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -193,7 +193,7 @@ def get_prefix_len(line: str) -> int: return counter return 0 - def whitespace_validation(first_line: str, second_line: str) -> bool: + def has_wrong_whitespace(first_line: str, second_line: str) -> bool: """ Checking if the two lines are mattching the unwanted pattern. @@ -276,7 +276,7 @@ def whitespace_validation(first_line: str, second_line: str) -> bool: get_prefix_len(third_token.string) + 1 : -1 ] - if whitespace_validation(first_string, second_string): + if has_wrong_whitespace(first_string, second_string): yield ( source_path, third_token.start[0], From d1a61826b7340200f25698d7de03a0d14220feca Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 20:42:10 +0200 Subject: [PATCH 44/69] Removed useless function, with a brilliant idea --- scripts/validate_string_concatenation.py | 46 +++++++----------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index a51e4daaa1dc7..ba937e612ff77 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -163,36 +163,6 @@ def strings_with_wrong_placed_whitespace( Explenation of the error. """ - def get_prefix_len(line: str) -> int: - """ - Get the prefix length from a string literal. - - Parameters - ---------- - line : str - Line to check. - - Returns - ------- - int - Length of the prefix of the string literal. - - Examples - -------- - >>> get_prefix_len('"Hello world"') - 0 - - >>> get_prefix_len('f"Hello world"') - 1 - - >>> get_prefix_len('rf"Hello world"') - 2 - """ - for counter, character in enumerate(line): - if character == r'"' or character == r"'": - return counter - return 0 - def has_wrong_whitespace(first_line: str, second_line: str) -> bool: """ Checking if the two lines are mattching the unwanted pattern. @@ -268,12 +238,22 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: first_token.type == third_token.type == token.STRING and second_token.type == token.NL ): - # Striping the quotes + # Striping the quotes, with the string litteral prefix first_string: str = first_token.string[ - get_prefix_len(first_token.string) + 1 : -1 + min( + first_token.string.find(quote) + for quote in (r'"', r"'") + if first_token.string.find(quote) >= 0 + ) + + 1 : -1 ] second_string: str = third_token.string[ - get_prefix_len(third_token.string) + 1 : -1 + min( + third_token.string.find(quote) + for quote in (r'"', r"'") + if third_token.string.find(quote) >= 0 + ) + + 1 : -1 ] if has_wrong_whitespace(first_string, second_string): From 7ce199f643e5d48eb469d3eab7452371ed8ba943 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 15 Jan 2020 23:02:37 +0200 Subject: [PATCH 45/69] Refactored the validation-type functions, to get a file object Previously the validation-type functions were getting a string that was the file/directory path --- scripts/validate_string_concatenation.py | 81 +++++++++++------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index ba937e612ff77..e0acf33778fdf 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -15,12 +15,12 @@ import sys import token import tokenize -from typing import Callable, Generator, List, Tuple +from typing import IO, Callable, Generator, List, Tuple FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") -def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None, None]: +def bare_pytest_raises(file_obj: IO) -> Generator[Tuple[int, str], None, None]: """ Test Case for bare pytest raises. @@ -36,13 +36,11 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None Parameters ---------- - source_path : str - File path pointing to a single file. + file_obj : IO + File object to operate on. Yields ------ - source_path : str - Source file path. line_number : int Line number of unconcatenated string. msg : str @@ -52,8 +50,7 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None ----- GH #23922 """ - with open(source_path, "r") as file_name: - tokens: List = list(tokenize.generate_tokens(file_name.readline)) + tokens: List = list(tokenize.generate_tokens(file_obj)) for counter, current_token in enumerate(tokens, start=1): if not (current_token.type == token.NAME and current_token.string == "raises"): @@ -65,7 +62,6 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None # unlike token.NL or "\n" which represents a newline if next_token.type == token.NEWLINE: yield ( - source_path, current_token.start[0], "Bare pytests raise have been found. " "Please pass in the argument 'match' as well the exception.", @@ -73,9 +69,7 @@ def bare_pytest_raises(source_path: str) -> Generator[Tuple[str, int, str], None break -def strings_to_concatenate( - source_path: str, -) -> Generator[Tuple[str, int, str], None, None]: +def strings_to_concatenate(file_obj: IO) -> Generator[Tuple[int, str], None, None]: """ This test case is necessary after 'Black' (https://github.com/psf/black), is formating strings over multiple lines. @@ -97,13 +91,11 @@ def strings_to_concatenate( Parameters ---------- - source_path : str - File path pointing to a single file. + file_obj : IO + File object to operate on. Yields ------ - source_path : str - Source file path. line_number : int Line number of unconcatenated string. msg : str @@ -113,13 +105,11 @@ def strings_to_concatenate( ----- GH #30454 """ - with open(source_path, "r") as file_name: - tokens: List = list(tokenize.generate_tokens(file_name.readline)) + tokens: List = list(tokenize.generate_tokens(file_obj)) for current_token, next_token in zip(tokens, tokens[1:]): if current_token.type == next_token.type == token.STRING: yield ( - source_path, current_token.start[0], ( "String unnecessarily split in two by black. " @@ -129,8 +119,8 @@ def strings_to_concatenate( def strings_with_wrong_placed_whitespace( - source_path: str, -) -> Generator[Tuple[str, int, str], None, None]: + file_obj: IO, +) -> Generator[Tuple[int, str], None, None]: """ Test case for leading spaces in concated strings. @@ -150,13 +140,11 @@ def strings_with_wrong_placed_whitespace( Parameters ---------- - source_path : str - File path pointing to a single file. + file_obj : IO + File object to operate on. Yields ------ - source_path : str - Source file path. line_number : int Line number of unconcatenated string. msg : str @@ -229,8 +217,7 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: return True return False - with open(source_path, "r") as file_name: - tokens: List = list(tokenize.generate_tokens(file_name.readline)) + tokens: List = list(tokenize.generate_tokens(file_obj)) for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]): # Checking if we are in a block of concated string @@ -258,7 +245,6 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: if has_wrong_whitespace(first_string, second_string): yield ( - source_path, third_token.start[0], ( "String has a space at the beginning instead " @@ -268,7 +254,7 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: def main( - function: Callable[[str], Generator[Tuple[str, int, str], None, None]], + function: Callable[[str], Generator[Tuple[int, str], None, None]], source_path: str, output_format: str, ) -> bool: @@ -278,7 +264,7 @@ def main( Parameters ---------- function : Callable - Function to execute for the test case. + Function to execute for the specified validation type. source_path : str Source path representing path to a file/directory. output_format : str @@ -295,35 +281,42 @@ def main( If the `source_path` is not pointing to existing file/directory. """ if not os.path.exists(source_path): - raise ValueError( - "Please enter a valid path, pointing to a valid file/directory." - ) + raise ValueError("Please enter a valid path, pointing to a file/directory.") is_failed: bool = False if os.path.isfile(source_path): - for source_path, line_number, msg in function(source_path): - is_failed = True - print( - output_format.format( - source_path=source_path, line_number=line_number, msg=msg + file_path: str = source_path + with open(file_path, "r") as file_obj: + file_desc = file_obj.readline + + for line_number, msg in function(file_desc): + is_failed = True + print( + output_format.format( + source_path=file_path, line_number=line_number, msg=msg + ) ) - ) for subdir, _, files in os.walk(source_path): for file_name in files: - if any( + if not any( file_name.endswith(extension) for extension in FILE_EXTENSIONS_TO_CHECK ): - for source_path, line_number, msg in function( - os.path.join(subdir, file_name) - ): + continue + + file_path: str = os.path.join(subdir, file_name) + with open(file_path, "r") as file_obj: + file_desc = file_obj.readline + + for line_number, msg in function(file_desc): is_failed = True print( output_format.format( - source_path=source_path, line_number=line_number, msg=msg + source_path=file_path, line_number=line_number, msg=msg ) ) + return is_failed From 467817420520e318e1aafeafab1b65e1f24bb386 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 01:34:40 +0200 Subject: [PATCH 46/69] Moved the "readline" to the function itself. In order to call functions with io.StringIO --- scripts/validate_string_concatenation.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index e0acf33778fdf..4d7f390385fb6 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -50,7 +50,7 @@ def bare_pytest_raises(file_obj: IO) -> Generator[Tuple[int, str], None, None]: ----- GH #23922 """ - tokens: List = list(tokenize.generate_tokens(file_obj)) + tokens: List = list(tokenize.generate_tokens(file_obj.readline)) for counter, current_token in enumerate(tokens, start=1): if not (current_token.type == token.NAME and current_token.string == "raises"): @@ -105,7 +105,7 @@ def strings_to_concatenate(file_obj: IO) -> Generator[Tuple[int, str], None, Non ----- GH #30454 """ - tokens: List = list(tokenize.generate_tokens(file_obj)) + tokens: List = list(tokenize.generate_tokens(file_obj.readline)) for current_token, next_token in zip(tokens, tokens[1:]): if current_token.type == next_token.type == token.STRING: @@ -217,7 +217,7 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: return True return False - tokens: List = list(tokenize.generate_tokens(file_obj)) + tokens: List = list(tokenize.generate_tokens(file_obj.readline)) for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]): # Checking if we are in a block of concated string @@ -288,9 +288,7 @@ def main( if os.path.isfile(source_path): file_path: str = source_path with open(file_path, "r") as file_obj: - file_desc = file_obj.readline - - for line_number, msg in function(file_desc): + for line_number, msg in function(file_obj): is_failed = True print( output_format.format( @@ -307,9 +305,7 @@ def main( file_path: str = os.path.join(subdir, file_name) with open(file_path, "r") as file_obj: - file_desc = file_obj.readline - - for line_number, msg in function(file_desc): + for line_number, msg in function(file_obj): is_failed = True print( output_format.format( From 68bbe585145ffdebac9c12633ae3ceee9bd9e5d1 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 02:06:31 +0200 Subject: [PATCH 47/69] Added some sample tests --- .../tests/test_validate_unwanted_patterns.py | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 scripts/tests/test_validate_unwanted_patterns.py diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py new file mode 100644 index 0000000000000..6e8908c501b62 --- /dev/null +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -0,0 +1,77 @@ +import io + +# the "as" is just so I won't have to change this in many places later. +import validate_string_concatenation as validate_unwanted_patterns + + +class GoodBarePytestRaises: + def normal_pytest_raises(self): + return io.StringIO( + """ +with pytest.raises(ValueError, match="foo"): + pass +""" + ) + + def good_pytest_raises_as_comment(self): + return io.StringIO( + """ +# with pytest.raises(ValueError, match="foo"): +# pass +""" + ) + + def good_bare_pytest_raises_as_comment(self): + """ + We do not care if the bare pytest raises is commented out. + """ + return io.StringIO( + """ +# with pytest.raises(ValueError): +# pass +""" + ) + + +class BadBarePytestRaises: + def normal_bare_pytest_raises(self): + return io.StringIO( + """ +with pytest.raises(ValueError): + raise ValueError("foo") +""" + ) + + +class TestGoodBarePytestRaises: + def test_good_normal_pytest_raises(self): + result = validate_unwanted_patterns.bare_pytest_raises( + GoodBarePytestRaises.normal_pytest_raises(self) + ) + + for _ in result: + assert False # Not sure about this + + def test_good_pytest_raises_as_comment(self): + result = validate_unwanted_patterns.bare_pytest_raises( + GoodBarePytestRaises.good_pytest_raises_as_comment(self) + ) + for _ in result: + assert False # Not sure about this + + def test_good_bare_pytest_raises_as_comment(self): + result = validate_unwanted_patterns.bare_pytest_raises( + GoodBarePytestRaises.good_bare_pytest_raises_as_comment(self) + ) + for _ in result: + assert False # Not sure about this + + +class TestBadBarePytestRaises: + def test_bad_normal_pytest_raises(self): + result = validate_unwanted_patterns.bare_pytest_raises( + BadBarePytestRaises.normal_bare_pytest_raises(self) + ) + + for bare_pytest_raise in result: + assert bare_pytest_raise[0] == 2 From f3b7c0254021e1e8aedae52ea20d51efffdc43a8 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 02:09:37 +0200 Subject: [PATCH 48/69] Changed functions names in the sample test --- scripts/tests/test_validate_unwanted_patterns.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 6e8908c501b62..302afc5afe0e4 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -13,7 +13,7 @@ def normal_pytest_raises(self): """ ) - def good_pytest_raises_as_comment(self): + def pytest_raises_as_comment(self): return io.StringIO( """ # with pytest.raises(ValueError, match="foo"): @@ -21,7 +21,7 @@ def good_pytest_raises_as_comment(self): """ ) - def good_bare_pytest_raises_as_comment(self): + def bare_pytest_raises_as_comment(self): """ We do not care if the bare pytest raises is commented out. """ @@ -54,14 +54,14 @@ def test_good_normal_pytest_raises(self): def test_good_pytest_raises_as_comment(self): result = validate_unwanted_patterns.bare_pytest_raises( - GoodBarePytestRaises.good_pytest_raises_as_comment(self) + GoodBarePytestRaises.pytest_raises_as_comment(self) ) for _ in result: assert False # Not sure about this def test_good_bare_pytest_raises_as_comment(self): result = validate_unwanted_patterns.bare_pytest_raises( - GoodBarePytestRaises.good_bare_pytest_raises_as_comment(self) + GoodBarePytestRaises.bare_pytest_raises_as_comment(self) ) for _ in result: assert False # Not sure about this From 886195c9a45bd4a3ae97a8d177da88e772a0b021 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 02:14:44 +0200 Subject: [PATCH 49/69] Changed the names of the test functions as well --- scripts/tests/test_validate_unwanted_patterns.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 302afc5afe0e4..e76ea20fa2483 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -52,14 +52,14 @@ def test_good_normal_pytest_raises(self): for _ in result: assert False # Not sure about this - def test_good_pytest_raises_as_comment(self): + def test_pytest_raises_as_comment(self): result = validate_unwanted_patterns.bare_pytest_raises( GoodBarePytestRaises.pytest_raises_as_comment(self) ) for _ in result: assert False # Not sure about this - def test_good_bare_pytest_raises_as_comment(self): + def test_bare_pytest_raises_as_comment(self): result = validate_unwanted_patterns.bare_pytest_raises( GoodBarePytestRaises.bare_pytest_raises_as_comment(self) ) From 9839384c6e493cb48d6c7de00854a503e1ec82c6 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 04:39:00 +0200 Subject: [PATCH 50/69] Refactored tests --- .../tests/test_validate_unwanted_patterns.py | 97 ++++++++----------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index e76ea20fa2483..7c283e7a1af18 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -4,74 +4,63 @@ import validate_string_concatenation as validate_unwanted_patterns -class GoodBarePytestRaises: - def normal_pytest_raises(self): - return io.StringIO( +class TestBarePytestRaises: + def test_bare_pytest_raises(self): + fd = io.StringIO( """ -with pytest.raises(ValueError, match="foo"): +with pytest.raises(ValueError): pass -""" +""".strip() ) + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + expected = [ + ( + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' as well the exception." + ), + ) + ] + assert result == expected - def pytest_raises_as_comment(self): - return io.StringIO( + def test_pytest_raises(self): + fd = io.StringIO( """ -# with pytest.raises(ValueError, match="foo"): -# pass -""" +with pytest.raises(ValueError, match="foo"): + pass +""".strip() ) + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + expected = [] + assert result == expected - def bare_pytest_raises_as_comment(self): - """ - We do not care if the bare pytest raises is commented out. - """ - return io.StringIO( + def test_bare_pytest_raises_as_comment(self): + fd = io.StringIO( """ # with pytest.raises(ValueError): -# pass -""" - ) - - -class BadBarePytestRaises: - def normal_bare_pytest_raises(self): - return io.StringIO( - """ -with pytest.raises(ValueError): - raise ValueError("foo") -""" +# pass +""".strip() ) - - -class TestGoodBarePytestRaises: - def test_good_normal_pytest_raises(self): - result = validate_unwanted_patterns.bare_pytest_raises( - GoodBarePytestRaises.normal_pytest_raises(self) - ) - - for _ in result: - assert False # Not sure about this + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + expected = [] + assert result == expected def test_pytest_raises_as_comment(self): - result = validate_unwanted_patterns.bare_pytest_raises( - GoodBarePytestRaises.pytest_raises_as_comment(self) + fd = io.StringIO( + """ +# with pytest.raises(ValueError, match="foo"): +# pass +""".strip() ) - for _ in result: - assert False # Not sure about this + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + expected = [] + assert result == expected - def test_bare_pytest_raises_as_comment(self): - result = validate_unwanted_patterns.bare_pytest_raises( - GoodBarePytestRaises.bare_pytest_raises_as_comment(self) - ) - for _ in result: - assert False # Not sure about this +class TestStringsToConcatenate: + pass -class TestBadBarePytestRaises: - def test_bad_normal_pytest_raises(self): - result = validate_unwanted_patterns.bare_pytest_raises( - BadBarePytestRaises.normal_bare_pytest_raises(self) - ) - for bare_pytest_raise in result: - assert bare_pytest_raise[0] == 2 +class TestStringsWithWrongPlacedWhitespace: + pass From 8263c2b51aaf9e59932cf92c92df2a0e74e108e0 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 04:51:53 +0200 Subject: [PATCH 51/69] Added tests to TestStringsToConcatenate --- .../tests/test_validate_unwanted_patterns.py | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 7c283e7a1af18..0dc67e65d168c 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -59,7 +59,48 @@ def test_pytest_raises_as_comment(self): class TestStringsToConcatenate: - pass + def test_strings_to_concatenate(self): + fd = io.StringIO( + """ +msg = ("bar " "baz") +""".strip() + ) + result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) + expected = [ + ( + 1, + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ) + ] + assert result == expected + + def test_strings_to_concatenate_two_occurrences_same_line(self): + fd = io.StringIO( + """ +msg = ("foo " "bar " "baz") +""".strip() + ) + result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) + expected = [ + ( + 1, + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ), + ( + 1, + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ), + ] + assert result == expected class TestStringsWithWrongPlacedWhitespace: From 5b0ce297a94a7b1edaf3561ef8c8ccf0108922a0 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 04:57:35 +0200 Subject: [PATCH 52/69] Fixed typing --- scripts/validate_string_concatenation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 4d7f390385fb6..ed6cd64e78b72 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -254,7 +254,7 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: def main( - function: Callable[[str], Generator[Tuple[int, str], None, None]], + function: Callable[[IO], Generator[Tuple[int, str], None, None]], source_path: str, output_format: str, ) -> bool: From 02aa4ce471e0312b5c438b392a52ac448d59c651 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 16 Jan 2020 05:13:06 +0200 Subject: [PATCH 53/69] Added tests for TestStringsWithWrongPlacedWhitespace --- .../tests/test_validate_unwanted_patterns.py | 110 +++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 0dc67e65d168c..ff097259dc362 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -104,4 +104,112 @@ def test_strings_to_concatenate_two_occurrences_same_line(self): class TestStringsWithWrongPlacedWhitespace: - pass + def test_strings_with_wrong_placed_whitespace(self): + fd = io.StringIO( + """ +msg = ( + "foo" + " bar" +) +""".strip() + ) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + expected = [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ] + assert result == expected + + def test_strings_with_wrong_placed_whitespace_ends_new_line(self): + fd = io.StringIO( + """ +msg = ( + "foo\n" + " bar" +) +""".strip() + ) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + expected = [] + assert result == expected + + def test_strings_with_wrong_placed_whitespace_first_line_starts_double_sapce(self): + fd = io.StringIO( + """ +msg = ( + " foo" + "bar" +) +""".strip() + ) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + expected = [] + assert result == expected + + def test_strings_with_wrong_placed_whitespace_second_line_starts_double_sapce(self): + fd = io.StringIO( + """ +msg = ( + "foo" + " bar" +) +""".strip() + ) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + expected = [] + assert result == expected + + def test_strings_with_wrong_placed_whitespace_first_line_string_literal_prefix( + self, + ): + fd = io.StringIO( + """ +msg = ( + f"foo" + " bar" +) +""".strip() + ) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + expected = [] + assert result == expected + + def test_strings_with_wrong_placed_whitespace_second_line_string_literal_prefix( + self, + ): + fd = io.StringIO( + """ +msg = ( + "foo" + f" bar" +) +""".strip() + ) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + expected = [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ] + assert result == expected From caa1bedd0b8986060596b96af51cc32970838770 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 19 Jan 2020 00:54:46 +0200 Subject: [PATCH 54/69] Changed paramerter description of "file_obj" as @datapythonista suggested here https://github.com/pandas-dev/pandas/pull/30755#discussion_r368203643 --- scripts/validate_string_concatenation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index ed6cd64e78b72..27c8734bb8ff0 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -37,7 +37,7 @@ def bare_pytest_raises(file_obj: IO) -> Generator[Tuple[int, str], None, None]: Parameters ---------- file_obj : IO - File object to operate on. + File-like object containing the Python code to validate. Yields ------ @@ -92,7 +92,7 @@ def strings_to_concatenate(file_obj: IO) -> Generator[Tuple[int, str], None, Non Parameters ---------- file_obj : IO - File object to operate on. + File-like object containing the Python code to validate. Yields ------ @@ -141,7 +141,7 @@ def strings_with_wrong_placed_whitespace( Parameters ---------- file_obj : IO - File object to operate on. + File-like object containing the Python code to validate. Yields ------ From 5e1d723bdbd76893bca0c6f2ab3630676930a453 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 19 Jan 2020 00:56:50 +0200 Subject: [PATCH 55/69] Fixed typo Ref https://github.com/pandas-dev/pandas/pull/30755#discussion_r368203493 --- scripts/tests/test_validate_unwanted_patterns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index ff097259dc362..a0be842fed306 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -142,7 +142,7 @@ def test_strings_with_wrong_placed_whitespace_ends_new_line(self): expected = [] assert result == expected - def test_strings_with_wrong_placed_whitespace_first_line_starts_double_sapce(self): + def test_strings_with_wrong_placed_whitespace_first_line_starts_double_space(self): fd = io.StringIO( """ msg = ( From da9d4f9c0596ac38d5ae9ecd4765c8f892f960a0 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 19 Jan 2020 02:44:04 +0200 Subject: [PATCH 56/69] Refactored test to use "pytest.mark.parametrize" --- .../tests/test_validate_unwanted_patterns.py | 469 ++++++++++++------ 1 file changed, 322 insertions(+), 147 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index a0be842fed306..943e06557f371 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -1,215 +1,390 @@ import io +import pytest + # the "as" is just so I won't have to change this in many places later. import validate_string_concatenation as validate_unwanted_patterns class TestBarePytestRaises: - def test_bare_pytest_raises(self): - fd = io.StringIO( - """ -with pytest.raises(ValueError): - pass -""".strip() - ) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - expected = [ + @pytest.mark.parametrize( + "fd, expected", + [ ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' as well the exception." - ), - ) - ] - assert result == expected - - def test_pytest_raises(self): - fd = io.StringIO( - """ + io.StringIO( + """ with pytest.raises(ValueError, match="foo"): pass """.strip() - ) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - expected = [] - assert result == expected - - def test_bare_pytest_raises_as_comment(self): - fd = io.StringIO( - """ -# with pytest.raises(ValueError): + ), + [], + ), + ( + io.StringIO( + """ +# with pytest.raises(ValueError, match="foo"): # pass """.strip() - ) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - expected = [] - assert result == expected - - def test_pytest_raises_as_comment(self): - fd = io.StringIO( - """ -# with pytest.raises(ValueError, match="foo"): + ), + [], + ), + ( + io.StringIO( + """ +# with pytest.raises(ValueError): # pass """.strip() - ) + ), + [], + ), + ], + ) + def test_good_pytest_raises(self, fd, expected): result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - expected = [] assert result == expected - -class TestStringsToConcatenate: - def test_strings_to_concatenate(self): - fd = io.StringIO( - """ -msg = ("bar " "baz") -""".strip() - ) - result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) - expected = [ + @pytest.mark.parametrize( + "fd, expected", + [ ( - 1, - ( - "String unnecessarily split in two by black. " - "Please merge them manually." + io.StringIO( + """ + with pytest.raises(ValueError): + pass + """.strip() ), - ) - ] - assert result == expected - - def test_strings_to_concatenate_two_occurrences_same_line(self): - fd = io.StringIO( - """ -msg = ("foo " "bar " "baz") -""".strip() - ) - result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) - expected = [ + [ + ( + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), + ), + ], + ), ( - 1, - ( - "String unnecessarily split in two by black. " - "Please merge them manually." + io.StringIO( + """ + with pytest.raises(ValueError, match="foo"): + with pytest.raises(ValueError): + pass + pass + """.strip() ), + [ + ( + 2, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), + ), + ], ), ( - 1, - ( - "String unnecessarily split in two by black. " - "Please merge them manually." + io.StringIO( + """ + with pytest.raises(ValueError): + with pytest.raises(ValueError, match="foo"): + pass + pass + """.strip() ), + [ + ( + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), + ), + ], + ), + ], + ) + def test_bad_pytest_raises(self, fd, expected): + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + assert result == expected + + +class TestStringsToConcatenate: + @pytest.mark.parametrize( + "fd, expected", + [ + ( + io.StringIO('msg = ("bar " "baz")'), + [ + ( + 1, + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ) + ], ), - ] + ( + io.StringIO('msg = ("foo " "bar " "baz")'), + [ + ( + 1, + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ), + ( + 1, + ( + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ), + ], + ), + ], + ) + def test_strings_to_concatenate(self, fd, expected): + result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) assert result == expected class TestStringsWithWrongPlacedWhitespace: - def test_strings_with_wrong_placed_whitespace(self): - fd = io.StringIO( - """ + @pytest.mark.parametrize( + "fd, expected", + [ + ( + io.StringIO( + """ msg = ( "foo" " bar" ) """.strip() - ) - result = list( - validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) - ) - expected = [ + ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], + ), ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." + io.StringIO( + """ +msg = ( + f"foo" + " bar" +) +""".strip() ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], ), - ] - assert result == expected - - def test_strings_with_wrong_placed_whitespace_ends_new_line(self): - fd = io.StringIO( - """ + ( + io.StringIO( + """ msg = ( - "foo\n" + "foo" + f" bar" +) +""".strip() + ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], + ), + ( + io.StringIO( + """ +msg = ( + f"foo" + f" bar" +) +""".strip() + ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], + ), + ( + io.StringIO( + """ +msg = ( + "foo" + rf" bar" + " baz" +) +""".strip() + ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ( + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ], + ), + ( + io.StringIO( + """ +msg = ( + "foo" " bar" + rf" baz" ) """.strip() - ) - result = list( - validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) - ) - expected = [] - assert result == expected - - def test_strings_with_wrong_placed_whitespace_first_line_starts_double_space(self): - fd = io.StringIO( - """ + ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ( + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ], + ), + ( + io.StringIO( + """ msg = ( - " foo" - "bar" + "foo" + rf" bar" + rf" baz" ) """.strip() - ) + ), + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ( + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ], + ), + ], + ) + def test_strings_with_wrong_placed_whitespace(self, fd, expected): result = list( validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) ) - expected = [] assert result == expected - def test_strings_with_wrong_placed_whitespace_second_line_starts_double_sapce(self): - fd = io.StringIO( - """ + @pytest.mark.parametrize( + "fd, expected", + [ + ( + io.StringIO( + """ +msg = ( + "foo\n" + " bar" +) +""".strip() + ), + [], + ), + ( + io.StringIO( + """ msg = ( "foo" " bar" + "baz" ) """.strip() - ) - result = list( - validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) - ) - expected = [] - assert result == expected - - def test_strings_with_wrong_placed_whitespace_first_line_string_literal_prefix( - self, - ): - fd = io.StringIO( - """ + ), + [], + ), + ( + io.StringIO( + """ msg = ( f"foo" " bar" ) """.strip() - ) - result = list( - validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) - ) - expected = [] - assert result == expected - - def test_strings_with_wrong_placed_whitespace_second_line_string_literal_prefix( - self, - ): - fd = io.StringIO( - """ + ), + [], + ), + ( + io.StringIO( + """ msg = ( "foo" - f" bar" + f" bar" ) """.strip() - ) + ), + [], + ), + ( + io.StringIO( + """ +msg = ( + "foo" + rf" bar" +) +""".strip() + ), + [], + ), + ], + ) + def test_excluded_strings_with_wrong_placed_whitespace(self, fd, expected): result = list( validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) ) - expected = [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ] assert result == expected From 4cc1aeecec35648ad809de07ff345445680c1747 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 19 Jan 2020 02:58:05 +0200 Subject: [PATCH 57/69] Added edge cases tests "for bare_pytest_raises" --- .../tests/test_validate_unwanted_patterns.py | 75 ++++++++++++++++--- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 943e06557f371..0be2825173da4 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -33,6 +33,18 @@ class TestBarePytestRaises: """ # with pytest.raises(ValueError): # pass +""".strip() + ), + [], + ), + ( + io.StringIO( + """ +with pytest.raises( + ValueError, + match="foo" + ): + pass """.strip() ), [], @@ -49,9 +61,9 @@ def test_good_pytest_raises(self, fd, expected): ( io.StringIO( """ - with pytest.raises(ValueError): - pass - """.strip() +with pytest.raises(ValueError): + pass +""".strip() ), [ ( @@ -67,11 +79,11 @@ def test_good_pytest_raises(self, fd, expected): ( io.StringIO( """ - with pytest.raises(ValueError, match="foo"): - with pytest.raises(ValueError): - pass +with pytest.raises(ValueError, match="foo"): + with pytest.raises(ValueError): pass - """.strip() + pass +""".strip() ), [ ( @@ -87,11 +99,52 @@ def test_good_pytest_raises(self, fd, expected): ( io.StringIO( """ - with pytest.raises(ValueError): - with pytest.raises(ValueError, match="foo"): - pass +with pytest.raises(ValueError): + with pytest.raises(ValueError, match="foo"): pass - """.strip() + pass +""".strip() + ), + [ + ( + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), + ), + ], + ), + ( + io.StringIO( + """ +with pytest.raises( + ValueError +): + pass +""".strip() + ), + [ + ( + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), + ), + ], + ), + ( + io.StringIO( + """ +with pytest.raises( + ValueError, + # match = "foo" +): + pass +""".strip() ), [ ( From 49445ebc8cd9c4139f0aa69f628b683dc2c5d070 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 24 Jan 2020 17:26:15 +0200 Subject: [PATCH 58/69] Type annotations --- scripts/validate_string_concatenation.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 6d5ea6698380a..f5fe0ee5301dd 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -17,10 +17,10 @@ import tokenize from typing import IO, Callable, Generator, List, Tuple -FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd") +FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pyx.ini", ".pxd") -def bare_pytest_raises(file_obj: IO) -> Generator[Tuple[int, str], None, None]: +def bare_pytest_raises(file_obj: IO[str]) -> Generator[Tuple[int, str], None, None]: """ Test Case for bare pytest raises. @@ -69,7 +69,7 @@ def bare_pytest_raises(file_obj: IO) -> Generator[Tuple[int, str], None, None]: break -def strings_to_concatenate(file_obj: IO) -> Generator[Tuple[int, str], None, None]: +def strings_to_concatenate(file_obj: IO[str]) -> Generator[Tuple[int, str], None, None]: """ This test case is necessary after 'Black' (https://github.com/psf/black), is formating strings over multiple lines. @@ -119,7 +119,7 @@ def strings_to_concatenate(file_obj: IO) -> Generator[Tuple[int, str], None, Non def strings_with_wrong_placed_whitespace( - file_obj: IO, + file_obj: IO[str], ) -> Generator[Tuple[int, str], None, None]: """ Test case for leading spaces in concated strings. @@ -254,7 +254,7 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: def main( - function: Callable[[IO], Generator[Tuple[int, str], None, None]], + function: Callable[[IO[str]], Generator[Tuple[int, str], None, None]], source_path: str, output_format: str, ) -> bool: @@ -284,9 +284,10 @@ def main( raise ValueError("Please enter a valid path, pointing to a file/directory.") is_failed: bool = False + file_path: str = "" if os.path.isfile(source_path): - file_path: str = source_path + file_path = source_path with open(file_path, "r") as file_obj: for line_number, msg in function(file_obj): is_failed = True @@ -303,7 +304,7 @@ def main( ): continue - file_path: str = os.path.join(subdir, file_name) + file_path = os.path.join(subdir, file_name) with open(file_path, "r") as file_obj: for line_number, msg in function(file_obj): is_failed = True @@ -346,7 +347,7 @@ def main( sys.exit( main( - function=globals().get(args.validation_type), + function=globals().get(args.validation_type), # type: ignore source_path=args.path, output_format=args.format, ) From 6a0f45d782c48883eeedd804f17b8bcc8d751a7a Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 25 Jan 2020 13:18:29 +0200 Subject: [PATCH 59/69] Making a function for getting the literal string prefix length REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r370911758 --- scripts/validate_string_concatenation.py | 47 ++++++++++++++++++------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index f5fe0ee5301dd..a95afe4314157 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -20,6 +20,39 @@ FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pyx.ini", ".pxd") +def _get_literal_string_prefix_len(token_string: str) -> int: + """ + Getting the length of the literal string prefix. + + Parameters + ---------- + token_string : str + String to check. + + Returns + ------- + int + Length of the literal string prefix. + + Examples + -------- + >>> example_string = "'Hello world'" + >>> _get_literal_string_prefix_len(example_string) + 0 + >>> example_string = "r'Hello world'" + >>> _get_literal_string_prefix_len(example_string) + 1 + """ + try: + return min( + token_string.find(quote) + for quote in (r"'", r'"') + if token_string.find(quote) >= 0 + ) + except ValueError: + return 0 + + def bare_pytest_raises(file_obj: IO[str]) -> Generator[Tuple[int, str], None, None]: """ Test Case for bare pytest raises. @@ -227,20 +260,10 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: ): # Striping the quotes, with the string litteral prefix first_string: str = first_token.string[ - min( - first_token.string.find(quote) - for quote in (r'"', r"'") - if first_token.string.find(quote) >= 0 - ) - + 1 : -1 + _get_literal_string_prefix_len(first_token.string) + 1 : -1 ] second_string: str = third_token.string[ - min( - third_token.string.find(quote) - for quote in (r'"', r"'") - if third_token.string.find(quote) >= 0 - ) - + 1 : -1 + _get_literal_string_prefix_len(third_token.string) + 1 : -1 ] if has_wrong_whitespace(first_string, second_string): From 2cb32d8e5d875cd9a5b58ce9bbcd057be117eedb Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 25 Jan 2020 13:32:40 +0200 Subject: [PATCH 60/69] Calling io.StringIO inside the bare_pytests_raises tests REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r370911991 --- .../tests/test_validate_unwanted_patterns.py | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 0be2825173da4..0bdbd1df910fc 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -8,62 +8,63 @@ class TestBarePytestRaises: @pytest.mark.parametrize( - "fd, expected", + "data, expected", [ ( - io.StringIO( + ( """ with pytest.raises(ValueError, match="foo"): pass -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ # with pytest.raises(ValueError, match="foo"): # pass -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ # with pytest.raises(ValueError): # pass -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ with pytest.raises( ValueError, match="foo" ): pass -""".strip() +""" ), [], ), ], ) - def test_good_pytest_raises(self, fd, expected): + def test_good_pytest_raises(self, data, expected): + fd = io.StringIO(data.strip()) result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) assert result == expected @pytest.mark.parametrize( - "fd, expected", + "data, expected", [ ( - io.StringIO( + ( """ with pytest.raises(ValueError): pass -""".strip() +""" ), [ ( @@ -77,13 +78,13 @@ def test_good_pytest_raises(self, fd, expected): ], ), ( - io.StringIO( + ( """ with pytest.raises(ValueError, match="foo"): with pytest.raises(ValueError): pass pass -""".strip() +""" ), [ ( @@ -97,13 +98,13 @@ def test_good_pytest_raises(self, fd, expected): ], ), ( - io.StringIO( + ( """ with pytest.raises(ValueError): with pytest.raises(ValueError, match="foo"): pass pass -""".strip() +""" ), [ ( @@ -117,13 +118,13 @@ def test_good_pytest_raises(self, fd, expected): ], ), ( - io.StringIO( + ( """ with pytest.raises( ValueError ): pass -""".strip() +""" ), [ ( @@ -137,14 +138,14 @@ def test_good_pytest_raises(self, fd, expected): ], ), ( - io.StringIO( + ( """ with pytest.raises( ValueError, # match = "foo" ): pass -""".strip() +""" ), [ ( @@ -159,7 +160,8 @@ def test_good_pytest_raises(self, fd, expected): ), ], ) - def test_bad_pytest_raises(self, fd, expected): + def test_bad_pytest_raises(self, data, expected): + fd = io.StringIO(data.strip()) result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) assert result == expected From c98a3a4859b6dc399c1d0f61dc90031caf4f2d2c Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 25 Jan 2020 13:41:10 +0200 Subject: [PATCH 61/69] Calling io.StringIO inside the strings_to_concatenate and strings_with_wrong_placed_whitespace tests REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r370911991 --- .../tests/test_validate_unwanted_patterns.py | 67 ++++++++++--------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 0bdbd1df910fc..1f5b91d3b75ba 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -168,10 +168,10 @@ def test_bad_pytest_raises(self, data, expected): class TestStringsToConcatenate: @pytest.mark.parametrize( - "fd, expected", + "data, expected", [ ( - io.StringIO('msg = ("bar " "baz")'), + 'msg = ("bar " "baz")', [ ( 1, @@ -183,7 +183,7 @@ class TestStringsToConcatenate: ], ), ( - io.StringIO('msg = ("foo " "bar " "baz")'), + 'msg = ("foo " "bar " "baz")', [ ( 1, @@ -203,23 +203,24 @@ class TestStringsToConcatenate: ), ], ) - def test_strings_to_concatenate(self, fd, expected): + def test_strings_to_concatenate(self, data, expected): + fd = io.StringIO(data.strip()) result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) assert result == expected class TestStringsWithWrongPlacedWhitespace: @pytest.mark.parametrize( - "fd, expected", + "data, expected", [ ( - io.StringIO( + ( """ msg = ( "foo" " bar" ) -""".strip() +""" ), [ ( @@ -232,13 +233,13 @@ class TestStringsWithWrongPlacedWhitespace: ], ), ( - io.StringIO( + ( """ msg = ( f"foo" " bar" ) -""".strip() +""" ), [ ( @@ -251,13 +252,13 @@ class TestStringsWithWrongPlacedWhitespace: ], ), ( - io.StringIO( + ( """ msg = ( "foo" f" bar" ) -""".strip() +""" ), [ ( @@ -270,13 +271,13 @@ class TestStringsWithWrongPlacedWhitespace: ], ), ( - io.StringIO( + ( """ msg = ( f"foo" f" bar" ) -""".strip() +""" ), [ ( @@ -289,14 +290,14 @@ class TestStringsWithWrongPlacedWhitespace: ], ), ( - io.StringIO( + ( """ msg = ( "foo" rf" bar" " baz" ) -""".strip() +""" ), [ ( @@ -316,14 +317,14 @@ class TestStringsWithWrongPlacedWhitespace: ], ), ( - io.StringIO( + ( """ msg = ( "foo" " bar" rf" baz" ) -""".strip() +""" ), [ ( @@ -343,14 +344,14 @@ class TestStringsWithWrongPlacedWhitespace: ], ), ( - io.StringIO( + ( """ msg = ( "foo" rf" bar" rf" baz" ) -""".strip() +""" ), [ ( @@ -371,74 +372,76 @@ class TestStringsWithWrongPlacedWhitespace: ), ], ) - def test_strings_with_wrong_placed_whitespace(self, fd, expected): + def test_strings_with_wrong_placed_whitespace(self, data, expected): + fd = io.StringIO(data.strip()) result = list( validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) ) assert result == expected @pytest.mark.parametrize( - "fd, expected", + "data, expected", [ ( - io.StringIO( + ( """ msg = ( "foo\n" " bar" ) -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ msg = ( "foo" " bar" "baz" ) -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ msg = ( f"foo" " bar" ) -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ msg = ( "foo" f" bar" ) -""".strip() +""" ), [], ), ( - io.StringIO( + ( """ msg = ( "foo" rf" bar" ) -""".strip() +""" ), [], ), ], ) - def test_excluded_strings_with_wrong_placed_whitespace(self, fd, expected): + def test_excluded_strings_with_wrong_placed_whitespace(self, data, expected): + fd = io.StringIO(data.strip()) result = list( validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) ) From 6b8bc435d353a07a64fbba07d5f96aed040db5b6 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 25 Jan 2020 13:48:15 +0200 Subject: [PATCH 62/69] Changed comment to something more clear REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r370912125 --- scripts/tests/test_validate_unwanted_patterns.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 1f5b91d3b75ba..e4dfeaceca01a 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -2,7 +2,9 @@ import pytest -# the "as" is just so I won't have to change this in many places later. +# TODO: change this import to "import validate_unwanted_patterns" +# when renaming "scripts/validate_string_concatenation.py" to +# "scripts/validate_unwanted_patterns.py" import validate_string_concatenation as validate_unwanted_patterns From 95f2275142fdafc0469e0a304f044fea4f8aad5d Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 25 Jan 2020 13:58:35 +0200 Subject: [PATCH 63/69] Unify bare_pytest_raises tests REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r370912235 --- .../tests/test_validate_unwanted_patterns.py | 183 ++++++++---------- 1 file changed, 86 insertions(+), 97 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index e4dfeaceca01a..0d1f180f4a161 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -8,164 +8,153 @@ import validate_string_concatenation as validate_unwanted_patterns -class TestBarePytestRaises: - @pytest.mark.parametrize( - "data, expected", - [ +@pytest.mark.parametrize( + "data, expected", + [ + ( ( - ( - """ + """ with pytest.raises(ValueError, match="foo"): pass """ - ), - [], ), + [], + ), + ( ( - ( - """ + """ # with pytest.raises(ValueError, match="foo"): # pass """ - ), - [], ), + [], + ), + ( ( - ( - """ + """ # with pytest.raises(ValueError): # pass """ - ), - [], ), + [], + ), + ( ( - ( - """ + """ with pytest.raises( ValueError, match="foo" - ): +): pass """ - ), - [], ), - ], - ) - def test_good_pytest_raises(self, data, expected): - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - assert result == expected - - @pytest.mark.parametrize( - "data, expected", - [ + [], + ), + ( ( - ( - """ + """ with pytest.raises(ValueError): pass """ - ), - [ + ), + [ + ( + 1, ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." ), - ], - ), + ), + ], + ), + ( ( - ( - """ + """ with pytest.raises(ValueError, match="foo"): with pytest.raises(ValueError): pass pass """ - ), - [ + ), + [ + ( + 2, ( - 2, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." ), - ], - ), + ), + ], + ), + ( ( - ( - """ + """ with pytest.raises(ValueError): with pytest.raises(ValueError, match="foo"): pass pass """ - ), - [ + ), + [ + ( + 1, ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." ), - ], - ), + ), + ], + ), + ( ( - ( - """ + """ with pytest.raises( ValueError ): pass """ - ), - [ + ), + [ + ( + 1, ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." ), - ], - ), + ), + ], + ), + ( ( - ( - """ + """ with pytest.raises( ValueError, # match = "foo" ): pass """ - ), - [ + ), + [ + ( + 1, ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." ), - ], - ), - ], - ) - def test_bad_pytest_raises(self, data, expected): - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - assert result == expected + ), + ], + ), + ], +) +def test_pytest_raises(data, expected): + fd = io.StringIO(data.strip()) + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + assert result == expected class TestStringsToConcatenate: From 4a00e51ca52ce97cfdf042c9780d8ed2df2140a3 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 25 Jan 2020 14:05:56 +0200 Subject: [PATCH 64/69] Unify strings_to_concatenate and strings_with_wrong_placed_whitespace tests REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r370912262 https://github.com/pandas-dev/pandas/pull/30755#discussion_r370912302 --- .../tests/test_validate_unwanted_patterns.py | 392 +++++++++--------- 1 file changed, 188 insertions(+), 204 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index 0d1f180f4a161..ee2ecced7c97f 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -157,283 +157,267 @@ def test_pytest_raises(data, expected): assert result == expected -class TestStringsToConcatenate: - @pytest.mark.parametrize( - "data, expected", - [ - ( - 'msg = ("bar " "baz")', - [ +@pytest.mark.parametrize( + "data, expected", + [ + ( + 'msg = ("bar " "baz")', + [ + ( + 1, ( - 1, - ( - "String unnecessarily split in two by black. " - "Please merge them manually." - ), - ) - ], - ), - ( - 'msg = ("foo " "bar " "baz")', - [ + "String unnecessarily split in two by black. " + "Please merge them manually." + ), + ) + ], + ), + ( + 'msg = ("foo " "bar " "baz")', + [ + ( + 1, ( - 1, - ( - "String unnecessarily split in two by black. " - "Please merge them manually." - ), + "String unnecessarily split in two by black. " + "Please merge them manually." ), + ), + ( + 1, ( - 1, - ( - "String unnecessarily split in two by black. " - "Please merge them manually." - ), + "String unnecessarily split in two by black. " + "Please merge them manually." ), - ], - ), - ], - ) - def test_strings_to_concatenate(self, data, expected): - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) - assert result == expected + ), + ], + ), + ], +) +def test_strings_to_concatenate(data, expected): + fd = io.StringIO(data.strip()) + result = list(validate_unwanted_patterns.strings_to_concatenate(fd)) + assert result == expected -class TestStringsWithWrongPlacedWhitespace: - @pytest.mark.parametrize( - "data, expected", - [ +@pytest.mark.parametrize( + "data, expected", + [ + ( ( - ( - """ + """ msg = ( - "foo" + "foo\n" " bar" ) """ - ), - [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], ), + [], + ), + ( ( - ( - """ + """ msg = ( - f"foo" - " bar" + "foo" + " bar" + "baz" ) """ - ), - [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], ), + [], + ), + ( ( - ( - """ + """ msg = ( - "foo" - f" bar" + f"foo" + " bar" ) """ - ), - [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], ), + [], + ), + ( ( - ( - """ + """ msg = ( - f"foo" - f" bar" + "foo" + f" bar" ) """ - ), - [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], ), + [], + ), + ( ( - ( - """ + """ msg = ( "foo" - rf" bar" - " baz" + rf" bar" ) """ - ), - [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ), - ( - 4, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ), - ], ), + [], + ), + ( ( - ( - """ + """ msg = ( "foo" " bar" - rf" baz" ) """ - ), - [ + ), + [ + ( + 3, ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), + "String has a space at the beginning instead " + "of the end of the previous string." ), + ) + ], + ), + ( + ( + """ +msg = ( + f"foo" + " bar" +) +""" + ), + [ + ( + 3, ( - 4, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), + "String has a space at the beginning instead " + "of the end of the previous string." ), - ], - ), + ) + ], + ), + ( ( - ( - """ + """ msg = ( "foo" - rf" bar" - rf" baz" + f" bar" ) """ - ), - [ - ( - 3, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ), + ), + [ + ( + 3, ( - 4, - ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), + "String has a space at the beginning instead " + "of the end of the previous string." ), - ], - ), - ], - ) - def test_strings_with_wrong_placed_whitespace(self, data, expected): - fd = io.StringIO(data.strip()) - result = list( - validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) - ) - assert result == expected - - @pytest.mark.parametrize( - "data, expected", - [ + ) + ], + ), + ( ( - ( - """ + """ msg = ( - "foo\n" - " bar" + f"foo" + f" bar" ) """ - ), - [], ), - ( + [ ( - """ + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], + ), + ( + ( + """ msg = ( "foo" - " bar" - "baz" + rf" bar" + " baz" ) """ - ), - [], ), - ( + [ ( - """ -msg = ( - f"foo" - " bar" -) -""" + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - [], - ), - ( ( - """ + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ], + ), + ( + ( + """ msg = ( "foo" - f" bar" + " bar" + rf" baz" ) """ - ), - [], ), - ( + [ ( - """ + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ( + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ], + ), + ( + ( + """ msg = ( "foo" - rf" bar" + rf" bar" + rf" baz" ) """ - ), - [], ), - ], - ) - def test_excluded_strings_with_wrong_placed_whitespace(self, data, expected): - fd = io.StringIO(data.strip()) - result = list( - validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) - ) - assert result == expected + [ + ( + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ( + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ), + ], + ), + ], +) +def test_strings_with_wrong_placed_whitespace(data, expected): + fd = io.StringIO(data.strip()) + result = list(validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd)) + assert result == expected From 421ffa68b7b2bbd72833a90e003e4c65ce19ff83 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 14 Feb 2020 11:24:36 +0200 Subject: [PATCH 65/69] Seperated test case REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r377162037 --- .../tests/test_validate_unwanted_patterns.py | 227 +++++++++--------- 1 file changed, 113 insertions(+), 114 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index ee2ecced7c97f..e84efff7f6439 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -8,153 +8,152 @@ import validate_string_concatenation as validate_unwanted_patterns -@pytest.mark.parametrize( - "data, expected", - [ - ( +class TestBarePytestRaises: + @pytest.mark.parametrize( + "data", + [ ( """ -with pytest.raises(ValueError, match="foo"): - pass -""" + with pytest.raises(ValueError, match="foo"): + pass + """ ), - [], - ), - ( ( """ -# with pytest.raises(ValueError, match="foo"): -# pass -""" + # with pytest.raises(ValueError, match="foo"): + # pass + """ ), - [], - ), - ( ( """ -# with pytest.raises(ValueError): -# pass -""" + # with pytest.raises(ValueError): + # pass + """ ), - [], - ), - ( ( """ -with pytest.raises( - ValueError, - match="foo" -): - pass -""" + with pytest.raises( + ValueError, + match="foo" + ): + pass + """ ), - [], - ), - ( + ], + ) + def test_pytest_raises(self, data): + fd = io.StringIO(data.strip()) + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + assert result == [] + + @pytest.mark.parametrize( + "data, expected", + [ ( - """ -with pytest.raises(ValueError): - pass -""" - ), - [ ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), - ), - ], - ), - ( - ( - """ -with pytest.raises(ValueError, match="foo"): + """ with pytest.raises(ValueError): pass - pass -""" - ), - [ - ( - 2, + """ + ), + [ ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), ), - ), - ], - ), - ( + ], + ), ( - """ -with pytest.raises(ValueError): + ( + """ with pytest.raises(ValueError, match="foo"): + with pytest.raises(ValueError): + pass pass - pass -""" + """ + ), + [ + ( + 2, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), + ), + ], ), - [ + ( ( - 1, + """ + with pytest.raises(ValueError): + with pytest.raises(ValueError, match="foo"): + pass + pass + """ + ), + [ ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), ), - ), - ], - ), - ( - ( - """ -with pytest.raises( - ValueError -): - pass -""" + ], ), - [ + ( ( - 1, + """ + with pytest.raises( + ValueError + ): + pass + """ + ), + [ ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), ), - ), - ], - ), - ( - ( - """ -with pytest.raises( - ValueError, - # match = "foo" -): - pass -""" + ], ), - [ + ( ( - 1, + """ + with pytest.raises( + ValueError, + # match = "foo" + ): + pass + """ + ), + [ ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." + 1, + ( + "Bare pytests raise have been found. " + "Please pass in the argument 'match' " + "as well the exception." + ), ), - ), - ], - ), - ], -) -def test_pytest_raises(data, expected): - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - assert result == expected + ], + ), + ], + ) + def test_pytest_raises_raises(self, data, expected): + fd = io.StringIO(data.strip()) + result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) + assert result == expected @pytest.mark.parametrize( From 7cbde168af62c745167112e6232dd5d8cef2c5ad Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 14 Feb 2020 11:45:13 +0200 Subject: [PATCH 66/69] Splitted test cases REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r377163380 --- .../tests/test_validate_unwanted_patterns.py | 354 +++++++++--------- 1 file changed, 177 insertions(+), 177 deletions(-) diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index e84efff7f6439..6ad5ab44a29d6 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -198,225 +198,225 @@ def test_strings_to_concatenate(data, expected): assert result == expected -@pytest.mark.parametrize( - "data, expected", - [ - ( +class TestStringsWithWrongPlacedWhitespace: + @pytest.mark.parametrize( + "data", + [ ( """ -msg = ( - "foo\n" - " bar" -) -""" + msg = ( + "foo\n" + " bar" + ) + """ ), - [], - ), - ( ( """ -msg = ( - "foo" - " bar" - "baz" -) -""" + msg = ( + "foo" + " bar" + "baz" + ) + """ ), - [], - ), - ( ( """ -msg = ( - f"foo" - " bar" -) -""" + msg = ( + f"foo" + " bar" + ) + """ ), - [], - ), - ( ( """ -msg = ( - "foo" - f" bar" -) -""" + msg = ( + "foo" + f" bar" + ) + """ ), - [], - ), - ( ( """ -msg = ( - "foo" - rf" bar" -) -""" + msg = ( + "foo" + rf" bar" + ) + """ ), - [], - ), - ( + ], + ) + def test_strings_with_wrong_placed_whitespace(self, data): + fd = io.StringIO(data.strip()) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + assert result == [] + + @pytest.mark.parametrize( + "data, expected", + [ ( - """ -msg = ( - "foo" - " bar" -) -""" - ), - [ ( - 3, + """ + msg = ( + "foo" + " bar" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], - ), - ( - ( - """ -msg = ( - f"foo" - " bar" -) -""" + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], ), - [ + ( ( - 3, + """ + msg = ( + f"foo" + " bar" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], - ), - ( - ( - """ -msg = ( - "foo" - f" bar" -) -""" + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], ), - [ + ( ( - 3, + """ + msg = ( + "foo" + f" bar" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], - ), - ( - ( - """ -msg = ( - f"foo" - f" bar" -) -""" + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], ), - [ + ( ( - 3, + """ + msg = ( + f"foo" + f" bar" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." - ), - ) - ], - ), - ( - ( - """ -msg = ( - "foo" - rf" bar" - " baz" -) -""" + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), + ) + ], ), - [ + ( ( - 3, + """ + msg = ( + "foo" + rf" bar" + " baz" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - ), - ( - 4, ( - "String has a space at the beginning instead " - "of the end of the previous string." + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - ), - ], - ), - ( - ( - """ -msg = ( - "foo" - " bar" - rf" baz" -) -""" + ], ), - [ + ( ( - 3, + """ + msg = ( + "foo" + " bar" + rf" baz" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - ), - ( - 4, ( - "String has a space at the beginning instead " - "of the end of the previous string." + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - ), - ], - ), - ( - ( - """ -msg = ( - "foo" - rf" bar" - rf" baz" -) -""" + ], ), - [ + ( ( - 3, + """ + msg = ( + "foo" + rf" bar" + rf" baz" + ) + """ + ), + [ ( - "String has a space at the beginning instead " - "of the end of the previous string." + 3, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - ), - ( - 4, ( - "String has a space at the beginning instead " - "of the end of the previous string." + 4, + ( + "String has a space at the beginning instead " + "of the end of the previous string." + ), ), - ), - ], - ), - ], -) -def test_strings_with_wrong_placed_whitespace(data, expected): - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd)) - assert result == expected + ], + ), + ], + ) + def test_strings_with_wrong_placed_whitespace_raises(self, data, expected): + fd = io.StringIO(data.strip()) + result = list( + validate_unwanted_patterns.strings_with_wrong_placed_whitespace(fd) + ) + assert result == expected From a2a12fc39417721c5722e0fb9fbe17aff698e556 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <50263213+MomIsBestFriend@users.noreply.github.com> Date: Fri, 14 Feb 2020 11:48:04 +0200 Subject: [PATCH 67/69] Update scripts/validate_string_concatenation.py Co-Authored-By: William Ayd --- scripts/validate_string_concatenation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index a95afe4314157..24cacde4290d6 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -17,7 +17,7 @@ import tokenize from typing import IO, Callable, Generator, List, Tuple -FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pyx.ini", ".pxd") +FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pxi.in", ".pxd") def _get_literal_string_prefix_len(token_string: str) -> int: From ff6ba1165bde66ac33775a48bb918bfe4ea23ade Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 14 Feb 2020 12:10:13 +0200 Subject: [PATCH 68/69] Typing change as @WillAyd suggested REF: https://github.com/pandas-dev/pandas/pull/30755#discussion_r377165490 --- scripts/validate_string_concatenation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index 24cacde4290d6..f96182b4e2bba 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -15,7 +15,7 @@ import sys import token import tokenize -from typing import IO, Callable, Generator, List, Tuple +from typing import IO, Callable, Iterable, List, Tuple FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pxi.in", ".pxd") @@ -53,7 +53,7 @@ def _get_literal_string_prefix_len(token_string: str) -> int: return 0 -def bare_pytest_raises(file_obj: IO[str]) -> Generator[Tuple[int, str], None, None]: +def bare_pytest_raises(file_obj: IO[str]) -> Iterable[Tuple[int, str]]: """ Test Case for bare pytest raises. @@ -102,7 +102,7 @@ def bare_pytest_raises(file_obj: IO[str]) -> Generator[Tuple[int, str], None, No break -def strings_to_concatenate(file_obj: IO[str]) -> Generator[Tuple[int, str], None, None]: +def strings_to_concatenate(file_obj: IO[str]) -> Iterable[Tuple[int, str]]: """ This test case is necessary after 'Black' (https://github.com/psf/black), is formating strings over multiple lines. @@ -153,7 +153,7 @@ def strings_to_concatenate(file_obj: IO[str]) -> Generator[Tuple[int, str], None def strings_with_wrong_placed_whitespace( file_obj: IO[str], -) -> Generator[Tuple[int, str], None, None]: +) -> Iterable[Tuple[int, str]]: """ Test case for leading spaces in concated strings. @@ -277,7 +277,7 @@ def has_wrong_whitespace(first_line: str, second_line: str) -> bool: def main( - function: Callable[[IO[str]], Generator[Tuple[int, str], None, None]], + function: Callable[[IO[str]], Iterable[Tuple[int, str]]], source_path: str, output_format: str, ) -> bool: From b1568f1a25145711916a9104f9c07407510e4265 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Fri, 14 Feb 2020 13:05:50 +0200 Subject: [PATCH 69/69] Reverted a2a12fc39417721c5722e0fb9fbe17aff698e556 --- scripts/validate_string_concatenation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/validate_string_concatenation.py b/scripts/validate_string_concatenation.py index f96182b4e2bba..c4be85ffe7306 100755 --- a/scripts/validate_string_concatenation.py +++ b/scripts/validate_string_concatenation.py @@ -17,7 +17,7 @@ import tokenize from typing import IO, Callable, Iterable, List, Tuple -FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pxi.in", ".pxd") +FILE_EXTENSIONS_TO_CHECK: Tuple[str, ...] = (".py", ".pyx", ".pxi.ini", ".pxd") def _get_literal_string_prefix_len(token_string: str) -> int: