From e86d859b792769b422f96fd625efebd8f60118e4 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Sun, 7 Mar 2021 20:21:07 +0100 Subject: Create subdirectory for crowded functional tests --- .pre-commit-config.yaml | 2 +- .../functional/a/abstract/abstract_abc_methods.py | 17 + .../abstract_class_instantiated_in_class.py | 17 + .../a/abstract/abstract_class_instantiated_py3.py | 128 +++ .../a/abstract/abstract_class_instantiated_py3.rc | 2 + .../a/abstract/abstract_class_instantiated_py3.txt | 5 + .../a/abstract/abstract_class_instantiated_py34.py | 19 + .../a/abstract/abstract_class_instantiated_py34.rc | 2 + .../abstract/abstract_class_instantiated_py34.txt | 1 + tests/functional/a/abstract/abstract_method_py3.py | 107 ++ tests/functional/a/abstract/abstract_method_py3.rc | 2 + .../functional/a/abstract/abstract_method_py3.txt | 16 + tests/functional/a/abstract_abc_methods.py | 17 - .../a/abstract_class_instantiated_in_class.py | 17 - .../a/abstract_class_instantiated_py3.py | 128 --- .../a/abstract_class_instantiated_py3.rc | 2 - .../a/abstract_class_instantiated_py3.txt | 5 - .../a/abstract_class_instantiated_py34.py | 19 - .../a/abstract_class_instantiated_py34.rc | 2 - .../a/abstract_class_instantiated_py34.txt | 1 - tests/functional/a/abstract_method_py3.py | 107 -- tests/functional/a/abstract_method_py3.rc | 2 - tests/functional/a/abstract_method_py3.txt | 16 - .../c/consider/consider_iterating_dictionary.py | 38 + .../c/consider/consider_iterating_dictionary.txt | 15 + tests/functional/c/consider/consider_join.py | 126 +++ tests/functional/c/consider/consider_join.txt | 11 + .../c/consider/consider_merging_isinstance.py | 37 + .../c/consider/consider_merging_isinstance.txt | 7 + .../c/consider/consider_swap_variables.py | 25 + .../c/consider/consider_swap_variables.txt | 2 + .../consider/consider_using_dict_comprehension.py | 12 + .../consider/consider_using_dict_comprehension.txt | 1 + .../c/consider/consider_using_enumerate.py | 73 ++ .../c/consider/consider_using_enumerate.txt | 4 + .../c/consider/consider_using_generator.py | 11 + .../c/consider/consider_using_generator.txt | 2 + tests/functional/c/consider/consider_using_get.py | 90 ++ tests/functional/c/consider/consider_using_get.txt | 4 + tests/functional/c/consider/consider_using_in.py | 46 + tests/functional/c/consider/consider_using_in.txt | 13 + .../c/consider/consider_using_set_comprehension.py | 9 + .../consider/consider_using_set_comprehension.txt | 1 + .../c/consider/consider_using_sys_exit.py | 14 + .../c/consider/consider_using_sys_exit.txt | 3 + .../c/consider/consider_using_sys_exit_exempted.py | 5 + .../consider_using_sys_exit_local_scope.py | 5 + .../functional/c/consider_iterating_dictionary.py | 38 - .../functional/c/consider_iterating_dictionary.txt | 15 - tests/functional/c/consider_join.py | 126 --- tests/functional/c/consider_join.txt | 11 - tests/functional/c/consider_merging_isinstance.py | 37 - tests/functional/c/consider_merging_isinstance.txt | 7 - tests/functional/c/consider_swap_variables.py | 25 - tests/functional/c/consider_swap_variables.txt | 2 - .../c/consider_using_dict_comprehension.py | 12 - .../c/consider_using_dict_comprehension.txt | 1 - tests/functional/c/consider_using_enumerate.py | 73 -- tests/functional/c/consider_using_enumerate.txt | 4 - tests/functional/c/consider_using_generator.py | 11 - tests/functional/c/consider_using_generator.txt | 2 - tests/functional/c/consider_using_get.py | 90 -- tests/functional/c/consider_using_get.txt | 4 - tests/functional/c/consider_using_in.py | 46 - tests/functional/c/consider_using_in.txt | 13 - .../c/consider_using_set_comprehension.py | 9 - .../c/consider_using_set_comprehension.txt | 1 - tests/functional/c/consider_using_sys_exit.py | 14 - tests/functional/c/consider_using_sys_exit.txt | 3 - .../c/consider_using_sys_exit_exempted.py | 5 - .../c/consider_using_sys_exit_local_scope.py | 5 - .../deprecated/deprecated_method_getmoduleinfo.py | 4 + .../deprecated/deprecated_method_getmoduleinfo.rc | 3 + .../deprecated/deprecated_method_getmoduleinfo.txt | 1 + .../d/deprecated/deprecated_methods_py3.py | 50 + .../d/deprecated/deprecated_methods_py3.rc | 3 + .../d/deprecated/deprecated_methods_py3.txt | 16 + .../d/deprecated/deprecated_methods_py36.py | 7 + .../d/deprecated/deprecated_methods_py36.rc | 2 + .../d/deprecated/deprecated_methods_py36.txt | 2 + .../d/deprecated/deprecated_methods_py38.py | 45 + .../d/deprecated/deprecated_methods_py38.rc | 3 + .../d/deprecated/deprecated_methods_py38.txt | 13 + .../d/deprecated/deprecated_module_py3.py | 4 + .../d/deprecated/deprecated_module_py3.rc | 3 + .../d/deprecated/deprecated_module_py3.txt | 1 + .../d/deprecated/deprecated_module_py36.py | 4 + .../d/deprecated/deprecated_module_py36.rc | 2 + .../d/deprecated/deprecated_module_py36.txt | 1 + .../d/deprecated/deprecated_module_py4.py | 4 + .../d/deprecated/deprecated_module_py4.rc | 4 + .../d/deprecated/deprecated_module_py4.txt | 2 + .../d/deprecated/deprecated_module_uninstalled.py | 5 + .../d/deprecated/deprecated_module_uninstalled.rc | 2 + .../d/deprecated/deprecated_module_uninstalled.txt | 2 + .../d/deprecated_method_getmoduleinfo.py | 4 - .../d/deprecated_method_getmoduleinfo.rc | 3 - .../d/deprecated_method_getmoduleinfo.txt | 1 - tests/functional/d/deprecated_methods_py3.py | 50 - tests/functional/d/deprecated_methods_py3.rc | 3 - tests/functional/d/deprecated_methods_py3.txt | 16 - tests/functional/d/deprecated_methods_py36.py | 7 - tests/functional/d/deprecated_methods_py36.rc | 2 - tests/functional/d/deprecated_methods_py36.txt | 2 - tests/functional/d/deprecated_methods_py38.py | 45 - tests/functional/d/deprecated_methods_py38.rc | 3 - tests/functional/d/deprecated_methods_py38.txt | 13 - tests/functional/d/deprecated_module_py3.py | 4 - tests/functional/d/deprecated_module_py3.rc | 3 - tests/functional/d/deprecated_module_py3.txt | 1 - tests/functional/d/deprecated_module_py36.py | 4 - tests/functional/d/deprecated_module_py36.rc | 2 - tests/functional/d/deprecated_module_py36.txt | 1 - tests/functional/d/deprecated_module_py4.py | 4 - tests/functional/d/deprecated_module_py4.rc | 4 - tests/functional/d/deprecated_module_py4.txt | 2 - .../functional/d/deprecated_module_uninstalled.py | 5 - .../functional/d/deprecated_module_uninstalled.rc | 2 - .../functional/d/deprecated_module_uninstalled.txt | 2 - tests/functional/i/implicit/implicit_str_concat.py | 31 + .../functional/i/implicit/implicit_str_concat.txt | 5 + .../i/implicit/implicit_str_concat_latin1.py | 4 + .../i/implicit/implicit_str_concat_multiline.py | 4 + .../i/implicit/implicit_str_concat_multiline.rc | 2 + .../i/implicit/implicit_str_concat_multiline.txt | 1 + .../i/implicit/implicit_str_concat_utf8.py | 3 + tests/functional/i/implicit_str_concat.py | 31 - tests/functional/i/implicit_str_concat.txt | 5 - tests/functional/i/implicit_str_concat_latin1.py | 4 - .../functional/i/implicit_str_concat_multiline.py | 4 - .../functional/i/implicit_str_concat_multiline.rc | 2 - .../functional/i/implicit_str_concat_multiline.txt | 1 - tests/functional/i/implicit_str_concat_utf8.py | 3 - .../functional/i/inconsistent/inconsistent_mro.py | 9 + .../functional/i/inconsistent/inconsistent_mro.txt | 1 + .../i/inconsistent/inconsistent_quotes.py | 16 + .../i/inconsistent/inconsistent_quotes.rc | 2 + .../i/inconsistent/inconsistent_quotes.txt | 1 + .../i/inconsistent/inconsistent_quotes2.py | 10 + .../i/inconsistent/inconsistent_quotes2.rc | 2 + .../i/inconsistent/inconsistent_quotes2.txt | 1 + .../i/inconsistent/inconsistent_returns.py | 337 +++++++ .../i/inconsistent/inconsistent_returns.rc | 2 + .../i/inconsistent/inconsistent_returns.txt | 16 + tests/functional/i/inconsistent_mro.py | 9 - tests/functional/i/inconsistent_mro.txt | 1 - tests/functional/i/inconsistent_quotes.py | 16 - tests/functional/i/inconsistent_quotes.rc | 2 - tests/functional/i/inconsistent_quotes.txt | 1 - tests/functional/i/inconsistent_quotes2.py | 10 - tests/functional/i/inconsistent_quotes2.rc | 2 - tests/functional/i/inconsistent_quotes2.txt | 1 - tests/functional/i/inconsistent_returns.py | 337 ------- tests/functional/i/inconsistent_returns.rc | 2 - tests/functional/i/inconsistent_returns.txt | 16 - tests/functional/i/invalid/invalid_all_object.py | 6 + tests/functional/i/invalid/invalid_all_object.txt | 3 + .../functional/i/invalid/invalid_bool_returned.py | 62 ++ .../functional/i/invalid/invalid_bool_returned.txt | 3 + .../functional/i/invalid/invalid_bytes_returned.py | 64 ++ .../i/invalid/invalid_bytes_returned.txt | 3 + tests/functional/i/invalid/invalid_envvar_value.py | 84 ++ .../functional/i/invalid/invalid_envvar_value.txt | 31 + .../i/invalid/invalid_exceptions_caught.py | 135 +++ .../i/invalid/invalid_exceptions_caught.rc | 2 + .../i/invalid/invalid_exceptions_caught.txt | 12 + .../i/invalid/invalid_exceptions_raised.py | 105 ++ .../i/invalid/invalid_exceptions_raised.txt | 10 + .../i/invalid/invalid_format_returned.py | 64 ++ .../i/invalid/invalid_format_returned.txt | 3 + .../i/invalid/invalid_getnewargs_ex_returned.py | 85 ++ .../i/invalid/invalid_getnewargs_ex_returned.txt | 6 + .../i/invalid/invalid_getnewargs_returned.py | 62 ++ .../i/invalid/invalid_getnewargs_returned.txt | 3 + .../functional/i/invalid/invalid_hash_returned.py | 71 ++ .../functional/i/invalid/invalid_hash_returned.txt | 4 + .../functional/i/invalid/invalid_index_returned.py | 71 ++ .../i/invalid/invalid_index_returned.txt | 4 + .../i/invalid/invalid_length_hint_returned.py | 64 ++ .../i/invalid/invalid_length_hint_returned.txt | 3 + .../i/invalid/invalid_length_returned.py | 64 ++ .../i/invalid/invalid_length_returned.txt | 3 + tests/functional/i/invalid/invalid_metaclass.py | 34 + .../functional/i/invalid/invalid_metaclass_py3.py | 19 + .../functional/i/invalid/invalid_metaclass_py3.rc | 2 + tests/functional/i/invalid/invalid_name.py | 44 + tests/functional/i/invalid/invalid_name.txt | 4 + .../i/invalid/invalid_overridden_method.py | 77 ++ .../i/invalid/invalid_overridden_method.txt | 4 + .../functional/i/invalid/invalid_repr_returned.py | 64 ++ .../functional/i/invalid/invalid_repr_returned.txt | 3 + .../functional/i/invalid/invalid_sequence_index.py | 242 +++++ .../i/invalid/invalid_sequence_index.txt | 19 + tests/functional/i/invalid/invalid_slice_index.py | 71 ++ tests/functional/i/invalid/invalid_slice_index.txt | 5 + .../i/invalid/invalid_star_assignment_target.py | 4 + .../i/invalid/invalid_star_assignment_target.rc | 2 + .../i/invalid/invalid_star_assignment_target.txt | 1 + tests/functional/i/invalid/invalid_str_returned.py | 64 ++ .../functional/i/invalid/invalid_str_returned.txt | 3 + .../i/invalid/invalid_unary_operand_type.py | 51 + .../i/invalid/invalid_unary_operand_type.txt | 14 + tests/functional/i/invalid_all_object.py | 6 - tests/functional/i/invalid_all_object.txt | 3 - tests/functional/i/invalid_bool_returned.py | 62 -- tests/functional/i/invalid_bool_returned.txt | 3 - tests/functional/i/invalid_bytes_returned.py | 64 -- tests/functional/i/invalid_bytes_returned.txt | 3 - tests/functional/i/invalid_envvar_value.py | 84 -- tests/functional/i/invalid_envvar_value.txt | 31 - tests/functional/i/invalid_exceptions_caught.py | 135 --- tests/functional/i/invalid_exceptions_caught.rc | 2 - tests/functional/i/invalid_exceptions_caught.txt | 12 - tests/functional/i/invalid_exceptions_raised.py | 105 -- tests/functional/i/invalid_exceptions_raised.txt | 10 - tests/functional/i/invalid_format_returned.py | 64 -- tests/functional/i/invalid_format_returned.txt | 3 - .../functional/i/invalid_getnewargs_ex_returned.py | 85 -- .../i/invalid_getnewargs_ex_returned.txt | 6 - tests/functional/i/invalid_getnewargs_returned.py | 62 -- tests/functional/i/invalid_getnewargs_returned.txt | 3 - tests/functional/i/invalid_hash_returned.py | 71 -- tests/functional/i/invalid_hash_returned.txt | 4 - tests/functional/i/invalid_index_returned.py | 71 -- tests/functional/i/invalid_index_returned.txt | 4 - tests/functional/i/invalid_length_hint_returned.py | 64 -- .../functional/i/invalid_length_hint_returned.txt | 3 - tests/functional/i/invalid_length_returned.py | 64 -- tests/functional/i/invalid_length_returned.txt | 3 - tests/functional/i/invalid_metaclass.py | 34 - tests/functional/i/invalid_metaclass_py3.py | 19 - tests/functional/i/invalid_metaclass_py3.rc | 2 - tests/functional/i/invalid_name.py | 44 - tests/functional/i/invalid_name.txt | 4 - tests/functional/i/invalid_overridden_method.py | 77 -- tests/functional/i/invalid_overridden_method.txt | 4 - tests/functional/i/invalid_repr_returned.py | 64 -- tests/functional/i/invalid_repr_returned.txt | 3 - tests/functional/i/invalid_sequence_index.py | 242 ----- tests/functional/i/invalid_sequence_index.txt | 19 - tests/functional/i/invalid_slice_index.py | 71 -- tests/functional/i/invalid_slice_index.txt | 5 - .../functional/i/invalid_star_assignment_target.py | 4 - .../functional/i/invalid_star_assignment_target.rc | 2 - .../i/invalid_star_assignment_target.txt | 1 - tests/functional/i/invalid_str_returned.py | 64 -- tests/functional/i/invalid_str_returned.txt | 3 - tests/functional/i/invalid_unary_operand_type.py | 51 - tests/functional/i/invalid_unary_operand_type.txt | 14 - tests/functional/m/member/member_checks.py | 233 +++++ tests/functional/m/member/member_checks.txt | 19 + tests/functional/m/member/member_checks_hints.py | 27 + tests/functional/m/member/member_checks_hints.rc | 3 + tests/functional/m/member/member_checks_hints.txt | 5 + .../m/member/member_checks_ignore_none.py | 7 + .../m/member/member_checks_ignore_none.rc | 2 + .../m/member/member_checks_ignore_none.txt | 1 + .../member/member_checks_inference_improvements.py | 11 + .../functional/m/member/member_checks_no_hints.py | 27 + .../functional/m/member/member_checks_no_hints.rc | 2 + .../functional/m/member/member_checks_no_hints.txt | 5 + tests/functional/m/member/member_checks_opaque.py | 12 + tests/functional/m/member/member_checks_opaque.rc | 2 + tests/functional/m/member/member_checks_opaque.txt | 1 + tests/functional/m/member/member_checks_py37.py | 19 + tests/functional/m/member/member_checks_py37.rc | 2 + tests/functional/m/member/member_checks_py37.txt | 1 + .../m/member/member_checks_typed_annotations.py | 25 + .../m/member/member_checks_typed_annotations.txt | 1 + tests/functional/m/member/membership_protocol.py | 123 +++ tests/functional/m/member/membership_protocol.txt | 7 + .../functional/m/member/membership_protocol_py3.py | 36 + .../functional/m/member/membership_protocol_py3.rc | 2 + .../m/member/membership_protocol_py3.txt | 3 + tests/functional/m/member_checks.py | 233 ----- tests/functional/m/member_checks.txt | 19 - tests/functional/m/member_checks_hints.py | 27 - tests/functional/m/member_checks_hints.rc | 3 - tests/functional/m/member_checks_hints.txt | 5 - tests/functional/m/member_checks_ignore_none.py | 7 - tests/functional/m/member_checks_ignore_none.rc | 2 - tests/functional/m/member_checks_ignore_none.txt | 1 - .../m/member_checks_inference_improvements.py | 11 - tests/functional/m/member_checks_no_hints.py | 27 - tests/functional/m/member_checks_no_hints.rc | 2 - tests/functional/m/member_checks_no_hints.txt | 5 - tests/functional/m/member_checks_opaque.py | 12 - tests/functional/m/member_checks_opaque.rc | 2 - tests/functional/m/member_checks_opaque.txt | 1 - tests/functional/m/member_checks_py37.py | 19 - tests/functional/m/member_checks_py37.rc | 2 - tests/functional/m/member_checks_py37.txt | 1 - .../m/member_checks_typed_annotations.py | 25 - .../m/member_checks_typed_annotations.txt | 1 - tests/functional/m/membership_protocol.py | 123 --- tests/functional/m/membership_protocol.txt | 7 - tests/functional/m/membership_protocol_py3.py | 36 - tests/functional/m/membership_protocol_py3.rc | 2 - tests/functional/m/membership_protocol_py3.txt | 3 - tests/functional/m/missing/missing_docstring.py | 58 ++ tests/functional/m/missing/missing_docstring.txt | 3 + .../m/missing/missing_docstring_new_style.py | 47 + .../m/missing/missing_docstring_new_style.txt | 5 + .../functional/m/missing/missing_final_newline.py | 4 + .../functional/m/missing/missing_final_newline.txt | 1 + tests/functional/m/missing/missing_kwoa_py3.py | 73 ++ tests/functional/m/missing/missing_kwoa_py3.rc | 2 + tests/functional/m/missing/missing_kwoa_py3.txt | 3 + .../m/missing/missing_module_docstring_disabled.py | 5 + .../missing_parentheses_for_call_in_test.py | 95 ++ .../missing_parentheses_for_call_in_test.txt | 15 + .../functional/m/missing/missing_self_argument.py | 21 + .../functional/m/missing/missing_self_argument.txt | 3 + tests/functional/m/missing_docstring.py | 58 -- tests/functional/m/missing_docstring.txt | 3 - tests/functional/m/missing_docstring_new_style.py | 47 - tests/functional/m/missing_docstring_new_style.txt | 5 - tests/functional/m/missing_final_newline.py | 4 - tests/functional/m/missing_final_newline.txt | 1 - tests/functional/m/missing_kwoa_py3.py | 73 -- tests/functional/m/missing_kwoa_py3.rc | 2 - tests/functional/m/missing_kwoa_py3.txt | 3 - .../m/missing_module_docstring_disabled.py | 5 - .../m/missing_parentheses_for_call_in_test.py | 95 -- .../m/missing_parentheses_for_call_in_test.txt | 15 - tests/functional/m/missing_self_argument.py | 21 - tests/functional/m/missing_self_argument.txt | 3 - tests/functional/n/name/namePresetCamelCase.py | 23 + tests/functional/n/name/namePresetCamelCase.rc | 13 + tests/functional/n/name/namePresetCamelCase.txt | 3 + .../functional/n/name/name_good_bad_names_regex.py | 20 + .../functional/n/name/name_good_bad_names_regex.rc | 15 + .../n/name/name_good_bad_names_regex.txt | 3 + tests/functional/n/name/name_preset_snake_case.py | 35 + tests/functional/n/name/name_preset_snake_case.rc | 14 + tests/functional/n/name/name_preset_snake_case.txt | 5 + tests/functional/n/name/name_styles.py | 156 +++ tests/functional/n/name/name_styles.rc | 5 + tests/functional/n/name/name_styles.txt | 18 + .../n/name/namedtuple_member_inference.py | 22 + .../n/name/namedtuple_member_inference.txt | 1 + tests/functional/n/name/names_in__all__.py | 49 + tests/functional/n/name/names_in__all__.txt | 6 + tests/functional/n/namePresetCamelCase.py | 23 - tests/functional/n/namePresetCamelCase.rc | 13 - tests/functional/n/namePresetCamelCase.txt | 3 - tests/functional/n/name_good_bad_names_regex.py | 20 - tests/functional/n/name_good_bad_names_regex.rc | 15 - tests/functional/n/name_good_bad_names_regex.txt | 3 - tests/functional/n/name_preset_snake_case.py | 35 - tests/functional/n/name_preset_snake_case.rc | 14 - tests/functional/n/name_preset_snake_case.txt | 5 - tests/functional/n/name_styles.py | 156 --- tests/functional/n/name_styles.rc | 5 - tests/functional/n/name_styles.txt | 18 - tests/functional/n/namedtuple_member_inference.py | 22 - tests/functional/n/namedtuple_member_inference.txt | 1 - tests/functional/n/names_in__all__.py | 49 - tests/functional/n/names_in__all__.txt | 6 - tests/functional/n/no/__init__.py | 0 tests/functional/n/no/no_classmethod_decorator.py | 35 + tests/functional/n/no/no_classmethod_decorator.txt | 3 + tests/functional/n/no/no_else_break.py | 137 +++ tests/functional/n/no/no_else_break.txt | 7 + tests/functional/n/no/no_else_continue.py | 137 +++ tests/functional/n/no/no_else_continue.txt | 7 + tests/functional/n/no/no_else_raise.py | 110 +++ tests/functional/n/no/no_else_raise.txt | 7 + tests/functional/n/no/no_else_return.py | 110 +++ tests/functional/n/no/no_else_return.txt | 7 + tests/functional/n/no/no_method_argument_py38.py | 6 + tests/functional/n/no/no_method_argument_py38.rc | 2 + tests/functional/n/no/no_name_in_module.py | 66 ++ tests/functional/n/no/no_name_in_module.txt | 14 + tests/functional/n/no/no_self_argument_py37.py | 15 + tests/functional/n/no/no_self_argument_py37.rc | 2 + tests/functional/n/no/no_self_argument_py37.txt | 1 + tests/functional/n/no/no_self_use.py | 78 ++ tests/functional/n/no/no_self_use.txt | 1 + tests/functional/n/no/no_self_use_py3.py | 12 + tests/functional/n/no/no_self_use_py3.rc | 2 + tests/functional/n/no/no_staticmethod_decorator.py | 35 + .../functional/n/no/no_staticmethod_decorator.txt | 3 + tests/functional/n/no_classmethod_decorator.py | 35 - tests/functional/n/no_classmethod_decorator.txt | 3 - tests/functional/n/no_else_break.py | 137 --- tests/functional/n/no_else_break.txt | 7 - tests/functional/n/no_else_continue.py | 137 --- tests/functional/n/no_else_continue.txt | 7 - tests/functional/n/no_else_raise.py | 110 --- tests/functional/n/no_else_raise.txt | 7 - tests/functional/n/no_else_return.py | 110 --- tests/functional/n/no_else_return.txt | 7 - tests/functional/n/no_method_argument_py38.py | 6 - tests/functional/n/no_method_argument_py38.rc | 2 - tests/functional/n/no_name_in_module.py | 66 -- tests/functional/n/no_name_in_module.txt | 14 - tests/functional/n/no_self_argument_py37.py | 15 - tests/functional/n/no_self_argument_py37.rc | 2 - tests/functional/n/no_self_argument_py37.txt | 1 - tests/functional/n/no_self_use.py | 78 -- tests/functional/n/no_self_use.txt | 1 - tests/functional/n/no_self_use_py3.py | 12 - tests/functional/n/no_self_use_py3.rc | 2 - tests/functional/n/no_staticmethod_decorator.py | 35 - tests/functional/n/no_staticmethod_decorator.txt | 3 - tests/functional/r/raise/raise_missing_from.py | 157 +++ tests/functional/r/raise/raise_missing_from.txt | 7 + tests/functional/r/raise/raising_format_tuple.py | 51 + tests/functional/r/raise/raising_format_tuple.txt | 7 + .../r/raise/raising_non_exception_py3.py | 13 + .../r/raise/raising_non_exception_py3.rc | 2 + .../r/raise/raising_non_exception_py3.txt | 1 + tests/functional/r/raise/raising_self.py | 10 + tests/functional/r/raise_missing_from.py | 157 --- tests/functional/r/raise_missing_from.txt | 7 - tests/functional/r/raising_format_tuple.py | 51 - tests/functional/r/raising_format_tuple.txt | 7 - tests/functional/r/raising_non_exception_py3.py | 13 - tests/functional/r/raising_non_exception_py3.rc | 2 - tests/functional/r/raising_non_exception_py3.txt | 1 - tests/functional/r/raising_self.py | 10 - .../functional/r/recursion/recursion_error_2667.py | 9 + .../functional/r/recursion/recursion_error_2836.py | 18 + .../functional/r/recursion/recursion_error_2861.py | 9 + .../functional/r/recursion/recursion_error_2899.py | 9 + .../functional/r/recursion/recursion_error_2906.py | 14 + .../functional/r/recursion/recursion_error_3152.py | 7 + .../functional/r/recursion/recursion_error_3159.py | 26 + .../functional/r/recursion/recursion_error_940.py | 13 + .../r/recursion/recursion_error_crash.py | 9 + .../r/recursion/recursion_error_crash_2683.py | 13 + .../recursion/recursion_error_crash_astroid_623.py | 10 + .../r/recursion/recursion_regression_2960.py | 4 + tests/functional/r/recursion_error_2667.py | 9 - tests/functional/r/recursion_error_2836.py | 18 - tests/functional/r/recursion_error_2861.py | 9 - tests/functional/r/recursion_error_2899.py | 9 - tests/functional/r/recursion_error_2906.py | 14 - tests/functional/r/recursion_error_3152.py | 7 - tests/functional/r/recursion_error_3159.py | 26 - tests/functional/r/recursion_error_940.py | 13 - tests/functional/r/recursion_error_crash.py | 9 - tests/functional/r/recursion_error_crash_2683.py | 13 - .../r/recursion_error_crash_astroid_623.py | 10 - tests/functional/r/recursion_regression_2960.py | 4 - .../regression_1326_crash_uninferable.py | 12 + .../regression/regression_2443_duplicate_bases.py | 28 + .../regression/regression_2443_duplicate_bases.rc | 2 + .../r/regression/regression_2937_ifexp.py | 20 + tests/functional/r/regression/regression_3091.py | 6 + .../regression_3231_no_member_property.py | 20 + .../regression_3416_unused_argument_raise.py | 14 + .../regression_3416_unused_argument_raise.txt | 3 + .../regression_infer_call_result_3690.py | 11 + .../r/regression/regression_no_member_1078.py | 14 + .../regression_no_value_for_parameter.py | 42 + .../r/regression/regression_posonly_args.py | 21 + .../r/regression/regression_posonly_args.rc | 2 + .../regression_property_no_member_2641.py | 40 + .../regression_property_no_member_3269.py | 23 + .../regression_property_no_member_844.py | 18 + .../regression_property_no_member_870.py | 15 + .../r/regression/regression_property_slots_2439.py | 22 + .../regression_too_many_arguments_2335.py | 11 + .../r/regression_1326_crash_uninferable.py | 12 - .../r/regression_2443_duplicate_bases.py | 28 - .../r/regression_2443_duplicate_bases.rc | 2 - tests/functional/r/regression_2937_ifexp.py | 20 - tests/functional/r/regression_3091.py | 6 - .../r/regression_3231_no_member_property.py | 20 - .../r/regression_3416_unused_argument_raise.py | 14 - .../r/regression_3416_unused_argument_raise.txt | 3 - .../r/regression_infer_call_result_3690.py | 11 - tests/functional/r/regression_no_member_1078.py | 14 - .../r/regression_no_value_for_parameter.py | 42 - tests/functional/r/regression_posonly_args.py | 21 - tests/functional/r/regression_posonly_args.rc | 2 - .../r/regression_property_no_member_2641.py | 40 - .../r/regression_property_no_member_3269.py | 23 - .../r/regression_property_no_member_844.py | 18 - .../r/regression_property_no_member_870.py | 15 - .../functional/r/regression_property_slots_2439.py | 22 - .../r/regression_too_many_arguments_2335.py | 11 - .../s/simplifiable/simplifiable_condition.py | 36 + .../s/simplifiable/simplifiable_condition.txt | 12 + .../s/simplifiable/simplifiable_if_expression.py | 27 + .../s/simplifiable/simplifiable_if_expression.txt | 4 + .../s/simplifiable/simplifiable_if_statement.py | 146 +++ .../s/simplifiable/simplifiable_if_statement.txt | 4 + .../s/simplifiable/simplify_chained_comparison.py | 89 ++ .../s/simplifiable/simplify_chained_comparison.txt | 18 + tests/functional/s/simplifiable_condition.py | 36 - tests/functional/s/simplifiable_condition.txt | 12 - tests/functional/s/simplifiable_if_expression.py | 27 - tests/functional/s/simplifiable_if_expression.txt | 4 - tests/functional/s/simplifiable_if_statement.py | 146 --- tests/functional/s/simplifiable_if_statement.txt | 4 - tests/functional/s/simplify_chained_comparison.py | 89 -- tests/functional/s/simplify_chained_comparison.txt | 18 - tests/functional/s/string/string_formatting.py | 197 ++++ tests/functional/s/string/string_formatting.txt | 41 + .../s/string/string_formatting_disable.py | 1 + .../s/string/string_formatting_disable.rc | 3 + .../s/string/string_formatting_disable.txt | 1 + .../s/string/string_formatting_failed_inference.py | 4 + .../string_formatting_failed_inference_py35.py | 6 + .../string_formatting_failed_inference_py35.rc | 2 + tests/functional/s/string/string_formatting_py3.py | 21 + tests/functional/s/string/string_formatting_py3.rc | 2 + .../functional/s/string/string_formatting_py3.txt | 2 + tests/functional/s/string_formatting.py | 197 ---- tests/functional/s/string_formatting.txt | 41 - tests/functional/s/string_formatting_disable.py | 1 - tests/functional/s/string_formatting_disable.rc | 3 - tests/functional/s/string_formatting_disable.txt | 1 - .../s/string_formatting_failed_inference.py | 4 - .../s/string_formatting_failed_inference_py35.py | 6 - .../s/string_formatting_failed_inference_py35.rc | 2 - tests/functional/s/string_formatting_py3.py | 21 - tests/functional/s/string_formatting_py3.rc | 2 - tests/functional/s/string_formatting_py3.txt | 2 - tests/functional/s/super/super_checks.py | 125 +++ tests/functional/s/super/super_checks.txt | 17 + tests/functional/s/super/super_with_arguments.py | 35 + tests/functional/s/super/super_with_arguments.rc | 3 + tests/functional/s/super/super_with_arguments.txt | 1 + tests/functional/s/super_checks.py | 125 --- tests/functional/s/super_checks.txt | 17 - tests/functional/s/super_with_arguments.py | 35 - tests/functional/s/super_with_arguments.rc | 3 - tests/functional/s/super_with_arguments.txt | 1 - tests/functional/t/too/__init__.py | 0 tests/functional/t/too/too_few_public_methods.py | 50 + tests/functional/t/too/too_few_public_methods.txt | 1 + .../functional/t/too/too_few_public_methods_37.py | 37 + .../functional/t/too/too_few_public_methods_37.rc | 2 + tests/functional/t/too/too_many_ancestors.py | 24 + tests/functional/t/too/too_many_ancestors.txt | 2 + tests/functional/t/too/too_many_arguments.py | 32 + tests/functional/t/too/too_many_arguments.txt | 1 + .../t/too/too_many_arguments_issue_1045.py | 13 + .../t/too/too_many_arguments_issue_1045.rc | 2 + .../t/too/too_many_arguments_overload.py | 38 + .../t/too/too_many_boolean_expressions.py | 20 + .../t/too/too_many_boolean_expressions.txt | 4 + tests/functional/t/too/too_many_branches.py | 69 ++ tests/functional/t/too/too_many_branches.txt | 1 + .../t/too/too_many_instance_attributes.py | 26 + .../t/too/too_many_instance_attributes.txt | 1 + tests/functional/t/too/too_many_lines.py | 1015 +++++++++++++++++++ tests/functional/t/too/too_many_lines.txt | 1 + tests/functional/t/too/too_many_lines_disabled.py | 1018 ++++++++++++++++++++ tests/functional/t/too/too_many_locals.py | 60 ++ tests/functional/t/too/too_many_locals.txt | 3 + tests/functional/t/too/too_many_nested_blocks.py | 97 ++ tests/functional/t/too/too_many_nested_blocks.txt | 2 + tests/functional/t/too/too_many_public_methods.py | 79 ++ tests/functional/t/too/too_many_public_methods.txt | 1 + .../functional/t/too/too_many_return_statements.py | 40 + .../t/too/too_many_return_statements.txt | 1 + .../functional/t/too/too_many_star_expressions.py | 7 + .../functional/t/too/too_many_star_expressions.rc | 2 + .../functional/t/too/too_many_star_expressions.txt | 2 + tests/functional/t/too/too_many_statements.py | 125 +++ tests/functional/t/too/too_many_statements.txt | 2 + tests/functional/too/__init__.py | 0 tests/functional/too/too_few_public_methods.py | 50 - tests/functional/too/too_few_public_methods.txt | 1 - tests/functional/too/too_few_public_methods_37.py | 37 - tests/functional/too/too_few_public_methods_37.rc | 2 - tests/functional/too/too_many_ancestors.py | 24 - tests/functional/too/too_many_ancestors.txt | 2 - tests/functional/too/too_many_arguments.py | 32 - tests/functional/too/too_many_arguments.txt | 1 - .../too/too_many_arguments_issue_1045.py | 13 - .../too/too_many_arguments_issue_1045.rc | 2 - .../functional/too/too_many_arguments_overload.py | 38 - .../functional/too/too_many_boolean_expressions.py | 20 - .../too/too_many_boolean_expressions.txt | 4 - tests/functional/too/too_many_branches.py | 69 -- tests/functional/too/too_many_branches.txt | 1 - .../functional/too/too_many_instance_attributes.py | 26 - .../too/too_many_instance_attributes.txt | 1 - tests/functional/too/too_many_lines.py | 1015 ------------------- tests/functional/too/too_many_lines.txt | 1 - tests/functional/too/too_many_lines_disabled.py | 1018 -------------------- tests/functional/too/too_many_locals.py | 60 -- tests/functional/too/too_many_locals.txt | 3 - tests/functional/too/too_many_nested_blocks.py | 97 -- tests/functional/too/too_many_nested_blocks.txt | 2 - tests/functional/too/too_many_public_methods.py | 79 -- tests/functional/too/too_many_public_methods.txt | 1 - tests/functional/too/too_many_return_statements.py | 40 - .../functional/too/too_many_return_statements.txt | 1 - tests/functional/too/too_many_star_expressions.py | 7 - tests/functional/too/too_many_star_expressions.rc | 2 - tests/functional/too/too_many_star_expressions.txt | 2 - tests/functional/too/too_many_statements.py | 125 --- tests/functional/too/too_many_statements.txt | 2 - .../u/undefined/undefined_loop_variable.py | 75 ++ .../u/undefined/undefined_loop_variable.txt | 3 + tests/functional/u/undefined/undefined_variable.py | 296 ++++++ .../functional/u/undefined/undefined_variable.txt | 30 + .../undefined_variable_crash_on_attribute.py | 6 + .../u/undefined/undefined_variable_py30.py | 86 ++ .../u/undefined/undefined_variable_py30.rc | 2 + .../u/undefined/undefined_variable_py30.txt | 8 + tests/functional/u/undefined_loop_variable.py | 75 -- tests/functional/u/undefined_loop_variable.txt | 3 - tests/functional/u/undefined_variable.py | 296 ------ tests/functional/u/undefined_variable.txt | 30 - .../u/undefined_variable_crash_on_attribute.py | 6 - tests/functional/u/undefined_variable_py30.py | 86 -- tests/functional/u/undefined_variable_py30.rc | 2 - tests/functional/u/undefined_variable_py30.txt | 8 - .../u/unnecessary/unnecessary_comprehension.py | 36 + .../u/unnecessary/unnecessary_comprehension.txt | 8 + .../functional/u/unnecessary/unnecessary_lambda.py | 53 + .../u/unnecessary/unnecessary_lambda.txt | 7 + tests/functional/u/unnecessary/unnecessary_not.py | 63 ++ tests/functional/u/unnecessary/unnecessary_not.txt | 14 + tests/functional/u/unnecessary/unnecessary_pass.py | 49 + .../functional/u/unnecessary/unnecessary_pass.txt | 3 + tests/functional/u/unnecessary_comprehension.py | 36 - tests/functional/u/unnecessary_comprehension.txt | 8 - tests/functional/u/unnecessary_lambda.py | 53 - tests/functional/u/unnecessary_lambda.txt | 7 - tests/functional/u/unnecessary_pass.py | 49 - tests/functional/u/unnecessary_pass.txt | 3 - tests/functional/u/unneeded_not.py | 63 -- tests/functional/u/unneeded_not.txt | 14 - .../unsupported_assignment_operation.py | 94 ++ .../unsupported_assignment_operation.rc | 2 + .../unsupported_assignment_operation.txt | 17 + .../u/unsupported/unsupported_binary_operation.py | 66 ++ .../u/unsupported/unsupported_binary_operation.rc | 2 + .../u/unsupported/unsupported_binary_operation.txt | 21 + .../u/unsupported/unsupported_delete_operation.py | 94 ++ .../u/unsupported/unsupported_delete_operation.rc | 2 + .../u/unsupported/unsupported_delete_operation.txt | 17 + .../u/unsupported_assignment_operation.py | 94 -- .../u/unsupported_assignment_operation.rc | 2 - .../u/unsupported_assignment_operation.txt | 17 - tests/functional/u/unsupported_binary_operation.py | 66 -- tests/functional/u/unsupported_binary_operation.rc | 2 - .../functional/u/unsupported_binary_operation.txt | 21 - tests/functional/u/unsupported_delete_operation.py | 94 -- tests/functional/u/unsupported_delete_operation.rc | 2 - .../functional/u/unsupported_delete_operation.txt | 17 - tests/functional/u/unused/__init__.py | 0 tests/functional/u/unused/unused_argument.py | 48 + tests/functional/u/unused/unused_argument.txt | 3 + tests/functional/u/unused/unused_argument_py3.py | 9 + tests/functional/u/unused/unused_argument_py3.rc | 2 + tests/functional/u/unused/unused_argument_py3.txt | 3 + .../functional/u/unused/unused_global_variable1.py | 2 + .../functional/u/unused/unused_global_variable2.py | 2 + .../functional/u/unused/unused_global_variable2.rc | 2 + .../u/unused/unused_global_variable2.txt | 1 + .../functional/u/unused/unused_global_variable3.py | 6 + .../functional/u/unused/unused_global_variable4.py | 3 + .../functional/u/unused/unused_global_variable4.rc | 2 + .../u/unused/unused_global_variable4.txt | 2 + tests/functional/u/unused/unused_import.py | 39 + tests/functional/u/unused/unused_import.txt | 9 + .../u/unused/unused_import_assigned_to.py | 25 + .../u/unused/unused_import_everything_disabled.py | 8 + .../u/unused/unused_import_everything_disabled.rc | 3 + .../u/unused/unused_import_positional_only_py38.py | 10 + .../u/unused/unused_import_positional_only_py38.rc | 2 + tests/functional/u/unused/unused_typing_imports.py | 85 ++ tests/functional/u/unused/unused_typing_imports.rc | 3 + tests/functional/u/unused/unused_variable.py | 67 ++ tests/functional/u/unused/unused_variable.txt | 14 + tests/functional/u/unused/unused_variable_py36.py | 13 + tests/functional/u/unused/unused_variable_py36.rc | 2 + tests/functional/u/unused_argument.py | 48 - tests/functional/u/unused_argument.txt | 3 - tests/functional/u/unused_argument_py3.py | 9 - tests/functional/u/unused_argument_py3.rc | 2 - tests/functional/u/unused_argument_py3.txt | 3 - tests/functional/u/unused_global_variable1.py | 2 - tests/functional/u/unused_global_variable2.py | 2 - tests/functional/u/unused_global_variable2.rc | 2 - tests/functional/u/unused_global_variable2.txt | 1 - tests/functional/u/unused_global_variable3.py | 6 - tests/functional/u/unused_global_variable4.py | 3 - tests/functional/u/unused_global_variable4.rc | 2 - tests/functional/u/unused_global_variable4.txt | 2 - tests/functional/u/unused_import.py | 39 - tests/functional/u/unused_import.txt | 9 - tests/functional/u/unused_import_assigned_to.py | 25 - .../u/unused_import_everything_disabled.py | 8 - .../u/unused_import_everything_disabled.rc | 3 - .../u/unused_import_positional_only_py38.py | 10 - .../u/unused_import_positional_only_py38.rc | 2 - tests/functional/u/unused_typing_imports.py | 85 -- tests/functional/u/unused_typing_imports.rc | 3 - tests/functional/u/unused_variable.py | 67 -- tests/functional/u/unused_variable.txt | 14 - tests/functional/u/unused_variable_py36.py | 13 - tests/functional/u/unused_variable_py36.rc | 2 - tests/functional/u/use/use_a_generator.py | 11 + tests/functional/u/use/use_a_generator.txt | 2 + .../functional/u/use/used_before_assignment_488.py | 9 + .../u/use/used_before_assignment_issue1081.py | 40 + .../u/use/used_before_assignment_issue1081.txt | 7 + .../u/use/used_before_assignment_issue853.py | 23 + .../u/use/used_before_assignment_nonlocal.py | 60 ++ .../u/use/used_before_assignment_nonlocal.rc | 2 + .../u/use/used_before_assignment_nonlocal.txt | 6 + .../u/use/used_prior_global_declaration.py | 39 + .../u/use/used_prior_global_declaration.rc | 2 + .../u/use/used_prior_global_declaration.txt | 1 + tests/functional/u/use/using_constant_test.py | 141 +++ tests/functional/u/use/using_constant_test.txt | 24 + tests/functional/u/use_a_generator.py | 11 - tests/functional/u/use_a_generator.txt | 2 - tests/functional/u/used_before_assignment_488.py | 9 - .../u/used_before_assignment_issue1081.py | 40 - .../u/used_before_assignment_issue1081.txt | 7 - .../u/used_before_assignment_issue853.py | 23 - .../u/used_before_assignment_nonlocal.py | 60 -- .../u/used_before_assignment_nonlocal.rc | 2 - .../u/used_before_assignment_nonlocal.txt | 6 - .../functional/u/used_prior_global_declaration.py | 39 - .../functional/u/used_prior_global_declaration.rc | 2 - .../functional/u/used_prior_global_declaration.txt | 1 - tests/functional/u/useless-import-alias.py | 21 - tests/functional/u/useless-import-alias.txt | 7 - tests/functional/u/useless/useless-import-alias.py | 21 + .../functional/u/useless/useless-import-alias.txt | 7 + tests/functional/u/useless/useless_else_on_loop.py | 103 ++ .../functional/u/useless/useless_else_on_loop.txt | 6 + .../u/useless/useless_object_inheritance.py | 27 + .../u/useless/useless_object_inheritance.txt | 4 + tests/functional/u/useless/useless_return.py | 15 + tests/functional/u/useless/useless_return.txt | 2 + .../u/useless/useless_super_delegation.py | 262 +++++ .../u/useless/useless_super_delegation.txt | 18 + .../u/useless/useless_super_delegation_py3.py | 43 + .../u/useless/useless_super_delegation_py3.rc | 2 + .../u/useless/useless_super_delegation_py3.txt | 2 + .../u/useless/useless_super_delegation_py35.py | 12 + .../u/useless/useless_super_delegation_py35.rc | 2 + .../u/useless/useless_super_delegation_py35.txt | 1 + .../u/useless/useless_super_delegation_py38.py | 17 + .../u/useless/useless_super_delegation_py38.rc | 2 + .../u/useless/useless_super_delegation_py38.txt | 1 + tests/functional/u/useless_else_on_loop.py | 103 -- tests/functional/u/useless_else_on_loop.txt | 6 - tests/functional/u/useless_object_inheritance.py | 27 - tests/functional/u/useless_object_inheritance.txt | 4 - tests/functional/u/useless_return.py | 15 - tests/functional/u/useless_return.txt | 2 - tests/functional/u/useless_super_delegation.py | 262 ----- tests/functional/u/useless_super_delegation.txt | 18 - tests/functional/u/useless_super_delegation_py3.py | 43 - tests/functional/u/useless_super_delegation_py3.rc | 2 - .../functional/u/useless_super_delegation_py3.txt | 2 - .../functional/u/useless_super_delegation_py35.py | 12 - .../functional/u/useless_super_delegation_py35.rc | 2 - .../functional/u/useless_super_delegation_py35.txt | 1 - .../functional/u/useless_super_delegation_py38.py | 17 - .../functional/u/useless_super_delegation_py38.rc | 2 - .../functional/u/useless_super_delegation_py38.txt | 1 - tests/functional/u/using_constant_test.py | 141 --- tests/functional/u/using_constant_test.txt | 24 - tests/test_self.py | 13 +- 770 files changed, 11977 insertions(+), 11980 deletions(-) create mode 100644 tests/functional/a/abstract/abstract_abc_methods.py create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_in_class.py create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_py3.py create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_py3.rc create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_py3.txt create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_py34.py create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_py34.rc create mode 100644 tests/functional/a/abstract/abstract_class_instantiated_py34.txt create mode 100644 tests/functional/a/abstract/abstract_method_py3.py create mode 100644 tests/functional/a/abstract/abstract_method_py3.rc create mode 100644 tests/functional/a/abstract/abstract_method_py3.txt delete mode 100644 tests/functional/a/abstract_abc_methods.py delete mode 100644 tests/functional/a/abstract_class_instantiated_in_class.py delete mode 100644 tests/functional/a/abstract_class_instantiated_py3.py delete mode 100644 tests/functional/a/abstract_class_instantiated_py3.rc delete mode 100644 tests/functional/a/abstract_class_instantiated_py3.txt delete mode 100644 tests/functional/a/abstract_class_instantiated_py34.py delete mode 100644 tests/functional/a/abstract_class_instantiated_py34.rc delete mode 100644 tests/functional/a/abstract_class_instantiated_py34.txt delete mode 100644 tests/functional/a/abstract_method_py3.py delete mode 100644 tests/functional/a/abstract_method_py3.rc delete mode 100644 tests/functional/a/abstract_method_py3.txt create mode 100644 tests/functional/c/consider/consider_iterating_dictionary.py create mode 100644 tests/functional/c/consider/consider_iterating_dictionary.txt create mode 100644 tests/functional/c/consider/consider_join.py create mode 100644 tests/functional/c/consider/consider_join.txt create mode 100644 tests/functional/c/consider/consider_merging_isinstance.py create mode 100644 tests/functional/c/consider/consider_merging_isinstance.txt create mode 100644 tests/functional/c/consider/consider_swap_variables.py create mode 100644 tests/functional/c/consider/consider_swap_variables.txt create mode 100644 tests/functional/c/consider/consider_using_dict_comprehension.py create mode 100644 tests/functional/c/consider/consider_using_dict_comprehension.txt create mode 100644 tests/functional/c/consider/consider_using_enumerate.py create mode 100644 tests/functional/c/consider/consider_using_enumerate.txt create mode 100644 tests/functional/c/consider/consider_using_generator.py create mode 100644 tests/functional/c/consider/consider_using_generator.txt create mode 100644 tests/functional/c/consider/consider_using_get.py create mode 100644 tests/functional/c/consider/consider_using_get.txt create mode 100644 tests/functional/c/consider/consider_using_in.py create mode 100644 tests/functional/c/consider/consider_using_in.txt create mode 100644 tests/functional/c/consider/consider_using_set_comprehension.py create mode 100644 tests/functional/c/consider/consider_using_set_comprehension.txt create mode 100644 tests/functional/c/consider/consider_using_sys_exit.py create mode 100644 tests/functional/c/consider/consider_using_sys_exit.txt create mode 100644 tests/functional/c/consider/consider_using_sys_exit_exempted.py create mode 100644 tests/functional/c/consider/consider_using_sys_exit_local_scope.py delete mode 100644 tests/functional/c/consider_iterating_dictionary.py delete mode 100644 tests/functional/c/consider_iterating_dictionary.txt delete mode 100644 tests/functional/c/consider_join.py delete mode 100644 tests/functional/c/consider_join.txt delete mode 100644 tests/functional/c/consider_merging_isinstance.py delete mode 100644 tests/functional/c/consider_merging_isinstance.txt delete mode 100644 tests/functional/c/consider_swap_variables.py delete mode 100644 tests/functional/c/consider_swap_variables.txt delete mode 100644 tests/functional/c/consider_using_dict_comprehension.py delete mode 100644 tests/functional/c/consider_using_dict_comprehension.txt delete mode 100644 tests/functional/c/consider_using_enumerate.py delete mode 100644 tests/functional/c/consider_using_enumerate.txt delete mode 100644 tests/functional/c/consider_using_generator.py delete mode 100644 tests/functional/c/consider_using_generator.txt delete mode 100644 tests/functional/c/consider_using_get.py delete mode 100644 tests/functional/c/consider_using_get.txt delete mode 100644 tests/functional/c/consider_using_in.py delete mode 100644 tests/functional/c/consider_using_in.txt delete mode 100644 tests/functional/c/consider_using_set_comprehension.py delete mode 100644 tests/functional/c/consider_using_set_comprehension.txt delete mode 100644 tests/functional/c/consider_using_sys_exit.py delete mode 100644 tests/functional/c/consider_using_sys_exit.txt delete mode 100644 tests/functional/c/consider_using_sys_exit_exempted.py delete mode 100644 tests/functional/c/consider_using_sys_exit_local_scope.py create mode 100644 tests/functional/d/deprecated/deprecated_method_getmoduleinfo.py create mode 100644 tests/functional/d/deprecated/deprecated_method_getmoduleinfo.rc create mode 100644 tests/functional/d/deprecated/deprecated_method_getmoduleinfo.txt create mode 100644 tests/functional/d/deprecated/deprecated_methods_py3.py create mode 100644 tests/functional/d/deprecated/deprecated_methods_py3.rc create mode 100644 tests/functional/d/deprecated/deprecated_methods_py3.txt create mode 100644 tests/functional/d/deprecated/deprecated_methods_py36.py create mode 100644 tests/functional/d/deprecated/deprecated_methods_py36.rc create mode 100644 tests/functional/d/deprecated/deprecated_methods_py36.txt create mode 100644 tests/functional/d/deprecated/deprecated_methods_py38.py create mode 100644 tests/functional/d/deprecated/deprecated_methods_py38.rc create mode 100644 tests/functional/d/deprecated/deprecated_methods_py38.txt create mode 100644 tests/functional/d/deprecated/deprecated_module_py3.py create mode 100644 tests/functional/d/deprecated/deprecated_module_py3.rc create mode 100644 tests/functional/d/deprecated/deprecated_module_py3.txt create mode 100644 tests/functional/d/deprecated/deprecated_module_py36.py create mode 100644 tests/functional/d/deprecated/deprecated_module_py36.rc create mode 100644 tests/functional/d/deprecated/deprecated_module_py36.txt create mode 100644 tests/functional/d/deprecated/deprecated_module_py4.py create mode 100644 tests/functional/d/deprecated/deprecated_module_py4.rc create mode 100644 tests/functional/d/deprecated/deprecated_module_py4.txt create mode 100644 tests/functional/d/deprecated/deprecated_module_uninstalled.py create mode 100644 tests/functional/d/deprecated/deprecated_module_uninstalled.rc create mode 100644 tests/functional/d/deprecated/deprecated_module_uninstalled.txt delete mode 100644 tests/functional/d/deprecated_method_getmoduleinfo.py delete mode 100644 tests/functional/d/deprecated_method_getmoduleinfo.rc delete mode 100644 tests/functional/d/deprecated_method_getmoduleinfo.txt delete mode 100644 tests/functional/d/deprecated_methods_py3.py delete mode 100644 tests/functional/d/deprecated_methods_py3.rc delete mode 100644 tests/functional/d/deprecated_methods_py3.txt delete mode 100644 tests/functional/d/deprecated_methods_py36.py delete mode 100644 tests/functional/d/deprecated_methods_py36.rc delete mode 100644 tests/functional/d/deprecated_methods_py36.txt delete mode 100644 tests/functional/d/deprecated_methods_py38.py delete mode 100644 tests/functional/d/deprecated_methods_py38.rc delete mode 100644 tests/functional/d/deprecated_methods_py38.txt delete mode 100644 tests/functional/d/deprecated_module_py3.py delete mode 100644 tests/functional/d/deprecated_module_py3.rc delete mode 100644 tests/functional/d/deprecated_module_py3.txt delete mode 100644 tests/functional/d/deprecated_module_py36.py delete mode 100644 tests/functional/d/deprecated_module_py36.rc delete mode 100644 tests/functional/d/deprecated_module_py36.txt delete mode 100644 tests/functional/d/deprecated_module_py4.py delete mode 100644 tests/functional/d/deprecated_module_py4.rc delete mode 100644 tests/functional/d/deprecated_module_py4.txt delete mode 100644 tests/functional/d/deprecated_module_uninstalled.py delete mode 100644 tests/functional/d/deprecated_module_uninstalled.rc delete mode 100644 tests/functional/d/deprecated_module_uninstalled.txt create mode 100644 tests/functional/i/implicit/implicit_str_concat.py create mode 100644 tests/functional/i/implicit/implicit_str_concat.txt create mode 100644 tests/functional/i/implicit/implicit_str_concat_latin1.py create mode 100755 tests/functional/i/implicit/implicit_str_concat_multiline.py create mode 100755 tests/functional/i/implicit/implicit_str_concat_multiline.rc create mode 100755 tests/functional/i/implicit/implicit_str_concat_multiline.txt create mode 100644 tests/functional/i/implicit/implicit_str_concat_utf8.py delete mode 100644 tests/functional/i/implicit_str_concat.py delete mode 100644 tests/functional/i/implicit_str_concat.txt delete mode 100644 tests/functional/i/implicit_str_concat_latin1.py delete mode 100755 tests/functional/i/implicit_str_concat_multiline.py delete mode 100755 tests/functional/i/implicit_str_concat_multiline.rc delete mode 100755 tests/functional/i/implicit_str_concat_multiline.txt delete mode 100644 tests/functional/i/implicit_str_concat_utf8.py create mode 100644 tests/functional/i/inconsistent/inconsistent_mro.py create mode 100644 tests/functional/i/inconsistent/inconsistent_mro.txt create mode 100644 tests/functional/i/inconsistent/inconsistent_quotes.py create mode 100644 tests/functional/i/inconsistent/inconsistent_quotes.rc create mode 100644 tests/functional/i/inconsistent/inconsistent_quotes.txt create mode 100644 tests/functional/i/inconsistent/inconsistent_quotes2.py create mode 100644 tests/functional/i/inconsistent/inconsistent_quotes2.rc create mode 100644 tests/functional/i/inconsistent/inconsistent_quotes2.txt create mode 100644 tests/functional/i/inconsistent/inconsistent_returns.py create mode 100644 tests/functional/i/inconsistent/inconsistent_returns.rc create mode 100644 tests/functional/i/inconsistent/inconsistent_returns.txt delete mode 100644 tests/functional/i/inconsistent_mro.py delete mode 100644 tests/functional/i/inconsistent_mro.txt delete mode 100644 tests/functional/i/inconsistent_quotes.py delete mode 100644 tests/functional/i/inconsistent_quotes.rc delete mode 100644 tests/functional/i/inconsistent_quotes.txt delete mode 100644 tests/functional/i/inconsistent_quotes2.py delete mode 100644 tests/functional/i/inconsistent_quotes2.rc delete mode 100644 tests/functional/i/inconsistent_quotes2.txt delete mode 100644 tests/functional/i/inconsistent_returns.py delete mode 100644 tests/functional/i/inconsistent_returns.rc delete mode 100644 tests/functional/i/inconsistent_returns.txt create mode 100644 tests/functional/i/invalid/invalid_all_object.py create mode 100644 tests/functional/i/invalid/invalid_all_object.txt create mode 100644 tests/functional/i/invalid/invalid_bool_returned.py create mode 100644 tests/functional/i/invalid/invalid_bool_returned.txt create mode 100644 tests/functional/i/invalid/invalid_bytes_returned.py create mode 100644 tests/functional/i/invalid/invalid_bytes_returned.txt create mode 100644 tests/functional/i/invalid/invalid_envvar_value.py create mode 100644 tests/functional/i/invalid/invalid_envvar_value.txt create mode 100644 tests/functional/i/invalid/invalid_exceptions_caught.py create mode 100644 tests/functional/i/invalid/invalid_exceptions_caught.rc create mode 100644 tests/functional/i/invalid/invalid_exceptions_caught.txt create mode 100644 tests/functional/i/invalid/invalid_exceptions_raised.py create mode 100644 tests/functional/i/invalid/invalid_exceptions_raised.txt create mode 100644 tests/functional/i/invalid/invalid_format_returned.py create mode 100644 tests/functional/i/invalid/invalid_format_returned.txt create mode 100644 tests/functional/i/invalid/invalid_getnewargs_ex_returned.py create mode 100644 tests/functional/i/invalid/invalid_getnewargs_ex_returned.txt create mode 100644 tests/functional/i/invalid/invalid_getnewargs_returned.py create mode 100644 tests/functional/i/invalid/invalid_getnewargs_returned.txt create mode 100644 tests/functional/i/invalid/invalid_hash_returned.py create mode 100644 tests/functional/i/invalid/invalid_hash_returned.txt create mode 100644 tests/functional/i/invalid/invalid_index_returned.py create mode 100644 tests/functional/i/invalid/invalid_index_returned.txt create mode 100644 tests/functional/i/invalid/invalid_length_hint_returned.py create mode 100644 tests/functional/i/invalid/invalid_length_hint_returned.txt create mode 100644 tests/functional/i/invalid/invalid_length_returned.py create mode 100644 tests/functional/i/invalid/invalid_length_returned.txt create mode 100644 tests/functional/i/invalid/invalid_metaclass.py create mode 100644 tests/functional/i/invalid/invalid_metaclass_py3.py create mode 100644 tests/functional/i/invalid/invalid_metaclass_py3.rc create mode 100644 tests/functional/i/invalid/invalid_name.py create mode 100644 tests/functional/i/invalid/invalid_name.txt create mode 100644 tests/functional/i/invalid/invalid_overridden_method.py create mode 100644 tests/functional/i/invalid/invalid_overridden_method.txt create mode 100644 tests/functional/i/invalid/invalid_repr_returned.py create mode 100644 tests/functional/i/invalid/invalid_repr_returned.txt create mode 100644 tests/functional/i/invalid/invalid_sequence_index.py create mode 100644 tests/functional/i/invalid/invalid_sequence_index.txt create mode 100644 tests/functional/i/invalid/invalid_slice_index.py create mode 100644 tests/functional/i/invalid/invalid_slice_index.txt create mode 100644 tests/functional/i/invalid/invalid_star_assignment_target.py create mode 100644 tests/functional/i/invalid/invalid_star_assignment_target.rc create mode 100644 tests/functional/i/invalid/invalid_star_assignment_target.txt create mode 100644 tests/functional/i/invalid/invalid_str_returned.py create mode 100644 tests/functional/i/invalid/invalid_str_returned.txt create mode 100644 tests/functional/i/invalid/invalid_unary_operand_type.py create mode 100644 tests/functional/i/invalid/invalid_unary_operand_type.txt delete mode 100644 tests/functional/i/invalid_all_object.py delete mode 100644 tests/functional/i/invalid_all_object.txt delete mode 100644 tests/functional/i/invalid_bool_returned.py delete mode 100644 tests/functional/i/invalid_bool_returned.txt delete mode 100644 tests/functional/i/invalid_bytes_returned.py delete mode 100644 tests/functional/i/invalid_bytes_returned.txt delete mode 100644 tests/functional/i/invalid_envvar_value.py delete mode 100644 tests/functional/i/invalid_envvar_value.txt delete mode 100644 tests/functional/i/invalid_exceptions_caught.py delete mode 100644 tests/functional/i/invalid_exceptions_caught.rc delete mode 100644 tests/functional/i/invalid_exceptions_caught.txt delete mode 100644 tests/functional/i/invalid_exceptions_raised.py delete mode 100644 tests/functional/i/invalid_exceptions_raised.txt delete mode 100644 tests/functional/i/invalid_format_returned.py delete mode 100644 tests/functional/i/invalid_format_returned.txt delete mode 100644 tests/functional/i/invalid_getnewargs_ex_returned.py delete mode 100644 tests/functional/i/invalid_getnewargs_ex_returned.txt delete mode 100644 tests/functional/i/invalid_getnewargs_returned.py delete mode 100644 tests/functional/i/invalid_getnewargs_returned.txt delete mode 100644 tests/functional/i/invalid_hash_returned.py delete mode 100644 tests/functional/i/invalid_hash_returned.txt delete mode 100644 tests/functional/i/invalid_index_returned.py delete mode 100644 tests/functional/i/invalid_index_returned.txt delete mode 100644 tests/functional/i/invalid_length_hint_returned.py delete mode 100644 tests/functional/i/invalid_length_hint_returned.txt delete mode 100644 tests/functional/i/invalid_length_returned.py delete mode 100644 tests/functional/i/invalid_length_returned.txt delete mode 100644 tests/functional/i/invalid_metaclass.py delete mode 100644 tests/functional/i/invalid_metaclass_py3.py delete mode 100644 tests/functional/i/invalid_metaclass_py3.rc delete mode 100644 tests/functional/i/invalid_name.py delete mode 100644 tests/functional/i/invalid_name.txt delete mode 100644 tests/functional/i/invalid_overridden_method.py delete mode 100644 tests/functional/i/invalid_overridden_method.txt delete mode 100644 tests/functional/i/invalid_repr_returned.py delete mode 100644 tests/functional/i/invalid_repr_returned.txt delete mode 100644 tests/functional/i/invalid_sequence_index.py delete mode 100644 tests/functional/i/invalid_sequence_index.txt delete mode 100644 tests/functional/i/invalid_slice_index.py delete mode 100644 tests/functional/i/invalid_slice_index.txt delete mode 100644 tests/functional/i/invalid_star_assignment_target.py delete mode 100644 tests/functional/i/invalid_star_assignment_target.rc delete mode 100644 tests/functional/i/invalid_star_assignment_target.txt delete mode 100644 tests/functional/i/invalid_str_returned.py delete mode 100644 tests/functional/i/invalid_str_returned.txt delete mode 100644 tests/functional/i/invalid_unary_operand_type.py delete mode 100644 tests/functional/i/invalid_unary_operand_type.txt create mode 100644 tests/functional/m/member/member_checks.py create mode 100644 tests/functional/m/member/member_checks.txt create mode 100644 tests/functional/m/member/member_checks_hints.py create mode 100644 tests/functional/m/member/member_checks_hints.rc create mode 100644 tests/functional/m/member/member_checks_hints.txt create mode 100644 tests/functional/m/member/member_checks_ignore_none.py create mode 100644 tests/functional/m/member/member_checks_ignore_none.rc create mode 100644 tests/functional/m/member/member_checks_ignore_none.txt create mode 100644 tests/functional/m/member/member_checks_inference_improvements.py create mode 100644 tests/functional/m/member/member_checks_no_hints.py create mode 100644 tests/functional/m/member/member_checks_no_hints.rc create mode 100644 tests/functional/m/member/member_checks_no_hints.txt create mode 100644 tests/functional/m/member/member_checks_opaque.py create mode 100644 tests/functional/m/member/member_checks_opaque.rc create mode 100644 tests/functional/m/member/member_checks_opaque.txt create mode 100644 tests/functional/m/member/member_checks_py37.py create mode 100644 tests/functional/m/member/member_checks_py37.rc create mode 100644 tests/functional/m/member/member_checks_py37.txt create mode 100644 tests/functional/m/member/member_checks_typed_annotations.py create mode 100644 tests/functional/m/member/member_checks_typed_annotations.txt create mode 100644 tests/functional/m/member/membership_protocol.py create mode 100644 tests/functional/m/member/membership_protocol.txt create mode 100644 tests/functional/m/member/membership_protocol_py3.py create mode 100644 tests/functional/m/member/membership_protocol_py3.rc create mode 100644 tests/functional/m/member/membership_protocol_py3.txt delete mode 100644 tests/functional/m/member_checks.py delete mode 100644 tests/functional/m/member_checks.txt delete mode 100644 tests/functional/m/member_checks_hints.py delete mode 100644 tests/functional/m/member_checks_hints.rc delete mode 100644 tests/functional/m/member_checks_hints.txt delete mode 100644 tests/functional/m/member_checks_ignore_none.py delete mode 100644 tests/functional/m/member_checks_ignore_none.rc delete mode 100644 tests/functional/m/member_checks_ignore_none.txt delete mode 100644 tests/functional/m/member_checks_inference_improvements.py delete mode 100644 tests/functional/m/member_checks_no_hints.py delete mode 100644 tests/functional/m/member_checks_no_hints.rc delete mode 100644 tests/functional/m/member_checks_no_hints.txt delete mode 100644 tests/functional/m/member_checks_opaque.py delete mode 100644 tests/functional/m/member_checks_opaque.rc delete mode 100644 tests/functional/m/member_checks_opaque.txt delete mode 100644 tests/functional/m/member_checks_py37.py delete mode 100644 tests/functional/m/member_checks_py37.rc delete mode 100644 tests/functional/m/member_checks_py37.txt delete mode 100644 tests/functional/m/member_checks_typed_annotations.py delete mode 100644 tests/functional/m/member_checks_typed_annotations.txt delete mode 100644 tests/functional/m/membership_protocol.py delete mode 100644 tests/functional/m/membership_protocol.txt delete mode 100644 tests/functional/m/membership_protocol_py3.py delete mode 100644 tests/functional/m/membership_protocol_py3.rc delete mode 100644 tests/functional/m/membership_protocol_py3.txt create mode 100644 tests/functional/m/missing/missing_docstring.py create mode 100644 tests/functional/m/missing/missing_docstring.txt create mode 100644 tests/functional/m/missing/missing_docstring_new_style.py create mode 100644 tests/functional/m/missing/missing_docstring_new_style.txt create mode 100644 tests/functional/m/missing/missing_final_newline.py create mode 100644 tests/functional/m/missing/missing_final_newline.txt create mode 100644 tests/functional/m/missing/missing_kwoa_py3.py create mode 100644 tests/functional/m/missing/missing_kwoa_py3.rc create mode 100644 tests/functional/m/missing/missing_kwoa_py3.txt create mode 100644 tests/functional/m/missing/missing_module_docstring_disabled.py create mode 100644 tests/functional/m/missing/missing_parentheses_for_call_in_test.py create mode 100644 tests/functional/m/missing/missing_parentheses_for_call_in_test.txt create mode 100644 tests/functional/m/missing/missing_self_argument.py create mode 100644 tests/functional/m/missing/missing_self_argument.txt delete mode 100644 tests/functional/m/missing_docstring.py delete mode 100644 tests/functional/m/missing_docstring.txt delete mode 100644 tests/functional/m/missing_docstring_new_style.py delete mode 100644 tests/functional/m/missing_docstring_new_style.txt delete mode 100644 tests/functional/m/missing_final_newline.py delete mode 100644 tests/functional/m/missing_final_newline.txt delete mode 100644 tests/functional/m/missing_kwoa_py3.py delete mode 100644 tests/functional/m/missing_kwoa_py3.rc delete mode 100644 tests/functional/m/missing_kwoa_py3.txt delete mode 100644 tests/functional/m/missing_module_docstring_disabled.py delete mode 100644 tests/functional/m/missing_parentheses_for_call_in_test.py delete mode 100644 tests/functional/m/missing_parentheses_for_call_in_test.txt delete mode 100644 tests/functional/m/missing_self_argument.py delete mode 100644 tests/functional/m/missing_self_argument.txt create mode 100644 tests/functional/n/name/namePresetCamelCase.py create mode 100644 tests/functional/n/name/namePresetCamelCase.rc create mode 100644 tests/functional/n/name/namePresetCamelCase.txt create mode 100644 tests/functional/n/name/name_good_bad_names_regex.py create mode 100644 tests/functional/n/name/name_good_bad_names_regex.rc create mode 100644 tests/functional/n/name/name_good_bad_names_regex.txt create mode 100644 tests/functional/n/name/name_preset_snake_case.py create mode 100644 tests/functional/n/name/name_preset_snake_case.rc create mode 100644 tests/functional/n/name/name_preset_snake_case.txt create mode 100644 tests/functional/n/name/name_styles.py create mode 100644 tests/functional/n/name/name_styles.rc create mode 100644 tests/functional/n/name/name_styles.txt create mode 100644 tests/functional/n/name/namedtuple_member_inference.py create mode 100644 tests/functional/n/name/namedtuple_member_inference.txt create mode 100644 tests/functional/n/name/names_in__all__.py create mode 100644 tests/functional/n/name/names_in__all__.txt delete mode 100644 tests/functional/n/namePresetCamelCase.py delete mode 100644 tests/functional/n/namePresetCamelCase.rc delete mode 100644 tests/functional/n/namePresetCamelCase.txt delete mode 100644 tests/functional/n/name_good_bad_names_regex.py delete mode 100644 tests/functional/n/name_good_bad_names_regex.rc delete mode 100644 tests/functional/n/name_good_bad_names_regex.txt delete mode 100644 tests/functional/n/name_preset_snake_case.py delete mode 100644 tests/functional/n/name_preset_snake_case.rc delete mode 100644 tests/functional/n/name_preset_snake_case.txt delete mode 100644 tests/functional/n/name_styles.py delete mode 100644 tests/functional/n/name_styles.rc delete mode 100644 tests/functional/n/name_styles.txt delete mode 100644 tests/functional/n/namedtuple_member_inference.py delete mode 100644 tests/functional/n/namedtuple_member_inference.txt delete mode 100644 tests/functional/n/names_in__all__.py delete mode 100644 tests/functional/n/names_in__all__.txt create mode 100644 tests/functional/n/no/__init__.py create mode 100644 tests/functional/n/no/no_classmethod_decorator.py create mode 100644 tests/functional/n/no/no_classmethod_decorator.txt create mode 100644 tests/functional/n/no/no_else_break.py create mode 100644 tests/functional/n/no/no_else_break.txt create mode 100644 tests/functional/n/no/no_else_continue.py create mode 100644 tests/functional/n/no/no_else_continue.txt create mode 100644 tests/functional/n/no/no_else_raise.py create mode 100644 tests/functional/n/no/no_else_raise.txt create mode 100644 tests/functional/n/no/no_else_return.py create mode 100644 tests/functional/n/no/no_else_return.txt create mode 100644 tests/functional/n/no/no_method_argument_py38.py create mode 100644 tests/functional/n/no/no_method_argument_py38.rc create mode 100644 tests/functional/n/no/no_name_in_module.py create mode 100644 tests/functional/n/no/no_name_in_module.txt create mode 100644 tests/functional/n/no/no_self_argument_py37.py create mode 100644 tests/functional/n/no/no_self_argument_py37.rc create mode 100644 tests/functional/n/no/no_self_argument_py37.txt create mode 100644 tests/functional/n/no/no_self_use.py create mode 100644 tests/functional/n/no/no_self_use.txt create mode 100644 tests/functional/n/no/no_self_use_py3.py create mode 100644 tests/functional/n/no/no_self_use_py3.rc create mode 100644 tests/functional/n/no/no_staticmethod_decorator.py create mode 100644 tests/functional/n/no/no_staticmethod_decorator.txt delete mode 100644 tests/functional/n/no_classmethod_decorator.py delete mode 100644 tests/functional/n/no_classmethod_decorator.txt delete mode 100644 tests/functional/n/no_else_break.py delete mode 100644 tests/functional/n/no_else_break.txt delete mode 100644 tests/functional/n/no_else_continue.py delete mode 100644 tests/functional/n/no_else_continue.txt delete mode 100644 tests/functional/n/no_else_raise.py delete mode 100644 tests/functional/n/no_else_raise.txt delete mode 100644 tests/functional/n/no_else_return.py delete mode 100644 tests/functional/n/no_else_return.txt delete mode 100644 tests/functional/n/no_method_argument_py38.py delete mode 100644 tests/functional/n/no_method_argument_py38.rc delete mode 100644 tests/functional/n/no_name_in_module.py delete mode 100644 tests/functional/n/no_name_in_module.txt delete mode 100644 tests/functional/n/no_self_argument_py37.py delete mode 100644 tests/functional/n/no_self_argument_py37.rc delete mode 100644 tests/functional/n/no_self_argument_py37.txt delete mode 100644 tests/functional/n/no_self_use.py delete mode 100644 tests/functional/n/no_self_use.txt delete mode 100644 tests/functional/n/no_self_use_py3.py delete mode 100644 tests/functional/n/no_self_use_py3.rc delete mode 100644 tests/functional/n/no_staticmethod_decorator.py delete mode 100644 tests/functional/n/no_staticmethod_decorator.txt create mode 100644 tests/functional/r/raise/raise_missing_from.py create mode 100644 tests/functional/r/raise/raise_missing_from.txt create mode 100644 tests/functional/r/raise/raising_format_tuple.py create mode 100644 tests/functional/r/raise/raising_format_tuple.txt create mode 100644 tests/functional/r/raise/raising_non_exception_py3.py create mode 100644 tests/functional/r/raise/raising_non_exception_py3.rc create mode 100644 tests/functional/r/raise/raising_non_exception_py3.txt create mode 100644 tests/functional/r/raise/raising_self.py delete mode 100644 tests/functional/r/raise_missing_from.py delete mode 100644 tests/functional/r/raise_missing_from.txt delete mode 100644 tests/functional/r/raising_format_tuple.py delete mode 100644 tests/functional/r/raising_format_tuple.txt delete mode 100644 tests/functional/r/raising_non_exception_py3.py delete mode 100644 tests/functional/r/raising_non_exception_py3.rc delete mode 100644 tests/functional/r/raising_non_exception_py3.txt delete mode 100644 tests/functional/r/raising_self.py create mode 100644 tests/functional/r/recursion/recursion_error_2667.py create mode 100644 tests/functional/r/recursion/recursion_error_2836.py create mode 100644 tests/functional/r/recursion/recursion_error_2861.py create mode 100644 tests/functional/r/recursion/recursion_error_2899.py create mode 100644 tests/functional/r/recursion/recursion_error_2906.py create mode 100644 tests/functional/r/recursion/recursion_error_3152.py create mode 100644 tests/functional/r/recursion/recursion_error_3159.py create mode 100644 tests/functional/r/recursion/recursion_error_940.py create mode 100644 tests/functional/r/recursion/recursion_error_crash.py create mode 100644 tests/functional/r/recursion/recursion_error_crash_2683.py create mode 100644 tests/functional/r/recursion/recursion_error_crash_astroid_623.py create mode 100644 tests/functional/r/recursion/recursion_regression_2960.py delete mode 100644 tests/functional/r/recursion_error_2667.py delete mode 100644 tests/functional/r/recursion_error_2836.py delete mode 100644 tests/functional/r/recursion_error_2861.py delete mode 100644 tests/functional/r/recursion_error_2899.py delete mode 100644 tests/functional/r/recursion_error_2906.py delete mode 100644 tests/functional/r/recursion_error_3152.py delete mode 100644 tests/functional/r/recursion_error_3159.py delete mode 100644 tests/functional/r/recursion_error_940.py delete mode 100644 tests/functional/r/recursion_error_crash.py delete mode 100644 tests/functional/r/recursion_error_crash_2683.py delete mode 100644 tests/functional/r/recursion_error_crash_astroid_623.py delete mode 100644 tests/functional/r/recursion_regression_2960.py create mode 100644 tests/functional/r/regression/regression_1326_crash_uninferable.py create mode 100644 tests/functional/r/regression/regression_2443_duplicate_bases.py create mode 100644 tests/functional/r/regression/regression_2443_duplicate_bases.rc create mode 100644 tests/functional/r/regression/regression_2937_ifexp.py create mode 100644 tests/functional/r/regression/regression_3091.py create mode 100644 tests/functional/r/regression/regression_3231_no_member_property.py create mode 100644 tests/functional/r/regression/regression_3416_unused_argument_raise.py create mode 100644 tests/functional/r/regression/regression_3416_unused_argument_raise.txt create mode 100644 tests/functional/r/regression/regression_infer_call_result_3690.py create mode 100644 tests/functional/r/regression/regression_no_member_1078.py create mode 100644 tests/functional/r/regression/regression_no_value_for_parameter.py create mode 100644 tests/functional/r/regression/regression_posonly_args.py create mode 100644 tests/functional/r/regression/regression_posonly_args.rc create mode 100644 tests/functional/r/regression/regression_property_no_member_2641.py create mode 100644 tests/functional/r/regression/regression_property_no_member_3269.py create mode 100644 tests/functional/r/regression/regression_property_no_member_844.py create mode 100644 tests/functional/r/regression/regression_property_no_member_870.py create mode 100644 tests/functional/r/regression/regression_property_slots_2439.py create mode 100644 tests/functional/r/regression/regression_too_many_arguments_2335.py delete mode 100644 tests/functional/r/regression_1326_crash_uninferable.py delete mode 100644 tests/functional/r/regression_2443_duplicate_bases.py delete mode 100644 tests/functional/r/regression_2443_duplicate_bases.rc delete mode 100644 tests/functional/r/regression_2937_ifexp.py delete mode 100644 tests/functional/r/regression_3091.py delete mode 100644 tests/functional/r/regression_3231_no_member_property.py delete mode 100644 tests/functional/r/regression_3416_unused_argument_raise.py delete mode 100644 tests/functional/r/regression_3416_unused_argument_raise.txt delete mode 100644 tests/functional/r/regression_infer_call_result_3690.py delete mode 100644 tests/functional/r/regression_no_member_1078.py delete mode 100644 tests/functional/r/regression_no_value_for_parameter.py delete mode 100644 tests/functional/r/regression_posonly_args.py delete mode 100644 tests/functional/r/regression_posonly_args.rc delete mode 100644 tests/functional/r/regression_property_no_member_2641.py delete mode 100644 tests/functional/r/regression_property_no_member_3269.py delete mode 100644 tests/functional/r/regression_property_no_member_844.py delete mode 100644 tests/functional/r/regression_property_no_member_870.py delete mode 100644 tests/functional/r/regression_property_slots_2439.py delete mode 100644 tests/functional/r/regression_too_many_arguments_2335.py create mode 100644 tests/functional/s/simplifiable/simplifiable_condition.py create mode 100644 tests/functional/s/simplifiable/simplifiable_condition.txt create mode 100644 tests/functional/s/simplifiable/simplifiable_if_expression.py create mode 100644 tests/functional/s/simplifiable/simplifiable_if_expression.txt create mode 100644 tests/functional/s/simplifiable/simplifiable_if_statement.py create mode 100644 tests/functional/s/simplifiable/simplifiable_if_statement.txt create mode 100644 tests/functional/s/simplifiable/simplify_chained_comparison.py create mode 100644 tests/functional/s/simplifiable/simplify_chained_comparison.txt delete mode 100644 tests/functional/s/simplifiable_condition.py delete mode 100644 tests/functional/s/simplifiable_condition.txt delete mode 100644 tests/functional/s/simplifiable_if_expression.py delete mode 100644 tests/functional/s/simplifiable_if_expression.txt delete mode 100644 tests/functional/s/simplifiable_if_statement.py delete mode 100644 tests/functional/s/simplifiable_if_statement.txt delete mode 100644 tests/functional/s/simplify_chained_comparison.py delete mode 100644 tests/functional/s/simplify_chained_comparison.txt create mode 100644 tests/functional/s/string/string_formatting.py create mode 100644 tests/functional/s/string/string_formatting.txt create mode 100644 tests/functional/s/string/string_formatting_disable.py create mode 100644 tests/functional/s/string/string_formatting_disable.rc create mode 100644 tests/functional/s/string/string_formatting_disable.txt create mode 100644 tests/functional/s/string/string_formatting_failed_inference.py create mode 100644 tests/functional/s/string/string_formatting_failed_inference_py35.py create mode 100644 tests/functional/s/string/string_formatting_failed_inference_py35.rc create mode 100644 tests/functional/s/string/string_formatting_py3.py create mode 100644 tests/functional/s/string/string_formatting_py3.rc create mode 100644 tests/functional/s/string/string_formatting_py3.txt delete mode 100644 tests/functional/s/string_formatting.py delete mode 100644 tests/functional/s/string_formatting.txt delete mode 100644 tests/functional/s/string_formatting_disable.py delete mode 100644 tests/functional/s/string_formatting_disable.rc delete mode 100644 tests/functional/s/string_formatting_disable.txt delete mode 100644 tests/functional/s/string_formatting_failed_inference.py delete mode 100644 tests/functional/s/string_formatting_failed_inference_py35.py delete mode 100644 tests/functional/s/string_formatting_failed_inference_py35.rc delete mode 100644 tests/functional/s/string_formatting_py3.py delete mode 100644 tests/functional/s/string_formatting_py3.rc delete mode 100644 tests/functional/s/string_formatting_py3.txt create mode 100644 tests/functional/s/super/super_checks.py create mode 100644 tests/functional/s/super/super_checks.txt create mode 100644 tests/functional/s/super/super_with_arguments.py create mode 100644 tests/functional/s/super/super_with_arguments.rc create mode 100644 tests/functional/s/super/super_with_arguments.txt delete mode 100644 tests/functional/s/super_checks.py delete mode 100644 tests/functional/s/super_checks.txt delete mode 100644 tests/functional/s/super_with_arguments.py delete mode 100644 tests/functional/s/super_with_arguments.rc delete mode 100644 tests/functional/s/super_with_arguments.txt create mode 100644 tests/functional/t/too/__init__.py create mode 100644 tests/functional/t/too/too_few_public_methods.py create mode 100644 tests/functional/t/too/too_few_public_methods.txt create mode 100644 tests/functional/t/too/too_few_public_methods_37.py create mode 100644 tests/functional/t/too/too_few_public_methods_37.rc create mode 100644 tests/functional/t/too/too_many_ancestors.py create mode 100644 tests/functional/t/too/too_many_ancestors.txt create mode 100644 tests/functional/t/too/too_many_arguments.py create mode 100644 tests/functional/t/too/too_many_arguments.txt create mode 100644 tests/functional/t/too/too_many_arguments_issue_1045.py create mode 100644 tests/functional/t/too/too_many_arguments_issue_1045.rc create mode 100644 tests/functional/t/too/too_many_arguments_overload.py create mode 100644 tests/functional/t/too/too_many_boolean_expressions.py create mode 100644 tests/functional/t/too/too_many_boolean_expressions.txt create mode 100644 tests/functional/t/too/too_many_branches.py create mode 100644 tests/functional/t/too/too_many_branches.txt create mode 100644 tests/functional/t/too/too_many_instance_attributes.py create mode 100644 tests/functional/t/too/too_many_instance_attributes.txt create mode 100644 tests/functional/t/too/too_many_lines.py create mode 100644 tests/functional/t/too/too_many_lines.txt create mode 100644 tests/functional/t/too/too_many_lines_disabled.py create mode 100644 tests/functional/t/too/too_many_locals.py create mode 100644 tests/functional/t/too/too_many_locals.txt create mode 100644 tests/functional/t/too/too_many_nested_blocks.py create mode 100644 tests/functional/t/too/too_many_nested_blocks.txt create mode 100644 tests/functional/t/too/too_many_public_methods.py create mode 100644 tests/functional/t/too/too_many_public_methods.txt create mode 100644 tests/functional/t/too/too_many_return_statements.py create mode 100644 tests/functional/t/too/too_many_return_statements.txt create mode 100644 tests/functional/t/too/too_many_star_expressions.py create mode 100644 tests/functional/t/too/too_many_star_expressions.rc create mode 100644 tests/functional/t/too/too_many_star_expressions.txt create mode 100644 tests/functional/t/too/too_many_statements.py create mode 100644 tests/functional/t/too/too_many_statements.txt delete mode 100644 tests/functional/too/__init__.py delete mode 100644 tests/functional/too/too_few_public_methods.py delete mode 100644 tests/functional/too/too_few_public_methods.txt delete mode 100644 tests/functional/too/too_few_public_methods_37.py delete mode 100644 tests/functional/too/too_few_public_methods_37.rc delete mode 100644 tests/functional/too/too_many_ancestors.py delete mode 100644 tests/functional/too/too_many_ancestors.txt delete mode 100644 tests/functional/too/too_many_arguments.py delete mode 100644 tests/functional/too/too_many_arguments.txt delete mode 100644 tests/functional/too/too_many_arguments_issue_1045.py delete mode 100644 tests/functional/too/too_many_arguments_issue_1045.rc delete mode 100644 tests/functional/too/too_many_arguments_overload.py delete mode 100644 tests/functional/too/too_many_boolean_expressions.py delete mode 100644 tests/functional/too/too_many_boolean_expressions.txt delete mode 100644 tests/functional/too/too_many_branches.py delete mode 100644 tests/functional/too/too_many_branches.txt delete mode 100644 tests/functional/too/too_many_instance_attributes.py delete mode 100644 tests/functional/too/too_many_instance_attributes.txt delete mode 100644 tests/functional/too/too_many_lines.py delete mode 100644 tests/functional/too/too_many_lines.txt delete mode 100644 tests/functional/too/too_many_lines_disabled.py delete mode 100644 tests/functional/too/too_many_locals.py delete mode 100644 tests/functional/too/too_many_locals.txt delete mode 100644 tests/functional/too/too_many_nested_blocks.py delete mode 100644 tests/functional/too/too_many_nested_blocks.txt delete mode 100644 tests/functional/too/too_many_public_methods.py delete mode 100644 tests/functional/too/too_many_public_methods.txt delete mode 100644 tests/functional/too/too_many_return_statements.py delete mode 100644 tests/functional/too/too_many_return_statements.txt delete mode 100644 tests/functional/too/too_many_star_expressions.py delete mode 100644 tests/functional/too/too_many_star_expressions.rc delete mode 100644 tests/functional/too/too_many_star_expressions.txt delete mode 100644 tests/functional/too/too_many_statements.py delete mode 100644 tests/functional/too/too_many_statements.txt create mode 100644 tests/functional/u/undefined/undefined_loop_variable.py create mode 100644 tests/functional/u/undefined/undefined_loop_variable.txt create mode 100644 tests/functional/u/undefined/undefined_variable.py create mode 100644 tests/functional/u/undefined/undefined_variable.txt create mode 100644 tests/functional/u/undefined/undefined_variable_crash_on_attribute.py create mode 100644 tests/functional/u/undefined/undefined_variable_py30.py create mode 100644 tests/functional/u/undefined/undefined_variable_py30.rc create mode 100644 tests/functional/u/undefined/undefined_variable_py30.txt delete mode 100644 tests/functional/u/undefined_loop_variable.py delete mode 100644 tests/functional/u/undefined_loop_variable.txt delete mode 100644 tests/functional/u/undefined_variable.py delete mode 100644 tests/functional/u/undefined_variable.txt delete mode 100644 tests/functional/u/undefined_variable_crash_on_attribute.py delete mode 100644 tests/functional/u/undefined_variable_py30.py delete mode 100644 tests/functional/u/undefined_variable_py30.rc delete mode 100644 tests/functional/u/undefined_variable_py30.txt create mode 100644 tests/functional/u/unnecessary/unnecessary_comprehension.py create mode 100644 tests/functional/u/unnecessary/unnecessary_comprehension.txt create mode 100644 tests/functional/u/unnecessary/unnecessary_lambda.py create mode 100644 tests/functional/u/unnecessary/unnecessary_lambda.txt create mode 100644 tests/functional/u/unnecessary/unnecessary_not.py create mode 100644 tests/functional/u/unnecessary/unnecessary_not.txt create mode 100644 tests/functional/u/unnecessary/unnecessary_pass.py create mode 100644 tests/functional/u/unnecessary/unnecessary_pass.txt delete mode 100644 tests/functional/u/unnecessary_comprehension.py delete mode 100644 tests/functional/u/unnecessary_comprehension.txt delete mode 100644 tests/functional/u/unnecessary_lambda.py delete mode 100644 tests/functional/u/unnecessary_lambda.txt delete mode 100644 tests/functional/u/unnecessary_pass.py delete mode 100644 tests/functional/u/unnecessary_pass.txt delete mode 100644 tests/functional/u/unneeded_not.py delete mode 100644 tests/functional/u/unneeded_not.txt create mode 100644 tests/functional/u/unsupported/unsupported_assignment_operation.py create mode 100644 tests/functional/u/unsupported/unsupported_assignment_operation.rc create mode 100644 tests/functional/u/unsupported/unsupported_assignment_operation.txt create mode 100644 tests/functional/u/unsupported/unsupported_binary_operation.py create mode 100644 tests/functional/u/unsupported/unsupported_binary_operation.rc create mode 100644 tests/functional/u/unsupported/unsupported_binary_operation.txt create mode 100644 tests/functional/u/unsupported/unsupported_delete_operation.py create mode 100644 tests/functional/u/unsupported/unsupported_delete_operation.rc create mode 100644 tests/functional/u/unsupported/unsupported_delete_operation.txt delete mode 100644 tests/functional/u/unsupported_assignment_operation.py delete mode 100644 tests/functional/u/unsupported_assignment_operation.rc delete mode 100644 tests/functional/u/unsupported_assignment_operation.txt delete mode 100644 tests/functional/u/unsupported_binary_operation.py delete mode 100644 tests/functional/u/unsupported_binary_operation.rc delete mode 100644 tests/functional/u/unsupported_binary_operation.txt delete mode 100644 tests/functional/u/unsupported_delete_operation.py delete mode 100644 tests/functional/u/unsupported_delete_operation.rc delete mode 100644 tests/functional/u/unsupported_delete_operation.txt create mode 100644 tests/functional/u/unused/__init__.py create mode 100644 tests/functional/u/unused/unused_argument.py create mode 100644 tests/functional/u/unused/unused_argument.txt create mode 100644 tests/functional/u/unused/unused_argument_py3.py create mode 100644 tests/functional/u/unused/unused_argument_py3.rc create mode 100644 tests/functional/u/unused/unused_argument_py3.txt create mode 100644 tests/functional/u/unused/unused_global_variable1.py create mode 100644 tests/functional/u/unused/unused_global_variable2.py create mode 100644 tests/functional/u/unused/unused_global_variable2.rc create mode 100644 tests/functional/u/unused/unused_global_variable2.txt create mode 100644 tests/functional/u/unused/unused_global_variable3.py create mode 100644 tests/functional/u/unused/unused_global_variable4.py create mode 100644 tests/functional/u/unused/unused_global_variable4.rc create mode 100644 tests/functional/u/unused/unused_global_variable4.txt create mode 100644 tests/functional/u/unused/unused_import.py create mode 100644 tests/functional/u/unused/unused_import.txt create mode 100644 tests/functional/u/unused/unused_import_assigned_to.py create mode 100644 tests/functional/u/unused/unused_import_everything_disabled.py create mode 100644 tests/functional/u/unused/unused_import_everything_disabled.rc create mode 100644 tests/functional/u/unused/unused_import_positional_only_py38.py create mode 100644 tests/functional/u/unused/unused_import_positional_only_py38.rc create mode 100644 tests/functional/u/unused/unused_typing_imports.py create mode 100644 tests/functional/u/unused/unused_typing_imports.rc create mode 100644 tests/functional/u/unused/unused_variable.py create mode 100644 tests/functional/u/unused/unused_variable.txt create mode 100644 tests/functional/u/unused/unused_variable_py36.py create mode 100644 tests/functional/u/unused/unused_variable_py36.rc delete mode 100644 tests/functional/u/unused_argument.py delete mode 100644 tests/functional/u/unused_argument.txt delete mode 100644 tests/functional/u/unused_argument_py3.py delete mode 100644 tests/functional/u/unused_argument_py3.rc delete mode 100644 tests/functional/u/unused_argument_py3.txt delete mode 100644 tests/functional/u/unused_global_variable1.py delete mode 100644 tests/functional/u/unused_global_variable2.py delete mode 100644 tests/functional/u/unused_global_variable2.rc delete mode 100644 tests/functional/u/unused_global_variable2.txt delete mode 100644 tests/functional/u/unused_global_variable3.py delete mode 100644 tests/functional/u/unused_global_variable4.py delete mode 100644 tests/functional/u/unused_global_variable4.rc delete mode 100644 tests/functional/u/unused_global_variable4.txt delete mode 100644 tests/functional/u/unused_import.py delete mode 100644 tests/functional/u/unused_import.txt delete mode 100644 tests/functional/u/unused_import_assigned_to.py delete mode 100644 tests/functional/u/unused_import_everything_disabled.py delete mode 100644 tests/functional/u/unused_import_everything_disabled.rc delete mode 100644 tests/functional/u/unused_import_positional_only_py38.py delete mode 100644 tests/functional/u/unused_import_positional_only_py38.rc delete mode 100644 tests/functional/u/unused_typing_imports.py delete mode 100644 tests/functional/u/unused_typing_imports.rc delete mode 100644 tests/functional/u/unused_variable.py delete mode 100644 tests/functional/u/unused_variable.txt delete mode 100644 tests/functional/u/unused_variable_py36.py delete mode 100644 tests/functional/u/unused_variable_py36.rc create mode 100644 tests/functional/u/use/use_a_generator.py create mode 100644 tests/functional/u/use/use_a_generator.txt create mode 100644 tests/functional/u/use/used_before_assignment_488.py create mode 100644 tests/functional/u/use/used_before_assignment_issue1081.py create mode 100644 tests/functional/u/use/used_before_assignment_issue1081.txt create mode 100644 tests/functional/u/use/used_before_assignment_issue853.py create mode 100644 tests/functional/u/use/used_before_assignment_nonlocal.py create mode 100644 tests/functional/u/use/used_before_assignment_nonlocal.rc create mode 100644 tests/functional/u/use/used_before_assignment_nonlocal.txt create mode 100644 tests/functional/u/use/used_prior_global_declaration.py create mode 100644 tests/functional/u/use/used_prior_global_declaration.rc create mode 100644 tests/functional/u/use/used_prior_global_declaration.txt create mode 100644 tests/functional/u/use/using_constant_test.py create mode 100644 tests/functional/u/use/using_constant_test.txt delete mode 100644 tests/functional/u/use_a_generator.py delete mode 100644 tests/functional/u/use_a_generator.txt delete mode 100644 tests/functional/u/used_before_assignment_488.py delete mode 100644 tests/functional/u/used_before_assignment_issue1081.py delete mode 100644 tests/functional/u/used_before_assignment_issue1081.txt delete mode 100644 tests/functional/u/used_before_assignment_issue853.py delete mode 100644 tests/functional/u/used_before_assignment_nonlocal.py delete mode 100644 tests/functional/u/used_before_assignment_nonlocal.rc delete mode 100644 tests/functional/u/used_before_assignment_nonlocal.txt delete mode 100644 tests/functional/u/used_prior_global_declaration.py delete mode 100644 tests/functional/u/used_prior_global_declaration.rc delete mode 100644 tests/functional/u/used_prior_global_declaration.txt delete mode 100644 tests/functional/u/useless-import-alias.py delete mode 100644 tests/functional/u/useless-import-alias.txt create mode 100644 tests/functional/u/useless/useless-import-alias.py create mode 100644 tests/functional/u/useless/useless-import-alias.txt create mode 100644 tests/functional/u/useless/useless_else_on_loop.py create mode 100644 tests/functional/u/useless/useless_else_on_loop.txt create mode 100644 tests/functional/u/useless/useless_object_inheritance.py create mode 100644 tests/functional/u/useless/useless_object_inheritance.txt create mode 100644 tests/functional/u/useless/useless_return.py create mode 100644 tests/functional/u/useless/useless_return.txt create mode 100644 tests/functional/u/useless/useless_super_delegation.py create mode 100644 tests/functional/u/useless/useless_super_delegation.txt create mode 100644 tests/functional/u/useless/useless_super_delegation_py3.py create mode 100644 tests/functional/u/useless/useless_super_delegation_py3.rc create mode 100644 tests/functional/u/useless/useless_super_delegation_py3.txt create mode 100644 tests/functional/u/useless/useless_super_delegation_py35.py create mode 100644 tests/functional/u/useless/useless_super_delegation_py35.rc create mode 100644 tests/functional/u/useless/useless_super_delegation_py35.txt create mode 100644 tests/functional/u/useless/useless_super_delegation_py38.py create mode 100644 tests/functional/u/useless/useless_super_delegation_py38.rc create mode 100644 tests/functional/u/useless/useless_super_delegation_py38.txt delete mode 100644 tests/functional/u/useless_else_on_loop.py delete mode 100644 tests/functional/u/useless_else_on_loop.txt delete mode 100644 tests/functional/u/useless_object_inheritance.py delete mode 100644 tests/functional/u/useless_object_inheritance.txt delete mode 100644 tests/functional/u/useless_return.py delete mode 100644 tests/functional/u/useless_return.txt delete mode 100644 tests/functional/u/useless_super_delegation.py delete mode 100644 tests/functional/u/useless_super_delegation.txt delete mode 100644 tests/functional/u/useless_super_delegation_py3.py delete mode 100644 tests/functional/u/useless_super_delegation_py3.rc delete mode 100644 tests/functional/u/useless_super_delegation_py3.txt delete mode 100644 tests/functional/u/useless_super_delegation_py35.py delete mode 100644 tests/functional/u/useless_super_delegation_py35.rc delete mode 100644 tests/functional/u/useless_super_delegation_py35.txt delete mode 100644 tests/functional/u/useless_super_delegation_py38.py delete mode 100644 tests/functional/u/useless_super_delegation_py38.rc delete mode 100644 tests/functional/u/useless_super_delegation_py38.txt delete mode 100644 tests/functional/u/using_constant_test.py delete mode 100644 tests/functional/u/using_constant_test.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f2d3b71ea..953b796ac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: - id: trailing-whitespace exclude: "tests/functional/t/trailing_whitespaces.py" - id: end-of-file-fixer - exclude: "tests/functional/m/missing_final_newline.py|tests/functional/t/trailing_newlines.py" + exclude: "tests/functional/m/missing/missing_final_newline.py|tests/functional/t/trailing_newlines.py" - repo: https://github.com/PyCQA/isort rev: 5.7.0 hooks: diff --git a/tests/functional/a/abstract/abstract_abc_methods.py b/tests/functional/a/abstract/abstract_abc_methods.py new file mode 100644 index 000000000..d174669a5 --- /dev/null +++ b/tests/functional/a/abstract/abstract_abc_methods.py @@ -0,0 +1,17 @@ +""" This should not warn about `prop` being abstract in Child """ +# pylint: disable=too-few-public-methods, no-absolute-import,metaclass-assignment, useless-object-inheritance + +import abc + +class Parent(object): + """Abstract Base Class """ + __metaclass__ = abc.ABCMeta + + @property + @abc.abstractmethod + def prop(self): + """ Abstract """ + +class Child(Parent): + """ No warning for the following. """ + prop = property(lambda self: 1) diff --git a/tests/functional/a/abstract/abstract_class_instantiated_in_class.py b/tests/functional/a/abstract/abstract_class_instantiated_in_class.py new file mode 100644 index 000000000..daaa3b689 --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_in_class.py @@ -0,0 +1,17 @@ +"""Don't warn if the class is instantiated in its own body.""" +# pylint: disable=missing-docstring, useless-object-inheritance + + +import abc + + +class Ala(object, metaclass=abc.ABCMeta): + + @abc.abstractmethod + def bala(self): + pass + + @classmethod + def portocala(cls): + instance = cls() + return instance diff --git a/tests/functional/a/abstract/abstract_class_instantiated_py3.py b/tests/functional/a/abstract/abstract_class_instantiated_py3.py new file mode 100644 index 000000000..c027833e7 --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_py3.py @@ -0,0 +1,128 @@ +"""Check that instantiating a class with +`abc.ABCMeta` as metaclass fails if it defines +abstract methods. +""" + +# pylint: disable=too-few-public-methods, missing-docstring +# pylint: disable=abstract-method, import-error, useless-object-inheritance + +import abc +import weakref +from lala import Bala + + +class GoodClass(object, metaclass=abc.ABCMeta): + pass + +class SecondGoodClass(object, metaclass=abc.ABCMeta): + def test(self): + """ do nothing. """ + +class ThirdGoodClass(object, metaclass=abc.ABCMeta): + """ This should not raise the warning. """ + def test(self): + raise NotImplementedError() + +class BadClass(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def test(self): + """ do nothing. """ + +class SecondBadClass(object, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def test(self): + """ do nothing. """ + +class ThirdBadClass(SecondBadClass): + pass + + +class Structure(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __iter__(self): + pass + @abc.abstractmethod + def __len__(self): + pass + @abc.abstractmethod + def __contains__(self, _): + pass + @abc.abstractmethod + def __hash__(self): + pass + +class Container(Structure): + def __contains__(self, _): + pass + +class Sizable(Structure): + def __len__(self): + pass + +class Hashable(Structure): + __hash__ = 42 + + +class Iterator(Structure): + def keys(self): # pylint: disable=no-self-use + return iter([1, 2, 3]) + + __iter__ = keys + +class AbstractSizable(Structure): + @abc.abstractmethod + def length(self): + pass + __len__ = length + +class NoMroAbstractMethods(Container, Iterator, Sizable, Hashable): + pass + +class BadMroAbstractMethods(Container, Iterator, AbstractSizable): + pass + +class SomeMetaclass(metaclass=abc.ABCMeta): + + @abc.abstractmethod + def prop(self): + pass + +class FourthGoodClass(SomeMetaclass): + """Don't consider this abstract if some attributes are + there, but can't be inferred. + """ + prop = Bala # missing + + +def main(): + """ do nothing """ + GoodClass() + SecondGoodClass() + ThirdGoodClass() + FourthGoodClass() + weakref.WeakKeyDictionary() + weakref.WeakValueDictionary() + NoMroAbstractMethods() + + BadMroAbstractMethods() # [abstract-class-instantiated] + BadClass() # [abstract-class-instantiated] + SecondBadClass() # [abstract-class-instantiated] + ThirdBadClass() # [abstract-class-instantiated] + + +if 1: # pylint: disable=using-constant-test + class FourthBadClass(object, metaclass=abc.ABCMeta): + + def test(self): + pass +else: + class FourthBadClass(object, metaclass=abc.ABCMeta): + + @abc.abstractmethod + def test(self): + pass + + +def main2(): + FourthBadClass() # [abstract-class-instantiated] diff --git a/tests/functional/a/abstract/abstract_class_instantiated_py3.rc b/tests/functional/a/abstract/abstract_class_instantiated_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/a/abstract/abstract_class_instantiated_py3.txt b/tests/functional/a/abstract/abstract_class_instantiated_py3.txt new file mode 100644 index 000000000..f08baf86f --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_py3.txt @@ -0,0 +1,5 @@ +abstract-class-instantiated:108:4:main:Abstract class 'BadMroAbstractMethods' with abstract methods instantiated +abstract-class-instantiated:109:4:main:Abstract class 'BadClass' with abstract methods instantiated +abstract-class-instantiated:110:4:main:Abstract class 'SecondBadClass' with abstract methods instantiated +abstract-class-instantiated:111:4:main:Abstract class 'ThirdBadClass' with abstract methods instantiated +abstract-class-instantiated:128:4:main2:Abstract class 'FourthBadClass' with abstract methods instantiated diff --git a/tests/functional/a/abstract/abstract_class_instantiated_py34.py b/tests/functional/a/abstract/abstract_class_instantiated_py34.py new file mode 100644 index 000000000..e24ad28f1 --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_py34.py @@ -0,0 +1,19 @@ +""" +Check that instantiating a class with `abc.ABCMeta` as ancestor fails if it +defines abstract methods. +""" + +# pylint: disable=too-few-public-methods, missing-docstring, no-init + +import abc + + + +class BadClass(abc.ABC): + @abc.abstractmethod + def test(self): + pass + +def main(): + """ do nothing """ + BadClass() # [abstract-class-instantiated] diff --git a/tests/functional/a/abstract/abstract_class_instantiated_py34.rc b/tests/functional/a/abstract/abstract_class_instantiated_py34.rc new file mode 100644 index 000000000..f400a86e6 --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_py34.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.4 diff --git a/tests/functional/a/abstract/abstract_class_instantiated_py34.txt b/tests/functional/a/abstract/abstract_class_instantiated_py34.txt new file mode 100644 index 000000000..88d0ef32c --- /dev/null +++ b/tests/functional/a/abstract/abstract_class_instantiated_py34.txt @@ -0,0 +1 @@ +abstract-class-instantiated:19:4:main:Abstract class 'BadClass' with abstract methods instantiated diff --git a/tests/functional/a/abstract/abstract_method_py3.py b/tests/functional/a/abstract/abstract_method_py3.py new file mode 100644 index 000000000..8bb491819 --- /dev/null +++ b/tests/functional/a/abstract/abstract_method_py3.py @@ -0,0 +1,107 @@ +"""Test abstract-method warning.""" +from __future__ import print_function + +# pylint: disable=missing-docstring, no-init, no-self-use +# pylint: disable=too-few-public-methods, useless-object-inheritance +import abc + + +class Abstract(object): + def aaaa(self): + """should be overridden in concrete class""" + raise NotImplementedError() + + def bbbb(self): + """should be overridden in concrete class""" + raise NotImplementedError() + + +class AbstractB(Abstract): + """Abstract class. + + this class is checking that it does not output an error msg for + unimplemeted methods in abstract classes + """ + def cccc(self): + """should be overridden in concrete class""" + raise NotImplementedError() + +class AbstractC(AbstractB, abc.ABC): + """ + Abstract class. + + Should not trigger a warning for unimplemented + abstract methods, because of explicit abc.ABC inheritance. + """ + + +class AbstractD(AbstractB, metaclass=abc.ABCMeta): + """ + Abstract class. + + Should not trigger a warning for unimplemented + abstract methods, because of explicit metaclass. + """ + + +class Concrete(Abstract): # [abstract-method] + """Concrete class""" + + def aaaa(self): + """overidden form Abstract""" + + +class Structure(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __iter__(self): + pass + @abc.abstractmethod + def __len__(self): + pass + @abc.abstractmethod + def __contains__(self, _): + pass + @abc.abstractmethod + def __hash__(self): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Container(Structure): + def __contains__(self, _): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Sizable(Structure): + def __len__(self): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Hashable(Structure): + __hash__ = 42 + + +# +1: [abstract-method, abstract-method, abstract-method] +class Iterator(Structure): + def keys(self): + return iter([1, 2, 3]) + + __iter__ = keys + + +class AbstractSizable(Structure): + @abc.abstractmethod + def length(self): + pass + __len__ = length + + +class GoodComplexMRO(Container, Iterator, Sizable, Hashable): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class BadComplexMro(Container, Iterator, AbstractSizable): + pass diff --git a/tests/functional/a/abstract/abstract_method_py3.rc b/tests/functional/a/abstract/abstract_method_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/a/abstract/abstract_method_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/a/abstract/abstract_method_py3.txt b/tests/functional/a/abstract/abstract_method_py3.txt new file mode 100644 index 000000000..783242fd5 --- /dev/null +++ b/tests/functional/a/abstract/abstract_method_py3.txt @@ -0,0 +1,16 @@ +abstract-method:47:0:Concrete:Method 'bbbb' is abstract in class 'Abstract' but is not overridden +abstract-method:70:0:Container:Method '__hash__' is abstract in class 'Structure' but is not overridden +abstract-method:70:0:Container:Method '__iter__' is abstract in class 'Structure' but is not overridden +abstract-method:70:0:Container:Method '__len__' is abstract in class 'Structure' but is not overridden +abstract-method:76:0:Sizable:Method '__contains__' is abstract in class 'Structure' but is not overridden +abstract-method:76:0:Sizable:Method '__hash__' is abstract in class 'Structure' but is not overridden +abstract-method:76:0:Sizable:Method '__iter__' is abstract in class 'Structure' but is not overridden +abstract-method:82:0:Hashable:Method '__contains__' is abstract in class 'Structure' but is not overridden +abstract-method:82:0:Hashable:Method '__iter__' is abstract in class 'Structure' but is not overridden +abstract-method:82:0:Hashable:Method '__len__' is abstract in class 'Structure' but is not overridden +abstract-method:87:0:Iterator:Method '__contains__' is abstract in class 'Structure' but is not overridden +abstract-method:87:0:Iterator:Method '__hash__' is abstract in class 'Structure' but is not overridden +abstract-method:87:0:Iterator:Method '__len__' is abstract in class 'Structure' but is not overridden +abstract-method:106:0:BadComplexMro:Method '__hash__' is abstract in class 'Structure' but is not overridden +abstract-method:106:0:BadComplexMro:Method '__len__' is abstract in class 'AbstractSizable' but is not overridden +abstract-method:106:0:BadComplexMro:Method 'length' is abstract in class 'AbstractSizable' but is not overridden diff --git a/tests/functional/a/abstract_abc_methods.py b/tests/functional/a/abstract_abc_methods.py deleted file mode 100644 index d174669a5..000000000 --- a/tests/functional/a/abstract_abc_methods.py +++ /dev/null @@ -1,17 +0,0 @@ -""" This should not warn about `prop` being abstract in Child """ -# pylint: disable=too-few-public-methods, no-absolute-import,metaclass-assignment, useless-object-inheritance - -import abc - -class Parent(object): - """Abstract Base Class """ - __metaclass__ = abc.ABCMeta - - @property - @abc.abstractmethod - def prop(self): - """ Abstract """ - -class Child(Parent): - """ No warning for the following. """ - prop = property(lambda self: 1) diff --git a/tests/functional/a/abstract_class_instantiated_in_class.py b/tests/functional/a/abstract_class_instantiated_in_class.py deleted file mode 100644 index daaa3b689..000000000 --- a/tests/functional/a/abstract_class_instantiated_in_class.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Don't warn if the class is instantiated in its own body.""" -# pylint: disable=missing-docstring, useless-object-inheritance - - -import abc - - -class Ala(object, metaclass=abc.ABCMeta): - - @abc.abstractmethod - def bala(self): - pass - - @classmethod - def portocala(cls): - instance = cls() - return instance diff --git a/tests/functional/a/abstract_class_instantiated_py3.py b/tests/functional/a/abstract_class_instantiated_py3.py deleted file mode 100644 index c027833e7..000000000 --- a/tests/functional/a/abstract_class_instantiated_py3.py +++ /dev/null @@ -1,128 +0,0 @@ -"""Check that instantiating a class with -`abc.ABCMeta` as metaclass fails if it defines -abstract methods. -""" - -# pylint: disable=too-few-public-methods, missing-docstring -# pylint: disable=abstract-method, import-error, useless-object-inheritance - -import abc -import weakref -from lala import Bala - - -class GoodClass(object, metaclass=abc.ABCMeta): - pass - -class SecondGoodClass(object, metaclass=abc.ABCMeta): - def test(self): - """ do nothing. """ - -class ThirdGoodClass(object, metaclass=abc.ABCMeta): - """ This should not raise the warning. """ - def test(self): - raise NotImplementedError() - -class BadClass(object, metaclass=abc.ABCMeta): - @abc.abstractmethod - def test(self): - """ do nothing. """ - -class SecondBadClass(object, metaclass=abc.ABCMeta): - @property - @abc.abstractmethod - def test(self): - """ do nothing. """ - -class ThirdBadClass(SecondBadClass): - pass - - -class Structure(object, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __iter__(self): - pass - @abc.abstractmethod - def __len__(self): - pass - @abc.abstractmethod - def __contains__(self, _): - pass - @abc.abstractmethod - def __hash__(self): - pass - -class Container(Structure): - def __contains__(self, _): - pass - -class Sizable(Structure): - def __len__(self): - pass - -class Hashable(Structure): - __hash__ = 42 - - -class Iterator(Structure): - def keys(self): # pylint: disable=no-self-use - return iter([1, 2, 3]) - - __iter__ = keys - -class AbstractSizable(Structure): - @abc.abstractmethod - def length(self): - pass - __len__ = length - -class NoMroAbstractMethods(Container, Iterator, Sizable, Hashable): - pass - -class BadMroAbstractMethods(Container, Iterator, AbstractSizable): - pass - -class SomeMetaclass(metaclass=abc.ABCMeta): - - @abc.abstractmethod - def prop(self): - pass - -class FourthGoodClass(SomeMetaclass): - """Don't consider this abstract if some attributes are - there, but can't be inferred. - """ - prop = Bala # missing - - -def main(): - """ do nothing """ - GoodClass() - SecondGoodClass() - ThirdGoodClass() - FourthGoodClass() - weakref.WeakKeyDictionary() - weakref.WeakValueDictionary() - NoMroAbstractMethods() - - BadMroAbstractMethods() # [abstract-class-instantiated] - BadClass() # [abstract-class-instantiated] - SecondBadClass() # [abstract-class-instantiated] - ThirdBadClass() # [abstract-class-instantiated] - - -if 1: # pylint: disable=using-constant-test - class FourthBadClass(object, metaclass=abc.ABCMeta): - - def test(self): - pass -else: - class FourthBadClass(object, metaclass=abc.ABCMeta): - - @abc.abstractmethod - def test(self): - pass - - -def main2(): - FourthBadClass() # [abstract-class-instantiated] diff --git a/tests/functional/a/abstract_class_instantiated_py3.rc b/tests/functional/a/abstract_class_instantiated_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/a/abstract_class_instantiated_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/a/abstract_class_instantiated_py3.txt b/tests/functional/a/abstract_class_instantiated_py3.txt deleted file mode 100644 index f08baf86f..000000000 --- a/tests/functional/a/abstract_class_instantiated_py3.txt +++ /dev/null @@ -1,5 +0,0 @@ -abstract-class-instantiated:108:4:main:Abstract class 'BadMroAbstractMethods' with abstract methods instantiated -abstract-class-instantiated:109:4:main:Abstract class 'BadClass' with abstract methods instantiated -abstract-class-instantiated:110:4:main:Abstract class 'SecondBadClass' with abstract methods instantiated -abstract-class-instantiated:111:4:main:Abstract class 'ThirdBadClass' with abstract methods instantiated -abstract-class-instantiated:128:4:main2:Abstract class 'FourthBadClass' with abstract methods instantiated diff --git a/tests/functional/a/abstract_class_instantiated_py34.py b/tests/functional/a/abstract_class_instantiated_py34.py deleted file mode 100644 index e24ad28f1..000000000 --- a/tests/functional/a/abstract_class_instantiated_py34.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Check that instantiating a class with `abc.ABCMeta` as ancestor fails if it -defines abstract methods. -""" - -# pylint: disable=too-few-public-methods, missing-docstring, no-init - -import abc - - - -class BadClass(abc.ABC): - @abc.abstractmethod - def test(self): - pass - -def main(): - """ do nothing """ - BadClass() # [abstract-class-instantiated] diff --git a/tests/functional/a/abstract_class_instantiated_py34.rc b/tests/functional/a/abstract_class_instantiated_py34.rc deleted file mode 100644 index f400a86e6..000000000 --- a/tests/functional/a/abstract_class_instantiated_py34.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.4 diff --git a/tests/functional/a/abstract_class_instantiated_py34.txt b/tests/functional/a/abstract_class_instantiated_py34.txt deleted file mode 100644 index 88d0ef32c..000000000 --- a/tests/functional/a/abstract_class_instantiated_py34.txt +++ /dev/null @@ -1 +0,0 @@ -abstract-class-instantiated:19:4:main:Abstract class 'BadClass' with abstract methods instantiated diff --git a/tests/functional/a/abstract_method_py3.py b/tests/functional/a/abstract_method_py3.py deleted file mode 100644 index 8bb491819..000000000 --- a/tests/functional/a/abstract_method_py3.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Test abstract-method warning.""" -from __future__ import print_function - -# pylint: disable=missing-docstring, no-init, no-self-use -# pylint: disable=too-few-public-methods, useless-object-inheritance -import abc - - -class Abstract(object): - def aaaa(self): - """should be overridden in concrete class""" - raise NotImplementedError() - - def bbbb(self): - """should be overridden in concrete class""" - raise NotImplementedError() - - -class AbstractB(Abstract): - """Abstract class. - - this class is checking that it does not output an error msg for - unimplemeted methods in abstract classes - """ - def cccc(self): - """should be overridden in concrete class""" - raise NotImplementedError() - -class AbstractC(AbstractB, abc.ABC): - """ - Abstract class. - - Should not trigger a warning for unimplemented - abstract methods, because of explicit abc.ABC inheritance. - """ - - -class AbstractD(AbstractB, metaclass=abc.ABCMeta): - """ - Abstract class. - - Should not trigger a warning for unimplemented - abstract methods, because of explicit metaclass. - """ - - -class Concrete(Abstract): # [abstract-method] - """Concrete class""" - - def aaaa(self): - """overidden form Abstract""" - - -class Structure(object, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __iter__(self): - pass - @abc.abstractmethod - def __len__(self): - pass - @abc.abstractmethod - def __contains__(self, _): - pass - @abc.abstractmethod - def __hash__(self): - pass - - -# +1: [abstract-method, abstract-method, abstract-method] -class Container(Structure): - def __contains__(self, _): - pass - - -# +1: [abstract-method, abstract-method, abstract-method] -class Sizable(Structure): - def __len__(self): - pass - - -# +1: [abstract-method, abstract-method, abstract-method] -class Hashable(Structure): - __hash__ = 42 - - -# +1: [abstract-method, abstract-method, abstract-method] -class Iterator(Structure): - def keys(self): - return iter([1, 2, 3]) - - __iter__ = keys - - -class AbstractSizable(Structure): - @abc.abstractmethod - def length(self): - pass - __len__ = length - - -class GoodComplexMRO(Container, Iterator, Sizable, Hashable): - pass - - -# +1: [abstract-method, abstract-method, abstract-method] -class BadComplexMro(Container, Iterator, AbstractSizable): - pass diff --git a/tests/functional/a/abstract_method_py3.rc b/tests/functional/a/abstract_method_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/a/abstract_method_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/a/abstract_method_py3.txt b/tests/functional/a/abstract_method_py3.txt deleted file mode 100644 index 783242fd5..000000000 --- a/tests/functional/a/abstract_method_py3.txt +++ /dev/null @@ -1,16 +0,0 @@ -abstract-method:47:0:Concrete:Method 'bbbb' is abstract in class 'Abstract' but is not overridden -abstract-method:70:0:Container:Method '__hash__' is abstract in class 'Structure' but is not overridden -abstract-method:70:0:Container:Method '__iter__' is abstract in class 'Structure' but is not overridden -abstract-method:70:0:Container:Method '__len__' is abstract in class 'Structure' but is not overridden -abstract-method:76:0:Sizable:Method '__contains__' is abstract in class 'Structure' but is not overridden -abstract-method:76:0:Sizable:Method '__hash__' is abstract in class 'Structure' but is not overridden -abstract-method:76:0:Sizable:Method '__iter__' is abstract in class 'Structure' but is not overridden -abstract-method:82:0:Hashable:Method '__contains__' is abstract in class 'Structure' but is not overridden -abstract-method:82:0:Hashable:Method '__iter__' is abstract in class 'Structure' but is not overridden -abstract-method:82:0:Hashable:Method '__len__' is abstract in class 'Structure' but is not overridden -abstract-method:87:0:Iterator:Method '__contains__' is abstract in class 'Structure' but is not overridden -abstract-method:87:0:Iterator:Method '__hash__' is abstract in class 'Structure' but is not overridden -abstract-method:87:0:Iterator:Method '__len__' is abstract in class 'Structure' but is not overridden -abstract-method:106:0:BadComplexMro:Method '__hash__' is abstract in class 'Structure' but is not overridden -abstract-method:106:0:BadComplexMro:Method '__len__' is abstract in class 'AbstractSizable' but is not overridden -abstract-method:106:0:BadComplexMro:Method 'length' is abstract in class 'AbstractSizable' but is not overridden diff --git a/tests/functional/c/consider/consider_iterating_dictionary.py b/tests/functional/c/consider/consider_iterating_dictionary.py new file mode 100644 index 000000000..1198de1cb --- /dev/null +++ b/tests/functional/c/consider/consider_iterating_dictionary.py @@ -0,0 +1,38 @@ +# pylint: disable=missing-docstring, expression-not-assigned, too-few-public-methods, no-member, import-error, no-self-use, line-too-long, useless-object-inheritance, unnecessary-comprehension + +from unknown import Unknown + + +class CustomClass(object): + def keys(self): + return [] + +for key in Unknown().keys(): + pass +for key in Unknown.keys(): + pass +for key in dict.keys(): + pass +for key in {}.values(): + pass +for key in {}.key(): + pass +for key in CustomClass().keys(): + pass + +[key for key in {}.keys()] # [consider-iterating-dictionary] +(key for key in {}.keys()) # [consider-iterating-dictionary] +{key for key in {}.keys()} # [consider-iterating-dictionary] +{key: key for key in {}.keys()} # [consider-iterating-dictionary] +COMP1 = [key for key in {}.keys()] # [consider-iterating-dictionary] +COMP2 = (key for key in {}.keys()) # [consider-iterating-dictionary] +COMP3 = {key for key in {}.keys()} # [consider-iterating-dictionary] +COMP4 = {key: key for key in {}.keys()} # [consider-iterating-dictionary] +for key in {}.keys(): # [consider-iterating-dictionary] + pass + +# Issue #1247 +DICT = {'a': 1, 'b': 2} +COMP1 = [k * 2 for k in DICT.keys()] + [k * 3 for k in DICT.keys()] # [consider-iterating-dictionary,consider-iterating-dictionary] +COMP2, COMP3 = [k * 2 for k in DICT.keys()], [k * 3 for k in DICT.keys()] # [consider-iterating-dictionary,consider-iterating-dictionary] +SOME_TUPLE = ([k * 2 for k in DICT.keys()], [k * 3 for k in DICT.keys()]) # [consider-iterating-dictionary,consider-iterating-dictionary] diff --git a/tests/functional/c/consider/consider_iterating_dictionary.txt b/tests/functional/c/consider/consider_iterating_dictionary.txt new file mode 100644 index 000000000..c1b12f976 --- /dev/null +++ b/tests/functional/c/consider/consider_iterating_dictionary.txt @@ -0,0 +1,15 @@ +consider-iterating-dictionary:23:16::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:24:16::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:25:16::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:26:21::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:27:24::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:28:24::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:29:24::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:30:29::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:31:11::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:36:24::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:36:55::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:37:31::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:37:61::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:38:30::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:38:60::Consider iterating the dictionary directly instead of calling .keys() diff --git a/tests/functional/c/consider/consider_join.py b/tests/functional/c/consider/consider_join.py new file mode 100644 index 000000000..24cd6dd49 --- /dev/null +++ b/tests/functional/c/consider/consider_join.py @@ -0,0 +1,126 @@ +# pylint: disable=missing-docstring,invalid-name,undefined-variable,multiple-statements + +# Variations of 'result' +result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = 'header' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = another_result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +another_result = result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = 0 # result is not a string +for number in ['1', '2', '3']: + result += number + +RESULT = '' # wrong name / initial variable missing +for number in ['1', '2', '3']: + result += [number] + +string_variable = '' +result = string_variable # type of 'result' not obviously a string +for number in ['1', '2', '3']: + result += number + +result = '' +another_result = '' # result defined too early +for number in ['1', '2', '3']: + result += [number] + +for number in ['1', '2', '3']: # 'result'-definition missing + result += number + + +# Variations of 'number' +result = '' # no concatenation (iterator-name differs) +for name in ['1', '2', '3']: + result += number + +result = '' # no concatenation (iterator-name differs) +for _ in ['1', '2', '3']: + result += number +# 'exprlist' is not a single name +for index, number in ['1', '2', '3']: + result += number + + +# Variations of 'iterable' +result = '' +for number in []: + result += number # [consider-using-join] + +result = '' +for number in "a text": + result += number # [consider-using-join] + +result = '' +for number in [1, 2, 3]: + result += number # [consider-using-join] + +a_list = [1, 2, 3] +result = '' +for number in a_list: + result += number # [consider-using-join] + +result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = '' +for number in undefined_iterable: + result += number # [consider-using-join] + + +# Variations of loop-body +result = '' # addition is not the only part of the body +for number in ['1', '2', '3']: + print(number) + result += number + +result = '' # addition is not the only part of the body +for number in ['1', '2', '3']: + result += number + print(number) + +result = '' # augmented addition is not a simple one +for number in ['1', '2', '3']: + result += '4' + number + +result = '' # assignment is not augmented +for number in ['1', '2', '3']: + result = number + +result = '' # augmented assignment is not an addition +for number in ['1', '2', '3']: + result -= number + +result = '' # addition is not the 'number'-iterable +for number in ['1', '2', '3']: + result += another_number + +result = '' +for number in ['1', '2', '3']: result += number # [consider-using-join] + +result = '' +for number in ['1']: + result.result += number + +# Does not emit if the body is more complex +result = {'context': 1} +result['context'] = 0 +for number in ['1']: + result1 = 42 + int(number) + result['context'] += result1 * 24 + +# Does not crash if the previous sibling does not have AssignNames +result['context'] = 0 +for number in ['1']: + result['context'] += 24 diff --git a/tests/functional/c/consider/consider_join.txt b/tests/functional/c/consider/consider_join.txt new file mode 100644 index 000000000..f544e55b8 --- /dev/null +++ b/tests/functional/c/consider/consider_join.txt @@ -0,0 +1,11 @@ +consider-using-join:6:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:10:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:14:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:18:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:58:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:62:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:66:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:71:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:75:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:79:4::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:110:31::Consider using str.join(sequence) for concatenating strings from an iterable diff --git a/tests/functional/c/consider/consider_merging_isinstance.py b/tests/functional/c/consider/consider_merging_isinstance.py new file mode 100644 index 000000000..d3387bd5c --- /dev/null +++ b/tests/functional/c/consider/consider_merging_isinstance.py @@ -0,0 +1,37 @@ +"""Checks use of consider-merging-isinstance""" +# pylint:disable=line-too-long, simplifiable-condition + + +def isinstances(): + "Examples of isinstances" + var = range(10) + + # merged + if isinstance(var[1], (int, float)): + pass + result = isinstance(var[2], (int, float)) + + # not merged + if isinstance(var[3], int) or isinstance(var[3], float) or isinstance(var[3], list) and True: # [consider-merging-isinstance] + pass + result = isinstance(var[4], int) or isinstance(var[4], float) or isinstance(var[5], list) and False # [consider-merging-isinstance] + + result = isinstance(var[5], int) or True or isinstance(var[5], float) # [consider-merging-isinstance] + + infered_isinstance = isinstance + result = infered_isinstance(var[6], int) or infered_isinstance(var[6], float) or infered_isinstance(var[6], list) and False # [consider-merging-isinstance] + result = isinstance(var[10], str) or isinstance(var[10], int) and var[8] * 14 or isinstance(var[10], float) and var[5] * 14.4 or isinstance(var[10], list) # [consider-merging-isinstance] + result = isinstance(var[11], int) or isinstance(var[11], int) or isinstance(var[11], float) # [consider-merging-isinstance] + + result = isinstance(var[20]) + result = isinstance() + + # Combination merged and not merged + result = isinstance(var[12], (int, float)) or isinstance(var[12], list) # [consider-merging-isinstance] + + # not merged but valid + result = isinstance(var[5], int) and var[5] * 14 or isinstance(var[5], float) and var[5] * 14.4 + result = isinstance(var[7], int) or not isinstance(var[7], float) + result = isinstance(var[6], int) or isinstance(var[7], float) + result = isinstance(var[6], int) or isinstance(var[7], int) + return result diff --git a/tests/functional/c/consider/consider_merging_isinstance.txt b/tests/functional/c/consider/consider_merging_isinstance.txt new file mode 100644 index 000000000..9728f1e15 --- /dev/null +++ b/tests/functional/c/consider/consider_merging_isinstance.txt @@ -0,0 +1,7 @@ +consider-merging-isinstance:15:7:isinstances:Consider merging these isinstance calls to isinstance(var[3], (float, int)) +consider-merging-isinstance:17:13:isinstances:Consider merging these isinstance calls to isinstance(var[4], (float, int)) +consider-merging-isinstance:19:13:isinstances:Consider merging these isinstance calls to isinstance(var[5], (float, int)) +consider-merging-isinstance:22:13:isinstances:Consider merging these isinstance calls to isinstance(var[6], (float, int)) +consider-merging-isinstance:23:13:isinstances:Consider merging these isinstance calls to isinstance(var[10], (list, str)) +consider-merging-isinstance:24:13:isinstances:Consider merging these isinstance calls to isinstance(var[11], (float, int)) +consider-merging-isinstance:30:13:isinstances:Consider merging these isinstance calls to isinstance(var[12], (float, int, list)) diff --git a/tests/functional/c/consider/consider_swap_variables.py b/tests/functional/c/consider/consider_swap_variables.py new file mode 100644 index 000000000..e3320773f --- /dev/null +++ b/tests/functional/c/consider/consider_swap_variables.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring,invalid-name,using-constant-test + +a, b, c, d = 'a b c d'.split() + +temp = a # [consider-swap-variables] +a = b +b = temp + +temp = a # only simple swaps are reported +a = b +if True: + b = a + +temp = a # this is no swap +a = b +b = a + +temp = a, b # complex swaps are ignored +a, b = c, d +c, d = temp + +temp = a # [consider-swap-variables] +a = b # longer swap circles are only reported once +b = temp +temp = a diff --git a/tests/functional/c/consider/consider_swap_variables.txt b/tests/functional/c/consider/consider_swap_variables.txt new file mode 100644 index 000000000..3e099d671 --- /dev/null +++ b/tests/functional/c/consider/consider_swap_variables.txt @@ -0,0 +1,2 @@ +consider-swap-variables:5:0::Consider using tuple unpacking for swapping variables +consider-swap-variables:22:0::Consider using tuple unpacking for swapping variables diff --git a/tests/functional/c/consider/consider_using_dict_comprehension.py b/tests/functional/c/consider/consider_using_dict_comprehension.py new file mode 100644 index 000000000..da0be6d5a --- /dev/null +++ b/tests/functional/c/consider/consider_using_dict_comprehension.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring, invalid-name + +numbers = [1, 2, 3, 4, 5, 6] + +dict() + +dict([]) + +dict([(number, number*2) for number in numbers]) # [consider-using-dict-comprehension] + +# Cannot emit as this cannot be written as a comprehension +dict([value.split("=") for value in ["a=b", "c=d"]]) diff --git a/tests/functional/c/consider/consider_using_dict_comprehension.txt b/tests/functional/c/consider/consider_using_dict_comprehension.txt new file mode 100644 index 000000000..ea2bb31ae --- /dev/null +++ b/tests/functional/c/consider/consider_using_dict_comprehension.txt @@ -0,0 +1 @@ +consider-using-dict-comprehension:9:0::Consider using a dictionary comprehension diff --git a/tests/functional/c/consider/consider_using_enumerate.py b/tests/functional/c/consider/consider_using_enumerate.py new file mode 100644 index 000000000..2ac382b18 --- /dev/null +++ b/tests/functional/c/consider/consider_using_enumerate.py @@ -0,0 +1,73 @@ +"""Emit a message for iteration through range and len is encountered.""" + +# pylint: disable=missing-docstring, import-error, useless-object-inheritance, unsubscriptable-object, too-few-public-methods + +def bad(): + iterable = [1, 2, 3] + for obj in range(len(iterable)): # [consider-using-enumerate] + yield iterable[obj] + for obj in range(0, len(iterable)): # [consider-using-enumerate] + yield iterable[obj] + + +class Bad(object): + + def __iter__(self): + iterable = [1, 2, 3] + for i in range(len(iterable)): # [consider-using-enumerate] + yield iterable[i] + + def test(self): + for i in range(len(self)): # [consider-using-enumerate] + yield self[i] + + +def good(): + iterable = other_obj = [1, 2, 3] + total = 0 + for obj in range(len(iterable)): + total += obj + yield total + yield iterable[obj + 1: 2] + yield iterable[len(obj)] + for obj in iterable: + yield iterable[obj - 1] + + for index, obj in enumerate(iterable): + yield iterable[index] + for index in range(0, 10): + yield iterable[index + 1] + for index in range(10): + yield iterable[index] + for index in range(len([1, 2, 3, 4])): + yield index + for index in range(1, len(iterable)): + yield index + for index in range(len(iterable)): + yield [1, 2, 3][index] + yield len([1, 2, 3]) + for index in range(len(iterable)): + yield other_obj[index] + + # pylint: disable=import-outside-toplevel + from unknown import unknown + for index in range(unknown(iterable)): + yield iterable[index] + + for index in range(len(iterable)): + def test(iterable): + return iterable[index] + yield test([1, 2, 3]) + + +class Good(object): + + def __iter__(self): + # Should not suggest enumerate on self + for i in range(len(self)): + yield self[i] + + +def does_not_crash_on_range_without_args(): + for elem in range(): + print(elem) diff --git a/tests/functional/c/consider/consider_using_enumerate.txt b/tests/functional/c/consider/consider_using_enumerate.txt new file mode 100644 index 000000000..31ee23f42 --- /dev/null +++ b/tests/functional/c/consider/consider_using_enumerate.txt @@ -0,0 +1,4 @@ +consider-using-enumerate:7:4:bad:Consider using enumerate instead of iterating with range and len +consider-using-enumerate:9:4:bad:Consider using enumerate instead of iterating with range and len +consider-using-enumerate:17:8:Bad.__iter__:Consider using enumerate instead of iterating with range and len +consider-using-enumerate:21:8:Bad.test:Consider using enumerate instead of iterating with range and len diff --git a/tests/functional/c/consider/consider_using_generator.py b/tests/functional/c/consider/consider_using_generator.py new file mode 100644 index 000000000..eadb34a56 --- /dev/null +++ b/tests/functional/c/consider/consider_using_generator.py @@ -0,0 +1,11 @@ +# pylint: disable=missing-docstring, invalid-name +# https://github.com/PyCQA/pylint/issues/3165 + +list([]) +tuple([]) + +list([0 for y in list(range(10))]) # [consider-using-generator] +tuple([0 for y in list(range(10))]) # [consider-using-generator] + +list(0 for y in list(range(10))) +tuple(0 for y in list(range(10))) diff --git a/tests/functional/c/consider/consider_using_generator.txt b/tests/functional/c/consider/consider_using_generator.txt new file mode 100644 index 000000000..3d3c5a494 --- /dev/null +++ b/tests/functional/c/consider/consider_using_generator.txt @@ -0,0 +1,2 @@ +consider-using-generator:7:0::Consider using a generator instead 'list(0 for y in list(range(10)))' +consider-using-generator:8:0::Consider using a generator instead 'tuple(0 for y in list(range(10)))' diff --git a/tests/functional/c/consider/consider_using_get.py b/tests/functional/c/consider/consider_using_get.py new file mode 100644 index 000000000..8c5c68901 --- /dev/null +++ b/tests/functional/c/consider/consider_using_get.py @@ -0,0 +1,90 @@ +# pylint: disable=missing-docstring,invalid-name,using-constant-test,invalid-sequence-index,undefined-variable +dictionary = dict() +key = 'key' + +if 'key' in dictionary: # [consider-using-get] + variable = dictionary['key'] + +if 'key' in dictionary: # [consider-using-get] + variable = dictionary['key'] +else: + variable = 'default' + +if key in dictionary: # [consider-using-get] + variable = dictionary[key] + +if 'key' in dictionary: # not accessing the dictionary in assignment + variable = "string" + +if 'key' in dictionary: # is a match, but not obvious and we ignore it for now + variable = dictionary[key] + +if 'key1' in dictionary: # dictionary querried for wrong key + variable = dictionary['key2'] + +if 'key' in dictionary: # body is not pure + variable = dictionary['key'] + print('found') + +if 'key' in dictionary: # body is not pure + variable = dictionary['key'] + print('found') +else: + variable = 'default' + +if 'key' in dictionary1: # different dictionaries + variable = dictionary2['key'] +else: + variable = 'default' + +if 'key' in dictionary: # body is not pure + variable = dictionary['key'] +else: + variable = 'default' + print('found') + +if 'key' in dictionary: # different variables + variable1 = dictionary['key'] +else: + variable2 = 'default' + +if 'key' in dictionary: # assignment is not simple + variable1 = variable2 = dictionary['key'] + +if 'key' in dictionary: # assignment is not simple + variable1 = dictionary['key'] +else: + variable1 = variable2 = "default" + +if 'word' in 'text': + variable = 'text'['word'] # already bogus, but to assert that this only works with dictionaries + +if 'word' in dictionary: + variable = 'dictionary'['word'] + +if 'key1' in dictionary: # not the simple case + variable = dictionary['key1'] +elif 'key2' in dictionary: # [consider-using-get] + variable = dictionary['key2'] +else: + variable = 'default' + +if 'key' in dictionary and bool(key): # not a simple compare + variable = dictionary['key1'] +else: + variable = 'default' + +if bool(key) and 'key' in dictionary: # not a simple compare + variable = dictionary['key1'] +else: + variable = 'default' + + +d1 = {'foo': None} +d2 = {} +# Cannot be represented as using .get() +if 'foo' in d1: + d2['bar'] = d1['foo'] + +if 'key' in dictionary: + variable = dictionary[1:] diff --git a/tests/functional/c/consider/consider_using_get.txt b/tests/functional/c/consider/consider_using_get.txt new file mode 100644 index 000000000..d57b4a269 --- /dev/null +++ b/tests/functional/c/consider/consider_using_get.txt @@ -0,0 +1,4 @@ +consider-using-get:5:0::Consider using dict.get for getting values from a dict if a key is present or a default if not +consider-using-get:8:0::Consider using dict.get for getting values from a dict if a key is present or a default if not +consider-using-get:13:0::Consider using dict.get for getting values from a dict if a key is present or a default if not +consider-using-get:67:0::Consider using dict.get for getting values from a dict if a key is present or a default if not diff --git a/tests/functional/c/consider/consider_using_in.py b/tests/functional/c/consider/consider_using_in.py new file mode 100644 index 000000000..fb68ac5e6 --- /dev/null +++ b/tests/functional/c/consider/consider_using_in.py @@ -0,0 +1,46 @@ +# pylint: disable=missing-docstring, invalid-name, pointless-statement, misplaced-comparison-constant, undefined-variable, literal-comparison, line-too-long, unneeded-not + +value = value1 = 1 +value2 = 2 +a_set = {1, 2, 3} +a_list = [1, 2, 3] +a_str = '1' + +# Positive +value == 1 or value == 1 # [consider-using-in] +value == 1 or value == 2 # [consider-using-in] +'value' == value or 'value' == value # [consider-using-in] +value == 1 or value == undef_value # [consider-using-in] +value == 1 or value == 2 or value == 3 # [consider-using-in] +value == '2' or value == 1 # [consider-using-in] +1 == value or 2 == value # [consider-using-in] +1 == value or value == 2 # [consider-using-in] +value == 1 or value == a_list # [consider-using-in] +value == a_set or value == a_list or value == a_str # [consider-using-in] +value != 1 and value != 2 # [consider-using-in] +value1 == value2 or value2 == value1 # [consider-using-in] +a_list == [1, 2, 3] or a_list == [] # [consider-using-in] + +# Negative +value != 1 or value != 2 # not a "not in"-case because of "or" +value == 1 and value == 2 # not a "in"-case because of "and" +value == 1 and value == 2 or value == 3 # not only 'or's +value == 1 or value == 2 or 3 < value < 4 # not only '==' +value == 1 # value not checked against multiple values +value == 1 or value == 2 or value == 3 and value == 4 # not all checks are concatenated with 'or' +value == 1 or 2 < value < 3 # length of 'ops' != 1 for second check +value is 1 or value is 2 # 'in' compares using '==' not 'is' and therefore not considered +not value == 1 and not value == 2 +value1 == 1 or value2 == 2 # different variables and only one comparison for each +value1 == value2 == 1 or value1 == 2 # not checking multi-compares for '==' +value1 != 1 == value2 and value2 != value1 != 2 # not checking multi-compares for '!=' +value1 == 1 or value1 == value2 or value2 == 3 # value1 or value2 do not occur in every check +value1 == 1 or value1 == 2 or value2 == 1 or value2 == 2 # value1 or value2 do not occur in every check +'value' == 1 or 'value' == 2 # only detect variables for now + + +def oops(): + return 5 / 0 + + +some_value = value == 4 or value == 5 or value == oops() # We only look for names and constants diff --git a/tests/functional/c/consider/consider_using_in.txt b/tests/functional/c/consider/consider_using_in.txt new file mode 100644 index 000000000..63e5fffff --- /dev/null +++ b/tests/functional/c/consider/consider_using_in.txt @@ -0,0 +1,13 @@ +consider-using-in:10:0::"Consider merging these comparisons with ""in"" to 'value in (1,)'" +consider-using-in:11:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2)'" +consider-using-in:12:0::"Consider merging these comparisons with ""in"" to ""value in ('value',)""" +consider-using-in:13:0::"Consider merging these comparisons with ""in"" to 'value in (1, undef_value)'" +consider-using-in:14:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2, 3)'" +consider-using-in:15:0::"Consider merging these comparisons with ""in"" to ""value in ('2', 1)""" +consider-using-in:16:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2)'" +consider-using-in:17:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2)'" +consider-using-in:18:0::"Consider merging these comparisons with ""in"" to 'value in (1, a_list)'" +consider-using-in:19:0::"Consider merging these comparisons with ""in"" to 'value in (a_set, a_list, a_str)'" +consider-using-in:20:0::"Consider merging these comparisons with ""in"" to 'value not in (1, 2)'" +consider-using-in:21:0::"Consider merging these comparisons with ""in"" to 'value1 in (value2,)'" +consider-using-in:22:0::"Consider merging these comparisons with ""in"" to 'a_list in ([1, 2, 3], [])'" diff --git a/tests/functional/c/consider/consider_using_set_comprehension.py b/tests/functional/c/consider/consider_using_set_comprehension.py new file mode 100644 index 000000000..345989c69 --- /dev/null +++ b/tests/functional/c/consider/consider_using_set_comprehension.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring, invalid-name, unnecessary-comprehension + +numbers = [1, 2, 3, 4, 5, 6] + +set() + +set([]) + +set([number for number in numbers]) # [consider-using-set-comprehension] diff --git a/tests/functional/c/consider/consider_using_set_comprehension.txt b/tests/functional/c/consider/consider_using_set_comprehension.txt new file mode 100644 index 000000000..4839a7a62 --- /dev/null +++ b/tests/functional/c/consider/consider_using_set_comprehension.txt @@ -0,0 +1 @@ +consider-using-set-comprehension:9:0::Consider using a set comprehension diff --git a/tests/functional/c/consider/consider_using_sys_exit.py b/tests/functional/c/consider/consider_using_sys_exit.py new file mode 100644 index 000000000..4cec44847 --- /dev/null +++ b/tests/functional/c/consider/consider_using_sys_exit.py @@ -0,0 +1,14 @@ +# pylint: disable=missing-docstring, invalid-name, blacklisted-name, redefined-builtin, unused-variable +import sys + +def foo(): + exit() # [consider-using-sys-exit] + +def foo_1(): + quit() # [consider-using-sys-exit] + +def foo_2(): + quit = 'abc' + sys.exit() + +quit() # [consider-using-sys-exit] diff --git a/tests/functional/c/consider/consider_using_sys_exit.txt b/tests/functional/c/consider/consider_using_sys_exit.txt new file mode 100644 index 000000000..c429c652e --- /dev/null +++ b/tests/functional/c/consider/consider_using_sys_exit.txt @@ -0,0 +1,3 @@ +consider-using-sys-exit:5:4:foo:Consider using sys.exit() +consider-using-sys-exit:8:4:foo_1:Consider using sys.exit() +consider-using-sys-exit:14:0::Consider using sys.exit() diff --git a/tests/functional/c/consider/consider_using_sys_exit_exempted.py b/tests/functional/c/consider/consider_using_sys_exit_exempted.py new file mode 100644 index 000000000..ba66989cb --- /dev/null +++ b/tests/functional/c/consider/consider_using_sys_exit_exempted.py @@ -0,0 +1,5 @@ +# pylint: disable=missing-docstring,redefined-builtin + +from sys import exit + +exit(0) diff --git a/tests/functional/c/consider/consider_using_sys_exit_local_scope.py b/tests/functional/c/consider/consider_using_sys_exit_local_scope.py new file mode 100644 index 000000000..05b57ae41 --- /dev/null +++ b/tests/functional/c/consider/consider_using_sys_exit_local_scope.py @@ -0,0 +1,5 @@ +# pylint: disable=missing-docstring,import-outside-toplevel,redefined-builtin + +def run(): + from sys import exit + exit() diff --git a/tests/functional/c/consider_iterating_dictionary.py b/tests/functional/c/consider_iterating_dictionary.py deleted file mode 100644 index 1198de1cb..000000000 --- a/tests/functional/c/consider_iterating_dictionary.py +++ /dev/null @@ -1,38 +0,0 @@ -# pylint: disable=missing-docstring, expression-not-assigned, too-few-public-methods, no-member, import-error, no-self-use, line-too-long, useless-object-inheritance, unnecessary-comprehension - -from unknown import Unknown - - -class CustomClass(object): - def keys(self): - return [] - -for key in Unknown().keys(): - pass -for key in Unknown.keys(): - pass -for key in dict.keys(): - pass -for key in {}.values(): - pass -for key in {}.key(): - pass -for key in CustomClass().keys(): - pass - -[key for key in {}.keys()] # [consider-iterating-dictionary] -(key for key in {}.keys()) # [consider-iterating-dictionary] -{key for key in {}.keys()} # [consider-iterating-dictionary] -{key: key for key in {}.keys()} # [consider-iterating-dictionary] -COMP1 = [key for key in {}.keys()] # [consider-iterating-dictionary] -COMP2 = (key for key in {}.keys()) # [consider-iterating-dictionary] -COMP3 = {key for key in {}.keys()} # [consider-iterating-dictionary] -COMP4 = {key: key for key in {}.keys()} # [consider-iterating-dictionary] -for key in {}.keys(): # [consider-iterating-dictionary] - pass - -# Issue #1247 -DICT = {'a': 1, 'b': 2} -COMP1 = [k * 2 for k in DICT.keys()] + [k * 3 for k in DICT.keys()] # [consider-iterating-dictionary,consider-iterating-dictionary] -COMP2, COMP3 = [k * 2 for k in DICT.keys()], [k * 3 for k in DICT.keys()] # [consider-iterating-dictionary,consider-iterating-dictionary] -SOME_TUPLE = ([k * 2 for k in DICT.keys()], [k * 3 for k in DICT.keys()]) # [consider-iterating-dictionary,consider-iterating-dictionary] diff --git a/tests/functional/c/consider_iterating_dictionary.txt b/tests/functional/c/consider_iterating_dictionary.txt deleted file mode 100644 index c1b12f976..000000000 --- a/tests/functional/c/consider_iterating_dictionary.txt +++ /dev/null @@ -1,15 +0,0 @@ -consider-iterating-dictionary:23:16::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:24:16::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:25:16::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:26:21::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:27:24::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:28:24::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:29:24::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:30:29::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:31:11::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:36:24::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:36:55::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:37:31::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:37:61::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:38:30::Consider iterating the dictionary directly instead of calling .keys() -consider-iterating-dictionary:38:60::Consider iterating the dictionary directly instead of calling .keys() diff --git a/tests/functional/c/consider_join.py b/tests/functional/c/consider_join.py deleted file mode 100644 index 24cd6dd49..000000000 --- a/tests/functional/c/consider_join.py +++ /dev/null @@ -1,126 +0,0 @@ -# pylint: disable=missing-docstring,invalid-name,undefined-variable,multiple-statements - -# Variations of 'result' -result = '' -for number in ['1', '2', '3']: - result += number # [consider-using-join] - -result = 'header' -for number in ['1', '2', '3']: - result += number # [consider-using-join] - -result = another_result = '' -for number in ['1', '2', '3']: - result += number # [consider-using-join] - -another_result = result = '' -for number in ['1', '2', '3']: - result += number # [consider-using-join] - -result = 0 # result is not a string -for number in ['1', '2', '3']: - result += number - -RESULT = '' # wrong name / initial variable missing -for number in ['1', '2', '3']: - result += [number] - -string_variable = '' -result = string_variable # type of 'result' not obviously a string -for number in ['1', '2', '3']: - result += number - -result = '' -another_result = '' # result defined too early -for number in ['1', '2', '3']: - result += [number] - -for number in ['1', '2', '3']: # 'result'-definition missing - result += number - - -# Variations of 'number' -result = '' # no concatenation (iterator-name differs) -for name in ['1', '2', '3']: - result += number - -result = '' # no concatenation (iterator-name differs) -for _ in ['1', '2', '3']: - result += number -# 'exprlist' is not a single name -for index, number in ['1', '2', '3']: - result += number - - -# Variations of 'iterable' -result = '' -for number in []: - result += number # [consider-using-join] - -result = '' -for number in "a text": - result += number # [consider-using-join] - -result = '' -for number in [1, 2, 3]: - result += number # [consider-using-join] - -a_list = [1, 2, 3] -result = '' -for number in a_list: - result += number # [consider-using-join] - -result = '' -for number in ['1', '2', '3']: - result += number # [consider-using-join] - -result = '' -for number in undefined_iterable: - result += number # [consider-using-join] - - -# Variations of loop-body -result = '' # addition is not the only part of the body -for number in ['1', '2', '3']: - print(number) - result += number - -result = '' # addition is not the only part of the body -for number in ['1', '2', '3']: - result += number - print(number) - -result = '' # augmented addition is not a simple one -for number in ['1', '2', '3']: - result += '4' + number - -result = '' # assignment is not augmented -for number in ['1', '2', '3']: - result = number - -result = '' # augmented assignment is not an addition -for number in ['1', '2', '3']: - result -= number - -result = '' # addition is not the 'number'-iterable -for number in ['1', '2', '3']: - result += another_number - -result = '' -for number in ['1', '2', '3']: result += number # [consider-using-join] - -result = '' -for number in ['1']: - result.result += number - -# Does not emit if the body is more complex -result = {'context': 1} -result['context'] = 0 -for number in ['1']: - result1 = 42 + int(number) - result['context'] += result1 * 24 - -# Does not crash if the previous sibling does not have AssignNames -result['context'] = 0 -for number in ['1']: - result['context'] += 24 diff --git a/tests/functional/c/consider_join.txt b/tests/functional/c/consider_join.txt deleted file mode 100644 index f544e55b8..000000000 --- a/tests/functional/c/consider_join.txt +++ /dev/null @@ -1,11 +0,0 @@ -consider-using-join:6:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:10:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:14:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:18:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:58:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:62:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:66:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:71:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:75:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:79:4::Consider using str.join(sequence) for concatenating strings from an iterable -consider-using-join:110:31::Consider using str.join(sequence) for concatenating strings from an iterable diff --git a/tests/functional/c/consider_merging_isinstance.py b/tests/functional/c/consider_merging_isinstance.py deleted file mode 100644 index d3387bd5c..000000000 --- a/tests/functional/c/consider_merging_isinstance.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Checks use of consider-merging-isinstance""" -# pylint:disable=line-too-long, simplifiable-condition - - -def isinstances(): - "Examples of isinstances" - var = range(10) - - # merged - if isinstance(var[1], (int, float)): - pass - result = isinstance(var[2], (int, float)) - - # not merged - if isinstance(var[3], int) or isinstance(var[3], float) or isinstance(var[3], list) and True: # [consider-merging-isinstance] - pass - result = isinstance(var[4], int) or isinstance(var[4], float) or isinstance(var[5], list) and False # [consider-merging-isinstance] - - result = isinstance(var[5], int) or True or isinstance(var[5], float) # [consider-merging-isinstance] - - infered_isinstance = isinstance - result = infered_isinstance(var[6], int) or infered_isinstance(var[6], float) or infered_isinstance(var[6], list) and False # [consider-merging-isinstance] - result = isinstance(var[10], str) or isinstance(var[10], int) and var[8] * 14 or isinstance(var[10], float) and var[5] * 14.4 or isinstance(var[10], list) # [consider-merging-isinstance] - result = isinstance(var[11], int) or isinstance(var[11], int) or isinstance(var[11], float) # [consider-merging-isinstance] - - result = isinstance(var[20]) - result = isinstance() - - # Combination merged and not merged - result = isinstance(var[12], (int, float)) or isinstance(var[12], list) # [consider-merging-isinstance] - - # not merged but valid - result = isinstance(var[5], int) and var[5] * 14 or isinstance(var[5], float) and var[5] * 14.4 - result = isinstance(var[7], int) or not isinstance(var[7], float) - result = isinstance(var[6], int) or isinstance(var[7], float) - result = isinstance(var[6], int) or isinstance(var[7], int) - return result diff --git a/tests/functional/c/consider_merging_isinstance.txt b/tests/functional/c/consider_merging_isinstance.txt deleted file mode 100644 index 9728f1e15..000000000 --- a/tests/functional/c/consider_merging_isinstance.txt +++ /dev/null @@ -1,7 +0,0 @@ -consider-merging-isinstance:15:7:isinstances:Consider merging these isinstance calls to isinstance(var[3], (float, int)) -consider-merging-isinstance:17:13:isinstances:Consider merging these isinstance calls to isinstance(var[4], (float, int)) -consider-merging-isinstance:19:13:isinstances:Consider merging these isinstance calls to isinstance(var[5], (float, int)) -consider-merging-isinstance:22:13:isinstances:Consider merging these isinstance calls to isinstance(var[6], (float, int)) -consider-merging-isinstance:23:13:isinstances:Consider merging these isinstance calls to isinstance(var[10], (list, str)) -consider-merging-isinstance:24:13:isinstances:Consider merging these isinstance calls to isinstance(var[11], (float, int)) -consider-merging-isinstance:30:13:isinstances:Consider merging these isinstance calls to isinstance(var[12], (float, int, list)) diff --git a/tests/functional/c/consider_swap_variables.py b/tests/functional/c/consider_swap_variables.py deleted file mode 100644 index e3320773f..000000000 --- a/tests/functional/c/consider_swap_variables.py +++ /dev/null @@ -1,25 +0,0 @@ -# pylint: disable=missing-docstring,invalid-name,using-constant-test - -a, b, c, d = 'a b c d'.split() - -temp = a # [consider-swap-variables] -a = b -b = temp - -temp = a # only simple swaps are reported -a = b -if True: - b = a - -temp = a # this is no swap -a = b -b = a - -temp = a, b # complex swaps are ignored -a, b = c, d -c, d = temp - -temp = a # [consider-swap-variables] -a = b # longer swap circles are only reported once -b = temp -temp = a diff --git a/tests/functional/c/consider_swap_variables.txt b/tests/functional/c/consider_swap_variables.txt deleted file mode 100644 index 3e099d671..000000000 --- a/tests/functional/c/consider_swap_variables.txt +++ /dev/null @@ -1,2 +0,0 @@ -consider-swap-variables:5:0::Consider using tuple unpacking for swapping variables -consider-swap-variables:22:0::Consider using tuple unpacking for swapping variables diff --git a/tests/functional/c/consider_using_dict_comprehension.py b/tests/functional/c/consider_using_dict_comprehension.py deleted file mode 100644 index da0be6d5a..000000000 --- a/tests/functional/c/consider_using_dict_comprehension.py +++ /dev/null @@ -1,12 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name - -numbers = [1, 2, 3, 4, 5, 6] - -dict() - -dict([]) - -dict([(number, number*2) for number in numbers]) # [consider-using-dict-comprehension] - -# Cannot emit as this cannot be written as a comprehension -dict([value.split("=") for value in ["a=b", "c=d"]]) diff --git a/tests/functional/c/consider_using_dict_comprehension.txt b/tests/functional/c/consider_using_dict_comprehension.txt deleted file mode 100644 index ea2bb31ae..000000000 --- a/tests/functional/c/consider_using_dict_comprehension.txt +++ /dev/null @@ -1 +0,0 @@ -consider-using-dict-comprehension:9:0::Consider using a dictionary comprehension diff --git a/tests/functional/c/consider_using_enumerate.py b/tests/functional/c/consider_using_enumerate.py deleted file mode 100644 index 2ac382b18..000000000 --- a/tests/functional/c/consider_using_enumerate.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Emit a message for iteration through range and len is encountered.""" - -# pylint: disable=missing-docstring, import-error, useless-object-inheritance, unsubscriptable-object, too-few-public-methods - -def bad(): - iterable = [1, 2, 3] - for obj in range(len(iterable)): # [consider-using-enumerate] - yield iterable[obj] - for obj in range(0, len(iterable)): # [consider-using-enumerate] - yield iterable[obj] - - -class Bad(object): - - def __iter__(self): - iterable = [1, 2, 3] - for i in range(len(iterable)): # [consider-using-enumerate] - yield iterable[i] - - def test(self): - for i in range(len(self)): # [consider-using-enumerate] - yield self[i] - - -def good(): - iterable = other_obj = [1, 2, 3] - total = 0 - for obj in range(len(iterable)): - total += obj - yield total - yield iterable[obj + 1: 2] - yield iterable[len(obj)] - for obj in iterable: - yield iterable[obj - 1] - - for index, obj in enumerate(iterable): - yield iterable[index] - for index in range(0, 10): - yield iterable[index + 1] - for index in range(10): - yield iterable[index] - for index in range(len([1, 2, 3, 4])): - yield index - for index in range(1, len(iterable)): - yield index - for index in range(len(iterable)): - yield [1, 2, 3][index] - yield len([1, 2, 3]) - for index in range(len(iterable)): - yield other_obj[index] - - # pylint: disable=import-outside-toplevel - from unknown import unknown - for index in range(unknown(iterable)): - yield iterable[index] - - for index in range(len(iterable)): - def test(iterable): - return iterable[index] - yield test([1, 2, 3]) - - -class Good(object): - - def __iter__(self): - # Should not suggest enumerate on self - for i in range(len(self)): - yield self[i] - - -def does_not_crash_on_range_without_args(): - for elem in range(): - print(elem) diff --git a/tests/functional/c/consider_using_enumerate.txt b/tests/functional/c/consider_using_enumerate.txt deleted file mode 100644 index 31ee23f42..000000000 --- a/tests/functional/c/consider_using_enumerate.txt +++ /dev/null @@ -1,4 +0,0 @@ -consider-using-enumerate:7:4:bad:Consider using enumerate instead of iterating with range and len -consider-using-enumerate:9:4:bad:Consider using enumerate instead of iterating with range and len -consider-using-enumerate:17:8:Bad.__iter__:Consider using enumerate instead of iterating with range and len -consider-using-enumerate:21:8:Bad.test:Consider using enumerate instead of iterating with range and len diff --git a/tests/functional/c/consider_using_generator.py b/tests/functional/c/consider_using_generator.py deleted file mode 100644 index eadb34a56..000000000 --- a/tests/functional/c/consider_using_generator.py +++ /dev/null @@ -1,11 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name -# https://github.com/PyCQA/pylint/issues/3165 - -list([]) -tuple([]) - -list([0 for y in list(range(10))]) # [consider-using-generator] -tuple([0 for y in list(range(10))]) # [consider-using-generator] - -list(0 for y in list(range(10))) -tuple(0 for y in list(range(10))) diff --git a/tests/functional/c/consider_using_generator.txt b/tests/functional/c/consider_using_generator.txt deleted file mode 100644 index 3d3c5a494..000000000 --- a/tests/functional/c/consider_using_generator.txt +++ /dev/null @@ -1,2 +0,0 @@ -consider-using-generator:7:0::Consider using a generator instead 'list(0 for y in list(range(10)))' -consider-using-generator:8:0::Consider using a generator instead 'tuple(0 for y in list(range(10)))' diff --git a/tests/functional/c/consider_using_get.py b/tests/functional/c/consider_using_get.py deleted file mode 100644 index 8c5c68901..000000000 --- a/tests/functional/c/consider_using_get.py +++ /dev/null @@ -1,90 +0,0 @@ -# pylint: disable=missing-docstring,invalid-name,using-constant-test,invalid-sequence-index,undefined-variable -dictionary = dict() -key = 'key' - -if 'key' in dictionary: # [consider-using-get] - variable = dictionary['key'] - -if 'key' in dictionary: # [consider-using-get] - variable = dictionary['key'] -else: - variable = 'default' - -if key in dictionary: # [consider-using-get] - variable = dictionary[key] - -if 'key' in dictionary: # not accessing the dictionary in assignment - variable = "string" - -if 'key' in dictionary: # is a match, but not obvious and we ignore it for now - variable = dictionary[key] - -if 'key1' in dictionary: # dictionary querried for wrong key - variable = dictionary['key2'] - -if 'key' in dictionary: # body is not pure - variable = dictionary['key'] - print('found') - -if 'key' in dictionary: # body is not pure - variable = dictionary['key'] - print('found') -else: - variable = 'default' - -if 'key' in dictionary1: # different dictionaries - variable = dictionary2['key'] -else: - variable = 'default' - -if 'key' in dictionary: # body is not pure - variable = dictionary['key'] -else: - variable = 'default' - print('found') - -if 'key' in dictionary: # different variables - variable1 = dictionary['key'] -else: - variable2 = 'default' - -if 'key' in dictionary: # assignment is not simple - variable1 = variable2 = dictionary['key'] - -if 'key' in dictionary: # assignment is not simple - variable1 = dictionary['key'] -else: - variable1 = variable2 = "default" - -if 'word' in 'text': - variable = 'text'['word'] # already bogus, but to assert that this only works with dictionaries - -if 'word' in dictionary: - variable = 'dictionary'['word'] - -if 'key1' in dictionary: # not the simple case - variable = dictionary['key1'] -elif 'key2' in dictionary: # [consider-using-get] - variable = dictionary['key2'] -else: - variable = 'default' - -if 'key' in dictionary and bool(key): # not a simple compare - variable = dictionary['key1'] -else: - variable = 'default' - -if bool(key) and 'key' in dictionary: # not a simple compare - variable = dictionary['key1'] -else: - variable = 'default' - - -d1 = {'foo': None} -d2 = {} -# Cannot be represented as using .get() -if 'foo' in d1: - d2['bar'] = d1['foo'] - -if 'key' in dictionary: - variable = dictionary[1:] diff --git a/tests/functional/c/consider_using_get.txt b/tests/functional/c/consider_using_get.txt deleted file mode 100644 index d57b4a269..000000000 --- a/tests/functional/c/consider_using_get.txt +++ /dev/null @@ -1,4 +0,0 @@ -consider-using-get:5:0::Consider using dict.get for getting values from a dict if a key is present or a default if not -consider-using-get:8:0::Consider using dict.get for getting values from a dict if a key is present or a default if not -consider-using-get:13:0::Consider using dict.get for getting values from a dict if a key is present or a default if not -consider-using-get:67:0::Consider using dict.get for getting values from a dict if a key is present or a default if not diff --git a/tests/functional/c/consider_using_in.py b/tests/functional/c/consider_using_in.py deleted file mode 100644 index fb68ac5e6..000000000 --- a/tests/functional/c/consider_using_in.py +++ /dev/null @@ -1,46 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name, pointless-statement, misplaced-comparison-constant, undefined-variable, literal-comparison, line-too-long, unneeded-not - -value = value1 = 1 -value2 = 2 -a_set = {1, 2, 3} -a_list = [1, 2, 3] -a_str = '1' - -# Positive -value == 1 or value == 1 # [consider-using-in] -value == 1 or value == 2 # [consider-using-in] -'value' == value or 'value' == value # [consider-using-in] -value == 1 or value == undef_value # [consider-using-in] -value == 1 or value == 2 or value == 3 # [consider-using-in] -value == '2' or value == 1 # [consider-using-in] -1 == value or 2 == value # [consider-using-in] -1 == value or value == 2 # [consider-using-in] -value == 1 or value == a_list # [consider-using-in] -value == a_set or value == a_list or value == a_str # [consider-using-in] -value != 1 and value != 2 # [consider-using-in] -value1 == value2 or value2 == value1 # [consider-using-in] -a_list == [1, 2, 3] or a_list == [] # [consider-using-in] - -# Negative -value != 1 or value != 2 # not a "not in"-case because of "or" -value == 1 and value == 2 # not a "in"-case because of "and" -value == 1 and value == 2 or value == 3 # not only 'or's -value == 1 or value == 2 or 3 < value < 4 # not only '==' -value == 1 # value not checked against multiple values -value == 1 or value == 2 or value == 3 and value == 4 # not all checks are concatenated with 'or' -value == 1 or 2 < value < 3 # length of 'ops' != 1 for second check -value is 1 or value is 2 # 'in' compares using '==' not 'is' and therefore not considered -not value == 1 and not value == 2 -value1 == 1 or value2 == 2 # different variables and only one comparison for each -value1 == value2 == 1 or value1 == 2 # not checking multi-compares for '==' -value1 != 1 == value2 and value2 != value1 != 2 # not checking multi-compares for '!=' -value1 == 1 or value1 == value2 or value2 == 3 # value1 or value2 do not occur in every check -value1 == 1 or value1 == 2 or value2 == 1 or value2 == 2 # value1 or value2 do not occur in every check -'value' == 1 or 'value' == 2 # only detect variables for now - - -def oops(): - return 5 / 0 - - -some_value = value == 4 or value == 5 or value == oops() # We only look for names and constants diff --git a/tests/functional/c/consider_using_in.txt b/tests/functional/c/consider_using_in.txt deleted file mode 100644 index 63e5fffff..000000000 --- a/tests/functional/c/consider_using_in.txt +++ /dev/null @@ -1,13 +0,0 @@ -consider-using-in:10:0::"Consider merging these comparisons with ""in"" to 'value in (1,)'" -consider-using-in:11:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2)'" -consider-using-in:12:0::"Consider merging these comparisons with ""in"" to ""value in ('value',)""" -consider-using-in:13:0::"Consider merging these comparisons with ""in"" to 'value in (1, undef_value)'" -consider-using-in:14:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2, 3)'" -consider-using-in:15:0::"Consider merging these comparisons with ""in"" to ""value in ('2', 1)""" -consider-using-in:16:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2)'" -consider-using-in:17:0::"Consider merging these comparisons with ""in"" to 'value in (1, 2)'" -consider-using-in:18:0::"Consider merging these comparisons with ""in"" to 'value in (1, a_list)'" -consider-using-in:19:0::"Consider merging these comparisons with ""in"" to 'value in (a_set, a_list, a_str)'" -consider-using-in:20:0::"Consider merging these comparisons with ""in"" to 'value not in (1, 2)'" -consider-using-in:21:0::"Consider merging these comparisons with ""in"" to 'value1 in (value2,)'" -consider-using-in:22:0::"Consider merging these comparisons with ""in"" to 'a_list in ([1, 2, 3], [])'" diff --git a/tests/functional/c/consider_using_set_comprehension.py b/tests/functional/c/consider_using_set_comprehension.py deleted file mode 100644 index 345989c69..000000000 --- a/tests/functional/c/consider_using_set_comprehension.py +++ /dev/null @@ -1,9 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name, unnecessary-comprehension - -numbers = [1, 2, 3, 4, 5, 6] - -set() - -set([]) - -set([number for number in numbers]) # [consider-using-set-comprehension] diff --git a/tests/functional/c/consider_using_set_comprehension.txt b/tests/functional/c/consider_using_set_comprehension.txt deleted file mode 100644 index 4839a7a62..000000000 --- a/tests/functional/c/consider_using_set_comprehension.txt +++ /dev/null @@ -1 +0,0 @@ -consider-using-set-comprehension:9:0::Consider using a set comprehension diff --git a/tests/functional/c/consider_using_sys_exit.py b/tests/functional/c/consider_using_sys_exit.py deleted file mode 100644 index 4cec44847..000000000 --- a/tests/functional/c/consider_using_sys_exit.py +++ /dev/null @@ -1,14 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name, blacklisted-name, redefined-builtin, unused-variable -import sys - -def foo(): - exit() # [consider-using-sys-exit] - -def foo_1(): - quit() # [consider-using-sys-exit] - -def foo_2(): - quit = 'abc' - sys.exit() - -quit() # [consider-using-sys-exit] diff --git a/tests/functional/c/consider_using_sys_exit.txt b/tests/functional/c/consider_using_sys_exit.txt deleted file mode 100644 index c429c652e..000000000 --- a/tests/functional/c/consider_using_sys_exit.txt +++ /dev/null @@ -1,3 +0,0 @@ -consider-using-sys-exit:5:4:foo:Consider using sys.exit() -consider-using-sys-exit:8:4:foo_1:Consider using sys.exit() -consider-using-sys-exit:14:0::Consider using sys.exit() diff --git a/tests/functional/c/consider_using_sys_exit_exempted.py b/tests/functional/c/consider_using_sys_exit_exempted.py deleted file mode 100644 index ba66989cb..000000000 --- a/tests/functional/c/consider_using_sys_exit_exempted.py +++ /dev/null @@ -1,5 +0,0 @@ -# pylint: disable=missing-docstring,redefined-builtin - -from sys import exit - -exit(0) diff --git a/tests/functional/c/consider_using_sys_exit_local_scope.py b/tests/functional/c/consider_using_sys_exit_local_scope.py deleted file mode 100644 index 05b57ae41..000000000 --- a/tests/functional/c/consider_using_sys_exit_local_scope.py +++ /dev/null @@ -1,5 +0,0 @@ -# pylint: disable=missing-docstring,import-outside-toplevel,redefined-builtin - -def run(): - from sys import exit - exit() diff --git a/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.py b/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.py new file mode 100644 index 000000000..3338c2456 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.py @@ -0,0 +1,4 @@ +"""Test that getmoduleinfo is deprecated.""" +import inspect + +inspect.getmoduleinfo(inspect) # [deprecated-method] diff --git a/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.rc b/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.rc new file mode 100644 index 000000000..a444ca6b8 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.rc @@ -0,0 +1,3 @@ +[testoptions] +max_pyver=3.6 +min_pyver=3.3 diff --git a/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.txt b/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.txt new file mode 100644 index 000000000..77632a157 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_method_getmoduleinfo.txt @@ -0,0 +1 @@ +deprecated-method:4:::Using deprecated method getmoduleinfo() diff --git a/tests/functional/d/deprecated/deprecated_methods_py3.py b/tests/functional/d/deprecated/deprecated_methods_py3.py new file mode 100644 index 000000000..80428c79f --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py3.py @@ -0,0 +1,50 @@ +""" Functional tests for method deprecation. """ +# pylint: disable=missing-docstring, super-init-not-called, not-callable +import base64 +import cgi +import inspect +import logging +import nntplib +import platform +import unittest +import xml.etree.ElementTree + + +class MyTest(unittest.TestCase): + def test(self): + self.assert_(True) # [deprecated-method] + +xml.etree.ElementTree.Element('tag').getchildren() # [deprecated-method] +xml.etree.ElementTree.Element('tag').getiterator() # [deprecated-method] +xml.etree.ElementTree.XMLParser('tag', None, None).doctype(None, None, None) # [deprecated-method] +nntplib.NNTP(None).xpath(None) # [deprecated-method] + + +inspect.getargspec(None) # [deprecated-method] +logging.warn("a") # [deprecated-method] +platform.popen([]) # [deprecated-method] +base64.encodestring("42") # [deprecated-method] +base64.decodestring("42") # [deprecated-method] +cgi.escape("a") # [deprecated-method] + + +class SuperCrash(unittest.TestCase): + + def __init__(self): + # should not crash. + super()() + +xml.etree.ElementTree.iterparse(None) + + +class Tests(unittest.TestCase): + + def test_foo(self): + self.assertEquals(2 + 2, 4) # [deprecated-method] + self.assertNotEquals(2 + 2, 4) # [deprecated-method] + self.assertAlmostEquals(2 + 2, 4) # [deprecated-method] + self.assertNotAlmostEquals(2 + 2, 4) # [deprecated-method] + self.assert_("abc" == "2") # [deprecated-method] + + self.assertRaisesRegex(ValueError, "exception") + self.assertRegex("something", r".+") diff --git a/tests/functional/d/deprecated/deprecated_methods_py3.rc b/tests/functional/d/deprecated/deprecated_methods_py3.rc new file mode 100644 index 000000000..6c3e72704 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.3 +max_pyver=3.7 diff --git a/tests/functional/d/deprecated/deprecated_methods_py3.txt b/tests/functional/d/deprecated/deprecated_methods_py3.txt new file mode 100644 index 000000000..9796114f6 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py3.txt @@ -0,0 +1,16 @@ +deprecated-method:15::MyTest.test:Using deprecated method assert_() +deprecated-method:17:::Using deprecated method getchildren() +deprecated-method:18:::Using deprecated method getiterator() +deprecated-method:19:::Using deprecated method doctype() +deprecated-method:20:::Using deprecated method xpath() +deprecated-method:23:::Using deprecated method getargspec() +deprecated-method:24:::Using deprecated method warn() +deprecated-method:25:::Using deprecated method popen() +deprecated-method:26:::Using deprecated method encodestring() +deprecated-method:27:::Using deprecated method decodestring() +deprecated-method:28:::Using deprecated method escape() +deprecated-method:43::Tests.test_foo:Using deprecated method assertEquals() +deprecated-method:44::Tests.test_foo:Using deprecated method assertNotEquals() +deprecated-method:45::Tests.test_foo:Using deprecated method assertAlmostEquals() +deprecated-method:46::Tests.test_foo:Using deprecated method assertNotAlmostEquals() +deprecated-method:47::Tests.test_foo:Using deprecated method assert_() diff --git a/tests/functional/d/deprecated/deprecated_methods_py36.py b/tests/functional/d/deprecated/deprecated_methods_py36.py new file mode 100644 index 000000000..f416a144c --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py36.py @@ -0,0 +1,7 @@ +""" Functional tests for method deprecation. """ +# pylint: disable=no-value-for-parameter +import unittest +from importlib.machinery import SourceFileLoader, SourcelessFileLoader + +SourceFileLoader('unittest', unittest.__file__).load_module() # [deprecated-method] +SourcelessFileLoader('unittest', unittest.__file__).load_module() # [deprecated-method] diff --git a/tests/functional/d/deprecated/deprecated_methods_py36.rc b/tests/functional/d/deprecated/deprecated_methods_py36.rc new file mode 100644 index 000000000..0ba2b6333 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/tests/functional/d/deprecated/deprecated_methods_py36.txt b/tests/functional/d/deprecated/deprecated_methods_py36.txt new file mode 100644 index 000000000..801d24b6e --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py36.txt @@ -0,0 +1,2 @@ +deprecated-method:6:0::Using deprecated method load_module() +deprecated-method:7:0::Using deprecated method load_module() diff --git a/tests/functional/d/deprecated/deprecated_methods_py38.py b/tests/functional/d/deprecated/deprecated_methods_py38.py new file mode 100644 index 000000000..57047f926 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py38.py @@ -0,0 +1,45 @@ +""" Functional tests for method deprecation. """ +# pylint: disable=missing-docstring, super-init-not-called, not-callable +import base64 +import inspect +import logging +import nntplib +import unittest +import xml.etree.ElementTree + + +class MyTest(unittest.TestCase): + def test(self): + self.assert_(True) # [deprecated-method] + +xml.etree.ElementTree.Element('tag').getchildren() # [deprecated-method] +xml.etree.ElementTree.Element('tag').getiterator() # [deprecated-method] +nntplib.NNTP(None).xpath(None) # [deprecated-method] + + +inspect.getargspec(None) # [deprecated-method] +logging.warn("a") # [deprecated-method] +base64.encodestring("42") # [deprecated-method] +base64.decodestring("42") # [deprecated-method] + + +class SuperCrash(unittest.TestCase): + + def __init__(self): + # should not crash. + super()() + +xml.etree.ElementTree.iterparse(None) + + +class Tests(unittest.TestCase): + + def test_foo(self): + self.assertEquals(2 + 2, 4) # [deprecated-method] + self.assertNotEquals(2 + 2, 4) # [deprecated-method] + self.assertAlmostEquals(2 + 2, 4) # [deprecated-method] + self.assertNotAlmostEquals(2 + 2, 4) # [deprecated-method] + self.assert_("abc" == "2") # [deprecated-method] + + self.assertRaisesRegex(ValueError, "exception") + self.assertRegex("something", r".+") diff --git a/tests/functional/d/deprecated/deprecated_methods_py38.rc b/tests/functional/d/deprecated/deprecated_methods_py38.rc new file mode 100644 index 000000000..35b185fdb --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py38.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.8 +max_pyver=3.9 diff --git a/tests/functional/d/deprecated/deprecated_methods_py38.txt b/tests/functional/d/deprecated/deprecated_methods_py38.txt new file mode 100644 index 000000000..00d7f7dda --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_methods_py38.txt @@ -0,0 +1,13 @@ +deprecated-method:13:8:MyTest.test:Using deprecated method assert_() +deprecated-method:15:0::Using deprecated method getchildren() +deprecated-method:16:0::Using deprecated method getiterator() +deprecated-method:17:0::Using deprecated method xpath() +deprecated-method:20:0::Using deprecated method getargspec() +deprecated-method:21:0::Using deprecated method warn() +deprecated-method:22:0::Using deprecated method encodestring() +deprecated-method:23:0::Using deprecated method decodestring() +deprecated-method:38:8:Tests.test_foo:Using deprecated method assertEquals() +deprecated-method:39:8:Tests.test_foo:Using deprecated method assertNotEquals() +deprecated-method:40:8:Tests.test_foo:Using deprecated method assertAlmostEquals() +deprecated-method:41:8:Tests.test_foo:Using deprecated method assertNotAlmostEquals() +deprecated-method:42:8:Tests.test_foo:Using deprecated method assert_() diff --git a/tests/functional/d/deprecated/deprecated_module_py3.py b/tests/functional/d/deprecated/deprecated_module_py3.py new file mode 100644 index 000000000..308d400e7 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py3.py @@ -0,0 +1,4 @@ +"""Test deprecated modules.""" +# pylint: disable=unused-import + +import optparse # [deprecated-module] diff --git a/tests/functional/d/deprecated/deprecated_module_py3.rc b/tests/functional/d/deprecated/deprecated_module_py3.rc new file mode 100644 index 000000000..46343d2f1 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.0 +max_pyver=3.6 diff --git a/tests/functional/d/deprecated/deprecated_module_py3.txt b/tests/functional/d/deprecated/deprecated_module_py3.txt new file mode 100644 index 000000000..79c0a418c --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py3.txt @@ -0,0 +1 @@ +deprecated-module:4:::Uses of a deprecated module 'optparse' diff --git a/tests/functional/d/deprecated/deprecated_module_py36.py b/tests/functional/d/deprecated/deprecated_module_py36.py new file mode 100644 index 000000000..c49f9f0bc --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py36.py @@ -0,0 +1,4 @@ +"""Test deprecated modules from Python 3.6.""" +# pylint: disable=unused-import,import-error + +import optparse # [deprecated-module] diff --git a/tests/functional/d/deprecated/deprecated_module_py36.rc b/tests/functional/d/deprecated/deprecated_module_py36.rc new file mode 100644 index 000000000..0ba2b6333 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/tests/functional/d/deprecated/deprecated_module_py36.txt b/tests/functional/d/deprecated/deprecated_module_py36.txt new file mode 100644 index 000000000..ab5f48996 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py36.txt @@ -0,0 +1 @@ +deprecated-module:4:0::Uses of a deprecated module 'optparse' diff --git a/tests/functional/d/deprecated/deprecated_module_py4.py b/tests/functional/d/deprecated/deprecated_module_py4.py new file mode 100644 index 000000000..3cad959e7 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py4.py @@ -0,0 +1,4 @@ +"""Test deprecated modules.""" + +from deprecated import foo # [deprecated-module] +import deprecated # [deprecated-module] diff --git a/tests/functional/d/deprecated/deprecated_module_py4.rc b/tests/functional/d/deprecated/deprecated_module_py4.rc new file mode 100644 index 000000000..6fbd3407e --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py4.rc @@ -0,0 +1,4 @@ +[Messages Control] +deprecated-modules=deprecated +disable=all +enable=deprecated-module diff --git a/tests/functional/d/deprecated/deprecated_module_py4.txt b/tests/functional/d/deprecated/deprecated_module_py4.txt new file mode 100644 index 000000000..f4800d0b9 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_py4.txt @@ -0,0 +1,2 @@ +deprecated-module:3:0::Uses of a deprecated module 'deprecated' +deprecated-module:4:0::Uses of a deprecated module 'deprecated' diff --git a/tests/functional/d/deprecated/deprecated_module_uninstalled.py b/tests/functional/d/deprecated/deprecated_module_uninstalled.py new file mode 100644 index 000000000..52d55fa84 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_uninstalled.py @@ -0,0 +1,5 @@ +"""Test deprecated modules uninstalled.""" +# pylint: disable=unused-import,no-name-in-module,import-error + +from uninstalled import uninstalled_module # [deprecated-module] +import uninstalled # [deprecated-module] diff --git a/tests/functional/d/deprecated/deprecated_module_uninstalled.rc b/tests/functional/d/deprecated/deprecated_module_uninstalled.rc new file mode 100644 index 000000000..d68fc0bc9 --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_uninstalled.rc @@ -0,0 +1,2 @@ +[Messages Control] +deprecated-modules=uninstalled diff --git a/tests/functional/d/deprecated/deprecated_module_uninstalled.txt b/tests/functional/d/deprecated/deprecated_module_uninstalled.txt new file mode 100644 index 000000000..7d9f01afa --- /dev/null +++ b/tests/functional/d/deprecated/deprecated_module_uninstalled.txt @@ -0,0 +1,2 @@ +deprecated-module:4:0::Uses of a deprecated module 'uninstalled' +deprecated-module:5:0::Uses of a deprecated module 'uninstalled' diff --git a/tests/functional/d/deprecated_method_getmoduleinfo.py b/tests/functional/d/deprecated_method_getmoduleinfo.py deleted file mode 100644 index 3338c2456..000000000 --- a/tests/functional/d/deprecated_method_getmoduleinfo.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Test that getmoduleinfo is deprecated.""" -import inspect - -inspect.getmoduleinfo(inspect) # [deprecated-method] diff --git a/tests/functional/d/deprecated_method_getmoduleinfo.rc b/tests/functional/d/deprecated_method_getmoduleinfo.rc deleted file mode 100644 index a444ca6b8..000000000 --- a/tests/functional/d/deprecated_method_getmoduleinfo.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -max_pyver=3.6 -min_pyver=3.3 diff --git a/tests/functional/d/deprecated_method_getmoduleinfo.txt b/tests/functional/d/deprecated_method_getmoduleinfo.txt deleted file mode 100644 index 77632a157..000000000 --- a/tests/functional/d/deprecated_method_getmoduleinfo.txt +++ /dev/null @@ -1 +0,0 @@ -deprecated-method:4:::Using deprecated method getmoduleinfo() diff --git a/tests/functional/d/deprecated_methods_py3.py b/tests/functional/d/deprecated_methods_py3.py deleted file mode 100644 index 80428c79f..000000000 --- a/tests/functional/d/deprecated_methods_py3.py +++ /dev/null @@ -1,50 +0,0 @@ -""" Functional tests for method deprecation. """ -# pylint: disable=missing-docstring, super-init-not-called, not-callable -import base64 -import cgi -import inspect -import logging -import nntplib -import platform -import unittest -import xml.etree.ElementTree - - -class MyTest(unittest.TestCase): - def test(self): - self.assert_(True) # [deprecated-method] - -xml.etree.ElementTree.Element('tag').getchildren() # [deprecated-method] -xml.etree.ElementTree.Element('tag').getiterator() # [deprecated-method] -xml.etree.ElementTree.XMLParser('tag', None, None).doctype(None, None, None) # [deprecated-method] -nntplib.NNTP(None).xpath(None) # [deprecated-method] - - -inspect.getargspec(None) # [deprecated-method] -logging.warn("a") # [deprecated-method] -platform.popen([]) # [deprecated-method] -base64.encodestring("42") # [deprecated-method] -base64.decodestring("42") # [deprecated-method] -cgi.escape("a") # [deprecated-method] - - -class SuperCrash(unittest.TestCase): - - def __init__(self): - # should not crash. - super()() - -xml.etree.ElementTree.iterparse(None) - - -class Tests(unittest.TestCase): - - def test_foo(self): - self.assertEquals(2 + 2, 4) # [deprecated-method] - self.assertNotEquals(2 + 2, 4) # [deprecated-method] - self.assertAlmostEquals(2 + 2, 4) # [deprecated-method] - self.assertNotAlmostEquals(2 + 2, 4) # [deprecated-method] - self.assert_("abc" == "2") # [deprecated-method] - - self.assertRaisesRegex(ValueError, "exception") - self.assertRegex("something", r".+") diff --git a/tests/functional/d/deprecated_methods_py3.rc b/tests/functional/d/deprecated_methods_py3.rc deleted file mode 100644 index 6c3e72704..000000000 --- a/tests/functional/d/deprecated_methods_py3.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -min_pyver=3.3 -max_pyver=3.7 diff --git a/tests/functional/d/deprecated_methods_py3.txt b/tests/functional/d/deprecated_methods_py3.txt deleted file mode 100644 index 9796114f6..000000000 --- a/tests/functional/d/deprecated_methods_py3.txt +++ /dev/null @@ -1,16 +0,0 @@ -deprecated-method:15::MyTest.test:Using deprecated method assert_() -deprecated-method:17:::Using deprecated method getchildren() -deprecated-method:18:::Using deprecated method getiterator() -deprecated-method:19:::Using deprecated method doctype() -deprecated-method:20:::Using deprecated method xpath() -deprecated-method:23:::Using deprecated method getargspec() -deprecated-method:24:::Using deprecated method warn() -deprecated-method:25:::Using deprecated method popen() -deprecated-method:26:::Using deprecated method encodestring() -deprecated-method:27:::Using deprecated method decodestring() -deprecated-method:28:::Using deprecated method escape() -deprecated-method:43::Tests.test_foo:Using deprecated method assertEquals() -deprecated-method:44::Tests.test_foo:Using deprecated method assertNotEquals() -deprecated-method:45::Tests.test_foo:Using deprecated method assertAlmostEquals() -deprecated-method:46::Tests.test_foo:Using deprecated method assertNotAlmostEquals() -deprecated-method:47::Tests.test_foo:Using deprecated method assert_() diff --git a/tests/functional/d/deprecated_methods_py36.py b/tests/functional/d/deprecated_methods_py36.py deleted file mode 100644 index f416a144c..000000000 --- a/tests/functional/d/deprecated_methods_py36.py +++ /dev/null @@ -1,7 +0,0 @@ -""" Functional tests for method deprecation. """ -# pylint: disable=no-value-for-parameter -import unittest -from importlib.machinery import SourceFileLoader, SourcelessFileLoader - -SourceFileLoader('unittest', unittest.__file__).load_module() # [deprecated-method] -SourcelessFileLoader('unittest', unittest.__file__).load_module() # [deprecated-method] diff --git a/tests/functional/d/deprecated_methods_py36.rc b/tests/functional/d/deprecated_methods_py36.rc deleted file mode 100644 index 0ba2b6333..000000000 --- a/tests/functional/d/deprecated_methods_py36.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.6 diff --git a/tests/functional/d/deprecated_methods_py36.txt b/tests/functional/d/deprecated_methods_py36.txt deleted file mode 100644 index 801d24b6e..000000000 --- a/tests/functional/d/deprecated_methods_py36.txt +++ /dev/null @@ -1,2 +0,0 @@ -deprecated-method:6:0::Using deprecated method load_module() -deprecated-method:7:0::Using deprecated method load_module() diff --git a/tests/functional/d/deprecated_methods_py38.py b/tests/functional/d/deprecated_methods_py38.py deleted file mode 100644 index 57047f926..000000000 --- a/tests/functional/d/deprecated_methods_py38.py +++ /dev/null @@ -1,45 +0,0 @@ -""" Functional tests for method deprecation. """ -# pylint: disable=missing-docstring, super-init-not-called, not-callable -import base64 -import inspect -import logging -import nntplib -import unittest -import xml.etree.ElementTree - - -class MyTest(unittest.TestCase): - def test(self): - self.assert_(True) # [deprecated-method] - -xml.etree.ElementTree.Element('tag').getchildren() # [deprecated-method] -xml.etree.ElementTree.Element('tag').getiterator() # [deprecated-method] -nntplib.NNTP(None).xpath(None) # [deprecated-method] - - -inspect.getargspec(None) # [deprecated-method] -logging.warn("a") # [deprecated-method] -base64.encodestring("42") # [deprecated-method] -base64.decodestring("42") # [deprecated-method] - - -class SuperCrash(unittest.TestCase): - - def __init__(self): - # should not crash. - super()() - -xml.etree.ElementTree.iterparse(None) - - -class Tests(unittest.TestCase): - - def test_foo(self): - self.assertEquals(2 + 2, 4) # [deprecated-method] - self.assertNotEquals(2 + 2, 4) # [deprecated-method] - self.assertAlmostEquals(2 + 2, 4) # [deprecated-method] - self.assertNotAlmostEquals(2 + 2, 4) # [deprecated-method] - self.assert_("abc" == "2") # [deprecated-method] - - self.assertRaisesRegex(ValueError, "exception") - self.assertRegex("something", r".+") diff --git a/tests/functional/d/deprecated_methods_py38.rc b/tests/functional/d/deprecated_methods_py38.rc deleted file mode 100644 index 35b185fdb..000000000 --- a/tests/functional/d/deprecated_methods_py38.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -min_pyver=3.8 -max_pyver=3.9 diff --git a/tests/functional/d/deprecated_methods_py38.txt b/tests/functional/d/deprecated_methods_py38.txt deleted file mode 100644 index 00d7f7dda..000000000 --- a/tests/functional/d/deprecated_methods_py38.txt +++ /dev/null @@ -1,13 +0,0 @@ -deprecated-method:13:8:MyTest.test:Using deprecated method assert_() -deprecated-method:15:0::Using deprecated method getchildren() -deprecated-method:16:0::Using deprecated method getiterator() -deprecated-method:17:0::Using deprecated method xpath() -deprecated-method:20:0::Using deprecated method getargspec() -deprecated-method:21:0::Using deprecated method warn() -deprecated-method:22:0::Using deprecated method encodestring() -deprecated-method:23:0::Using deprecated method decodestring() -deprecated-method:38:8:Tests.test_foo:Using deprecated method assertEquals() -deprecated-method:39:8:Tests.test_foo:Using deprecated method assertNotEquals() -deprecated-method:40:8:Tests.test_foo:Using deprecated method assertAlmostEquals() -deprecated-method:41:8:Tests.test_foo:Using deprecated method assertNotAlmostEquals() -deprecated-method:42:8:Tests.test_foo:Using deprecated method assert_() diff --git a/tests/functional/d/deprecated_module_py3.py b/tests/functional/d/deprecated_module_py3.py deleted file mode 100644 index 308d400e7..000000000 --- a/tests/functional/d/deprecated_module_py3.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Test deprecated modules.""" -# pylint: disable=unused-import - -import optparse # [deprecated-module] diff --git a/tests/functional/d/deprecated_module_py3.rc b/tests/functional/d/deprecated_module_py3.rc deleted file mode 100644 index 46343d2f1..000000000 --- a/tests/functional/d/deprecated_module_py3.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -min_pyver=3.0 -max_pyver=3.6 diff --git a/tests/functional/d/deprecated_module_py3.txt b/tests/functional/d/deprecated_module_py3.txt deleted file mode 100644 index 79c0a418c..000000000 --- a/tests/functional/d/deprecated_module_py3.txt +++ /dev/null @@ -1 +0,0 @@ -deprecated-module:4:::Uses of a deprecated module 'optparse' diff --git a/tests/functional/d/deprecated_module_py36.py b/tests/functional/d/deprecated_module_py36.py deleted file mode 100644 index c49f9f0bc..000000000 --- a/tests/functional/d/deprecated_module_py36.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Test deprecated modules from Python 3.6.""" -# pylint: disable=unused-import,import-error - -import optparse # [deprecated-module] diff --git a/tests/functional/d/deprecated_module_py36.rc b/tests/functional/d/deprecated_module_py36.rc deleted file mode 100644 index 0ba2b6333..000000000 --- a/tests/functional/d/deprecated_module_py36.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.6 diff --git a/tests/functional/d/deprecated_module_py36.txt b/tests/functional/d/deprecated_module_py36.txt deleted file mode 100644 index ab5f48996..000000000 --- a/tests/functional/d/deprecated_module_py36.txt +++ /dev/null @@ -1 +0,0 @@ -deprecated-module:4:0::Uses of a deprecated module 'optparse' diff --git a/tests/functional/d/deprecated_module_py4.py b/tests/functional/d/deprecated_module_py4.py deleted file mode 100644 index 3cad959e7..000000000 --- a/tests/functional/d/deprecated_module_py4.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Test deprecated modules.""" - -from deprecated import foo # [deprecated-module] -import deprecated # [deprecated-module] diff --git a/tests/functional/d/deprecated_module_py4.rc b/tests/functional/d/deprecated_module_py4.rc deleted file mode 100644 index 6fbd3407e..000000000 --- a/tests/functional/d/deprecated_module_py4.rc +++ /dev/null @@ -1,4 +0,0 @@ -[Messages Control] -deprecated-modules=deprecated -disable=all -enable=deprecated-module diff --git a/tests/functional/d/deprecated_module_py4.txt b/tests/functional/d/deprecated_module_py4.txt deleted file mode 100644 index f4800d0b9..000000000 --- a/tests/functional/d/deprecated_module_py4.txt +++ /dev/null @@ -1,2 +0,0 @@ -deprecated-module:3:0::Uses of a deprecated module 'deprecated' -deprecated-module:4:0::Uses of a deprecated module 'deprecated' diff --git a/tests/functional/d/deprecated_module_uninstalled.py b/tests/functional/d/deprecated_module_uninstalled.py deleted file mode 100644 index 52d55fa84..000000000 --- a/tests/functional/d/deprecated_module_uninstalled.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Test deprecated modules uninstalled.""" -# pylint: disable=unused-import,no-name-in-module,import-error - -from uninstalled import uninstalled_module # [deprecated-module] -import uninstalled # [deprecated-module] diff --git a/tests/functional/d/deprecated_module_uninstalled.rc b/tests/functional/d/deprecated_module_uninstalled.rc deleted file mode 100644 index d68fc0bc9..000000000 --- a/tests/functional/d/deprecated_module_uninstalled.rc +++ /dev/null @@ -1,2 +0,0 @@ -[Messages Control] -deprecated-modules=uninstalled diff --git a/tests/functional/d/deprecated_module_uninstalled.txt b/tests/functional/d/deprecated_module_uninstalled.txt deleted file mode 100644 index 7d9f01afa..000000000 --- a/tests/functional/d/deprecated_module_uninstalled.txt +++ /dev/null @@ -1,2 +0,0 @@ -deprecated-module:4:0::Uses of a deprecated module 'uninstalled' -deprecated-module:5:0::Uses of a deprecated module 'uninstalled' diff --git a/tests/functional/i/implicit/implicit_str_concat.py b/tests/functional/i/implicit/implicit_str_concat.py new file mode 100644 index 000000000..707fa75bf --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat.py @@ -0,0 +1,31 @@ +#pylint: disable=invalid-name,missing-docstring + +# Basic test with a list +TEST_LIST1 = ['a' 'b'] # [implicit-str-concat] +# Testing with unicode strings in a tuple, with a comma AFTER concatenation +TEST_LIST2 = (u"a" u"b", u"c") # [implicit-str-concat] +# Testing with raw strings in a set, with a comma BEFORE concatenation +TEST_LIST3 = {r'''a''', r'''b''' r'''c'''} # [implicit-str-concat] +# Testing that only ONE warning is generated when string concatenation happens +# in the middle of a list +TEST_LIST4 = ["""a""", """b""" """c""", """d"""] # [implicit-str-concat] + +# The following shouldn't raise a warning because it is a function call +print('a', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'ccc') + +# The following shouldn't raise a warning because string literals are +# on different lines +TEST_LIST5 = ('a', 'b' + 'c') + +# The following shouldn't raise a warning because of the escaped newline +TEST_LIST6 = ('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \ + ccc') + +# But we should emit when there is an actual juxtaposition +# +1: [implicit-str-concat] +TEST_LIST7 = ('a' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \ + ccc') + +# No warning for bytes +TEST_LIST8 = [b'A' b'B'] diff --git a/tests/functional/i/implicit/implicit_str_concat.txt b/tests/functional/i/implicit/implicit_str_concat.txt new file mode 100644 index 000000000..11cecd777 --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat.txt @@ -0,0 +1,5 @@ +implicit-str-concat:4:0::Implicit string concatenation found in list +implicit-str-concat:6:0::Implicit string concatenation found in tuple +implicit-str-concat:8:0::Implicit string concatenation found in set +implicit-str-concat:11:0::Implicit string concatenation found in list +implicit-str-concat:27:0::Implicit string concatenation found in assignment diff --git a/tests/functional/i/implicit/implicit_str_concat_latin1.py b/tests/functional/i/implicit/implicit_str_concat_latin1.py new file mode 100644 index 000000000..cf8c3e6ab --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat_latin1.py @@ -0,0 +1,4 @@ +# coding: latin_1 +#pylint: disable=invalid-name,missing-docstring + +TOTO = ('Café', 'Café', 'Café') diff --git a/tests/functional/i/implicit/implicit_str_concat_multiline.py b/tests/functional/i/implicit/implicit_str_concat_multiline.py new file mode 100755 index 000000000..337ac8035 --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat_multiline.py @@ -0,0 +1,4 @@ +#pylint: disable=missing-docstring + +TEST_TUPLE = ('a', 'b' # [implicit-str-concat] + 'c') diff --git a/tests/functional/i/implicit/implicit_str_concat_multiline.rc b/tests/functional/i/implicit/implicit_str_concat_multiline.rc new file mode 100755 index 000000000..e5b344774 --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat_multiline.rc @@ -0,0 +1,2 @@ +[STRING_CONSTANT] +check-str-concat-over-line-jumps=yes diff --git a/tests/functional/i/implicit/implicit_str_concat_multiline.txt b/tests/functional/i/implicit/implicit_str_concat_multiline.txt new file mode 100755 index 000000000..c796269e4 --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat_multiline.txt @@ -0,0 +1 @@ +implicit-str-concat:3:0::Implicit string concatenation found in tuple diff --git a/tests/functional/i/implicit/implicit_str_concat_utf8.py b/tests/functional/i/implicit/implicit_str_concat_utf8.py new file mode 100644 index 000000000..7cd661860 --- /dev/null +++ b/tests/functional/i/implicit/implicit_str_concat_utf8.py @@ -0,0 +1,3 @@ +#pylint: disable=invalid-name,missing-docstring + +TOTO = ('Café', 'Café', 'Café') diff --git a/tests/functional/i/implicit_str_concat.py b/tests/functional/i/implicit_str_concat.py deleted file mode 100644 index 707fa75bf..000000000 --- a/tests/functional/i/implicit_str_concat.py +++ /dev/null @@ -1,31 +0,0 @@ -#pylint: disable=invalid-name,missing-docstring - -# Basic test with a list -TEST_LIST1 = ['a' 'b'] # [implicit-str-concat] -# Testing with unicode strings in a tuple, with a comma AFTER concatenation -TEST_LIST2 = (u"a" u"b", u"c") # [implicit-str-concat] -# Testing with raw strings in a set, with a comma BEFORE concatenation -TEST_LIST3 = {r'''a''', r'''b''' r'''c'''} # [implicit-str-concat] -# Testing that only ONE warning is generated when string concatenation happens -# in the middle of a list -TEST_LIST4 = ["""a""", """b""" """c""", """d"""] # [implicit-str-concat] - -# The following shouldn't raise a warning because it is a function call -print('a', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'ccc') - -# The following shouldn't raise a warning because string literals are -# on different lines -TEST_LIST5 = ('a', 'b' - 'c') - -# The following shouldn't raise a warning because of the escaped newline -TEST_LIST6 = ('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \ - ccc') - -# But we should emit when there is an actual juxtaposition -# +1: [implicit-str-concat] -TEST_LIST7 = ('a' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \ - ccc') - -# No warning for bytes -TEST_LIST8 = [b'A' b'B'] diff --git a/tests/functional/i/implicit_str_concat.txt b/tests/functional/i/implicit_str_concat.txt deleted file mode 100644 index 11cecd777..000000000 --- a/tests/functional/i/implicit_str_concat.txt +++ /dev/null @@ -1,5 +0,0 @@ -implicit-str-concat:4:0::Implicit string concatenation found in list -implicit-str-concat:6:0::Implicit string concatenation found in tuple -implicit-str-concat:8:0::Implicit string concatenation found in set -implicit-str-concat:11:0::Implicit string concatenation found in list -implicit-str-concat:27:0::Implicit string concatenation found in assignment diff --git a/tests/functional/i/implicit_str_concat_latin1.py b/tests/functional/i/implicit_str_concat_latin1.py deleted file mode 100644 index cf8c3e6ab..000000000 --- a/tests/functional/i/implicit_str_concat_latin1.py +++ /dev/null @@ -1,4 +0,0 @@ -# coding: latin_1 -#pylint: disable=invalid-name,missing-docstring - -TOTO = ('Café', 'Café', 'Café') diff --git a/tests/functional/i/implicit_str_concat_multiline.py b/tests/functional/i/implicit_str_concat_multiline.py deleted file mode 100755 index 337ac8035..000000000 --- a/tests/functional/i/implicit_str_concat_multiline.py +++ /dev/null @@ -1,4 +0,0 @@ -#pylint: disable=missing-docstring - -TEST_TUPLE = ('a', 'b' # [implicit-str-concat] - 'c') diff --git a/tests/functional/i/implicit_str_concat_multiline.rc b/tests/functional/i/implicit_str_concat_multiline.rc deleted file mode 100755 index e5b344774..000000000 --- a/tests/functional/i/implicit_str_concat_multiline.rc +++ /dev/null @@ -1,2 +0,0 @@ -[STRING_CONSTANT] -check-str-concat-over-line-jumps=yes diff --git a/tests/functional/i/implicit_str_concat_multiline.txt b/tests/functional/i/implicit_str_concat_multiline.txt deleted file mode 100755 index c796269e4..000000000 --- a/tests/functional/i/implicit_str_concat_multiline.txt +++ /dev/null @@ -1 +0,0 @@ -implicit-str-concat:3:0::Implicit string concatenation found in tuple diff --git a/tests/functional/i/implicit_str_concat_utf8.py b/tests/functional/i/implicit_str_concat_utf8.py deleted file mode 100644 index 7cd661860..000000000 --- a/tests/functional/i/implicit_str_concat_utf8.py +++ /dev/null @@ -1,3 +0,0 @@ -#pylint: disable=invalid-name,missing-docstring - -TOTO = ('Café', 'Café', 'Café') diff --git a/tests/functional/i/inconsistent/inconsistent_mro.py b/tests/functional/i/inconsistent/inconsistent_mro.py new file mode 100644 index 000000000..0b65068d7 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_mro.py @@ -0,0 +1,9 @@ +"""Tests for inconsistent-mro.""" +# pylint: disable=missing-docstring,too-few-public-methods,no-init + +class Str(str): + pass + + +class Inconsistent(str, Str): # [inconsistent-mro] + pass diff --git a/tests/functional/i/inconsistent/inconsistent_mro.txt b/tests/functional/i/inconsistent/inconsistent_mro.txt new file mode 100644 index 000000000..a0708be85 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_mro.txt @@ -0,0 +1 @@ +inconsistent-mro:8:0:Inconsistent:Inconsistent method resolution order for class 'Inconsistent' diff --git a/tests/functional/i/inconsistent/inconsistent_quotes.py b/tests/functional/i/inconsistent/inconsistent_quotes.py new file mode 100644 index 000000000..76553f98b --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_quotes.py @@ -0,0 +1,16 @@ +"""Tests for inconsistent quoting strategy. + +In this file, double quotes are the majority quote delimiter. +""" + +FIRST_STRING = "double-quoted string" +SECOND_STRING = 'single-quoted string' # [inconsistent-quotes] +THIRD_STRING = "another double-quoted string" +FOURTH_STRING = "yet another double-quoted string" +FIFTH_STRING = 'single-quoted string with an unescaped "double quote"' + +def function_with_docstring(): + '''This is a multi-line docstring that should not raise a warning even though the + delimiter it uses for quotes is not the delimiter used in the majority of the + module. + ''' diff --git a/tests/functional/i/inconsistent/inconsistent_quotes.rc b/tests/functional/i/inconsistent/inconsistent_quotes.rc new file mode 100644 index 000000000..9935ff9b7 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_quotes.rc @@ -0,0 +1,2 @@ +[STRING] +check-quote-consistency=yes diff --git a/tests/functional/i/inconsistent/inconsistent_quotes.txt b/tests/functional/i/inconsistent/inconsistent_quotes.txt new file mode 100644 index 000000000..042fe85c2 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_quotes.txt @@ -0,0 +1 @@ +inconsistent-quotes:7:0::Quote delimiter ' is inconsistent with the rest of the file diff --git a/tests/functional/i/inconsistent/inconsistent_quotes2.py b/tests/functional/i/inconsistent/inconsistent_quotes2.py new file mode 100644 index 000000000..d9b157e34 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_quotes2.py @@ -0,0 +1,10 @@ +"""Tests for inconsistent quoting strategy. + +In this file, single quotes are the majority quote delimiter. +""" + +FIRST_STRING = "double-quoted string" # [inconsistent-quotes] +SECOND_STRING = 'single-quoted string' +THIRD_STRING = 'another single-quoted string' +FOURTH_STRING = 'yet another single-quoted string' +FIFTH_STRING = "double-quoted string with an unescaped 'single quote'" diff --git a/tests/functional/i/inconsistent/inconsistent_quotes2.rc b/tests/functional/i/inconsistent/inconsistent_quotes2.rc new file mode 100644 index 000000000..9935ff9b7 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_quotes2.rc @@ -0,0 +1,2 @@ +[STRING] +check-quote-consistency=yes diff --git a/tests/functional/i/inconsistent/inconsistent_quotes2.txt b/tests/functional/i/inconsistent/inconsistent_quotes2.txt new file mode 100644 index 000000000..0f2f77bf8 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_quotes2.txt @@ -0,0 +1 @@ +inconsistent-quotes:6:0::"Quote delimiter "" is inconsistent with the rest of the file" diff --git a/tests/functional/i/inconsistent/inconsistent_returns.py b/tests/functional/i/inconsistent/inconsistent_returns.py new file mode 100644 index 000000000..9997e9a2c --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_returns.py @@ -0,0 +1,337 @@ +#pylint: disable=missing-docstring, no-else-return, no-else-break, invalid-name, unused-variable, superfluous-parens, try-except-raise +#pylint: disable=blacklisted-name +"""Testing inconsistent returns""" +import math +import sys + +# These ones are consistent +def explicit_returns(var): + if var >= 0: + return math.sqrt(var) + else: + return None + +def explicit_returns2(var): + if var < 0: + return None + return math.sqrt(var) + +def empty_implicit_returns(var): + if var < 0: + return + +def returns_in_exceptions(): + try: + raise ValueError('test') + except ValueError: + return 1 + except (OSError, TypeError): + return 2 + +def returns_and_exceptions(var): + if var < 10: + return var**2 + else: + raise ValueError("Incorrect value") + +def returns_and_exceptions_issue1770(var): + try: + if var == 1: + return 'a' + elif var == 2: + return 'b' + else: + raise ValueError + except AssertionError: + return None + +def explicit_returns3(arg): + if arg: + return False + else: + if arg < 3: + print('arg < 3') + return True + +def explicit_returns4(arg): + if arg: + if arg > 2: + print('arg > 2') + return False + else: + if arg < 3: + print('arg < 3') + return True + +def explicit_returns5(arg): + if arg: + if arg > 2: + print('arg > 2') + return False + else: + return True + +def nested_function(): + def dummy_return(): + return True + return dummy_return + +def explicit_returns6(x, y, z): + if x: # pylint: disable=no-else-return + a = 1 + if y: # pylint: disable=no-else-return + b = 2 + return y + else: + c = 3 + return x + else: + d = 4 + return z + +def explicit_returns7(arg): + if arg < 0: + arg = 2 * arg + return 'below 0' + elif arg == 0: + print("Null arg") + return '0' + else: + arg = 3 * arg + return 'above 0' + +def bug_1772(): + """Don't check inconsistent return statements inside while loop""" + counter = 1 + while True: + counter += 1 + if counter == 100: + return 7 + +def bug_1771(var): + if var == 1: + sys.exit(1) + else: + return var * 2 + +def bug_1771_with_user_config(var): + # sys.getdefaultencoding is considered as a never + # returning function in the inconsistent_returns.rc file. + if var == 1: + sys.getdefaultencoding() + else: + return var * 2 + +def bug_1794_inner_func_in_if(var): + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return None + return None + else: + return None + +try: + import ConfigParser as configparser +except ImportError: + import configparser + +# Due to the try/except import above, astroid cannot safely +# infer the exception type. It doesn't matter here, because +# as the raise statement is not inside a try/except one, there +# is no need to infer the exception type. It is just an exception +# that is raised. +def bug_1794(a): + for x in range(a): + if x == 100: + return a + raise configparser.NoSectionError('toto') + +#pylint: disable = no-else-return +def bug_1782_bis(val=3): + if val == 3: + while True: + break + return True + else: + raise RuntimeError() + +# Next ones are not consistent +def explicit_implicit_returns(var): # [inconsistent-return-statements] + if var >= 0: + return math.sqrt(var) + +def empty_explicit_returns(var): # [inconsistent-return-statements] + if var < 0: + return + return math.sqrt(var) + +def explicit_implicit_returns2(arg): # [inconsistent-return-statements] + if arg: + if arg > 2: + print('arg > 2') + return False + else: + return True + +def explicit_implicit_returns3(arg): # [inconsistent-return-statements] + if arg: + if arg > 2: + print('arg > 2') + return False + else: + return True + +def returns_missing_in_catched_exceptions(arg): # [inconsistent-return-statements] + try: + arg = arg**2 + raise ValueError('test') + except ValueError: + print('ValueError') + arg = 0 + except (OSError, TypeError): + return 2 + +def complex_func(arg): # [inconsistent-return-statements] + for i in range(arg): + if i > arg / 2: + break + else: + return arg + +def inconsistent_returns_in_nested_function(): + def not_consistent_returns_inner(arg): # [inconsistent-return-statements] + for i in range(arg): + if i > arg / 2: + break + else: + return arg + return not_consistent_returns_inner + +def bug_1771_counter_example(var): # [inconsistent-return-statements] + if var == 1: + inconsistent_returns_in_nested_function() + else: + return var * 2 + +class BlargException(Exception): + pass + + +def blarg(someval): + try: + if someval: + raise BlargException() + return 5 + except BlargException: + raise + +def bug_1772_counter_example(): # [inconsistent-return-statements] + counter = 1 + if counter == 1: + while True: + counter += 1 + if counter == 100: + return 7 + +def bug_1794_inner_func_in_if_counter_example_1(var): # [inconsistent-return-statements] + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return None + return None + else: + return + +def bug_1794_inner_func_in_if_counter_example_2(var): # [inconsistent-return-statements] + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return + return None + else: + return + +def bug_1794_inner_func_in_if_counter_example_3(var): # [inconsistent-return-statements] + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return None + return None + else: + def _inner2(var_bis): # [inconsistent-return-statements] + if var_bis: + return True + return + +def bug_3468(bar): # [inconsistent-return-statements] + """ + In case of AttributeError the function returns implicitly None. + There are one explicit return and one implicit. + """ + try: + return bar.baz + except AttributeError: + pass + +def bug_3468_variant(bar): # [inconsistent-return-statements] + """ + In case of AttributeError the function returns implicitly None + There are one explicit return and one implicit. + """ + try: + return bar.baz + except AttributeError: + pass + except KeyError: + return True + except ValueError: + raise + +def bug_3468_counter_example(bar): + """ + In case of AttributeError the function returns explicitly None. + Thus all returns are explicit. + """ + try: + return bar.baz + except AttributeError: + pass + return None + +def bug_3468_counter_example_2(bar): + """ + In case of AttributeError the function returns explicitly None. + Thus all returns are explicit. + """ + try: + return bar.baz + except AttributeError: + return None + +def nothing_to_do(): + pass + +def bug_pylint_3873(): + try: + nothing_to_do() + return True + except IndexError: + return False + +def bug_pylint_3873_1(): # [inconsistent-return-statements] + try: + nothing_to_do() + return True + except IndexError: + pass + except ValueError: + return False + +def bug_pylint_3873_2(): + try: + nothing_to_do() + return True + except IndexError: + nothing_to_do() + return False diff --git a/tests/functional/i/inconsistent/inconsistent_returns.rc b/tests/functional/i/inconsistent/inconsistent_returns.rc new file mode 100644 index 000000000..dd6cbb598 --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_returns.rc @@ -0,0 +1,2 @@ +[REFACTORING] +never-returning-functions=sys.exit,sys.getdefaultencoding diff --git a/tests/functional/i/inconsistent/inconsistent_returns.txt b/tests/functional/i/inconsistent/inconsistent_returns.txt new file mode 100644 index 000000000..34978d5fd --- /dev/null +++ b/tests/functional/i/inconsistent/inconsistent_returns.txt @@ -0,0 +1,16 @@ +inconsistent-return-statements:160:0:explicit_implicit_returns:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:164:0:empty_explicit_returns:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:169:0:explicit_implicit_returns2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:177:0:explicit_implicit_returns3:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:185:0:returns_missing_in_catched_exceptions:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:195:0:complex_func:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:203:4:inconsistent_returns_in_nested_function.not_consistent_returns_inner:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:211:0:bug_1771_counter_example:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:229:0:bug_1772_counter_example:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:237:0:bug_1794_inner_func_in_if_counter_example_1:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:246:0:bug_1794_inner_func_in_if_counter_example_2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:255:0:bug_1794_inner_func_in_if_counter_example_3:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:262:8:bug_1794_inner_func_in_if_counter_example_3._inner2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:267:0:bug_3468:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:277:0:bug_3468_variant:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:322:0:bug_pylint_3873_1:Either all return statements in a function should return an expression, or none of them should. diff --git a/tests/functional/i/inconsistent_mro.py b/tests/functional/i/inconsistent_mro.py deleted file mode 100644 index 0b65068d7..000000000 --- a/tests/functional/i/inconsistent_mro.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Tests for inconsistent-mro.""" -# pylint: disable=missing-docstring,too-few-public-methods,no-init - -class Str(str): - pass - - -class Inconsistent(str, Str): # [inconsistent-mro] - pass diff --git a/tests/functional/i/inconsistent_mro.txt b/tests/functional/i/inconsistent_mro.txt deleted file mode 100644 index a0708be85..000000000 --- a/tests/functional/i/inconsistent_mro.txt +++ /dev/null @@ -1 +0,0 @@ -inconsistent-mro:8:0:Inconsistent:Inconsistent method resolution order for class 'Inconsistent' diff --git a/tests/functional/i/inconsistent_quotes.py b/tests/functional/i/inconsistent_quotes.py deleted file mode 100644 index 76553f98b..000000000 --- a/tests/functional/i/inconsistent_quotes.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Tests for inconsistent quoting strategy. - -In this file, double quotes are the majority quote delimiter. -""" - -FIRST_STRING = "double-quoted string" -SECOND_STRING = 'single-quoted string' # [inconsistent-quotes] -THIRD_STRING = "another double-quoted string" -FOURTH_STRING = "yet another double-quoted string" -FIFTH_STRING = 'single-quoted string with an unescaped "double quote"' - -def function_with_docstring(): - '''This is a multi-line docstring that should not raise a warning even though the - delimiter it uses for quotes is not the delimiter used in the majority of the - module. - ''' diff --git a/tests/functional/i/inconsistent_quotes.rc b/tests/functional/i/inconsistent_quotes.rc deleted file mode 100644 index 9935ff9b7..000000000 --- a/tests/functional/i/inconsistent_quotes.rc +++ /dev/null @@ -1,2 +0,0 @@ -[STRING] -check-quote-consistency=yes diff --git a/tests/functional/i/inconsistent_quotes.txt b/tests/functional/i/inconsistent_quotes.txt deleted file mode 100644 index 042fe85c2..000000000 --- a/tests/functional/i/inconsistent_quotes.txt +++ /dev/null @@ -1 +0,0 @@ -inconsistent-quotes:7:0::Quote delimiter ' is inconsistent with the rest of the file diff --git a/tests/functional/i/inconsistent_quotes2.py b/tests/functional/i/inconsistent_quotes2.py deleted file mode 100644 index d9b157e34..000000000 --- a/tests/functional/i/inconsistent_quotes2.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Tests for inconsistent quoting strategy. - -In this file, single quotes are the majority quote delimiter. -""" - -FIRST_STRING = "double-quoted string" # [inconsistent-quotes] -SECOND_STRING = 'single-quoted string' -THIRD_STRING = 'another single-quoted string' -FOURTH_STRING = 'yet another single-quoted string' -FIFTH_STRING = "double-quoted string with an unescaped 'single quote'" diff --git a/tests/functional/i/inconsistent_quotes2.rc b/tests/functional/i/inconsistent_quotes2.rc deleted file mode 100644 index 9935ff9b7..000000000 --- a/tests/functional/i/inconsistent_quotes2.rc +++ /dev/null @@ -1,2 +0,0 @@ -[STRING] -check-quote-consistency=yes diff --git a/tests/functional/i/inconsistent_quotes2.txt b/tests/functional/i/inconsistent_quotes2.txt deleted file mode 100644 index 0f2f77bf8..000000000 --- a/tests/functional/i/inconsistent_quotes2.txt +++ /dev/null @@ -1 +0,0 @@ -inconsistent-quotes:6:0::"Quote delimiter "" is inconsistent with the rest of the file" diff --git a/tests/functional/i/inconsistent_returns.py b/tests/functional/i/inconsistent_returns.py deleted file mode 100644 index 9997e9a2c..000000000 --- a/tests/functional/i/inconsistent_returns.py +++ /dev/null @@ -1,337 +0,0 @@ -#pylint: disable=missing-docstring, no-else-return, no-else-break, invalid-name, unused-variable, superfluous-parens, try-except-raise -#pylint: disable=blacklisted-name -"""Testing inconsistent returns""" -import math -import sys - -# These ones are consistent -def explicit_returns(var): - if var >= 0: - return math.sqrt(var) - else: - return None - -def explicit_returns2(var): - if var < 0: - return None - return math.sqrt(var) - -def empty_implicit_returns(var): - if var < 0: - return - -def returns_in_exceptions(): - try: - raise ValueError('test') - except ValueError: - return 1 - except (OSError, TypeError): - return 2 - -def returns_and_exceptions(var): - if var < 10: - return var**2 - else: - raise ValueError("Incorrect value") - -def returns_and_exceptions_issue1770(var): - try: - if var == 1: - return 'a' - elif var == 2: - return 'b' - else: - raise ValueError - except AssertionError: - return None - -def explicit_returns3(arg): - if arg: - return False - else: - if arg < 3: - print('arg < 3') - return True - -def explicit_returns4(arg): - if arg: - if arg > 2: - print('arg > 2') - return False - else: - if arg < 3: - print('arg < 3') - return True - -def explicit_returns5(arg): - if arg: - if arg > 2: - print('arg > 2') - return False - else: - return True - -def nested_function(): - def dummy_return(): - return True - return dummy_return - -def explicit_returns6(x, y, z): - if x: # pylint: disable=no-else-return - a = 1 - if y: # pylint: disable=no-else-return - b = 2 - return y - else: - c = 3 - return x - else: - d = 4 - return z - -def explicit_returns7(arg): - if arg < 0: - arg = 2 * arg - return 'below 0' - elif arg == 0: - print("Null arg") - return '0' - else: - arg = 3 * arg - return 'above 0' - -def bug_1772(): - """Don't check inconsistent return statements inside while loop""" - counter = 1 - while True: - counter += 1 - if counter == 100: - return 7 - -def bug_1771(var): - if var == 1: - sys.exit(1) - else: - return var * 2 - -def bug_1771_with_user_config(var): - # sys.getdefaultencoding is considered as a never - # returning function in the inconsistent_returns.rc file. - if var == 1: - sys.getdefaultencoding() - else: - return var * 2 - -def bug_1794_inner_func_in_if(var): - # pylint: disable = no-else-return,useless-return - if var: - def _inner(): - return None - return None - else: - return None - -try: - import ConfigParser as configparser -except ImportError: - import configparser - -# Due to the try/except import above, astroid cannot safely -# infer the exception type. It doesn't matter here, because -# as the raise statement is not inside a try/except one, there -# is no need to infer the exception type. It is just an exception -# that is raised. -def bug_1794(a): - for x in range(a): - if x == 100: - return a - raise configparser.NoSectionError('toto') - -#pylint: disable = no-else-return -def bug_1782_bis(val=3): - if val == 3: - while True: - break - return True - else: - raise RuntimeError() - -# Next ones are not consistent -def explicit_implicit_returns(var): # [inconsistent-return-statements] - if var >= 0: - return math.sqrt(var) - -def empty_explicit_returns(var): # [inconsistent-return-statements] - if var < 0: - return - return math.sqrt(var) - -def explicit_implicit_returns2(arg): # [inconsistent-return-statements] - if arg: - if arg > 2: - print('arg > 2') - return False - else: - return True - -def explicit_implicit_returns3(arg): # [inconsistent-return-statements] - if arg: - if arg > 2: - print('arg > 2') - return False - else: - return True - -def returns_missing_in_catched_exceptions(arg): # [inconsistent-return-statements] - try: - arg = arg**2 - raise ValueError('test') - except ValueError: - print('ValueError') - arg = 0 - except (OSError, TypeError): - return 2 - -def complex_func(arg): # [inconsistent-return-statements] - for i in range(arg): - if i > arg / 2: - break - else: - return arg - -def inconsistent_returns_in_nested_function(): - def not_consistent_returns_inner(arg): # [inconsistent-return-statements] - for i in range(arg): - if i > arg / 2: - break - else: - return arg - return not_consistent_returns_inner - -def bug_1771_counter_example(var): # [inconsistent-return-statements] - if var == 1: - inconsistent_returns_in_nested_function() - else: - return var * 2 - -class BlargException(Exception): - pass - - -def blarg(someval): - try: - if someval: - raise BlargException() - return 5 - except BlargException: - raise - -def bug_1772_counter_example(): # [inconsistent-return-statements] - counter = 1 - if counter == 1: - while True: - counter += 1 - if counter == 100: - return 7 - -def bug_1794_inner_func_in_if_counter_example_1(var): # [inconsistent-return-statements] - # pylint: disable = no-else-return,useless-return - if var: - def _inner(): - return None - return None - else: - return - -def bug_1794_inner_func_in_if_counter_example_2(var): # [inconsistent-return-statements] - # pylint: disable = no-else-return,useless-return - if var: - def _inner(): - return - return None - else: - return - -def bug_1794_inner_func_in_if_counter_example_3(var): # [inconsistent-return-statements] - # pylint: disable = no-else-return,useless-return - if var: - def _inner(): - return None - return None - else: - def _inner2(var_bis): # [inconsistent-return-statements] - if var_bis: - return True - return - -def bug_3468(bar): # [inconsistent-return-statements] - """ - In case of AttributeError the function returns implicitly None. - There are one explicit return and one implicit. - """ - try: - return bar.baz - except AttributeError: - pass - -def bug_3468_variant(bar): # [inconsistent-return-statements] - """ - In case of AttributeError the function returns implicitly None - There are one explicit return and one implicit. - """ - try: - return bar.baz - except AttributeError: - pass - except KeyError: - return True - except ValueError: - raise - -def bug_3468_counter_example(bar): - """ - In case of AttributeError the function returns explicitly None. - Thus all returns are explicit. - """ - try: - return bar.baz - except AttributeError: - pass - return None - -def bug_3468_counter_example_2(bar): - """ - In case of AttributeError the function returns explicitly None. - Thus all returns are explicit. - """ - try: - return bar.baz - except AttributeError: - return None - -def nothing_to_do(): - pass - -def bug_pylint_3873(): - try: - nothing_to_do() - return True - except IndexError: - return False - -def bug_pylint_3873_1(): # [inconsistent-return-statements] - try: - nothing_to_do() - return True - except IndexError: - pass - except ValueError: - return False - -def bug_pylint_3873_2(): - try: - nothing_to_do() - return True - except IndexError: - nothing_to_do() - return False diff --git a/tests/functional/i/inconsistent_returns.rc b/tests/functional/i/inconsistent_returns.rc deleted file mode 100644 index dd6cbb598..000000000 --- a/tests/functional/i/inconsistent_returns.rc +++ /dev/null @@ -1,2 +0,0 @@ -[REFACTORING] -never-returning-functions=sys.exit,sys.getdefaultencoding diff --git a/tests/functional/i/inconsistent_returns.txt b/tests/functional/i/inconsistent_returns.txt deleted file mode 100644 index 34978d5fd..000000000 --- a/tests/functional/i/inconsistent_returns.txt +++ /dev/null @@ -1,16 +0,0 @@ -inconsistent-return-statements:160:0:explicit_implicit_returns:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:164:0:empty_explicit_returns:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:169:0:explicit_implicit_returns2:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:177:0:explicit_implicit_returns3:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:185:0:returns_missing_in_catched_exceptions:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:195:0:complex_func:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:203:4:inconsistent_returns_in_nested_function.not_consistent_returns_inner:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:211:0:bug_1771_counter_example:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:229:0:bug_1772_counter_example:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:237:0:bug_1794_inner_func_in_if_counter_example_1:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:246:0:bug_1794_inner_func_in_if_counter_example_2:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:255:0:bug_1794_inner_func_in_if_counter_example_3:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:262:8:bug_1794_inner_func_in_if_counter_example_3._inner2:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:267:0:bug_3468:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:277:0:bug_3468_variant:Either all return statements in a function should return an expression, or none of them should. -inconsistent-return-statements:322:0:bug_pylint_3873_1:Either all return statements in a function should return an expression, or none of them should. diff --git a/tests/functional/i/invalid/invalid_all_object.py b/tests/functional/i/invalid/invalid_all_object.py new file mode 100644 index 000000000..4468c987b --- /dev/null +++ b/tests/functional/i/invalid/invalid_all_object.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring +__all__ = ( + 1, # [invalid-all-object] + lambda: None, # [invalid-all-object] + None, # [invalid-all-object] +) diff --git a/tests/functional/i/invalid/invalid_all_object.txt b/tests/functional/i/invalid/invalid_all_object.txt new file mode 100644 index 000000000..ebcdb8d35 --- /dev/null +++ b/tests/functional/i/invalid/invalid_all_object.txt @@ -0,0 +1,3 @@ +invalid-all-object:3:4::Invalid object '1' in __all__, must contain only strings +invalid-all-object:4:4::"Invalid object 'lambda: None' in __all__, must contain only strings" +invalid-all-object:5:4::Invalid object 'None' in __all__, must contain only strings diff --git a/tests/functional/i/invalid/invalid_bool_returned.py b/tests/functional/i/invalid/invalid_bool_returned.py new file mode 100644 index 000000000..0e68ed263 --- /dev/null +++ b/tests/functional/i/invalid/invalid_bool_returned.py @@ -0,0 +1,62 @@ +"""Check invalid value returned by __bool__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodBool(object): + """__bool__ returns """ + + def __bool__(self): + return True + + +class SecondGoodBool(object): + """__bool__ returns """ + + def __bool__(self): + return bool(0) + + +class BoolMetaclass(type): + def __bool__(cls): + return True + + +@six.add_metaclass(BoolMetaclass) +class ThirdGoodBool(object): + """Bool through the metaclass.""" + + +class FirstBadBool(object): + """ __bool__ returns an integer """ + + def __bool__(self): # [invalid-bool-returned] + return 1 + + +class SecondBadBool(object): + """ __bool__ returns str """ + + def __bool__(self): # [invalid-bool-returned] + return "True" + + +class ThirdBadBool(object): + """ __bool__ returns node which does not have 'value' in AST """ + + def __bool__(self): # [invalid-bool-returned] + return lambda: 3 + + +class AmbigousBool(object): + """ Uninferable return value """ + __bool__ = lambda self: Missing + + +class AnotherAmbiguousBool(object): + """Potential uninferable return value""" + def __bool__(self): + return bool(Missing) diff --git a/tests/functional/i/invalid/invalid_bool_returned.txt b/tests/functional/i/invalid/invalid_bool_returned.txt new file mode 100644 index 000000000..9af5b182c --- /dev/null +++ b/tests/functional/i/invalid/invalid_bool_returned.txt @@ -0,0 +1,3 @@ +invalid-bool-returned:36:4:FirstBadBool.__bool__:__bool__ does not return bool +invalid-bool-returned:43:4:SecondBadBool.__bool__:__bool__ does not return bool +invalid-bool-returned:50:4:ThirdBadBool.__bool__:__bool__ does not return bool diff --git a/tests/functional/i/invalid/invalid_bytes_returned.py b/tests/functional/i/invalid/invalid_bytes_returned.py new file mode 100644 index 000000000..703fea278 --- /dev/null +++ b/tests/functional/i/invalid/invalid_bytes_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __bytes__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodBytes(object): + """__bytes__ returns """ + + def __bytes__(self): + return b"some bytes" + + +class SecondGoodBytes(object): + """__bytes__ returns """ + + def __bytes__(self): + return bytes("123", "ascii") + + +class BytesMetaclass(type): + def __bytes__(cls): + return b"some bytes" + + +@six.add_metaclass(BytesMetaclass) +class ThirdGoodBytes(object): + """Bytes through the metaclass.""" + + +class FirstBadBytes(object): + """ __bytes__ returns bytes """ + + def __bytes__(self): # [invalid-bytes-returned] + return "123" + + +class SecondBadBytes(object): + """ __bytes__ returns int """ + + def __bytes__(self): # [invalid-bytes-returned] + return 1 + + +class ThirdBadBytes(object): + """ __bytes__ returns node which does not have 'value' in AST """ + + def __bytes__(self): # [invalid-bytes-returned] + return lambda: b"some bytes" + + +class AmbiguousBytes(object): + """ Uninferable return value """ + + __bytes__ = lambda self: Missing + + +class AnotherAmbiguousBytes(object): + """Potential uninferable return value""" + + def __bytes__(self): + return bytes(Missing) diff --git a/tests/functional/i/invalid/invalid_bytes_returned.txt b/tests/functional/i/invalid/invalid_bytes_returned.txt new file mode 100644 index 000000000..63440cbbc --- /dev/null +++ b/tests/functional/i/invalid/invalid_bytes_returned.txt @@ -0,0 +1,3 @@ +invalid-bytes-returned:36:4:FirstBadBytes.__bytes__:__bytes__ does not return bytes +invalid-bytes-returned:43:4:SecondBadBytes.__bytes__:__bytes__ does not return bytes +invalid-bytes-returned:50:4:ThirdBadBytes.__bytes__:__bytes__ does not return bytes diff --git a/tests/functional/i/invalid/invalid_envvar_value.py b/tests/functional/i/invalid/invalid_envvar_value.py new file mode 100644 index 000000000..3c1a8882b --- /dev/null +++ b/tests/functional/i/invalid/invalid_envvar_value.py @@ -0,0 +1,84 @@ +# pylint: disable=useless-return,missing-docstring +from os import getenv + + +def function_returning_list(): + return [] + +def function_returning_none(): + return None + +def function_returning_string(): + return "Result" + +def function_returning_bytes(): + return b"Result" + +def deep_function_returning_string(): + return function_returning_string() + +def deep_function_returning_bytes(): + return function_returning_bytes() + + +# --------------------------------------------------------------------------- # +# Testing getenv # +# --------------------------------------------------------------------------- # + +getenv() # pylint: disable=no-value-for-parameter + +getenv(b"TEST") # [invalid-envvar-value] +getenv("TEST") +getenv(None) # [invalid-envvar-value] +getenv(["Crap"]) # [invalid-envvar-value] +getenv(function_returning_bytes()) # [invalid-envvar-value] +getenv(deep_function_returning_bytes()) # [invalid-envvar-value] +getenv(function_returning_list()) # [invalid-envvar-value] +getenv(function_returning_none()) # [invalid-envvar-value] +getenv(function_returning_string()) +getenv(deep_function_returning_string()) + +getenv(b"TEST", "default") # [invalid-envvar-value] +getenv("TEST", "default") +getenv(None, "default") # [invalid-envvar-value] +getenv(["Crap"], "default") # [invalid-envvar-value] +getenv(function_returning_bytes(), "default") # [invalid-envvar-value] +getenv(function_returning_list(), "default") # [invalid-envvar-value] +getenv(function_returning_none(), "default") # [invalid-envvar-value] +getenv(function_returning_string(), "default") + +getenv(key=b"TEST") # [invalid-envvar-value] +getenv(key="TEST") +getenv(key=None) # [invalid-envvar-value] +getenv(key=["Crap"]) # [invalid-envvar-value] +getenv(key=function_returning_bytes()) # [invalid-envvar-value] +getenv(key=function_returning_list()) # [invalid-envvar-value] +getenv(key=function_returning_none()) # [invalid-envvar-value] +getenv(key=function_returning_string()) + +getenv('TEST', "value") +getenv('TEST', []) # [invalid-envvar-default] +getenv('TEST', None) +getenv('TEST', b"123") # [invalid-envvar-default] +getenv('TEST', function_returning_list()) # [invalid-envvar-default] +getenv('TEST', function_returning_none()) +getenv('TEST', function_returning_string()) +getenv('TEST', function_returning_bytes()) # [invalid-envvar-default] + +getenv('TEST', default="value") +getenv('TEST', default=[]) # [invalid-envvar-default] +getenv('TEST', default=None) +getenv('TEST', default=b"123") # [invalid-envvar-default] +getenv('TEST', default=function_returning_list()) # [invalid-envvar-default] +getenv('TEST', default=function_returning_none()) +getenv('TEST', default=function_returning_string()) +getenv('TEST', default=function_returning_bytes()) # [invalid-envvar-default] + +getenv(key='TEST') +getenv(key='TEST', default="value") +getenv(key='TEST', default=b"value") # [invalid-envvar-default] +getenv(key='TEST', default=["Crap"]) # [invalid-envvar-default] +getenv(key='TEST', default=function_returning_list()) # [invalid-envvar-default] +getenv(key='TEST', default=function_returning_none()) +getenv(key='TEST', default=function_returning_string()) +getenv(key='TEST', default=function_returning_bytes()) # [invalid-envvar-default] diff --git a/tests/functional/i/invalid/invalid_envvar_value.txt b/tests/functional/i/invalid/invalid_envvar_value.txt new file mode 100644 index 000000000..cec352b61 --- /dev/null +++ b/tests/functional/i/invalid/invalid_envvar_value.txt @@ -0,0 +1,31 @@ +invalid-envvar-value:30:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:32:0::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:33:0::os.getenv does not support builtins.list type argument +invalid-envvar-value:34:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:35:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:36:0::os.getenv does not support builtins.list type argument +invalid-envvar-value:37:0::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:41:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:43:0::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:44:0::os.getenv does not support builtins.list type argument +invalid-envvar-value:45:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:46:0::os.getenv does not support builtins.list type argument +invalid-envvar-value:47:0::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:50:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:52:0::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:53:0::os.getenv does not support builtins.list type argument +invalid-envvar-value:54:0::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:55:0::os.getenv does not support builtins.list type argument +invalid-envvar-value:56:0::os.getenv does not support builtins.NoneType type argument +invalid-envvar-default:60:0::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:62:0::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:63:0::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:66:0::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:69:0::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:71:0::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:72:0::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:75:0::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:79:0::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:80:0::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:81:0::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:84:0::os.getenv default type is builtins.bytes. Expected str or None. diff --git a/tests/functional/i/invalid/invalid_exceptions_caught.py b/tests/functional/i/invalid/invalid_exceptions_caught.py new file mode 100644 index 000000000..252643446 --- /dev/null +++ b/tests/functional/i/invalid/invalid_exceptions_caught.py @@ -0,0 +1,135 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance +# pylint: disable=too-many-ancestors, no-absolute-import, import-error, multiple-imports,wrong-import-position +from __future__ import print_function + +import socket, binascii, abc, six + +class MyException(object): + """Custom 'exception'.""" + +class MySecondException(object): + """Custom 'exception'.""" + +class MyGoodException(Exception): + """Custom exception.""" + +class MySecondGoodException(MyGoodException): + """Custom exception.""" + +class SkipException(socket.error): + """Not an exception for Python 2, but one in 3.""" + +class SecondSkipException(SkipException): + """Also a good exception.""" + +try: + 1 + 1 +except MyException: # [catching-non-exception] + print("caught") + +try: + 1 + 2 +# +1:[catching-non-exception,catching-non-exception] +except (MyException, MySecondException): + print("caught") + +try: + 1 + 3 +except MyGoodException: + print("caught") + +try: + 1 + 3 +except (MyGoodException, MySecondGoodException): + print("caught") + +try: + 1 + 3 +except (SkipException, SecondSkipException): + print("caught") + +try: + 1 + 42 +# +1:[catching-non-exception,catching-non-exception] +except (None, list()): + print("caught") + +try: + 1 + 24 +except None: # [catching-non-exception] + print("caught") + +EXCEPTION = None +EXCEPTION = ZeroDivisionError +try: + 1 + 46 +except EXCEPTION: + print("caught") + +try: + 1 + 42 +# +1:[catching-non-exception,catching-non-exception,catching-non-exception] +except (list([4, 5, 6]), None, ZeroDivisionError, 4): + print("caught") + +EXCEPTION_TUPLE = (ZeroDivisionError, OSError) +NON_EXCEPTION_TUPLE = (ZeroDivisionError, OSError, 4) + +try: + 1 + 42 +except EXCEPTION_TUPLE: + print("caught") + +try: + 1 + 42 +except NON_EXCEPTION_TUPLE: # [catching-non-exception] + print("caught") + +from missing_import import UnknownError +UNKNOWN_COMPONENTS = (ZeroDivisionError, UnknownError) + +try: + 1 + 42 +except UNKNOWN_COMPONENTS: + print("caught") + +try: + 1 + 42 +except binascii.Error: + print('builtin and detected') + +try: + 1 + 45 +except object: # [catching-non-exception] + print('caught') + +try: + 1 + 42 +except range: # [catching-non-exception] + print('caught') + + +class HasErrorInMRO(six.with_metaclass(abc.ABCMeta, Exception)): + pass + + +class Second(HasErrorInMRO): + pass + + +try: + raise Second +except Second: + pass + + +class SomeBase(UnknownError): + pass + + +EXCEPTIONS = (SomeBase, ValueError) + +try: + raise ValueError +except EXCEPTIONS: + pass diff --git a/tests/functional/i/invalid/invalid_exceptions_caught.rc b/tests/functional/i/invalid/invalid_exceptions_caught.rc new file mode 100644 index 000000000..6a8ee96ca --- /dev/null +++ b/tests/functional/i/invalid/invalid_exceptions_caught.rc @@ -0,0 +1,2 @@ +[testoptions] +requires = six diff --git a/tests/functional/i/invalid/invalid_exceptions_caught.txt b/tests/functional/i/invalid/invalid_exceptions_caught.txt new file mode 100644 index 000000000..4beed611c --- /dev/null +++ b/tests/functional/i/invalid/invalid_exceptions_caught.txt @@ -0,0 +1,12 @@ +catching-non-exception:27:7::"Catching an exception which doesn't inherit from Exception: MyException" +catching-non-exception:33:7::"Catching an exception which doesn't inherit from Exception: MyException" +catching-non-exception:33:7::"Catching an exception which doesn't inherit from Exception: MySecondException" +catching-non-exception:54:7::"Catching an exception which doesn't inherit from Exception: None" +catching-non-exception:54:7::"Catching an exception which doesn't inherit from Exception: list()" +catching-non-exception:59:7::"Catching an exception which doesn't inherit from Exception: None" +catching-non-exception:72:7::"Catching an exception which doesn't inherit from Exception: 4" +catching-non-exception:72:7::"Catching an exception which doesn't inherit from Exception: None" +catching-non-exception:72:7::"Catching an exception which doesn't inherit from Exception: list([4, 5, 6])" +catching-non-exception:85:7::"Catching an exception which doesn't inherit from Exception: NON_EXCEPTION_TUPLE" +catching-non-exception:103:7::"Catching an exception which doesn't inherit from Exception: object" +catching-non-exception:108:7::"Catching an exception which doesn't inherit from Exception: range" diff --git a/tests/functional/i/invalid/invalid_exceptions_raised.py b/tests/functional/i/invalid/invalid_exceptions_raised.py new file mode 100644 index 000000000..34f740de4 --- /dev/null +++ b/tests/functional/i/invalid/invalid_exceptions_raised.py @@ -0,0 +1,105 @@ +# pylint:disable=too-few-public-methods,no-init,import-error,missing-docstring, not-callable, useless-object-inheritance,import-outside-toplevel +"""test pb with exceptions and old/new style classes""" + + +class ValidException(Exception): + """Valid Exception.""" + +class OldStyleClass: + """Not an exception.""" + +class NewStyleClass(object): + """Not an exception.""" + + +def good_case(): + """raise""" + raise ValidException('hop') + +def good_case1(): + """zlib.error is defined in C module.""" + import zlib + raise zlib.error(4) + +def good_case2(): + """decimal.DivisionByZero is defined in C on Python 3.""" + import decimal + raise decimal.DivisionByZero(4) + +def good_case3(): + """io.BlockingIOError is defined in C.""" + import io + raise io.BlockingIOError + +def bad_case0(): + """raise""" + # +2:<3.0:[nonstandard-exception] + # +1:>=3.0:[raising-non-exception] + raise OldStyleClass('hop') + +def bad_case1(): + """raise""" + raise NewStyleClass() # [raising-non-exception] + +def bad_case2(): + """raise""" + # +2:<3.0:[nonstandard-exception] + # +1:>=3.0:[raising-non-exception] + raise OldStyleClass('hop') + +def bad_case3(): + """raise""" + raise NewStyleClass # [raising-non-exception] + +def bad_case4(): + """raise""" + raise NotImplemented('hop') # [notimplemented-raised] + +def bad_case5(): + """raise""" + raise 1 # [raising-bad-type] + +def bad_case6(): + """raise""" + raise None # [raising-bad-type] + +def bad_case7(): + """raise list""" + raise list # [raising-non-exception] + +def bad_case8(): + """raise tuple""" + raise tuple # [raising-non-exception] + +def bad_case9(): + """raise dict""" + raise dict # [raising-non-exception] + +def unknown_bases(): + """Don't emit when we don't know the bases.""" + from lala import bala # pylint: disable=import-outside-toplevel + class MyException(bala): + pass + raise MyException + + +def exception_instance_regression(): + """Exceptions have a particular class type""" + try: + int("9a") + except ValueError as exc: + raise exc + + +def reusing_same_name_picks_the_latest_raised_value(): + class Error(Exception): + """some error""" + + exceptions = tuple([ValueError, TypeError]) + try: + raise ValueError + except exceptions as exc: # pylint: disable=catching-non-exception + # https://github.com/PyCQA/pylint/issues/1756 + exc = Error(exc) + if exc: + raise exc diff --git a/tests/functional/i/invalid/invalid_exceptions_raised.txt b/tests/functional/i/invalid/invalid_exceptions_raised.txt new file mode 100644 index 000000000..7985a71bf --- /dev/null +++ b/tests/functional/i/invalid/invalid_exceptions_raised.txt @@ -0,0 +1,10 @@ +raising-non-exception:38:4:bad_case0:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:42:4:bad_case1:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:48:4:bad_case2:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:52:4:bad_case3:Raising a new style class which doesn't inherit from BaseException +notimplemented-raised:56:4:bad_case4:NotImplemented raised - should raise NotImplementedError +raising-bad-type:60:4:bad_case5:Raising int while only classes or instances are allowed +raising-bad-type:64:4:bad_case6:Raising NoneType while only classes or instances are allowed +raising-non-exception:68:4:bad_case7:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:72:4:bad_case8:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:76:4:bad_case9:Raising a new style class which doesn't inherit from BaseException diff --git a/tests/functional/i/invalid/invalid_format_returned.py b/tests/functional/i/invalid/invalid_format_returned.py new file mode 100644 index 000000000..ec428b4b3 --- /dev/null +++ b/tests/functional/i/invalid/invalid_format_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __format__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodFormat(object): + """__format__ returns """ + + def __format__(self, format_spec): + return "some format" + + +class SecondGoodFormat(object): + """__format__ returns """ + + def __format__(self, format_spec): + return str(123) + + +class FormatMetaclass(type): + def __format__(cls, format_spec): + return "some format" + + +@six.add_metaclass(FormatMetaclass) +class ThirdGoodFormat(object): + """Format through the metaclass.""" + + +class FirstBadFormat(object): + """ __format__ returns bytes """ + + def __format__(self, format_spec): # [invalid-format-returned] + return b"123" + + +class SecondBadFormat(object): + """ __format__ returns int """ + + def __format__(self, format_spec): # [invalid-format-returned] + return 1 + + +class ThirdBadFormat(object): + """ __format__ returns node which does not have 'value' in AST """ + + def __format__(self, format_spec): # [invalid-format-returned] + return lambda: "some format" + + +class AmbiguousFormat(object): + """ Uninferable return value """ + + __format__ = lambda self, format_spec: Missing + + +class AnotherAmbiguousFormat(object): + """Potential uninferable return value""" + + def __format__(self, format_spec): + return str(Missing) diff --git a/tests/functional/i/invalid/invalid_format_returned.txt b/tests/functional/i/invalid/invalid_format_returned.txt new file mode 100644 index 000000000..3a3e1ae67 --- /dev/null +++ b/tests/functional/i/invalid/invalid_format_returned.txt @@ -0,0 +1,3 @@ +invalid-format-returned:36:4:FirstBadFormat.__format__:__format__ does not return str +invalid-format-returned:43:4:SecondBadFormat.__format__:__format__ does not return str +invalid-format-returned:50:4:ThirdBadFormat.__format__:__format__ does not return str diff --git a/tests/functional/i/invalid/invalid_getnewargs_ex_returned.py b/tests/functional/i/invalid/invalid_getnewargs_ex_returned.py new file mode 100644 index 000000000..e37895096 --- /dev/null +++ b/tests/functional/i/invalid/invalid_getnewargs_ex_returned.py @@ -0,0 +1,85 @@ +"""Check invalid value returned by __getnewargs_ex__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodGetNewArgsEx(object): + """__getnewargs_ex__ returns """ + + def __getnewargs_ex__(self): + return ((1,), {"2": "2"}) + + +class SecondGoodGetNewArgsEx(object): + """__getnewargs_ex__ returns """ + + def __getnewargs_ex__(self): + return (tuple(), dict()) + + +class GetNewArgsExMetaclass(type): + def __getnewargs_ex__(cls): + return ((1,), {"2": "2"}) + + +@six.add_metaclass(GetNewArgsExMetaclass) +class ThirdGoodGetNewArgsEx(object): + """GetNewArgsEx through the metaclass.""" + + +class FirstBadGetNewArgsEx(object): + """ __getnewargs_ex__ returns an integer """ + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return 1 + + +class SecondBadGetNewArgsEx(object): + """ __getnewargs_ex__ returns tuple with incorrect arg length""" + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return (tuple(1), dict(x="y"), 1) + + +class ThirdBadGetNewArgsEx(object): + """ __getnewargs_ex__ returns tuple with wrong type for first arg """ + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return (dict(x="y"), dict(x="y")) + + +class FourthBadGetNewArgsEx(object): + """ __getnewargs_ex__ returns tuple with wrong type for second arg """ + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return ((1, ), (1, )) + + +class FifthBadGetNewArgsEx(object): + """ __getnewargs_ex__ returns tuple with wrong type for both args """ + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return ({'x': 'y'}, (2,)) + + +class SixthBadGetNewArgsEx(object): + """ __getnewargs_ex__ returns node which does not have 'value' in AST """ + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return lambda: (1, 2) + + +class AmbigousGetNewArgsEx(object): + """ Uninferable return value """ + + __getnewargs_ex__ = lambda self: Missing + + +class AnotherAmbiguousGetNewArgsEx(object): + """Potential uninferable return value""" + + def __getnewargs_ex__(self): + return tuple(Missing) diff --git a/tests/functional/i/invalid/invalid_getnewargs_ex_returned.txt b/tests/functional/i/invalid/invalid_getnewargs_ex_returned.txt new file mode 100644 index 000000000..ea8c1703f --- /dev/null +++ b/tests/functional/i/invalid/invalid_getnewargs_ex_returned.txt @@ -0,0 +1,6 @@ +invalid-getnewargs-ex-returned:36:4:FirstBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) +invalid-getnewargs-ex-returned:43:4:SecondBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) +invalid-getnewargs-ex-returned:50:4:ThirdBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) +invalid-getnewargs-ex-returned:57:4:FourthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) +invalid-getnewargs-ex-returned:64:4:FifthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) +invalid-getnewargs-ex-returned:71:4:SixthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) diff --git a/tests/functional/i/invalid/invalid_getnewargs_returned.py b/tests/functional/i/invalid/invalid_getnewargs_returned.py new file mode 100644 index 000000000..ee5305fe8 --- /dev/null +++ b/tests/functional/i/invalid/invalid_getnewargs_returned.py @@ -0,0 +1,62 @@ +"""Check invalid value returned by __getnewargs__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodGetNewArgs(object): + """__getnewargs__ returns """ + + def __getnewargs__(self): + return (1, "2", 3) + + +class SecondGoodGetNewArgs(object): + """__getnewargs__ returns """ + + def __getnewargs__(self): + return tuple() + + +class GetNewArgsMetaclass(type): + def __getnewargs__(cls): + return (1, 2, 3) + + +@six.add_metaclass(GetNewArgsMetaclass) +class ThirdGoodGetNewArgs(object): + """GetNewArgs through the metaclass.""" + + +class FirstBadGetNewArgs(object): + """ __getnewargs__ returns an integer """ + + def __getnewargs__(self): # [invalid-getnewargs-returned] + return 1 + + +class SecondBadGetNewArgs(object): + """ __getnewargs__ returns str """ + + def __getnewargs__(self): # [invalid-getnewargs-returned] + return "(1, 2, 3)" + + +class ThirdBadGetNewArgs(object): + """ __getnewargs__ returns node which does not have 'value' in AST """ + + def __getnewargs__(self): # [invalid-getnewargs-returned] + return lambda: tuple(1, 2) + + +class AmbigousGetNewArgs(object): + """ Uninferable return value """ + __getnewargs__ = lambda self: Missing + + +class AnotherAmbiguousGetNewArgs(object): + """Potential uninferable return value""" + def __getnewargs__(self): + return tuple(Missing) diff --git a/tests/functional/i/invalid/invalid_getnewargs_returned.txt b/tests/functional/i/invalid/invalid_getnewargs_returned.txt new file mode 100644 index 000000000..3560a80f9 --- /dev/null +++ b/tests/functional/i/invalid/invalid_getnewargs_returned.txt @@ -0,0 +1,3 @@ +invalid-getnewargs-returned:36:4:FirstBadGetNewArgs.__getnewargs__:__getnewargs__ does not return a tuple +invalid-getnewargs-returned:43:4:SecondBadGetNewArgs.__getnewargs__:__getnewargs__ does not return a tuple +invalid-getnewargs-returned:50:4:ThirdBadGetNewArgs.__getnewargs__:__getnewargs__ does not return a tuple diff --git a/tests/functional/i/invalid/invalid_hash_returned.py b/tests/functional/i/invalid/invalid_hash_returned.py new file mode 100644 index 000000000..47f63e99b --- /dev/null +++ b/tests/functional/i/invalid/invalid_hash_returned.py @@ -0,0 +1,71 @@ +"""Check invalid value returned by __hash__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodHash(object): + """__hash__ returns """ + + def __hash__(self): + return 1 + + +class SecondGoodHash(object): + """__hash__ returns """ + + def __hash__(self): + return 0 + + +class HashMetaclass(type): + def __hash__(cls): + return 1 + + +@six.add_metaclass(HashMetaclass) +class ThirdGoodHash(object): + """Hash through the metaclass.""" + + +class FirstBadHash(object): + """ __hash__ returns a dict """ + + def __hash__(self): # [invalid-hash-returned] + return {} + + +class SecondBadHash(object): + """ __hash__ returns str """ + + def __hash__(self): # [invalid-hash-returned] + return "True" + + +class ThirdBadHash(object): + """ __hash__ returns a float""" + + def __hash__(self): # [invalid-hash-returned] + return 1.11 + + +class FourthBadHash(object): + """ __hash__ returns node which does not have 'value' in AST """ + + def __hash__(self): # [invalid-hash-returned] + return lambda: 3 + + +class AmbigousHash(object): + """ Uninferable return value """ + + __hash__ = lambda self: Missing + + +class AnotherAmbiguousHash(object): + """Potential uninferable return value""" + + def __hash__(self): + return hash(Missing) diff --git a/tests/functional/i/invalid/invalid_hash_returned.txt b/tests/functional/i/invalid/invalid_hash_returned.txt new file mode 100644 index 000000000..f30e51417 --- /dev/null +++ b/tests/functional/i/invalid/invalid_hash_returned.txt @@ -0,0 +1,4 @@ +invalid-hash-returned:36:4:FirstBadHash.__hash__:__hash__ does not return int +invalid-hash-returned:43:4:SecondBadHash.__hash__:__hash__ does not return int +invalid-hash-returned:50:4:ThirdBadHash.__hash__:__hash__ does not return int +invalid-hash-returned:57:4:FourthBadHash.__hash__:__hash__ does not return int diff --git a/tests/functional/i/invalid/invalid_index_returned.py b/tests/functional/i/invalid/invalid_index_returned.py new file mode 100644 index 000000000..c48d9a837 --- /dev/null +++ b/tests/functional/i/invalid/invalid_index_returned.py @@ -0,0 +1,71 @@ +"""Check invalid value returned by __index__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodIndex(object): + """__index__ returns """ + + def __index__(self): + return 1 + + +class SecondGoodIndex(object): + """__index__ returns """ + + def __index__(self): + return 0 + + +class IndexMetaclass(type): + def __index__(cls): + return 1 + + +@six.add_metaclass(IndexMetaclass) +class ThirdGoodIndex(object): + """Index through the metaclass.""" + + +class FirstBadIndex(object): + """ __index__ returns a dict """ + + def __index__(self): # [invalid-index-returned] + return {'1': '1'} + + +class SecondBadIndex(object): + """ __index__ returns str """ + + def __index__(self): # [invalid-index-returned] + return "42" + + +class ThirdBadIndex(object): + """ __index__ returns a float""" + + def __index__(self): # [invalid-index-returned] + return 1.11 + + +class FourthBadIndex(object): + """ __index__ returns node which does not have 'value' in AST """ + + def __index__(self): # [invalid-index-returned] + return lambda: 3 + + +class AmbigousIndex(object): + """ Uninferable return value """ + + __index__ = lambda self: Missing + + +class AnotherAmbiguousIndex(object): + """Potential uninferable return value""" + + def __index__(self): + return int(Missing) diff --git a/tests/functional/i/invalid/invalid_index_returned.txt b/tests/functional/i/invalid/invalid_index_returned.txt new file mode 100644 index 000000000..840d74a91 --- /dev/null +++ b/tests/functional/i/invalid/invalid_index_returned.txt @@ -0,0 +1,4 @@ +invalid-index-returned:36:4:FirstBadIndex.__index__:__index__ does not return int +invalid-index-returned:43:4:SecondBadIndex.__index__:__index__ does not return int +invalid-index-returned:50:4:ThirdBadIndex.__index__:__index__ does not return int +invalid-index-returned:57:4:FourthBadIndex.__index__:__index__ does not return int diff --git a/tests/functional/i/invalid/invalid_length_hint_returned.py b/tests/functional/i/invalid/invalid_length_hint_returned.py new file mode 100644 index 000000000..7696bc9fd --- /dev/null +++ b/tests/functional/i/invalid/invalid_length_hint_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __length_hint__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import sys + +import six + +from missing import Missing + + +class FirstGoodLengthHint(object): + """__length_hint__ returns """ + + def __length_hint__(self): + return 0 + + +class SecondGoodLengthHint(object): + """__length_hint__ returns """ + + def __length_hint__(self): + return sys.maxsize + 1 + + +class LengthHintMetaclass(type): + def __length_hint__(cls): + return 1 + + +@six.add_metaclass(LengthHintMetaclass) +class ThirdGoodLengthHint(object): + """LengthHintgth through the metaclass.""" + + +class FirstBadLengthHint(object): + """ __length_hint__ returns a negative integer """ + + def __length_hint__(self): # [invalid-length-hint-returned] + return -1 + + +class SecondBadLengthHint(object): + """ __length_hint__ returns non-int """ + + def __length_hint__(self): # [invalid-length-hint-returned] + return 3.0 + + +class ThirdBadLengthHint(object): + """ __length_hint__ returns node which does not have 'value' in AST """ + + def __length_hint__(self): # [invalid-length-hint-returned] + return lambda: 3 + + +class AmbigousLengthHint(object): + """ Uninferable return value """ + __length_hint__ = lambda self: Missing + + +class AnotherAmbiguousLengthHint(object): + """Potential uninferable return value""" + def __length_hint__(self): + return int(Missing) diff --git a/tests/functional/i/invalid/invalid_length_hint_returned.txt b/tests/functional/i/invalid/invalid_length_hint_returned.txt new file mode 100644 index 000000000..dd31af76e --- /dev/null +++ b/tests/functional/i/invalid/invalid_length_hint_returned.txt @@ -0,0 +1,3 @@ +invalid-length-hint-returned:38:4:FirstBadLengthHint.__length_hint__:__length_hint__ does not return non-negative integer +invalid-length-hint-returned:45:4:SecondBadLengthHint.__length_hint__:__length_hint__ does not return non-negative integer +invalid-length-hint-returned:52:4:ThirdBadLengthHint.__length_hint__:__length_hint__ does not return non-negative integer diff --git a/tests/functional/i/invalid/invalid_length_returned.py b/tests/functional/i/invalid/invalid_length_returned.py new file mode 100644 index 000000000..e57db5290 --- /dev/null +++ b/tests/functional/i/invalid/invalid_length_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __len__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import sys + +import six + +from missing import Missing + + +class FirstGoodLen(object): + """__len__ returns """ + + def __len__(self): + return 0 + + +class SecondGoodLen(object): + """__len__ returns """ + + def __len__(self): + return sys.maxsize + 1 + + +class LenMetaclass(type): + def __len__(cls): + return 1 + + +@six.add_metaclass(LenMetaclass) +class ThirdGoodLen(object): + """Length through the metaclass.""" + + +class FirstBadLen(object): + """ __len__ returns a negative integer """ + + def __len__(self): # [invalid-length-returned] + return -1 + + +class SecondBadLen(object): + """ __len__ returns non-int """ + + def __len__(self): # [invalid-length-returned] + return 3.0 + + +class ThirdBadLen(object): + """ __len__ returns node which does not have 'value' in AST """ + + def __len__(self): # [invalid-length-returned] + return lambda: 3 + + +class AmbigousLen(object): + """ Uninferable return value """ + __len__ = lambda self: Missing + + +class AnotherAmbiguousLen(object): + """Potential uninferable return value""" + def __len__(self): + return int(Missing) diff --git a/tests/functional/i/invalid/invalid_length_returned.txt b/tests/functional/i/invalid/invalid_length_returned.txt new file mode 100644 index 000000000..2a271fb29 --- /dev/null +++ b/tests/functional/i/invalid/invalid_length_returned.txt @@ -0,0 +1,3 @@ +invalid-length-returned:38:4:FirstBadLen.__len__:__len__ does not return non-negative integer +invalid-length-returned:45:4:SecondBadLen.__len__:__len__ does not return non-negative integer +invalid-length-returned:52:4:ThirdBadLen.__len__:__len__ does not return non-negative integer diff --git a/tests/functional/i/invalid/invalid_metaclass.py b/tests/functional/i/invalid/invalid_metaclass.py new file mode 100644 index 000000000..c0e9d74be --- /dev/null +++ b/tests/functional/i/invalid/invalid_metaclass.py @@ -0,0 +1,34 @@ +# pylint: disable=missing-docstring, too-few-public-methods, import-error,unused-argument, useless-object-inheritance + +import abc + +import six +from unknown import Unknown + + +class InvalidAsMetaclass(object): + pass + + +class ValidAsMetaclass(type): + pass + + +@six.add_metaclass(type) +class FirstGood(object): + pass + + +@six.add_metaclass(abc.ABCMeta) +class SecondGood(object): + pass + + +@six.add_metaclass(Unknown) +class ThirdGood(object): + pass + + +@six.add_metaclass(ValidAsMetaclass) +class FourthGood(object): + pass diff --git a/tests/functional/i/invalid/invalid_metaclass_py3.py b/tests/functional/i/invalid/invalid_metaclass_py3.py new file mode 100644 index 000000000..2fc458f5c --- /dev/null +++ b/tests/functional/i/invalid/invalid_metaclass_py3.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring, too-few-public-methods, import-error,unused-argument + +from unknown import Unknown + + +def valid_metaclass_1(name, _, attrs): + return type + + +def valid_metaclass_2(_name, _bases, _attrs): + return Unknown + + +class GoodMetaclass(metaclass=valid_metaclass_1): + pass + + +class SecondGoodMetaclass(metaclass=valid_metaclass_2): + pass diff --git a/tests/functional/i/invalid/invalid_metaclass_py3.rc b/tests/functional/i/invalid/invalid_metaclass_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/i/invalid/invalid_metaclass_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/i/invalid/invalid_name.py b/tests/functional/i/invalid/invalid_name.py new file mode 100644 index 000000000..6259b9b50 --- /dev/null +++ b/tests/functional/i/invalid/invalid_name.py @@ -0,0 +1,44 @@ +""" Tests for invalid-name checker. """ +# pylint: disable=unused-import, no-absolute-import, wrong-import-position,import-outside-toplevel + +AAA = 24 +try: + import collections +except ImportError: + collections = None + +aaa = 42 # [invalid-name] +try: + import time +except ValueError: + time = None # [invalid-name] + +try: + from sys import argv, executable as python +except ImportError: + argv = 42 + python = 24 + +def test(): + """ Shouldn't emit an invalid-name here. """ + try: + import re + except ImportError: + re = None + return re + +def a(): # [invalid-name] + """yo""" + + +def _generate_cmdline_tests(): + TestCase = collections.namedtuple('TestCase', 'cmd, valid') + valid = ['leave-mode', 'hint all'] + # Valid command only -> valid + for item in valid: + yield TestCase(''.join(item), True) + + +# We should emit for the loop variable. +for i in range(10): + Foocapfor = 2 # [invalid-name] diff --git a/tests/functional/i/invalid/invalid_name.txt b/tests/functional/i/invalid/invalid_name.txt new file mode 100644 index 000000000..749980e13 --- /dev/null +++ b/tests/functional/i/invalid/invalid_name.txt @@ -0,0 +1,4 @@ +invalid-name:10:0::"Constant name ""aaa"" doesn't conform to UPPER_CASE naming style" +invalid-name:14:4::"Constant name ""time"" doesn't conform to UPPER_CASE naming style" +invalid-name:30:0:a:"Function name ""a"" doesn't conform to snake_case naming style" +invalid-name:44:4::"Constant name ""Foocapfor"" doesn't conform to UPPER_CASE naming style" diff --git a/tests/functional/i/invalid/invalid_overridden_method.py b/tests/functional/i/invalid/invalid_overridden_method.py new file mode 100644 index 000000000..213c05b7d --- /dev/null +++ b/tests/functional/i/invalid/invalid_overridden_method.py @@ -0,0 +1,77 @@ +# pylint: disable=missing-docstring, too-few-public-methods +import abc + + +class SuperClass(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def prop(self): + pass + + @abc.abstractmethod + async def async_method(self): + pass + + @abc.abstractmethod + def method_a(self): + pass + + @abc.abstractmethod + def method_b(self): + pass + +class ValidDerived(SuperClass): + @property + def prop(self): + return None + + async def async_method(self): + return None + + def method_a(self): + pass + + def method_b(self): + pass + +class InvalidDerived(SuperClass): + def prop(self): # [invalid-overridden-method] + return None + + def async_method(self): # [invalid-overridden-method] + return None + + @property + def method_a(self): # [invalid-overridden-method] + return None + + async def method_b(self): # [invalid-overridden-method] + return None + +class Property: + + @property + def close(self): + pass + + +class PropertySetter(Property): + + @property + def close(self): + pass + + @close.setter + def close(self, attr): + return attr + + @close.deleter + def close(self): + return None + + +class AbstractProperty: + + @abc.abstractproperty + def prop(self): + return diff --git a/tests/functional/i/invalid/invalid_overridden_method.txt b/tests/functional/i/invalid/invalid_overridden_method.txt new file mode 100644 index 000000000..a44daa752 --- /dev/null +++ b/tests/functional/i/invalid/invalid_overridden_method.txt @@ -0,0 +1,4 @@ +invalid-overridden-method:38:4:InvalidDerived.prop:Method 'prop' was expected to be 'property', found it instead as 'method' +invalid-overridden-method:41:4:InvalidDerived.async_method:Method 'async_method' was expected to be 'async', found it instead as 'non-async' +invalid-overridden-method:45:4:InvalidDerived.method_a:Method 'method_a' was expected to be 'method', found it instead as 'property' +invalid-overridden-method:48:4:InvalidDerived.method_b:Method 'method_b' was expected to be 'non-async', found it instead as 'async' diff --git a/tests/functional/i/invalid/invalid_repr_returned.py b/tests/functional/i/invalid/invalid_repr_returned.py new file mode 100644 index 000000000..3bbd7828d --- /dev/null +++ b/tests/functional/i/invalid/invalid_repr_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __repr__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodRepr(object): + """__repr__ returns """ + + def __repr__(self): + return "some repr" + + +class SecondGoodRepr(object): + """__repr__ returns """ + + def __repr__(self): + return str(123) + + +class ReprMetaclass(type): + def __repr__(cls): + return "some repr" + + +@six.add_metaclass(ReprMetaclass) +class ThirdGoodRepr(object): + """Repr through the metaclass.""" + + +class FirstBadRepr(object): + """ __repr__ returns bytes """ + + def __repr__(self): # [invalid-repr-returned] + return b"123" + + +class SecondBadRepr(object): + """ __repr__ returns int """ + + def __repr__(self): # [invalid-repr-returned] + return 1 + + +class ThirdBadRepr(object): + """ __repr__ returns node which does not have 'value' in AST """ + + def __repr__(self): # [invalid-repr-returned] + return lambda: "some repr" + + +class AmbiguousRepr(object): + """ Uninferable return value """ + + __repr__ = lambda self: Missing + + +class AnotherAmbiguousRepr(object): + """Potential uninferable return value""" + + def __repr__(self): + return str(Missing) diff --git a/tests/functional/i/invalid/invalid_repr_returned.txt b/tests/functional/i/invalid/invalid_repr_returned.txt new file mode 100644 index 000000000..4be375f1f --- /dev/null +++ b/tests/functional/i/invalid/invalid_repr_returned.txt @@ -0,0 +1,3 @@ +invalid-repr-returned:36:4:FirstBadRepr.__repr__:__repr__ does not return str +invalid-repr-returned:43:4:SecondBadRepr.__repr__:__repr__ does not return str +invalid-repr-returned:50:4:ThirdBadRepr.__repr__:__repr__ does not return str diff --git a/tests/functional/i/invalid/invalid_sequence_index.py b/tests/functional/i/invalid/invalid_sequence_index.py new file mode 100644 index 000000000..d11155c02 --- /dev/null +++ b/tests/functional/i/invalid/invalid_sequence_index.py @@ -0,0 +1,242 @@ +"""Errors for invalid sequence indices""" +# pylint: disable=too-few-public-methods, no-self-use, import-error, missing-docstring, useless-object-inheritance, unnecessary-pass +import six +from unknown import Unknown + +TESTLIST = [1, 2, 3] +TESTTUPLE = (1, 2, 3) +TESTSTR = '123' + +# getitem tests with bad indices +def function1(): + """list index is a function""" + return TESTLIST[id] # [invalid-sequence-index] + +def function2(): + """list index is None""" + return TESTLIST[None] # [invalid-sequence-index] + +def function3(): + """list index is a float expression""" + return TESTLIST[float(0)] # [invalid-sequence-index] + +def function4(): + """list index is a str constant""" + return TESTLIST['0'] # [invalid-sequence-index] + +def function5(): + """list index does not implement __index__""" + class NonIndexType(object): + """Class without __index__ method""" + pass + + return TESTLIST[NonIndexType()] # [invalid-sequence-index] + +def function6(): + """Tuple index is None""" + return TESTTUPLE[None] # [invalid-sequence-index] + +def function7(): + """String index is None""" + return TESTSTR[None] # [invalid-sequence-index] + +def function8(): + """Index of subclass of tuple is None""" + class TupleTest(tuple): + """Subclass of tuple""" + pass + return TupleTest()[None] # [invalid-sequence-index] + +# getitem tests with good indices +def function9(): + """list index is an int constant""" + return TESTLIST[0] # no error + +def function10(): + """list index is an integer expression""" + return TESTLIST[int(0.0)] # no error + +def function11(): + """list index is a slice""" + return TESTLIST[slice(1, 2, 3)] # no error + +def function12(): + """list index implements __index__""" + class IndexType(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + return TESTLIST[IndexType()] # no error + +def function13(): + """list index implements __index__ in a superclass""" + class IndexType(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + class IndexSubType(IndexType): + """Class with __index__ in parent""" + pass + + return TESTLIST[IndexSubType()] # no error + +def function14(): + """Tuple index is an int constant""" + return TESTTUPLE[0] + +def function15(): + """String index is an int constant""" + return TESTSTR[0] + +def function16(): + """Index of subclass of tuple is an int constant""" + class TupleTest(tuple): + """Subclass of tuple""" + pass + return TupleTest()[0] # no error + +def function17(): + """Index of subclass of tuple with custom __getitem__ is None""" + class TupleTest(tuple): + """Subclass of tuple with custom __getitem__""" + def __getitem__(self, index): + """Allow non-integer indices""" + return 0 + return TupleTest()[None] # no error + +def function18(): + """Index of subclass of tuple with __getitem__ in superclass is None""" + class TupleTest(tuple): + """Subclass of tuple with custom __getitem__""" + def __getitem__(self, index): + """Allow non-integer indices""" + return 0 + + class SubTupleTest(TupleTest): + """Subclass of a subclass of tuple""" + pass + + return SubTupleTest()[None] # no error + +# Test with set and delete statements +def function19(): + """Set with None and integer indices""" + TESTLIST[None] = 0 # [invalid-sequence-index] + TESTLIST[0] = 0 # no error + +def function20(): + """Delete with None and integer indicies""" + del TESTLIST[None] # [invalid-sequence-index] + del TESTLIST[0] # no error + +def function21(): + """Set and delete on a subclass of list""" + class ListTest(list): + """Inherit all list get/set/del handlers""" + pass + test = ListTest() + + # Set and delete with invalid indices + test[None] = 0 # [invalid-sequence-index] + del test[None] # [invalid-sequence-index] + + # Set and delete with valid indices + test[0] = 0 # no error + del test[0] # no error + +def function22(): + """Get, set, and delete on a subclass of list that overrides __setitem__""" + class ListTest(list): + """Override setitem but not get or del""" + def __setitem__(self, key, value): + pass + test = ListTest() + + # failure on the getitem with None + test[None][0] = 0 # [invalid-sequence-index] + # failure on the getitem with None + del test[None] # [invalid-sequence-index] + + test[0][0] = 0 # getitem with int and setitem with int, no error + test[None] = 0 # setitem overridden, no error + test[0] = 0 # setitem with int, no error + del test[0] # delitem with int, no error + +def function23(): + """Get, set, and delete on a subclass of list that overrides __delitem__""" + class ListTest(list): + """Override delitem but not get or set""" + def __delitem__(self, key): + pass + test = ListTest() + + # failure on the getitem with None + test[None][0] = 0 # [invalid-sequence-index] + # setitem with invalid index + test[None] = 0 # [invalid-sequence-index] + + test[0][0] = 0 # getitem with int and setitem with int, no error + test[0] = 0 # setitem with int, no error + del test[None] # delitem overridden, no error + del test[0] # delitem with int, no error + +def function24(): + """Get, set, and delete on a subclass of list that overrides __getitem__""" + class ListTest(list): + """Override gelitem but not del or set""" + def __getitem__(self, key): + pass + test = ListTest() + + # setitem with invalid index + test[None] = 0 # [invalid-sequence-index] + # delitem with invalid index + del test[None] # [invalid-sequence-index] + + test[None][0] = 0 # getitem overridden, no error + test[0][0] = 0 # getitem with int and setitem with int, no error + test[0] = 0 # setitem with int, no error + del test[0] # delitem with int, no error + +# Teest ExtSlice usage +def function25(): + """Extended slice used with a list""" + return TESTLIST[..., 0] # [invalid-sequence-index] + +def function26(): + """Extended slice used with an object that implements __getitem__""" + class ExtSliceTest(object): + """Permit extslice syntax by implementing __getitem__""" + def __getitem__(self, index): + return 0 + return ExtSliceTest()[..., 0] # no error + +def function27(): + """Don't warn in the case where the indexed object has unknown base classes.""" + class UnknownBase(Unknown): + pass + slices = UnknownBase["aaaa"] + UnknownBase()[object] + ext_slices = UnknownBase[..., 0] + UnknownBase()[..., 0] + return slices, ext_slices + + +def function28(): + """Don't emit for classes with the right implementation.""" + + class Meta(type): + def __getitem__(cls, arg): + return 24 + + @six.add_metaclass(Meta) + class Works(object): + pass + + @six.add_metaclass(Meta) + class Error(list): + pass + + return Works['hello'] + Error['hello'] diff --git a/tests/functional/i/invalid/invalid_sequence_index.txt b/tests/functional/i/invalid/invalid_sequence_index.txt new file mode 100644 index 000000000..baf1b2167 --- /dev/null +++ b/tests/functional/i/invalid/invalid_sequence_index.txt @@ -0,0 +1,19 @@ +invalid-sequence-index:13:11:function1:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:17:11:function2:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:21:11:function3:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:25:11:function4:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:33:11:function5:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:37:11:function6:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:41:11:function7:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:48:11:function8:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:128:4:function19:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:133:8:function20:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:144:4:function21:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:145:8:function21:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:160:4:function22:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:162:8:function22:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:178:4:function23:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:180:4:function23:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:196:4:function24:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:198:8:function24:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:208:11:function25:Sequence index is not an int, slice, or instance with __index__ diff --git a/tests/functional/i/invalid/invalid_slice_index.py b/tests/functional/i/invalid/invalid_slice_index.py new file mode 100644 index 000000000..1eb2fda9c --- /dev/null +++ b/tests/functional/i/invalid/invalid_slice_index.py @@ -0,0 +1,71 @@ +"""Errors for invalid slice indices""" +# pylint: disable=too-few-public-methods, no-self-use,missing-docstring,expression-not-assigned, useless-object-inheritance, unnecessary-pass + + +TESTLIST = [1, 2, 3] + +# Invalid indices +def function1(): + """functions used as indices""" + return TESTLIST[id:id:] # [invalid-slice-index,invalid-slice-index] + +def function2(): + """strings used as indices""" + return TESTLIST['0':'1':] # [invalid-slice-index,invalid-slice-index] + +def function3(): + """class without __index__ used as index""" + + class NoIndexTest(object): + """Class with no __index__ method""" + pass + + return TESTLIST[NoIndexTest()::] # [invalid-slice-index] + +# Valid indices +def function4(): + """integers used as indices""" + return TESTLIST[0:0:0] # no error + +def function5(): + """None used as indices""" + return TESTLIST[None:None:None] # no error + +def function6(): + """class with __index__ used as index""" + class IndexTest(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + return TESTLIST[IndexTest():None:None] # no error + +def function7(): + """class with __index__ in superclass used as index""" + class IndexType(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + class IndexSubType(IndexType): + """Class with __index__ in parent""" + pass + + return TESTLIST[IndexSubType():None:None] # no error + +def function8(): + """slice object used as index""" + return TESTLIST[slice(1, 2, 3)] # no error + + +def function9(): + """Use a custom class that knows how to handle string slices""" + class StringSlice: + def __getitem__(self, item): + return item + + StringSlice()["a":"b":"c"] + StringSlice()["a":"b":"c", "a":"b"] + StringSlice()[slice("a", "b", "c")] diff --git a/tests/functional/i/invalid/invalid_slice_index.txt b/tests/functional/i/invalid/invalid_slice_index.txt new file mode 100644 index 000000000..e715138b4 --- /dev/null +++ b/tests/functional/i/invalid/invalid_slice_index.txt @@ -0,0 +1,5 @@ +invalid-slice-index:10:0:function1:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:10:0:function1:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:14:0:function2:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:14:0:function2:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:23:0:function3:Slice index is not an int, None, or instance with __index__ diff --git a/tests/functional/i/invalid/invalid_star_assignment_target.py b/tests/functional/i/invalid/invalid_star_assignment_target.py new file mode 100644 index 000000000..452f9a728 --- /dev/null +++ b/tests/functional/i/invalid/invalid_star_assignment_target.py @@ -0,0 +1,4 @@ +"""Test for *a = b """ + +*FIRST = [1, 2, 3] # [invalid-star-assignment-target] +(*FIRST, ) = [1, 2, 3] diff --git a/tests/functional/i/invalid/invalid_star_assignment_target.rc b/tests/functional/i/invalid/invalid_star_assignment_target.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/i/invalid/invalid_star_assignment_target.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/i/invalid/invalid_star_assignment_target.txt b/tests/functional/i/invalid/invalid_star_assignment_target.txt new file mode 100644 index 000000000..eb9f27c90 --- /dev/null +++ b/tests/functional/i/invalid/invalid_star_assignment_target.txt @@ -0,0 +1 @@ +invalid-star-assignment-target:3:0::Starred assignment target must be in a list or tuple diff --git a/tests/functional/i/invalid/invalid_str_returned.py b/tests/functional/i/invalid/invalid_str_returned.py new file mode 100644 index 000000000..00ef22046 --- /dev/null +++ b/tests/functional/i/invalid/invalid_str_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __str__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import six + +from missing import Missing + + +class FirstGoodStr(object): + """__str__ returns """ + + def __str__(self): + return "some str" + + +class SecondGoodStr(object): + """__str__ returns """ + + def __str__(self): + return str(123) + + +class StrMetaclass(type): + def __str__(cls): + return "some str" + + +@six.add_metaclass(StrMetaclass) +class ThirdGoodStr(object): + """Str through the metaclass.""" + + +class FirstBadStr(object): + """ __str__ returns bytes """ + + def __str__(self): # [invalid-str-returned] + return b"123" + + +class SecondBadStr(object): + """ __str__ returns int """ + + def __str__(self): # [invalid-str-returned] + return 1 + + +class ThirdBadStr(object): + """ __str__ returns node which does not have 'value' in AST """ + + def __str__(self): # [invalid-str-returned] + return lambda: "some str" + + +class AmbiguousStr(object): + """ Uninferable return value """ + + __str__ = lambda self: Missing + + +class AnotherAmbiguousStr(object): + """Potential uninferable return value""" + + def __str__(self): + return str(Missing) diff --git a/tests/functional/i/invalid/invalid_str_returned.txt b/tests/functional/i/invalid/invalid_str_returned.txt new file mode 100644 index 000000000..36b7ec57c --- /dev/null +++ b/tests/functional/i/invalid/invalid_str_returned.txt @@ -0,0 +1,3 @@ +invalid-str-returned:36:4:FirstBadStr.__str__:__str__ does not return str +invalid-str-returned:43:4:SecondBadStr.__str__:__str__ does not return str +invalid-str-returned:50:4:ThirdBadStr.__str__:__str__ does not return str diff --git a/tests/functional/i/invalid/invalid_unary_operand_type.py b/tests/functional/i/invalid/invalid_unary_operand_type.py new file mode 100644 index 000000000..f2a0124f6 --- /dev/null +++ b/tests/functional/i/invalid/invalid_unary_operand_type.py @@ -0,0 +1,51 @@ +"""Detect problems with invalid operands used on invalid objects.""" +# pylint: disable=missing-docstring,too-few-public-methods,invalid-name +# pylint: disable=unused-variable, useless-object-inheritance + +import collections + + +class Implemented(object): + def __invert__(self): + return 42 + def __pos__(self): + return 42 + def __neg__(self): + return 42 + + +def these_are_good(): + negative = -1 + negative1 = -1.0 + positive = +1 + positive2 = +1.0 + inverted = ~1 + not_int = not 1 + not_float = not 2.0 + not_string = not "" + not_list = not [] + not_dict = not {} + not_tuple = not (1, 2) + inverted_instance = ~Implemented() + positive_instance = +Implemented() + negative_instance = -Implemented() + not_instance = not Implemented() + + +def these_are_bad(): + invert_list = ~[] # [invalid-unary-operand-type] + invert_tuple = ~() # [invalid-unary-operand-type] + invert_dict = ~dict() # [invalid-unary-operand-type] + invert_dict_1 = ~{} # [invalid-unary-operand-type] + invert_set = ~set() # [invalid-unary-operand-type] + neg_set = -set() # [invalid-unary-operand-type] + neg_str = -"" # [invalid-unary-operand-type] + invert_str = ~"" # [invalid-unary-operand-type] + pos_str = +"" # [invalid-unary-operand-type] + class A(object): + pass + invert_func = ~(lambda: None) # [invalid-unary-operand-type] + invert_class = ~A # [invalid-unary-operand-type] + invert_instance = ~A() # [invalid-unary-operand-type] + invert_module = ~collections # [invalid-unary-operand-type] + invert_float = ~2.0 # [invalid-unary-operand-type] diff --git a/tests/functional/i/invalid/invalid_unary_operand_type.txt b/tests/functional/i/invalid/invalid_unary_operand_type.txt new file mode 100644 index 000000000..6a3dd591d --- /dev/null +++ b/tests/functional/i/invalid/invalid_unary_operand_type.txt @@ -0,0 +1,14 @@ +invalid-unary-operand-type:36:18:these_are_bad:"bad operand type for unary ~: list" +invalid-unary-operand-type:37:19:these_are_bad:"bad operand type for unary ~: tuple" +invalid-unary-operand-type:38:18:these_are_bad:"bad operand type for unary ~: dict" +invalid-unary-operand-type:39:20:these_are_bad:"bad operand type for unary ~: dict" +invalid-unary-operand-type:40:17:these_are_bad:"bad operand type for unary ~: set" +invalid-unary-operand-type:41:14:these_are_bad:"bad operand type for unary -: set" +invalid-unary-operand-type:42:14:these_are_bad:"bad operand type for unary -: str" +invalid-unary-operand-type:43:17:these_are_bad:"bad operand type for unary ~: str" +invalid-unary-operand-type:44:14:these_are_bad:"bad operand type for unary +: str" +invalid-unary-operand-type:47:18:these_are_bad:"bad operand type for unary ~: " +invalid-unary-operand-type:48:19:these_are_bad:"bad operand type for unary ~: A" +invalid-unary-operand-type:49:22:these_are_bad:"bad operand type for unary ~: A" +invalid-unary-operand-type:50:20:these_are_bad:"bad operand type for unary ~: collections" +invalid-unary-operand-type:51:19:these_are_bad:"bad operand type for unary ~: float" diff --git a/tests/functional/i/invalid_all_object.py b/tests/functional/i/invalid_all_object.py deleted file mode 100644 index 4468c987b..000000000 --- a/tests/functional/i/invalid_all_object.py +++ /dev/null @@ -1,6 +0,0 @@ -# pylint: disable=missing-docstring -__all__ = ( - 1, # [invalid-all-object] - lambda: None, # [invalid-all-object] - None, # [invalid-all-object] -) diff --git a/tests/functional/i/invalid_all_object.txt b/tests/functional/i/invalid_all_object.txt deleted file mode 100644 index ebcdb8d35..000000000 --- a/tests/functional/i/invalid_all_object.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-all-object:3:4::Invalid object '1' in __all__, must contain only strings -invalid-all-object:4:4::"Invalid object 'lambda: None' in __all__, must contain only strings" -invalid-all-object:5:4::Invalid object 'None' in __all__, must contain only strings diff --git a/tests/functional/i/invalid_bool_returned.py b/tests/functional/i/invalid_bool_returned.py deleted file mode 100644 index 0e68ed263..000000000 --- a/tests/functional/i/invalid_bool_returned.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Check invalid value returned by __bool__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodBool(object): - """__bool__ returns """ - - def __bool__(self): - return True - - -class SecondGoodBool(object): - """__bool__ returns """ - - def __bool__(self): - return bool(0) - - -class BoolMetaclass(type): - def __bool__(cls): - return True - - -@six.add_metaclass(BoolMetaclass) -class ThirdGoodBool(object): - """Bool through the metaclass.""" - - -class FirstBadBool(object): - """ __bool__ returns an integer """ - - def __bool__(self): # [invalid-bool-returned] - return 1 - - -class SecondBadBool(object): - """ __bool__ returns str """ - - def __bool__(self): # [invalid-bool-returned] - return "True" - - -class ThirdBadBool(object): - """ __bool__ returns node which does not have 'value' in AST """ - - def __bool__(self): # [invalid-bool-returned] - return lambda: 3 - - -class AmbigousBool(object): - """ Uninferable return value """ - __bool__ = lambda self: Missing - - -class AnotherAmbiguousBool(object): - """Potential uninferable return value""" - def __bool__(self): - return bool(Missing) diff --git a/tests/functional/i/invalid_bool_returned.txt b/tests/functional/i/invalid_bool_returned.txt deleted file mode 100644 index 9af5b182c..000000000 --- a/tests/functional/i/invalid_bool_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-bool-returned:36:4:FirstBadBool.__bool__:__bool__ does not return bool -invalid-bool-returned:43:4:SecondBadBool.__bool__:__bool__ does not return bool -invalid-bool-returned:50:4:ThirdBadBool.__bool__:__bool__ does not return bool diff --git a/tests/functional/i/invalid_bytes_returned.py b/tests/functional/i/invalid_bytes_returned.py deleted file mode 100644 index 703fea278..000000000 --- a/tests/functional/i/invalid_bytes_returned.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Check invalid value returned by __bytes__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodBytes(object): - """__bytes__ returns """ - - def __bytes__(self): - return b"some bytes" - - -class SecondGoodBytes(object): - """__bytes__ returns """ - - def __bytes__(self): - return bytes("123", "ascii") - - -class BytesMetaclass(type): - def __bytes__(cls): - return b"some bytes" - - -@six.add_metaclass(BytesMetaclass) -class ThirdGoodBytes(object): - """Bytes through the metaclass.""" - - -class FirstBadBytes(object): - """ __bytes__ returns bytes """ - - def __bytes__(self): # [invalid-bytes-returned] - return "123" - - -class SecondBadBytes(object): - """ __bytes__ returns int """ - - def __bytes__(self): # [invalid-bytes-returned] - return 1 - - -class ThirdBadBytes(object): - """ __bytes__ returns node which does not have 'value' in AST """ - - def __bytes__(self): # [invalid-bytes-returned] - return lambda: b"some bytes" - - -class AmbiguousBytes(object): - """ Uninferable return value """ - - __bytes__ = lambda self: Missing - - -class AnotherAmbiguousBytes(object): - """Potential uninferable return value""" - - def __bytes__(self): - return bytes(Missing) diff --git a/tests/functional/i/invalid_bytes_returned.txt b/tests/functional/i/invalid_bytes_returned.txt deleted file mode 100644 index 63440cbbc..000000000 --- a/tests/functional/i/invalid_bytes_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-bytes-returned:36:4:FirstBadBytes.__bytes__:__bytes__ does not return bytes -invalid-bytes-returned:43:4:SecondBadBytes.__bytes__:__bytes__ does not return bytes -invalid-bytes-returned:50:4:ThirdBadBytes.__bytes__:__bytes__ does not return bytes diff --git a/tests/functional/i/invalid_envvar_value.py b/tests/functional/i/invalid_envvar_value.py deleted file mode 100644 index 3c1a8882b..000000000 --- a/tests/functional/i/invalid_envvar_value.py +++ /dev/null @@ -1,84 +0,0 @@ -# pylint: disable=useless-return,missing-docstring -from os import getenv - - -def function_returning_list(): - return [] - -def function_returning_none(): - return None - -def function_returning_string(): - return "Result" - -def function_returning_bytes(): - return b"Result" - -def deep_function_returning_string(): - return function_returning_string() - -def deep_function_returning_bytes(): - return function_returning_bytes() - - -# --------------------------------------------------------------------------- # -# Testing getenv # -# --------------------------------------------------------------------------- # - -getenv() # pylint: disable=no-value-for-parameter - -getenv(b"TEST") # [invalid-envvar-value] -getenv("TEST") -getenv(None) # [invalid-envvar-value] -getenv(["Crap"]) # [invalid-envvar-value] -getenv(function_returning_bytes()) # [invalid-envvar-value] -getenv(deep_function_returning_bytes()) # [invalid-envvar-value] -getenv(function_returning_list()) # [invalid-envvar-value] -getenv(function_returning_none()) # [invalid-envvar-value] -getenv(function_returning_string()) -getenv(deep_function_returning_string()) - -getenv(b"TEST", "default") # [invalid-envvar-value] -getenv("TEST", "default") -getenv(None, "default") # [invalid-envvar-value] -getenv(["Crap"], "default") # [invalid-envvar-value] -getenv(function_returning_bytes(), "default") # [invalid-envvar-value] -getenv(function_returning_list(), "default") # [invalid-envvar-value] -getenv(function_returning_none(), "default") # [invalid-envvar-value] -getenv(function_returning_string(), "default") - -getenv(key=b"TEST") # [invalid-envvar-value] -getenv(key="TEST") -getenv(key=None) # [invalid-envvar-value] -getenv(key=["Crap"]) # [invalid-envvar-value] -getenv(key=function_returning_bytes()) # [invalid-envvar-value] -getenv(key=function_returning_list()) # [invalid-envvar-value] -getenv(key=function_returning_none()) # [invalid-envvar-value] -getenv(key=function_returning_string()) - -getenv('TEST', "value") -getenv('TEST', []) # [invalid-envvar-default] -getenv('TEST', None) -getenv('TEST', b"123") # [invalid-envvar-default] -getenv('TEST', function_returning_list()) # [invalid-envvar-default] -getenv('TEST', function_returning_none()) -getenv('TEST', function_returning_string()) -getenv('TEST', function_returning_bytes()) # [invalid-envvar-default] - -getenv('TEST', default="value") -getenv('TEST', default=[]) # [invalid-envvar-default] -getenv('TEST', default=None) -getenv('TEST', default=b"123") # [invalid-envvar-default] -getenv('TEST', default=function_returning_list()) # [invalid-envvar-default] -getenv('TEST', default=function_returning_none()) -getenv('TEST', default=function_returning_string()) -getenv('TEST', default=function_returning_bytes()) # [invalid-envvar-default] - -getenv(key='TEST') -getenv(key='TEST', default="value") -getenv(key='TEST', default=b"value") # [invalid-envvar-default] -getenv(key='TEST', default=["Crap"]) # [invalid-envvar-default] -getenv(key='TEST', default=function_returning_list()) # [invalid-envvar-default] -getenv(key='TEST', default=function_returning_none()) -getenv(key='TEST', default=function_returning_string()) -getenv(key='TEST', default=function_returning_bytes()) # [invalid-envvar-default] diff --git a/tests/functional/i/invalid_envvar_value.txt b/tests/functional/i/invalid_envvar_value.txt deleted file mode 100644 index cec352b61..000000000 --- a/tests/functional/i/invalid_envvar_value.txt +++ /dev/null @@ -1,31 +0,0 @@ -invalid-envvar-value:30:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:32:0::os.getenv does not support builtins.NoneType type argument -invalid-envvar-value:33:0::os.getenv does not support builtins.list type argument -invalid-envvar-value:34:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:35:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:36:0::os.getenv does not support builtins.list type argument -invalid-envvar-value:37:0::os.getenv does not support builtins.NoneType type argument -invalid-envvar-value:41:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:43:0::os.getenv does not support builtins.NoneType type argument -invalid-envvar-value:44:0::os.getenv does not support builtins.list type argument -invalid-envvar-value:45:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:46:0::os.getenv does not support builtins.list type argument -invalid-envvar-value:47:0::os.getenv does not support builtins.NoneType type argument -invalid-envvar-value:50:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:52:0::os.getenv does not support builtins.NoneType type argument -invalid-envvar-value:53:0::os.getenv does not support builtins.list type argument -invalid-envvar-value:54:0::os.getenv does not support builtins.bytes type argument -invalid-envvar-value:55:0::os.getenv does not support builtins.list type argument -invalid-envvar-value:56:0::os.getenv does not support builtins.NoneType type argument -invalid-envvar-default:60:0::os.getenv default type is builtins.list. Expected str or None. -invalid-envvar-default:62:0::os.getenv default type is builtins.bytes. Expected str or None. -invalid-envvar-default:63:0::os.getenv default type is builtins.list. Expected str or None. -invalid-envvar-default:66:0::os.getenv default type is builtins.bytes. Expected str or None. -invalid-envvar-default:69:0::os.getenv default type is builtins.list. Expected str or None. -invalid-envvar-default:71:0::os.getenv default type is builtins.bytes. Expected str or None. -invalid-envvar-default:72:0::os.getenv default type is builtins.list. Expected str or None. -invalid-envvar-default:75:0::os.getenv default type is builtins.bytes. Expected str or None. -invalid-envvar-default:79:0::os.getenv default type is builtins.bytes. Expected str or None. -invalid-envvar-default:80:0::os.getenv default type is builtins.list. Expected str or None. -invalid-envvar-default:81:0::os.getenv default type is builtins.list. Expected str or None. -invalid-envvar-default:84:0::os.getenv default type is builtins.bytes. Expected str or None. diff --git a/tests/functional/i/invalid_exceptions_caught.py b/tests/functional/i/invalid_exceptions_caught.py deleted file mode 100644 index 252643446..000000000 --- a/tests/functional/i/invalid_exceptions_caught.py +++ /dev/null @@ -1,135 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance -# pylint: disable=too-many-ancestors, no-absolute-import, import-error, multiple-imports,wrong-import-position -from __future__ import print_function - -import socket, binascii, abc, six - -class MyException(object): - """Custom 'exception'.""" - -class MySecondException(object): - """Custom 'exception'.""" - -class MyGoodException(Exception): - """Custom exception.""" - -class MySecondGoodException(MyGoodException): - """Custom exception.""" - -class SkipException(socket.error): - """Not an exception for Python 2, but one in 3.""" - -class SecondSkipException(SkipException): - """Also a good exception.""" - -try: - 1 + 1 -except MyException: # [catching-non-exception] - print("caught") - -try: - 1 + 2 -# +1:[catching-non-exception,catching-non-exception] -except (MyException, MySecondException): - print("caught") - -try: - 1 + 3 -except MyGoodException: - print("caught") - -try: - 1 + 3 -except (MyGoodException, MySecondGoodException): - print("caught") - -try: - 1 + 3 -except (SkipException, SecondSkipException): - print("caught") - -try: - 1 + 42 -# +1:[catching-non-exception,catching-non-exception] -except (None, list()): - print("caught") - -try: - 1 + 24 -except None: # [catching-non-exception] - print("caught") - -EXCEPTION = None -EXCEPTION = ZeroDivisionError -try: - 1 + 46 -except EXCEPTION: - print("caught") - -try: - 1 + 42 -# +1:[catching-non-exception,catching-non-exception,catching-non-exception] -except (list([4, 5, 6]), None, ZeroDivisionError, 4): - print("caught") - -EXCEPTION_TUPLE = (ZeroDivisionError, OSError) -NON_EXCEPTION_TUPLE = (ZeroDivisionError, OSError, 4) - -try: - 1 + 42 -except EXCEPTION_TUPLE: - print("caught") - -try: - 1 + 42 -except NON_EXCEPTION_TUPLE: # [catching-non-exception] - print("caught") - -from missing_import import UnknownError -UNKNOWN_COMPONENTS = (ZeroDivisionError, UnknownError) - -try: - 1 + 42 -except UNKNOWN_COMPONENTS: - print("caught") - -try: - 1 + 42 -except binascii.Error: - print('builtin and detected') - -try: - 1 + 45 -except object: # [catching-non-exception] - print('caught') - -try: - 1 + 42 -except range: # [catching-non-exception] - print('caught') - - -class HasErrorInMRO(six.with_metaclass(abc.ABCMeta, Exception)): - pass - - -class Second(HasErrorInMRO): - pass - - -try: - raise Second -except Second: - pass - - -class SomeBase(UnknownError): - pass - - -EXCEPTIONS = (SomeBase, ValueError) - -try: - raise ValueError -except EXCEPTIONS: - pass diff --git a/tests/functional/i/invalid_exceptions_caught.rc b/tests/functional/i/invalid_exceptions_caught.rc deleted file mode 100644 index 6a8ee96ca..000000000 --- a/tests/functional/i/invalid_exceptions_caught.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -requires = six diff --git a/tests/functional/i/invalid_exceptions_caught.txt b/tests/functional/i/invalid_exceptions_caught.txt deleted file mode 100644 index 4beed611c..000000000 --- a/tests/functional/i/invalid_exceptions_caught.txt +++ /dev/null @@ -1,12 +0,0 @@ -catching-non-exception:27:7::"Catching an exception which doesn't inherit from Exception: MyException" -catching-non-exception:33:7::"Catching an exception which doesn't inherit from Exception: MyException" -catching-non-exception:33:7::"Catching an exception which doesn't inherit from Exception: MySecondException" -catching-non-exception:54:7::"Catching an exception which doesn't inherit from Exception: None" -catching-non-exception:54:7::"Catching an exception which doesn't inherit from Exception: list()" -catching-non-exception:59:7::"Catching an exception which doesn't inherit from Exception: None" -catching-non-exception:72:7::"Catching an exception which doesn't inherit from Exception: 4" -catching-non-exception:72:7::"Catching an exception which doesn't inherit from Exception: None" -catching-non-exception:72:7::"Catching an exception which doesn't inherit from Exception: list([4, 5, 6])" -catching-non-exception:85:7::"Catching an exception which doesn't inherit from Exception: NON_EXCEPTION_TUPLE" -catching-non-exception:103:7::"Catching an exception which doesn't inherit from Exception: object" -catching-non-exception:108:7::"Catching an exception which doesn't inherit from Exception: range" diff --git a/tests/functional/i/invalid_exceptions_raised.py b/tests/functional/i/invalid_exceptions_raised.py deleted file mode 100644 index 34f740de4..000000000 --- a/tests/functional/i/invalid_exceptions_raised.py +++ /dev/null @@ -1,105 +0,0 @@ -# pylint:disable=too-few-public-methods,no-init,import-error,missing-docstring, not-callable, useless-object-inheritance,import-outside-toplevel -"""test pb with exceptions and old/new style classes""" - - -class ValidException(Exception): - """Valid Exception.""" - -class OldStyleClass: - """Not an exception.""" - -class NewStyleClass(object): - """Not an exception.""" - - -def good_case(): - """raise""" - raise ValidException('hop') - -def good_case1(): - """zlib.error is defined in C module.""" - import zlib - raise zlib.error(4) - -def good_case2(): - """decimal.DivisionByZero is defined in C on Python 3.""" - import decimal - raise decimal.DivisionByZero(4) - -def good_case3(): - """io.BlockingIOError is defined in C.""" - import io - raise io.BlockingIOError - -def bad_case0(): - """raise""" - # +2:<3.0:[nonstandard-exception] - # +1:>=3.0:[raising-non-exception] - raise OldStyleClass('hop') - -def bad_case1(): - """raise""" - raise NewStyleClass() # [raising-non-exception] - -def bad_case2(): - """raise""" - # +2:<3.0:[nonstandard-exception] - # +1:>=3.0:[raising-non-exception] - raise OldStyleClass('hop') - -def bad_case3(): - """raise""" - raise NewStyleClass # [raising-non-exception] - -def bad_case4(): - """raise""" - raise NotImplemented('hop') # [notimplemented-raised] - -def bad_case5(): - """raise""" - raise 1 # [raising-bad-type] - -def bad_case6(): - """raise""" - raise None # [raising-bad-type] - -def bad_case7(): - """raise list""" - raise list # [raising-non-exception] - -def bad_case8(): - """raise tuple""" - raise tuple # [raising-non-exception] - -def bad_case9(): - """raise dict""" - raise dict # [raising-non-exception] - -def unknown_bases(): - """Don't emit when we don't know the bases.""" - from lala import bala # pylint: disable=import-outside-toplevel - class MyException(bala): - pass - raise MyException - - -def exception_instance_regression(): - """Exceptions have a particular class type""" - try: - int("9a") - except ValueError as exc: - raise exc - - -def reusing_same_name_picks_the_latest_raised_value(): - class Error(Exception): - """some error""" - - exceptions = tuple([ValueError, TypeError]) - try: - raise ValueError - except exceptions as exc: # pylint: disable=catching-non-exception - # https://github.com/PyCQA/pylint/issues/1756 - exc = Error(exc) - if exc: - raise exc diff --git a/tests/functional/i/invalid_exceptions_raised.txt b/tests/functional/i/invalid_exceptions_raised.txt deleted file mode 100644 index 7985a71bf..000000000 --- a/tests/functional/i/invalid_exceptions_raised.txt +++ /dev/null @@ -1,10 +0,0 @@ -raising-non-exception:38:4:bad_case0:Raising a new style class which doesn't inherit from BaseException -raising-non-exception:42:4:bad_case1:Raising a new style class which doesn't inherit from BaseException -raising-non-exception:48:4:bad_case2:Raising a new style class which doesn't inherit from BaseException -raising-non-exception:52:4:bad_case3:Raising a new style class which doesn't inherit from BaseException -notimplemented-raised:56:4:bad_case4:NotImplemented raised - should raise NotImplementedError -raising-bad-type:60:4:bad_case5:Raising int while only classes or instances are allowed -raising-bad-type:64:4:bad_case6:Raising NoneType while only classes or instances are allowed -raising-non-exception:68:4:bad_case7:Raising a new style class which doesn't inherit from BaseException -raising-non-exception:72:4:bad_case8:Raising a new style class which doesn't inherit from BaseException -raising-non-exception:76:4:bad_case9:Raising a new style class which doesn't inherit from BaseException diff --git a/tests/functional/i/invalid_format_returned.py b/tests/functional/i/invalid_format_returned.py deleted file mode 100644 index ec428b4b3..000000000 --- a/tests/functional/i/invalid_format_returned.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Check invalid value returned by __format__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodFormat(object): - """__format__ returns """ - - def __format__(self, format_spec): - return "some format" - - -class SecondGoodFormat(object): - """__format__ returns """ - - def __format__(self, format_spec): - return str(123) - - -class FormatMetaclass(type): - def __format__(cls, format_spec): - return "some format" - - -@six.add_metaclass(FormatMetaclass) -class ThirdGoodFormat(object): - """Format through the metaclass.""" - - -class FirstBadFormat(object): - """ __format__ returns bytes """ - - def __format__(self, format_spec): # [invalid-format-returned] - return b"123" - - -class SecondBadFormat(object): - """ __format__ returns int """ - - def __format__(self, format_spec): # [invalid-format-returned] - return 1 - - -class ThirdBadFormat(object): - """ __format__ returns node which does not have 'value' in AST """ - - def __format__(self, format_spec): # [invalid-format-returned] - return lambda: "some format" - - -class AmbiguousFormat(object): - """ Uninferable return value """ - - __format__ = lambda self, format_spec: Missing - - -class AnotherAmbiguousFormat(object): - """Potential uninferable return value""" - - def __format__(self, format_spec): - return str(Missing) diff --git a/tests/functional/i/invalid_format_returned.txt b/tests/functional/i/invalid_format_returned.txt deleted file mode 100644 index 3a3e1ae67..000000000 --- a/tests/functional/i/invalid_format_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-format-returned:36:4:FirstBadFormat.__format__:__format__ does not return str -invalid-format-returned:43:4:SecondBadFormat.__format__:__format__ does not return str -invalid-format-returned:50:4:ThirdBadFormat.__format__:__format__ does not return str diff --git a/tests/functional/i/invalid_getnewargs_ex_returned.py b/tests/functional/i/invalid_getnewargs_ex_returned.py deleted file mode 100644 index e37895096..000000000 --- a/tests/functional/i/invalid_getnewargs_ex_returned.py +++ /dev/null @@ -1,85 +0,0 @@ -"""Check invalid value returned by __getnewargs_ex__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodGetNewArgsEx(object): - """__getnewargs_ex__ returns """ - - def __getnewargs_ex__(self): - return ((1,), {"2": "2"}) - - -class SecondGoodGetNewArgsEx(object): - """__getnewargs_ex__ returns """ - - def __getnewargs_ex__(self): - return (tuple(), dict()) - - -class GetNewArgsExMetaclass(type): - def __getnewargs_ex__(cls): - return ((1,), {"2": "2"}) - - -@six.add_metaclass(GetNewArgsExMetaclass) -class ThirdGoodGetNewArgsEx(object): - """GetNewArgsEx through the metaclass.""" - - -class FirstBadGetNewArgsEx(object): - """ __getnewargs_ex__ returns an integer """ - - def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] - return 1 - - -class SecondBadGetNewArgsEx(object): - """ __getnewargs_ex__ returns tuple with incorrect arg length""" - - def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] - return (tuple(1), dict(x="y"), 1) - - -class ThirdBadGetNewArgsEx(object): - """ __getnewargs_ex__ returns tuple with wrong type for first arg """ - - def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] - return (dict(x="y"), dict(x="y")) - - -class FourthBadGetNewArgsEx(object): - """ __getnewargs_ex__ returns tuple with wrong type for second arg """ - - def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] - return ((1, ), (1, )) - - -class FifthBadGetNewArgsEx(object): - """ __getnewargs_ex__ returns tuple with wrong type for both args """ - - def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] - return ({'x': 'y'}, (2,)) - - -class SixthBadGetNewArgsEx(object): - """ __getnewargs_ex__ returns node which does not have 'value' in AST """ - - def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] - return lambda: (1, 2) - - -class AmbigousGetNewArgsEx(object): - """ Uninferable return value """ - - __getnewargs_ex__ = lambda self: Missing - - -class AnotherAmbiguousGetNewArgsEx(object): - """Potential uninferable return value""" - - def __getnewargs_ex__(self): - return tuple(Missing) diff --git a/tests/functional/i/invalid_getnewargs_ex_returned.txt b/tests/functional/i/invalid_getnewargs_ex_returned.txt deleted file mode 100644 index ea8c1703f..000000000 --- a/tests/functional/i/invalid_getnewargs_ex_returned.txt +++ /dev/null @@ -1,6 +0,0 @@ -invalid-getnewargs-ex-returned:36:4:FirstBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) -invalid-getnewargs-ex-returned:43:4:SecondBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) -invalid-getnewargs-ex-returned:50:4:ThirdBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) -invalid-getnewargs-ex-returned:57:4:FourthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) -invalid-getnewargs-ex-returned:64:4:FifthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) -invalid-getnewargs-ex-returned:71:4:SixthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict) diff --git a/tests/functional/i/invalid_getnewargs_returned.py b/tests/functional/i/invalid_getnewargs_returned.py deleted file mode 100644 index ee5305fe8..000000000 --- a/tests/functional/i/invalid_getnewargs_returned.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Check invalid value returned by __getnewargs__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodGetNewArgs(object): - """__getnewargs__ returns """ - - def __getnewargs__(self): - return (1, "2", 3) - - -class SecondGoodGetNewArgs(object): - """__getnewargs__ returns """ - - def __getnewargs__(self): - return tuple() - - -class GetNewArgsMetaclass(type): - def __getnewargs__(cls): - return (1, 2, 3) - - -@six.add_metaclass(GetNewArgsMetaclass) -class ThirdGoodGetNewArgs(object): - """GetNewArgs through the metaclass.""" - - -class FirstBadGetNewArgs(object): - """ __getnewargs__ returns an integer """ - - def __getnewargs__(self): # [invalid-getnewargs-returned] - return 1 - - -class SecondBadGetNewArgs(object): - """ __getnewargs__ returns str """ - - def __getnewargs__(self): # [invalid-getnewargs-returned] - return "(1, 2, 3)" - - -class ThirdBadGetNewArgs(object): - """ __getnewargs__ returns node which does not have 'value' in AST """ - - def __getnewargs__(self): # [invalid-getnewargs-returned] - return lambda: tuple(1, 2) - - -class AmbigousGetNewArgs(object): - """ Uninferable return value """ - __getnewargs__ = lambda self: Missing - - -class AnotherAmbiguousGetNewArgs(object): - """Potential uninferable return value""" - def __getnewargs__(self): - return tuple(Missing) diff --git a/tests/functional/i/invalid_getnewargs_returned.txt b/tests/functional/i/invalid_getnewargs_returned.txt deleted file mode 100644 index 3560a80f9..000000000 --- a/tests/functional/i/invalid_getnewargs_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-getnewargs-returned:36:4:FirstBadGetNewArgs.__getnewargs__:__getnewargs__ does not return a tuple -invalid-getnewargs-returned:43:4:SecondBadGetNewArgs.__getnewargs__:__getnewargs__ does not return a tuple -invalid-getnewargs-returned:50:4:ThirdBadGetNewArgs.__getnewargs__:__getnewargs__ does not return a tuple diff --git a/tests/functional/i/invalid_hash_returned.py b/tests/functional/i/invalid_hash_returned.py deleted file mode 100644 index 47f63e99b..000000000 --- a/tests/functional/i/invalid_hash_returned.py +++ /dev/null @@ -1,71 +0,0 @@ -"""Check invalid value returned by __hash__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodHash(object): - """__hash__ returns """ - - def __hash__(self): - return 1 - - -class SecondGoodHash(object): - """__hash__ returns """ - - def __hash__(self): - return 0 - - -class HashMetaclass(type): - def __hash__(cls): - return 1 - - -@six.add_metaclass(HashMetaclass) -class ThirdGoodHash(object): - """Hash through the metaclass.""" - - -class FirstBadHash(object): - """ __hash__ returns a dict """ - - def __hash__(self): # [invalid-hash-returned] - return {} - - -class SecondBadHash(object): - """ __hash__ returns str """ - - def __hash__(self): # [invalid-hash-returned] - return "True" - - -class ThirdBadHash(object): - """ __hash__ returns a float""" - - def __hash__(self): # [invalid-hash-returned] - return 1.11 - - -class FourthBadHash(object): - """ __hash__ returns node which does not have 'value' in AST """ - - def __hash__(self): # [invalid-hash-returned] - return lambda: 3 - - -class AmbigousHash(object): - """ Uninferable return value """ - - __hash__ = lambda self: Missing - - -class AnotherAmbiguousHash(object): - """Potential uninferable return value""" - - def __hash__(self): - return hash(Missing) diff --git a/tests/functional/i/invalid_hash_returned.txt b/tests/functional/i/invalid_hash_returned.txt deleted file mode 100644 index f30e51417..000000000 --- a/tests/functional/i/invalid_hash_returned.txt +++ /dev/null @@ -1,4 +0,0 @@ -invalid-hash-returned:36:4:FirstBadHash.__hash__:__hash__ does not return int -invalid-hash-returned:43:4:SecondBadHash.__hash__:__hash__ does not return int -invalid-hash-returned:50:4:ThirdBadHash.__hash__:__hash__ does not return int -invalid-hash-returned:57:4:FourthBadHash.__hash__:__hash__ does not return int diff --git a/tests/functional/i/invalid_index_returned.py b/tests/functional/i/invalid_index_returned.py deleted file mode 100644 index c48d9a837..000000000 --- a/tests/functional/i/invalid_index_returned.py +++ /dev/null @@ -1,71 +0,0 @@ -"""Check invalid value returned by __index__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodIndex(object): - """__index__ returns """ - - def __index__(self): - return 1 - - -class SecondGoodIndex(object): - """__index__ returns """ - - def __index__(self): - return 0 - - -class IndexMetaclass(type): - def __index__(cls): - return 1 - - -@six.add_metaclass(IndexMetaclass) -class ThirdGoodIndex(object): - """Index through the metaclass.""" - - -class FirstBadIndex(object): - """ __index__ returns a dict """ - - def __index__(self): # [invalid-index-returned] - return {'1': '1'} - - -class SecondBadIndex(object): - """ __index__ returns str """ - - def __index__(self): # [invalid-index-returned] - return "42" - - -class ThirdBadIndex(object): - """ __index__ returns a float""" - - def __index__(self): # [invalid-index-returned] - return 1.11 - - -class FourthBadIndex(object): - """ __index__ returns node which does not have 'value' in AST """ - - def __index__(self): # [invalid-index-returned] - return lambda: 3 - - -class AmbigousIndex(object): - """ Uninferable return value """ - - __index__ = lambda self: Missing - - -class AnotherAmbiguousIndex(object): - """Potential uninferable return value""" - - def __index__(self): - return int(Missing) diff --git a/tests/functional/i/invalid_index_returned.txt b/tests/functional/i/invalid_index_returned.txt deleted file mode 100644 index 840d74a91..000000000 --- a/tests/functional/i/invalid_index_returned.txt +++ /dev/null @@ -1,4 +0,0 @@ -invalid-index-returned:36:4:FirstBadIndex.__index__:__index__ does not return int -invalid-index-returned:43:4:SecondBadIndex.__index__:__index__ does not return int -invalid-index-returned:50:4:ThirdBadIndex.__index__:__index__ does not return int -invalid-index-returned:57:4:FourthBadIndex.__index__:__index__ does not return int diff --git a/tests/functional/i/invalid_length_hint_returned.py b/tests/functional/i/invalid_length_hint_returned.py deleted file mode 100644 index 7696bc9fd..000000000 --- a/tests/functional/i/invalid_length_hint_returned.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Check invalid value returned by __length_hint__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import sys - -import six - -from missing import Missing - - -class FirstGoodLengthHint(object): - """__length_hint__ returns """ - - def __length_hint__(self): - return 0 - - -class SecondGoodLengthHint(object): - """__length_hint__ returns """ - - def __length_hint__(self): - return sys.maxsize + 1 - - -class LengthHintMetaclass(type): - def __length_hint__(cls): - return 1 - - -@six.add_metaclass(LengthHintMetaclass) -class ThirdGoodLengthHint(object): - """LengthHintgth through the metaclass.""" - - -class FirstBadLengthHint(object): - """ __length_hint__ returns a negative integer """ - - def __length_hint__(self): # [invalid-length-hint-returned] - return -1 - - -class SecondBadLengthHint(object): - """ __length_hint__ returns non-int """ - - def __length_hint__(self): # [invalid-length-hint-returned] - return 3.0 - - -class ThirdBadLengthHint(object): - """ __length_hint__ returns node which does not have 'value' in AST """ - - def __length_hint__(self): # [invalid-length-hint-returned] - return lambda: 3 - - -class AmbigousLengthHint(object): - """ Uninferable return value """ - __length_hint__ = lambda self: Missing - - -class AnotherAmbiguousLengthHint(object): - """Potential uninferable return value""" - def __length_hint__(self): - return int(Missing) diff --git a/tests/functional/i/invalid_length_hint_returned.txt b/tests/functional/i/invalid_length_hint_returned.txt deleted file mode 100644 index dd31af76e..000000000 --- a/tests/functional/i/invalid_length_hint_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-length-hint-returned:38:4:FirstBadLengthHint.__length_hint__:__length_hint__ does not return non-negative integer -invalid-length-hint-returned:45:4:SecondBadLengthHint.__length_hint__:__length_hint__ does not return non-negative integer -invalid-length-hint-returned:52:4:ThirdBadLengthHint.__length_hint__:__length_hint__ does not return non-negative integer diff --git a/tests/functional/i/invalid_length_returned.py b/tests/functional/i/invalid_length_returned.py deleted file mode 100644 index e57db5290..000000000 --- a/tests/functional/i/invalid_length_returned.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Check invalid value returned by __len__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import sys - -import six - -from missing import Missing - - -class FirstGoodLen(object): - """__len__ returns """ - - def __len__(self): - return 0 - - -class SecondGoodLen(object): - """__len__ returns """ - - def __len__(self): - return sys.maxsize + 1 - - -class LenMetaclass(type): - def __len__(cls): - return 1 - - -@six.add_metaclass(LenMetaclass) -class ThirdGoodLen(object): - """Length through the metaclass.""" - - -class FirstBadLen(object): - """ __len__ returns a negative integer """ - - def __len__(self): # [invalid-length-returned] - return -1 - - -class SecondBadLen(object): - """ __len__ returns non-int """ - - def __len__(self): # [invalid-length-returned] - return 3.0 - - -class ThirdBadLen(object): - """ __len__ returns node which does not have 'value' in AST """ - - def __len__(self): # [invalid-length-returned] - return lambda: 3 - - -class AmbigousLen(object): - """ Uninferable return value """ - __len__ = lambda self: Missing - - -class AnotherAmbiguousLen(object): - """Potential uninferable return value""" - def __len__(self): - return int(Missing) diff --git a/tests/functional/i/invalid_length_returned.txt b/tests/functional/i/invalid_length_returned.txt deleted file mode 100644 index 2a271fb29..000000000 --- a/tests/functional/i/invalid_length_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-length-returned:38:4:FirstBadLen.__len__:__len__ does not return non-negative integer -invalid-length-returned:45:4:SecondBadLen.__len__:__len__ does not return non-negative integer -invalid-length-returned:52:4:ThirdBadLen.__len__:__len__ does not return non-negative integer diff --git a/tests/functional/i/invalid_metaclass.py b/tests/functional/i/invalid_metaclass.py deleted file mode 100644 index c0e9d74be..000000000 --- a/tests/functional/i/invalid_metaclass.py +++ /dev/null @@ -1,34 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, import-error,unused-argument, useless-object-inheritance - -import abc - -import six -from unknown import Unknown - - -class InvalidAsMetaclass(object): - pass - - -class ValidAsMetaclass(type): - pass - - -@six.add_metaclass(type) -class FirstGood(object): - pass - - -@six.add_metaclass(abc.ABCMeta) -class SecondGood(object): - pass - - -@six.add_metaclass(Unknown) -class ThirdGood(object): - pass - - -@six.add_metaclass(ValidAsMetaclass) -class FourthGood(object): - pass diff --git a/tests/functional/i/invalid_metaclass_py3.py b/tests/functional/i/invalid_metaclass_py3.py deleted file mode 100644 index 2fc458f5c..000000000 --- a/tests/functional/i/invalid_metaclass_py3.py +++ /dev/null @@ -1,19 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, import-error,unused-argument - -from unknown import Unknown - - -def valid_metaclass_1(name, _, attrs): - return type - - -def valid_metaclass_2(_name, _bases, _attrs): - return Unknown - - -class GoodMetaclass(metaclass=valid_metaclass_1): - pass - - -class SecondGoodMetaclass(metaclass=valid_metaclass_2): - pass diff --git a/tests/functional/i/invalid_metaclass_py3.rc b/tests/functional/i/invalid_metaclass_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/i/invalid_metaclass_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/i/invalid_name.py b/tests/functional/i/invalid_name.py deleted file mode 100644 index 6259b9b50..000000000 --- a/tests/functional/i/invalid_name.py +++ /dev/null @@ -1,44 +0,0 @@ -""" Tests for invalid-name checker. """ -# pylint: disable=unused-import, no-absolute-import, wrong-import-position,import-outside-toplevel - -AAA = 24 -try: - import collections -except ImportError: - collections = None - -aaa = 42 # [invalid-name] -try: - import time -except ValueError: - time = None # [invalid-name] - -try: - from sys import argv, executable as python -except ImportError: - argv = 42 - python = 24 - -def test(): - """ Shouldn't emit an invalid-name here. """ - try: - import re - except ImportError: - re = None - return re - -def a(): # [invalid-name] - """yo""" - - -def _generate_cmdline_tests(): - TestCase = collections.namedtuple('TestCase', 'cmd, valid') - valid = ['leave-mode', 'hint all'] - # Valid command only -> valid - for item in valid: - yield TestCase(''.join(item), True) - - -# We should emit for the loop variable. -for i in range(10): - Foocapfor = 2 # [invalid-name] diff --git a/tests/functional/i/invalid_name.txt b/tests/functional/i/invalid_name.txt deleted file mode 100644 index 749980e13..000000000 --- a/tests/functional/i/invalid_name.txt +++ /dev/null @@ -1,4 +0,0 @@ -invalid-name:10:0::"Constant name ""aaa"" doesn't conform to UPPER_CASE naming style" -invalid-name:14:4::"Constant name ""time"" doesn't conform to UPPER_CASE naming style" -invalid-name:30:0:a:"Function name ""a"" doesn't conform to snake_case naming style" -invalid-name:44:4::"Constant name ""Foocapfor"" doesn't conform to UPPER_CASE naming style" diff --git a/tests/functional/i/invalid_overridden_method.py b/tests/functional/i/invalid_overridden_method.py deleted file mode 100644 index 213c05b7d..000000000 --- a/tests/functional/i/invalid_overridden_method.py +++ /dev/null @@ -1,77 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods -import abc - - -class SuperClass(metaclass=abc.ABCMeta): - @property - @abc.abstractmethod - def prop(self): - pass - - @abc.abstractmethod - async def async_method(self): - pass - - @abc.abstractmethod - def method_a(self): - pass - - @abc.abstractmethod - def method_b(self): - pass - -class ValidDerived(SuperClass): - @property - def prop(self): - return None - - async def async_method(self): - return None - - def method_a(self): - pass - - def method_b(self): - pass - -class InvalidDerived(SuperClass): - def prop(self): # [invalid-overridden-method] - return None - - def async_method(self): # [invalid-overridden-method] - return None - - @property - def method_a(self): # [invalid-overridden-method] - return None - - async def method_b(self): # [invalid-overridden-method] - return None - -class Property: - - @property - def close(self): - pass - - -class PropertySetter(Property): - - @property - def close(self): - pass - - @close.setter - def close(self, attr): - return attr - - @close.deleter - def close(self): - return None - - -class AbstractProperty: - - @abc.abstractproperty - def prop(self): - return diff --git a/tests/functional/i/invalid_overridden_method.txt b/tests/functional/i/invalid_overridden_method.txt deleted file mode 100644 index a44daa752..000000000 --- a/tests/functional/i/invalid_overridden_method.txt +++ /dev/null @@ -1,4 +0,0 @@ -invalid-overridden-method:38:4:InvalidDerived.prop:Method 'prop' was expected to be 'property', found it instead as 'method' -invalid-overridden-method:41:4:InvalidDerived.async_method:Method 'async_method' was expected to be 'async', found it instead as 'non-async' -invalid-overridden-method:45:4:InvalidDerived.method_a:Method 'method_a' was expected to be 'method', found it instead as 'property' -invalid-overridden-method:48:4:InvalidDerived.method_b:Method 'method_b' was expected to be 'non-async', found it instead as 'async' diff --git a/tests/functional/i/invalid_repr_returned.py b/tests/functional/i/invalid_repr_returned.py deleted file mode 100644 index 3bbd7828d..000000000 --- a/tests/functional/i/invalid_repr_returned.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Check invalid value returned by __repr__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodRepr(object): - """__repr__ returns """ - - def __repr__(self): - return "some repr" - - -class SecondGoodRepr(object): - """__repr__ returns """ - - def __repr__(self): - return str(123) - - -class ReprMetaclass(type): - def __repr__(cls): - return "some repr" - - -@six.add_metaclass(ReprMetaclass) -class ThirdGoodRepr(object): - """Repr through the metaclass.""" - - -class FirstBadRepr(object): - """ __repr__ returns bytes """ - - def __repr__(self): # [invalid-repr-returned] - return b"123" - - -class SecondBadRepr(object): - """ __repr__ returns int """ - - def __repr__(self): # [invalid-repr-returned] - return 1 - - -class ThirdBadRepr(object): - """ __repr__ returns node which does not have 'value' in AST """ - - def __repr__(self): # [invalid-repr-returned] - return lambda: "some repr" - - -class AmbiguousRepr(object): - """ Uninferable return value """ - - __repr__ = lambda self: Missing - - -class AnotherAmbiguousRepr(object): - """Potential uninferable return value""" - - def __repr__(self): - return str(Missing) diff --git a/tests/functional/i/invalid_repr_returned.txt b/tests/functional/i/invalid_repr_returned.txt deleted file mode 100644 index 4be375f1f..000000000 --- a/tests/functional/i/invalid_repr_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-repr-returned:36:4:FirstBadRepr.__repr__:__repr__ does not return str -invalid-repr-returned:43:4:SecondBadRepr.__repr__:__repr__ does not return str -invalid-repr-returned:50:4:ThirdBadRepr.__repr__:__repr__ does not return str diff --git a/tests/functional/i/invalid_sequence_index.py b/tests/functional/i/invalid_sequence_index.py deleted file mode 100644 index d11155c02..000000000 --- a/tests/functional/i/invalid_sequence_index.py +++ /dev/null @@ -1,242 +0,0 @@ -"""Errors for invalid sequence indices""" -# pylint: disable=too-few-public-methods, no-self-use, import-error, missing-docstring, useless-object-inheritance, unnecessary-pass -import six -from unknown import Unknown - -TESTLIST = [1, 2, 3] -TESTTUPLE = (1, 2, 3) -TESTSTR = '123' - -# getitem tests with bad indices -def function1(): - """list index is a function""" - return TESTLIST[id] # [invalid-sequence-index] - -def function2(): - """list index is None""" - return TESTLIST[None] # [invalid-sequence-index] - -def function3(): - """list index is a float expression""" - return TESTLIST[float(0)] # [invalid-sequence-index] - -def function4(): - """list index is a str constant""" - return TESTLIST['0'] # [invalid-sequence-index] - -def function5(): - """list index does not implement __index__""" - class NonIndexType(object): - """Class without __index__ method""" - pass - - return TESTLIST[NonIndexType()] # [invalid-sequence-index] - -def function6(): - """Tuple index is None""" - return TESTTUPLE[None] # [invalid-sequence-index] - -def function7(): - """String index is None""" - return TESTSTR[None] # [invalid-sequence-index] - -def function8(): - """Index of subclass of tuple is None""" - class TupleTest(tuple): - """Subclass of tuple""" - pass - return TupleTest()[None] # [invalid-sequence-index] - -# getitem tests with good indices -def function9(): - """list index is an int constant""" - return TESTLIST[0] # no error - -def function10(): - """list index is an integer expression""" - return TESTLIST[int(0.0)] # no error - -def function11(): - """list index is a slice""" - return TESTLIST[slice(1, 2, 3)] # no error - -def function12(): - """list index implements __index__""" - class IndexType(object): - """Class with __index__ method""" - def __index__(self): - """Allow objects of this class to be used as slice indices""" - return 0 - - return TESTLIST[IndexType()] # no error - -def function13(): - """list index implements __index__ in a superclass""" - class IndexType(object): - """Class with __index__ method""" - def __index__(self): - """Allow objects of this class to be used as slice indices""" - return 0 - - class IndexSubType(IndexType): - """Class with __index__ in parent""" - pass - - return TESTLIST[IndexSubType()] # no error - -def function14(): - """Tuple index is an int constant""" - return TESTTUPLE[0] - -def function15(): - """String index is an int constant""" - return TESTSTR[0] - -def function16(): - """Index of subclass of tuple is an int constant""" - class TupleTest(tuple): - """Subclass of tuple""" - pass - return TupleTest()[0] # no error - -def function17(): - """Index of subclass of tuple with custom __getitem__ is None""" - class TupleTest(tuple): - """Subclass of tuple with custom __getitem__""" - def __getitem__(self, index): - """Allow non-integer indices""" - return 0 - return TupleTest()[None] # no error - -def function18(): - """Index of subclass of tuple with __getitem__ in superclass is None""" - class TupleTest(tuple): - """Subclass of tuple with custom __getitem__""" - def __getitem__(self, index): - """Allow non-integer indices""" - return 0 - - class SubTupleTest(TupleTest): - """Subclass of a subclass of tuple""" - pass - - return SubTupleTest()[None] # no error - -# Test with set and delete statements -def function19(): - """Set with None and integer indices""" - TESTLIST[None] = 0 # [invalid-sequence-index] - TESTLIST[0] = 0 # no error - -def function20(): - """Delete with None and integer indicies""" - del TESTLIST[None] # [invalid-sequence-index] - del TESTLIST[0] # no error - -def function21(): - """Set and delete on a subclass of list""" - class ListTest(list): - """Inherit all list get/set/del handlers""" - pass - test = ListTest() - - # Set and delete with invalid indices - test[None] = 0 # [invalid-sequence-index] - del test[None] # [invalid-sequence-index] - - # Set and delete with valid indices - test[0] = 0 # no error - del test[0] # no error - -def function22(): - """Get, set, and delete on a subclass of list that overrides __setitem__""" - class ListTest(list): - """Override setitem but not get or del""" - def __setitem__(self, key, value): - pass - test = ListTest() - - # failure on the getitem with None - test[None][0] = 0 # [invalid-sequence-index] - # failure on the getitem with None - del test[None] # [invalid-sequence-index] - - test[0][0] = 0 # getitem with int and setitem with int, no error - test[None] = 0 # setitem overridden, no error - test[0] = 0 # setitem with int, no error - del test[0] # delitem with int, no error - -def function23(): - """Get, set, and delete on a subclass of list that overrides __delitem__""" - class ListTest(list): - """Override delitem but not get or set""" - def __delitem__(self, key): - pass - test = ListTest() - - # failure on the getitem with None - test[None][0] = 0 # [invalid-sequence-index] - # setitem with invalid index - test[None] = 0 # [invalid-sequence-index] - - test[0][0] = 0 # getitem with int and setitem with int, no error - test[0] = 0 # setitem with int, no error - del test[None] # delitem overridden, no error - del test[0] # delitem with int, no error - -def function24(): - """Get, set, and delete on a subclass of list that overrides __getitem__""" - class ListTest(list): - """Override gelitem but not del or set""" - def __getitem__(self, key): - pass - test = ListTest() - - # setitem with invalid index - test[None] = 0 # [invalid-sequence-index] - # delitem with invalid index - del test[None] # [invalid-sequence-index] - - test[None][0] = 0 # getitem overridden, no error - test[0][0] = 0 # getitem with int and setitem with int, no error - test[0] = 0 # setitem with int, no error - del test[0] # delitem with int, no error - -# Teest ExtSlice usage -def function25(): - """Extended slice used with a list""" - return TESTLIST[..., 0] # [invalid-sequence-index] - -def function26(): - """Extended slice used with an object that implements __getitem__""" - class ExtSliceTest(object): - """Permit extslice syntax by implementing __getitem__""" - def __getitem__(self, index): - return 0 - return ExtSliceTest()[..., 0] # no error - -def function27(): - """Don't warn in the case where the indexed object has unknown base classes.""" - class UnknownBase(Unknown): - pass - slices = UnknownBase["aaaa"] + UnknownBase()[object] - ext_slices = UnknownBase[..., 0] + UnknownBase()[..., 0] - return slices, ext_slices - - -def function28(): - """Don't emit for classes with the right implementation.""" - - class Meta(type): - def __getitem__(cls, arg): - return 24 - - @six.add_metaclass(Meta) - class Works(object): - pass - - @six.add_metaclass(Meta) - class Error(list): - pass - - return Works['hello'] + Error['hello'] diff --git a/tests/functional/i/invalid_sequence_index.txt b/tests/functional/i/invalid_sequence_index.txt deleted file mode 100644 index baf1b2167..000000000 --- a/tests/functional/i/invalid_sequence_index.txt +++ /dev/null @@ -1,19 +0,0 @@ -invalid-sequence-index:13:11:function1:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:17:11:function2:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:21:11:function3:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:25:11:function4:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:33:11:function5:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:37:11:function6:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:41:11:function7:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:48:11:function8:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:128:4:function19:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:133:8:function20:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:144:4:function21:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:145:8:function21:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:160:4:function22:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:162:8:function22:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:178:4:function23:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:180:4:function23:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:196:4:function24:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:198:8:function24:Sequence index is not an int, slice, or instance with __index__ -invalid-sequence-index:208:11:function25:Sequence index is not an int, slice, or instance with __index__ diff --git a/tests/functional/i/invalid_slice_index.py b/tests/functional/i/invalid_slice_index.py deleted file mode 100644 index 1eb2fda9c..000000000 --- a/tests/functional/i/invalid_slice_index.py +++ /dev/null @@ -1,71 +0,0 @@ -"""Errors for invalid slice indices""" -# pylint: disable=too-few-public-methods, no-self-use,missing-docstring,expression-not-assigned, useless-object-inheritance, unnecessary-pass - - -TESTLIST = [1, 2, 3] - -# Invalid indices -def function1(): - """functions used as indices""" - return TESTLIST[id:id:] # [invalid-slice-index,invalid-slice-index] - -def function2(): - """strings used as indices""" - return TESTLIST['0':'1':] # [invalid-slice-index,invalid-slice-index] - -def function3(): - """class without __index__ used as index""" - - class NoIndexTest(object): - """Class with no __index__ method""" - pass - - return TESTLIST[NoIndexTest()::] # [invalid-slice-index] - -# Valid indices -def function4(): - """integers used as indices""" - return TESTLIST[0:0:0] # no error - -def function5(): - """None used as indices""" - return TESTLIST[None:None:None] # no error - -def function6(): - """class with __index__ used as index""" - class IndexTest(object): - """Class with __index__ method""" - def __index__(self): - """Allow objects of this class to be used as slice indices""" - return 0 - - return TESTLIST[IndexTest():None:None] # no error - -def function7(): - """class with __index__ in superclass used as index""" - class IndexType(object): - """Class with __index__ method""" - def __index__(self): - """Allow objects of this class to be used as slice indices""" - return 0 - - class IndexSubType(IndexType): - """Class with __index__ in parent""" - pass - - return TESTLIST[IndexSubType():None:None] # no error - -def function8(): - """slice object used as index""" - return TESTLIST[slice(1, 2, 3)] # no error - - -def function9(): - """Use a custom class that knows how to handle string slices""" - class StringSlice: - def __getitem__(self, item): - return item - - StringSlice()["a":"b":"c"] - StringSlice()["a":"b":"c", "a":"b"] - StringSlice()[slice("a", "b", "c")] diff --git a/tests/functional/i/invalid_slice_index.txt b/tests/functional/i/invalid_slice_index.txt deleted file mode 100644 index e715138b4..000000000 --- a/tests/functional/i/invalid_slice_index.txt +++ /dev/null @@ -1,5 +0,0 @@ -invalid-slice-index:10:0:function1:Slice index is not an int, None, or instance with __index__ -invalid-slice-index:10:0:function1:Slice index is not an int, None, or instance with __index__ -invalid-slice-index:14:0:function2:Slice index is not an int, None, or instance with __index__ -invalid-slice-index:14:0:function2:Slice index is not an int, None, or instance with __index__ -invalid-slice-index:23:0:function3:Slice index is not an int, None, or instance with __index__ diff --git a/tests/functional/i/invalid_star_assignment_target.py b/tests/functional/i/invalid_star_assignment_target.py deleted file mode 100644 index 452f9a728..000000000 --- a/tests/functional/i/invalid_star_assignment_target.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Test for *a = b """ - -*FIRST = [1, 2, 3] # [invalid-star-assignment-target] -(*FIRST, ) = [1, 2, 3] diff --git a/tests/functional/i/invalid_star_assignment_target.rc b/tests/functional/i/invalid_star_assignment_target.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/i/invalid_star_assignment_target.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/i/invalid_star_assignment_target.txt b/tests/functional/i/invalid_star_assignment_target.txt deleted file mode 100644 index eb9f27c90..000000000 --- a/tests/functional/i/invalid_star_assignment_target.txt +++ /dev/null @@ -1 +0,0 @@ -invalid-star-assignment-target:3:0::Starred assignment target must be in a list or tuple diff --git a/tests/functional/i/invalid_str_returned.py b/tests/functional/i/invalid_str_returned.py deleted file mode 100644 index 00ef22046..000000000 --- a/tests/functional/i/invalid_str_returned.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Check invalid value returned by __str__ """ - -# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance -import six - -from missing import Missing - - -class FirstGoodStr(object): - """__str__ returns """ - - def __str__(self): - return "some str" - - -class SecondGoodStr(object): - """__str__ returns """ - - def __str__(self): - return str(123) - - -class StrMetaclass(type): - def __str__(cls): - return "some str" - - -@six.add_metaclass(StrMetaclass) -class ThirdGoodStr(object): - """Str through the metaclass.""" - - -class FirstBadStr(object): - """ __str__ returns bytes """ - - def __str__(self): # [invalid-str-returned] - return b"123" - - -class SecondBadStr(object): - """ __str__ returns int """ - - def __str__(self): # [invalid-str-returned] - return 1 - - -class ThirdBadStr(object): - """ __str__ returns node which does not have 'value' in AST """ - - def __str__(self): # [invalid-str-returned] - return lambda: "some str" - - -class AmbiguousStr(object): - """ Uninferable return value """ - - __str__ = lambda self: Missing - - -class AnotherAmbiguousStr(object): - """Potential uninferable return value""" - - def __str__(self): - return str(Missing) diff --git a/tests/functional/i/invalid_str_returned.txt b/tests/functional/i/invalid_str_returned.txt deleted file mode 100644 index 36b7ec57c..000000000 --- a/tests/functional/i/invalid_str_returned.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-str-returned:36:4:FirstBadStr.__str__:__str__ does not return str -invalid-str-returned:43:4:SecondBadStr.__str__:__str__ does not return str -invalid-str-returned:50:4:ThirdBadStr.__str__:__str__ does not return str diff --git a/tests/functional/i/invalid_unary_operand_type.py b/tests/functional/i/invalid_unary_operand_type.py deleted file mode 100644 index f2a0124f6..000000000 --- a/tests/functional/i/invalid_unary_operand_type.py +++ /dev/null @@ -1,51 +0,0 @@ -"""Detect problems with invalid operands used on invalid objects.""" -# pylint: disable=missing-docstring,too-few-public-methods,invalid-name -# pylint: disable=unused-variable, useless-object-inheritance - -import collections - - -class Implemented(object): - def __invert__(self): - return 42 - def __pos__(self): - return 42 - def __neg__(self): - return 42 - - -def these_are_good(): - negative = -1 - negative1 = -1.0 - positive = +1 - positive2 = +1.0 - inverted = ~1 - not_int = not 1 - not_float = not 2.0 - not_string = not "" - not_list = not [] - not_dict = not {} - not_tuple = not (1, 2) - inverted_instance = ~Implemented() - positive_instance = +Implemented() - negative_instance = -Implemented() - not_instance = not Implemented() - - -def these_are_bad(): - invert_list = ~[] # [invalid-unary-operand-type] - invert_tuple = ~() # [invalid-unary-operand-type] - invert_dict = ~dict() # [invalid-unary-operand-type] - invert_dict_1 = ~{} # [invalid-unary-operand-type] - invert_set = ~set() # [invalid-unary-operand-type] - neg_set = -set() # [invalid-unary-operand-type] - neg_str = -"" # [invalid-unary-operand-type] - invert_str = ~"" # [invalid-unary-operand-type] - pos_str = +"" # [invalid-unary-operand-type] - class A(object): - pass - invert_func = ~(lambda: None) # [invalid-unary-operand-type] - invert_class = ~A # [invalid-unary-operand-type] - invert_instance = ~A() # [invalid-unary-operand-type] - invert_module = ~collections # [invalid-unary-operand-type] - invert_float = ~2.0 # [invalid-unary-operand-type] diff --git a/tests/functional/i/invalid_unary_operand_type.txt b/tests/functional/i/invalid_unary_operand_type.txt deleted file mode 100644 index 6a3dd591d..000000000 --- a/tests/functional/i/invalid_unary_operand_type.txt +++ /dev/null @@ -1,14 +0,0 @@ -invalid-unary-operand-type:36:18:these_are_bad:"bad operand type for unary ~: list" -invalid-unary-operand-type:37:19:these_are_bad:"bad operand type for unary ~: tuple" -invalid-unary-operand-type:38:18:these_are_bad:"bad operand type for unary ~: dict" -invalid-unary-operand-type:39:20:these_are_bad:"bad operand type for unary ~: dict" -invalid-unary-operand-type:40:17:these_are_bad:"bad operand type for unary ~: set" -invalid-unary-operand-type:41:14:these_are_bad:"bad operand type for unary -: set" -invalid-unary-operand-type:42:14:these_are_bad:"bad operand type for unary -: str" -invalid-unary-operand-type:43:17:these_are_bad:"bad operand type for unary ~: str" -invalid-unary-operand-type:44:14:these_are_bad:"bad operand type for unary +: str" -invalid-unary-operand-type:47:18:these_are_bad:"bad operand type for unary ~: " -invalid-unary-operand-type:48:19:these_are_bad:"bad operand type for unary ~: A" -invalid-unary-operand-type:49:22:these_are_bad:"bad operand type for unary ~: A" -invalid-unary-operand-type:50:20:these_are_bad:"bad operand type for unary ~: collections" -invalid-unary-operand-type:51:19:these_are_bad:"bad operand type for unary ~: float" diff --git a/tests/functional/m/member/member_checks.py b/tests/functional/m/member/member_checks.py new file mode 100644 index 000000000..291daee12 --- /dev/null +++ b/tests/functional/m/member/member_checks.py @@ -0,0 +1,233 @@ +# pylint: disable=print-statement,missing-docstring,no-self-use,too-few-public-methods,bare-except,broad-except, useless-object-inheritance +# pylint: disable=using-constant-test,expression-not-assigned, assigning-non-slot, unused-variable,pointless-statement, wrong-import-order, wrong-import-position,import-outside-toplevel +from __future__ import print_function +class Provider(object): + """provide some attributes and method""" + cattr = 4 + def __init__(self): + self.attr = 4 + def method(self, val): + """impressive method""" + return self.attr * val + def hophop(self): + """hop method""" + print('hop hop hop', self) + + +class Client(object): + """use provider class""" + + def __init__(self): + self._prov = Provider() + self._prov_attr = Provider.cattr + self._prov_attr2 = Provider.cattribute # [no-member] + self.set_later = 0 + + def set_set_later(self, value): + """set set_later attribute (introduce an inference ambiguity)""" + self.set_later = value + + def use_method(self): + """use provider's method""" + self._prov.hophop() + self._prov.hophophop() # [no-member] + + def use_attr(self): + """use provider's attr""" + print(self._prov.attr) + print(self._prov.attribute) # [no-member] + + def debug(self): + """print debug information""" + print(self.__class__.__name__) + print(self.__doc__) + print(self.__dict__) + print(self.__module__) + + def test_bt_types(self): + """test access to unexistant member of builtin types""" + lis = [] + lis.apppend(self) # [no-member] + dic = {} + dic.set(self) # [no-member] + tup = () + tup.append(self) # [no-member] + string = 'toto' + print(string.loower()) # [no-member] + integer = 1 + print(integer.whatever) # [no-member] + + def test_no_false_positives(self): + none = None + print(none.whatever) + # No misssing in the parents. + super().misssing() # [no-member] + + +class Mixin(object): + """No no-member should be emitted for mixins.""" + +class Getattr(object): + """no-member shouldn't be emitted for classes with dunder getattr.""" + + def __getattr__(self, attr): + return self.__dict__[attr] + + +class Getattribute(object): + """no-member shouldn't be emitted for classes with dunder getattribute.""" + + def __getattribute__(self, attr): + return 42 + +print(object.__init__) +print(property.__init__) +print(Client().set_later.lower()) +print(Mixin().nanana()) +print(Getattr().nananan()) +print(Getattribute().batman()) + +try: + Client().missing_method() +except AttributeError: + pass + +try: + Client().indeed() # [no-member] +except ImportError: + pass + +try: + Client.missing() +except AttributeError: + Client.missing() # [no-member] + +try: + Client.missing() +except AttributeError: + try: + Client.missing() # [no-member] + except ValueError: + pass + +try: + if Client: + Client().missing() +except AttributeError: + pass + +try: + Client().indeed() +except AttributeError: + try: + Client.missing() # [no-member] + except Exception: + pass + + +class SuperChecks(str, str): # pylint: disable=duplicate-bases + """Don't fail when the MRO is invalid.""" + def test(self): + super().lalala() + +type(Client()).ala # [no-member] +type({}).bala # [no-member] +type('').portocala # [no-member] + + +def socket_false_positive(): + """Test a regression + Version used: + + - Pylint 0.10.0 + - Logilab common 0.15.0 + - Logilab astroid 0.15.1 + + False E1101 positive, line 23: + Instance of '_socketobject' has no 'connect' member + """ + + import socket + sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sckt.connect(('127.0.0.1', 80)) + sckt.close() + + +def no_conjugate_member(magic_flag): + """should not raise E1101 on something.conjugate""" + if magic_flag: + something = 1.0 + else: + something = 1.0j + if isinstance(something, float): + return something + return something.conjugate() + + +class NoDunderNameInInstance(object): + """Emit a warning when accessing __name__ from an instance.""" + def __init__(self): + self.var = self.__name__ # [no-member] + + +class InvalidAccessBySlots(object): + __slots__ = ('a', ) + def __init__(self): + var = self.teta # [no-member] + self.teta = 24 + + +class MetaWithDynamicGetattr(type): + + def __getattr__(cls, attr): + return attr + + +class SomeClass(object, metaclass=MetaWithDynamicGetattr): + pass + + +SomeClass.does_not_exist + +class ClassWithMangledAttribute(object): + def __init__(self): + self.name = 'Bug1643' + def __bar(self): + print(self.name + "xD") + +ClassWithMangledAttribute()._ClassWithMangledAttribute__bar() # pylint: disable=protected-access + + +import enum + + +class Cls(enum.IntEnum): + BAR = 0 + + +SOME_VALUE = Cls.BAZ # [no-member] + + + +# Does not crash when inferring the `append` attribute on the slice object +class SomeClassUsingSlice: + def __init__(self, flag): + if flag: + self.attribute = slice(None) + else: + self.attribute = [] + self.attribute.append(1) + +from enum import Enum +class Animal(Enum): + ANT = 1 + BEE = 2 + CAT = 3 + DOG = 4 +# To test false positive no-member on Enum.__members__.items() +for itm in Animal.__members__.items(): + print(itm) +for keyy in Animal.__members__.keys: + print(keyy) +for vall in Animal.__members__.values: + print(vall) diff --git a/tests/functional/m/member/member_checks.txt b/tests/functional/m/member/member_checks.txt new file mode 100644 index 000000000..0b7ee9478 --- /dev/null +++ b/tests/functional/m/member/member_checks.txt @@ -0,0 +1,19 @@ +no-member:23:27:Client.__init__:Class 'Provider' has no 'cattribute' member:INFERENCE +no-member:33:8:Client.use_method:Instance of 'Provider' has no 'hophophop' member:INFERENCE +no-member:38:14:Client.use_attr:Instance of 'Provider' has no 'attribute' member:INFERENCE +no-member:50:8:Client.test_bt_types:Instance of 'list' has no 'apppend' member; maybe 'append'?:INFERENCE +no-member:52:8:Client.test_bt_types:Instance of 'dict' has no 'set' member; maybe 'get'?:INFERENCE +no-member:54:8:Client.test_bt_types:Instance of 'tuple' has no 'append' member:INFERENCE +no-member:56:14:Client.test_bt_types:Instance of 'str' has no 'loower' member; maybe 'lower'?:INFERENCE +no-member:58:14:Client.test_bt_types:Instance of 'int' has no 'whatever' member:INFERENCE +no-member:64:8:Client.test_no_false_positives:Super of 'Client' has no 'misssing' member:INFERENCE +no-member:96:4::Instance of 'Client' has no 'indeed' member:INFERENCE +no-member:103:4::Class 'Client' has no 'missing' member:INFERENCE +no-member:109:8::Class 'Client' has no 'missing' member:INFERENCE +no-member:123:8::Class 'Client' has no 'missing' member:INFERENCE +no-member:133:0::Class 'Client' has no 'ala' member:INFERENCE +no-member:134:0::Class 'dict' has no 'bala' member:INFERENCE +no-member:135:0::Class 'str' has no 'portocala' member:INFERENCE +no-member:170:19:NoDunderNameInInstance.__init__:Instance of 'NoDunderNameInInstance' has no '__name__' member:INFERENCE +no-member:176:14:InvalidAccessBySlots.__init__:Instance of 'InvalidAccessBySlots' has no 'teta' member:INFERENCE +no-member:208:13::Class 'Cls' has no 'BAZ' member; maybe 'BAR'?:INFERENCE diff --git a/tests/functional/m/member/member_checks_hints.py b/tests/functional/m/member/member_checks_hints.py new file mode 100644 index 000000000..3925f4741 --- /dev/null +++ b/tests/functional/m/member/member_checks_hints.py @@ -0,0 +1,27 @@ +# pylint: disable=missing-docstring, too-few-public-methods, pointless-statement, useless-object-inheritance + + +class Parent(object): + + def __init__(self): + self._parent = 42 + self._registry = {} + self._similar1 = 24 + self._similar2 = 23 + self._similar3 = 24 + self._really_similar1 = 23 + self._really_similar2 = 42 + + +class Child(Parent): + + def __init__(self): + super().__init__() + + self._similar # [no-member] + self._really_similar # [no-member] + self._paren # [no-member] + # Distance is too big + self._registryyyy # [no-member] + # Nothing close. + self._pretty_sure_this_wont_match # [no-member] diff --git a/tests/functional/m/member/member_checks_hints.rc b/tests/functional/m/member/member_checks_hints.rc new file mode 100644 index 000000000..8d4b587f4 --- /dev/null +++ b/tests/functional/m/member/member_checks_hints.rc @@ -0,0 +1,3 @@ +[TYPECHECK] +missing-member-max-choices = 3 +missing-member-hint-distance = 1 diff --git a/tests/functional/m/member/member_checks_hints.txt b/tests/functional/m/member/member_checks_hints.txt new file mode 100644 index 000000000..9dd977b13 --- /dev/null +++ b/tests/functional/m/member/member_checks_hints.txt @@ -0,0 +1,5 @@ +no-member:21:8:Child.__init__:Instance of 'Child' has no '_similar' member; maybe one of '_similar1', '_similar2' or '_similar3'?:INFERENCE +no-member:22:8:Child.__init__:Instance of 'Child' has no '_really_similar' member; maybe one of '_really_similar1' or '_really_similar2'?:INFERENCE +no-member:23:8:Child.__init__:Instance of 'Child' has no '_paren' member; maybe '_parent'?:INFERENCE +no-member:25:8:Child.__init__:Instance of 'Child' has no '_registryyyy' member:INFERENCE +no-member:27:8:Child.__init__:Instance of 'Child' has no '_pretty_sure_this_wont_match' member:INFERENCE diff --git a/tests/functional/m/member/member_checks_ignore_none.py b/tests/functional/m/member/member_checks_ignore_none.py new file mode 100644 index 000000000..06f01cb6a --- /dev/null +++ b/tests/functional/m/member/member_checks_ignore_none.py @@ -0,0 +1,7 @@ +# pylint: disable=missing-docstring, useless-return + +def func(): + return None + + +SOME_VAR = func().DOES_NOT_EXIST # [no-member] diff --git a/tests/functional/m/member/member_checks_ignore_none.rc b/tests/functional/m/member/member_checks_ignore_none.rc new file mode 100644 index 000000000..9ec706ec6 --- /dev/null +++ b/tests/functional/m/member/member_checks_ignore_none.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +ignore-none=no diff --git a/tests/functional/m/member/member_checks_ignore_none.txt b/tests/functional/m/member/member_checks_ignore_none.txt new file mode 100644 index 000000000..ead0e7efe --- /dev/null +++ b/tests/functional/m/member/member_checks_ignore_none.txt @@ -0,0 +1 @@ +no-member:7:11::Instance of 'NoneType' has no 'DOES_NOT_EXIST' member:INFERENCE diff --git a/tests/functional/m/member/member_checks_inference_improvements.py b/tests/functional/m/member/member_checks_inference_improvements.py new file mode 100644 index 000000000..6eefa7958 --- /dev/null +++ b/tests/functional/m/member/member_checks_inference_improvements.py @@ -0,0 +1,11 @@ +# pylint: disable=missing-docstring + + +def test_oserror_has_strerror(): + # https://github.com/PyCQA/pylint/issues/2553 + try: + raise OSError() + except OSError as exc: + if exc.strerror is not None: + return exc.strerror.lower() + return None diff --git a/tests/functional/m/member/member_checks_no_hints.py b/tests/functional/m/member/member_checks_no_hints.py new file mode 100644 index 000000000..3925f4741 --- /dev/null +++ b/tests/functional/m/member/member_checks_no_hints.py @@ -0,0 +1,27 @@ +# pylint: disable=missing-docstring, too-few-public-methods, pointless-statement, useless-object-inheritance + + +class Parent(object): + + def __init__(self): + self._parent = 42 + self._registry = {} + self._similar1 = 24 + self._similar2 = 23 + self._similar3 = 24 + self._really_similar1 = 23 + self._really_similar2 = 42 + + +class Child(Parent): + + def __init__(self): + super().__init__() + + self._similar # [no-member] + self._really_similar # [no-member] + self._paren # [no-member] + # Distance is too big + self._registryyyy # [no-member] + # Nothing close. + self._pretty_sure_this_wont_match # [no-member] diff --git a/tests/functional/m/member/member_checks_no_hints.rc b/tests/functional/m/member/member_checks_no_hints.rc new file mode 100644 index 000000000..0f9c9ca3b --- /dev/null +++ b/tests/functional/m/member/member_checks_no_hints.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +missing-member-hint=no diff --git a/tests/functional/m/member/member_checks_no_hints.txt b/tests/functional/m/member/member_checks_no_hints.txt new file mode 100644 index 000000000..6d818641e --- /dev/null +++ b/tests/functional/m/member/member_checks_no_hints.txt @@ -0,0 +1,5 @@ +no-member:21:8:Child.__init__:Instance of 'Child' has no '_similar' member:INFERENCE +no-member:22:8:Child.__init__:Instance of 'Child' has no '_really_similar' member:INFERENCE +no-member:23:8:Child.__init__:Instance of 'Child' has no '_paren' member:INFERENCE +no-member:25:8:Child.__init__:Instance of 'Child' has no '_registryyyy' member:INFERENCE +no-member:27:8:Child.__init__:Instance of 'Child' has no '_pretty_sure_this_wont_match' member:INFERENCE diff --git a/tests/functional/m/member/member_checks_opaque.py b/tests/functional/m/member/member_checks_opaque.py new file mode 100644 index 000000000..9b592af64 --- /dev/null +++ b/tests/functional/m/member/member_checks_opaque.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring,import-error + +from unknown import Unknown, some_value + + +def test(argument): + if argument: + return 42 + return Unknown + + +test(some_value).test() # [no-member] diff --git a/tests/functional/m/member/member_checks_opaque.rc b/tests/functional/m/member/member_checks_opaque.rc new file mode 100644 index 000000000..025cd2a0f --- /dev/null +++ b/tests/functional/m/member/member_checks_opaque.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +ignore-on-opaque-inference=n diff --git a/tests/functional/m/member/member_checks_opaque.txt b/tests/functional/m/member/member_checks_opaque.txt new file mode 100644 index 000000000..2fabce4e2 --- /dev/null +++ b/tests/functional/m/member/member_checks_opaque.txt @@ -0,0 +1 @@ +no-member:12:0::Instance of 'int' has no 'test' member:INFERENCE diff --git a/tests/functional/m/member/member_checks_py37.py b/tests/functional/m/member/member_checks_py37.py new file mode 100644 index 000000000..8d59b7d80 --- /dev/null +++ b/tests/functional/m/member/member_checks_py37.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring +import collections +import asyncio + +isinstance([], collections.Iterable) + + +async def gen(): + await asyncio.sleep(0.1) + value = yield 42 + print(value) + await asyncio.sleep(0.2) + + +async def test(): + generator = gen() + + await generator.asend(None) + await generator.send(None) # [no-member] diff --git a/tests/functional/m/member/member_checks_py37.rc b/tests/functional/m/member/member_checks_py37.rc new file mode 100644 index 000000000..a17bb22da --- /dev/null +++ b/tests/functional/m/member/member_checks_py37.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 diff --git a/tests/functional/m/member/member_checks_py37.txt b/tests/functional/m/member/member_checks_py37.txt new file mode 100644 index 000000000..c52eab13c --- /dev/null +++ b/tests/functional/m/member/member_checks_py37.txt @@ -0,0 +1 @@ +no-member:19:10:test:AsyncGenerator 'async_generator' has no 'send' member; maybe 'asend'?:INFERENCE diff --git a/tests/functional/m/member/member_checks_typed_annotations.py b/tests/functional/m/member/member_checks_typed_annotations.py new file mode 100644 index 000000000..90f775a43 --- /dev/null +++ b/tests/functional/m/member/member_checks_typed_annotations.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods +class A: + myfield: int + +class B(A): + pass + +class C: + pass + +class D(C, B): + pass + + +a = A() +print(a.myfield) + +b = B() +print(b.myfield) + +d = D() +print(d.myfield) + +c = C() +print(c.myfield) # [no-member] diff --git a/tests/functional/m/member/member_checks_typed_annotations.txt b/tests/functional/m/member/member_checks_typed_annotations.txt new file mode 100644 index 000000000..6261a31aa --- /dev/null +++ b/tests/functional/m/member/member_checks_typed_annotations.txt @@ -0,0 +1 @@ +no-member:25:6::Instance of 'C' has no 'myfield' member:INFERENCE diff --git a/tests/functional/m/member/membership_protocol.py b/tests/functional/m/member/membership_protocol.py new file mode 100644 index 000000000..3401f4bb4 --- /dev/null +++ b/tests/functional/m/member/membership_protocol.py @@ -0,0 +1,123 @@ +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,too-few-public-methods,import-error,no-init,wrong-import-position,no-else-return, comparison-with-itself, useless-object-inheritance + +# standard types +1 in [1, 2, 3] +1 in {'a': 1, 'b': 2} +1 in {1, 2, 3} +1 in (1, 2, 3) +'1' in "123" +'1' in u"123" +'1' in bytearray(b"123") +1 in frozenset([1, 2, 3]) + +# comprehensions +1 in [x ** 2 % 10 for x in range(10)] +1 in {x ** 2 % 10 for x in range(10)} +1 in {x: x ** 2 % 10 for x in range(10)} + +# iterators +1 in iter([1, 2, 3]) + +# generator +def count(upto=float("inf")): + i = 0 + while True: + if i > upto: + break + yield i + i += 1 + +10 in count(upto=10) + +# custom instance +class UniversalContainer(object): + def __contains__(self, key): + return True + +42 in UniversalContainer() + +# custom iterable +class CustomIterable(object): + def __iter__(self): + return iter((1, 2, 3)) +3 in CustomIterable() + +# old-style iterable +class OldStyleIterable(object): + def __getitem__(self, key): + if key < 10: + return 2 ** key + else: + raise IndexError("bad index") +64 in OldStyleIterable() + +# do not emit warning if class has unknown bases +from some_missing_module import ImportedClass + +class MaybeIterable(ImportedClass): + pass + +10 in MaybeIterable() + +# do not emit warning inside mixins/abstract/base classes +class UsefulMixin(object): + stuff = None + + def get_stuff(self): + return self.stuff + + def act(self, thing): + stuff = self.get_stuff() + if thing in stuff: + pass + +class BaseThing(object): + valid_values = None + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + return value in self.valid_values + +class AbstractThing(object): + valid_values = None + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + return value in self.valid_values + +# class is not named as abstract +# but still is deduceably abstract +class Thing(object): + valid_values = None + + def __init__(self): + self._init_values() + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + return value in self.valid_values + + def _init_values(self): + raise NotImplementedError + +# error cases +42 in 42 # [unsupported-membership-test] +42 not in None # [unsupported-membership-test] +42 in 8.5 # [unsupported-membership-test] + +class EmptyClass(object): + pass + +42 not in EmptyClass() # [unsupported-membership-test] +42 in EmptyClass # [unsupported-membership-test] +42 not in count # [unsupported-membership-test] +42 in range # [unsupported-membership-test] diff --git a/tests/functional/m/member/membership_protocol.txt b/tests/functional/m/member/membership_protocol.txt new file mode 100644 index 000000000..e021062da --- /dev/null +++ b/tests/functional/m/member/membership_protocol.txt @@ -0,0 +1,7 @@ +unsupported-membership-test:113:6::Value '42' doesn't support membership test +unsupported-membership-test:114:10::Value 'None' doesn't support membership test +unsupported-membership-test:115:6::Value '8.5' doesn't support membership test +unsupported-membership-test:120:10::Value 'EmptyClass()' doesn't support membership test +unsupported-membership-test:121:6::Value 'EmptyClass' doesn't support membership test +unsupported-membership-test:122:10::Value 'count' doesn't support membership test +unsupported-membership-test:123:6::Value 'range' doesn't support membership test diff --git a/tests/functional/m/member/membership_protocol_py3.py b/tests/functional/m/member/membership_protocol_py3.py new file mode 100644 index 000000000..678072354 --- /dev/null +++ b/tests/functional/m/member/membership_protocol_py3.py @@ -0,0 +1,36 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,pointless-statement,expression-not-assigned + +# metaclasses that support membership test protocol +class MetaIterable(type): + def __iter__(cls): + return iter((1, 2, 3)) + +class MetaOldIterable(type): + def __getitem__(cls, key): + if key < 10: + return key ** 2 + + raise IndexError("bad index") + +class MetaContainer(type): + def __contains__(cls, key): + return False + + +class IterableClass(metaclass=MetaOldIterable): + pass + +class OldIterableClass(metaclass=MetaOldIterable): + pass + +class ContainerClass(metaclass=MetaContainer): + pass + + +def test(): + 1 in IterableClass + 1 in OldIterableClass + 1 in ContainerClass + 1 in IterableClass() # [unsupported-membership-test] + 1 in OldIterableClass() # [unsupported-membership-test] + 1 in ContainerClass() # [unsupported-membership-test] diff --git a/tests/functional/m/member/membership_protocol_py3.rc b/tests/functional/m/member/membership_protocol_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/m/member/membership_protocol_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/m/member/membership_protocol_py3.txt b/tests/functional/m/member/membership_protocol_py3.txt new file mode 100644 index 000000000..495cf94db --- /dev/null +++ b/tests/functional/m/member/membership_protocol_py3.txt @@ -0,0 +1,3 @@ +unsupported-membership-test:34:9:test:Value 'IterableClass()' doesn't support membership test +unsupported-membership-test:35:9:test:Value 'OldIterableClass()' doesn't support membership test +unsupported-membership-test:36:9:test:Value 'ContainerClass()' doesn't support membership test diff --git a/tests/functional/m/member_checks.py b/tests/functional/m/member_checks.py deleted file mode 100644 index 291daee12..000000000 --- a/tests/functional/m/member_checks.py +++ /dev/null @@ -1,233 +0,0 @@ -# pylint: disable=print-statement,missing-docstring,no-self-use,too-few-public-methods,bare-except,broad-except, useless-object-inheritance -# pylint: disable=using-constant-test,expression-not-assigned, assigning-non-slot, unused-variable,pointless-statement, wrong-import-order, wrong-import-position,import-outside-toplevel -from __future__ import print_function -class Provider(object): - """provide some attributes and method""" - cattr = 4 - def __init__(self): - self.attr = 4 - def method(self, val): - """impressive method""" - return self.attr * val - def hophop(self): - """hop method""" - print('hop hop hop', self) - - -class Client(object): - """use provider class""" - - def __init__(self): - self._prov = Provider() - self._prov_attr = Provider.cattr - self._prov_attr2 = Provider.cattribute # [no-member] - self.set_later = 0 - - def set_set_later(self, value): - """set set_later attribute (introduce an inference ambiguity)""" - self.set_later = value - - def use_method(self): - """use provider's method""" - self._prov.hophop() - self._prov.hophophop() # [no-member] - - def use_attr(self): - """use provider's attr""" - print(self._prov.attr) - print(self._prov.attribute) # [no-member] - - def debug(self): - """print debug information""" - print(self.__class__.__name__) - print(self.__doc__) - print(self.__dict__) - print(self.__module__) - - def test_bt_types(self): - """test access to unexistant member of builtin types""" - lis = [] - lis.apppend(self) # [no-member] - dic = {} - dic.set(self) # [no-member] - tup = () - tup.append(self) # [no-member] - string = 'toto' - print(string.loower()) # [no-member] - integer = 1 - print(integer.whatever) # [no-member] - - def test_no_false_positives(self): - none = None - print(none.whatever) - # No misssing in the parents. - super().misssing() # [no-member] - - -class Mixin(object): - """No no-member should be emitted for mixins.""" - -class Getattr(object): - """no-member shouldn't be emitted for classes with dunder getattr.""" - - def __getattr__(self, attr): - return self.__dict__[attr] - - -class Getattribute(object): - """no-member shouldn't be emitted for classes with dunder getattribute.""" - - def __getattribute__(self, attr): - return 42 - -print(object.__init__) -print(property.__init__) -print(Client().set_later.lower()) -print(Mixin().nanana()) -print(Getattr().nananan()) -print(Getattribute().batman()) - -try: - Client().missing_method() -except AttributeError: - pass - -try: - Client().indeed() # [no-member] -except ImportError: - pass - -try: - Client.missing() -except AttributeError: - Client.missing() # [no-member] - -try: - Client.missing() -except AttributeError: - try: - Client.missing() # [no-member] - except ValueError: - pass - -try: - if Client: - Client().missing() -except AttributeError: - pass - -try: - Client().indeed() -except AttributeError: - try: - Client.missing() # [no-member] - except Exception: - pass - - -class SuperChecks(str, str): # pylint: disable=duplicate-bases - """Don't fail when the MRO is invalid.""" - def test(self): - super().lalala() - -type(Client()).ala # [no-member] -type({}).bala # [no-member] -type('').portocala # [no-member] - - -def socket_false_positive(): - """Test a regression - Version used: - - - Pylint 0.10.0 - - Logilab common 0.15.0 - - Logilab astroid 0.15.1 - - False E1101 positive, line 23: - Instance of '_socketobject' has no 'connect' member - """ - - import socket - sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sckt.connect(('127.0.0.1', 80)) - sckt.close() - - -def no_conjugate_member(magic_flag): - """should not raise E1101 on something.conjugate""" - if magic_flag: - something = 1.0 - else: - something = 1.0j - if isinstance(something, float): - return something - return something.conjugate() - - -class NoDunderNameInInstance(object): - """Emit a warning when accessing __name__ from an instance.""" - def __init__(self): - self.var = self.__name__ # [no-member] - - -class InvalidAccessBySlots(object): - __slots__ = ('a', ) - def __init__(self): - var = self.teta # [no-member] - self.teta = 24 - - -class MetaWithDynamicGetattr(type): - - def __getattr__(cls, attr): - return attr - - -class SomeClass(object, metaclass=MetaWithDynamicGetattr): - pass - - -SomeClass.does_not_exist - -class ClassWithMangledAttribute(object): - def __init__(self): - self.name = 'Bug1643' - def __bar(self): - print(self.name + "xD") - -ClassWithMangledAttribute()._ClassWithMangledAttribute__bar() # pylint: disable=protected-access - - -import enum - - -class Cls(enum.IntEnum): - BAR = 0 - - -SOME_VALUE = Cls.BAZ # [no-member] - - - -# Does not crash when inferring the `append` attribute on the slice object -class SomeClassUsingSlice: - def __init__(self, flag): - if flag: - self.attribute = slice(None) - else: - self.attribute = [] - self.attribute.append(1) - -from enum import Enum -class Animal(Enum): - ANT = 1 - BEE = 2 - CAT = 3 - DOG = 4 -# To test false positive no-member on Enum.__members__.items() -for itm in Animal.__members__.items(): - print(itm) -for keyy in Animal.__members__.keys: - print(keyy) -for vall in Animal.__members__.values: - print(vall) diff --git a/tests/functional/m/member_checks.txt b/tests/functional/m/member_checks.txt deleted file mode 100644 index 0b7ee9478..000000000 --- a/tests/functional/m/member_checks.txt +++ /dev/null @@ -1,19 +0,0 @@ -no-member:23:27:Client.__init__:Class 'Provider' has no 'cattribute' member:INFERENCE -no-member:33:8:Client.use_method:Instance of 'Provider' has no 'hophophop' member:INFERENCE -no-member:38:14:Client.use_attr:Instance of 'Provider' has no 'attribute' member:INFERENCE -no-member:50:8:Client.test_bt_types:Instance of 'list' has no 'apppend' member; maybe 'append'?:INFERENCE -no-member:52:8:Client.test_bt_types:Instance of 'dict' has no 'set' member; maybe 'get'?:INFERENCE -no-member:54:8:Client.test_bt_types:Instance of 'tuple' has no 'append' member:INFERENCE -no-member:56:14:Client.test_bt_types:Instance of 'str' has no 'loower' member; maybe 'lower'?:INFERENCE -no-member:58:14:Client.test_bt_types:Instance of 'int' has no 'whatever' member:INFERENCE -no-member:64:8:Client.test_no_false_positives:Super of 'Client' has no 'misssing' member:INFERENCE -no-member:96:4::Instance of 'Client' has no 'indeed' member:INFERENCE -no-member:103:4::Class 'Client' has no 'missing' member:INFERENCE -no-member:109:8::Class 'Client' has no 'missing' member:INFERENCE -no-member:123:8::Class 'Client' has no 'missing' member:INFERENCE -no-member:133:0::Class 'Client' has no 'ala' member:INFERENCE -no-member:134:0::Class 'dict' has no 'bala' member:INFERENCE -no-member:135:0::Class 'str' has no 'portocala' member:INFERENCE -no-member:170:19:NoDunderNameInInstance.__init__:Instance of 'NoDunderNameInInstance' has no '__name__' member:INFERENCE -no-member:176:14:InvalidAccessBySlots.__init__:Instance of 'InvalidAccessBySlots' has no 'teta' member:INFERENCE -no-member:208:13::Class 'Cls' has no 'BAZ' member; maybe 'BAR'?:INFERENCE diff --git a/tests/functional/m/member_checks_hints.py b/tests/functional/m/member_checks_hints.py deleted file mode 100644 index 3925f4741..000000000 --- a/tests/functional/m/member_checks_hints.py +++ /dev/null @@ -1,27 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, pointless-statement, useless-object-inheritance - - -class Parent(object): - - def __init__(self): - self._parent = 42 - self._registry = {} - self._similar1 = 24 - self._similar2 = 23 - self._similar3 = 24 - self._really_similar1 = 23 - self._really_similar2 = 42 - - -class Child(Parent): - - def __init__(self): - super().__init__() - - self._similar # [no-member] - self._really_similar # [no-member] - self._paren # [no-member] - # Distance is too big - self._registryyyy # [no-member] - # Nothing close. - self._pretty_sure_this_wont_match # [no-member] diff --git a/tests/functional/m/member_checks_hints.rc b/tests/functional/m/member_checks_hints.rc deleted file mode 100644 index 8d4b587f4..000000000 --- a/tests/functional/m/member_checks_hints.rc +++ /dev/null @@ -1,3 +0,0 @@ -[TYPECHECK] -missing-member-max-choices = 3 -missing-member-hint-distance = 1 diff --git a/tests/functional/m/member_checks_hints.txt b/tests/functional/m/member_checks_hints.txt deleted file mode 100644 index 9dd977b13..000000000 --- a/tests/functional/m/member_checks_hints.txt +++ /dev/null @@ -1,5 +0,0 @@ -no-member:21:8:Child.__init__:Instance of 'Child' has no '_similar' member; maybe one of '_similar1', '_similar2' or '_similar3'?:INFERENCE -no-member:22:8:Child.__init__:Instance of 'Child' has no '_really_similar' member; maybe one of '_really_similar1' or '_really_similar2'?:INFERENCE -no-member:23:8:Child.__init__:Instance of 'Child' has no '_paren' member; maybe '_parent'?:INFERENCE -no-member:25:8:Child.__init__:Instance of 'Child' has no '_registryyyy' member:INFERENCE -no-member:27:8:Child.__init__:Instance of 'Child' has no '_pretty_sure_this_wont_match' member:INFERENCE diff --git a/tests/functional/m/member_checks_ignore_none.py b/tests/functional/m/member_checks_ignore_none.py deleted file mode 100644 index 06f01cb6a..000000000 --- a/tests/functional/m/member_checks_ignore_none.py +++ /dev/null @@ -1,7 +0,0 @@ -# pylint: disable=missing-docstring, useless-return - -def func(): - return None - - -SOME_VAR = func().DOES_NOT_EXIST # [no-member] diff --git a/tests/functional/m/member_checks_ignore_none.rc b/tests/functional/m/member_checks_ignore_none.rc deleted file mode 100644 index 9ec706ec6..000000000 --- a/tests/functional/m/member_checks_ignore_none.rc +++ /dev/null @@ -1,2 +0,0 @@ -[TYPECHECK] -ignore-none=no diff --git a/tests/functional/m/member_checks_ignore_none.txt b/tests/functional/m/member_checks_ignore_none.txt deleted file mode 100644 index ead0e7efe..000000000 --- a/tests/functional/m/member_checks_ignore_none.txt +++ /dev/null @@ -1 +0,0 @@ -no-member:7:11::Instance of 'NoneType' has no 'DOES_NOT_EXIST' member:INFERENCE diff --git a/tests/functional/m/member_checks_inference_improvements.py b/tests/functional/m/member_checks_inference_improvements.py deleted file mode 100644 index 6eefa7958..000000000 --- a/tests/functional/m/member_checks_inference_improvements.py +++ /dev/null @@ -1,11 +0,0 @@ -# pylint: disable=missing-docstring - - -def test_oserror_has_strerror(): - # https://github.com/PyCQA/pylint/issues/2553 - try: - raise OSError() - except OSError as exc: - if exc.strerror is not None: - return exc.strerror.lower() - return None diff --git a/tests/functional/m/member_checks_no_hints.py b/tests/functional/m/member_checks_no_hints.py deleted file mode 100644 index 3925f4741..000000000 --- a/tests/functional/m/member_checks_no_hints.py +++ /dev/null @@ -1,27 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, pointless-statement, useless-object-inheritance - - -class Parent(object): - - def __init__(self): - self._parent = 42 - self._registry = {} - self._similar1 = 24 - self._similar2 = 23 - self._similar3 = 24 - self._really_similar1 = 23 - self._really_similar2 = 42 - - -class Child(Parent): - - def __init__(self): - super().__init__() - - self._similar # [no-member] - self._really_similar # [no-member] - self._paren # [no-member] - # Distance is too big - self._registryyyy # [no-member] - # Nothing close. - self._pretty_sure_this_wont_match # [no-member] diff --git a/tests/functional/m/member_checks_no_hints.rc b/tests/functional/m/member_checks_no_hints.rc deleted file mode 100644 index 0f9c9ca3b..000000000 --- a/tests/functional/m/member_checks_no_hints.rc +++ /dev/null @@ -1,2 +0,0 @@ -[TYPECHECK] -missing-member-hint=no diff --git a/tests/functional/m/member_checks_no_hints.txt b/tests/functional/m/member_checks_no_hints.txt deleted file mode 100644 index 6d818641e..000000000 --- a/tests/functional/m/member_checks_no_hints.txt +++ /dev/null @@ -1,5 +0,0 @@ -no-member:21:8:Child.__init__:Instance of 'Child' has no '_similar' member:INFERENCE -no-member:22:8:Child.__init__:Instance of 'Child' has no '_really_similar' member:INFERENCE -no-member:23:8:Child.__init__:Instance of 'Child' has no '_paren' member:INFERENCE -no-member:25:8:Child.__init__:Instance of 'Child' has no '_registryyyy' member:INFERENCE -no-member:27:8:Child.__init__:Instance of 'Child' has no '_pretty_sure_this_wont_match' member:INFERENCE diff --git a/tests/functional/m/member_checks_opaque.py b/tests/functional/m/member_checks_opaque.py deleted file mode 100644 index 9b592af64..000000000 --- a/tests/functional/m/member_checks_opaque.py +++ /dev/null @@ -1,12 +0,0 @@ -# pylint: disable=missing-docstring,import-error - -from unknown import Unknown, some_value - - -def test(argument): - if argument: - return 42 - return Unknown - - -test(some_value).test() # [no-member] diff --git a/tests/functional/m/member_checks_opaque.rc b/tests/functional/m/member_checks_opaque.rc deleted file mode 100644 index 025cd2a0f..000000000 --- a/tests/functional/m/member_checks_opaque.rc +++ /dev/null @@ -1,2 +0,0 @@ -[TYPECHECK] -ignore-on-opaque-inference=n diff --git a/tests/functional/m/member_checks_opaque.txt b/tests/functional/m/member_checks_opaque.txt deleted file mode 100644 index 2fabce4e2..000000000 --- a/tests/functional/m/member_checks_opaque.txt +++ /dev/null @@ -1 +0,0 @@ -no-member:12:0::Instance of 'int' has no 'test' member:INFERENCE diff --git a/tests/functional/m/member_checks_py37.py b/tests/functional/m/member_checks_py37.py deleted file mode 100644 index 8d59b7d80..000000000 --- a/tests/functional/m/member_checks_py37.py +++ /dev/null @@ -1,19 +0,0 @@ -# pylint: disable=missing-docstring -import collections -import asyncio - -isinstance([], collections.Iterable) - - -async def gen(): - await asyncio.sleep(0.1) - value = yield 42 - print(value) - await asyncio.sleep(0.2) - - -async def test(): - generator = gen() - - await generator.asend(None) - await generator.send(None) # [no-member] diff --git a/tests/functional/m/member_checks_py37.rc b/tests/functional/m/member_checks_py37.rc deleted file mode 100644 index a17bb22da..000000000 --- a/tests/functional/m/member_checks_py37.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.7 diff --git a/tests/functional/m/member_checks_py37.txt b/tests/functional/m/member_checks_py37.txt deleted file mode 100644 index c52eab13c..000000000 --- a/tests/functional/m/member_checks_py37.txt +++ /dev/null @@ -1 +0,0 @@ -no-member:19:10:test:AsyncGenerator 'async_generator' has no 'send' member; maybe 'asend'?:INFERENCE diff --git a/tests/functional/m/member_checks_typed_annotations.py b/tests/functional/m/member_checks_typed_annotations.py deleted file mode 100644 index 90f775a43..000000000 --- a/tests/functional/m/member_checks_typed_annotations.py +++ /dev/null @@ -1,25 +0,0 @@ -# pylint: disable=missing-docstring,invalid-name,too-few-public-methods -class A: - myfield: int - -class B(A): - pass - -class C: - pass - -class D(C, B): - pass - - -a = A() -print(a.myfield) - -b = B() -print(b.myfield) - -d = D() -print(d.myfield) - -c = C() -print(c.myfield) # [no-member] diff --git a/tests/functional/m/member_checks_typed_annotations.txt b/tests/functional/m/member_checks_typed_annotations.txt deleted file mode 100644 index 6261a31aa..000000000 --- a/tests/functional/m/member_checks_typed_annotations.txt +++ /dev/null @@ -1 +0,0 @@ -no-member:25:6::Instance of 'C' has no 'myfield' member:INFERENCE diff --git a/tests/functional/m/membership_protocol.py b/tests/functional/m/membership_protocol.py deleted file mode 100644 index 3401f4bb4..000000000 --- a/tests/functional/m/membership_protocol.py +++ /dev/null @@ -1,123 +0,0 @@ -# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,too-few-public-methods,import-error,no-init,wrong-import-position,no-else-return, comparison-with-itself, useless-object-inheritance - -# standard types -1 in [1, 2, 3] -1 in {'a': 1, 'b': 2} -1 in {1, 2, 3} -1 in (1, 2, 3) -'1' in "123" -'1' in u"123" -'1' in bytearray(b"123") -1 in frozenset([1, 2, 3]) - -# comprehensions -1 in [x ** 2 % 10 for x in range(10)] -1 in {x ** 2 % 10 for x in range(10)} -1 in {x: x ** 2 % 10 for x in range(10)} - -# iterators -1 in iter([1, 2, 3]) - -# generator -def count(upto=float("inf")): - i = 0 - while True: - if i > upto: - break - yield i - i += 1 - -10 in count(upto=10) - -# custom instance -class UniversalContainer(object): - def __contains__(self, key): - return True - -42 in UniversalContainer() - -# custom iterable -class CustomIterable(object): - def __iter__(self): - return iter((1, 2, 3)) -3 in CustomIterable() - -# old-style iterable -class OldStyleIterable(object): - def __getitem__(self, key): - if key < 10: - return 2 ** key - else: - raise IndexError("bad index") -64 in OldStyleIterable() - -# do not emit warning if class has unknown bases -from some_missing_module import ImportedClass - -class MaybeIterable(ImportedClass): - pass - -10 in MaybeIterable() - -# do not emit warning inside mixins/abstract/base classes -class UsefulMixin(object): - stuff = None - - def get_stuff(self): - return self.stuff - - def act(self, thing): - stuff = self.get_stuff() - if thing in stuff: - pass - -class BaseThing(object): - valid_values = None - - def validate(self, value): - if self.valid_values is None: - return True - else: - # error should not be emitted here - return value in self.valid_values - -class AbstractThing(object): - valid_values = None - - def validate(self, value): - if self.valid_values is None: - return True - else: - # error should not be emitted here - return value in self.valid_values - -# class is not named as abstract -# but still is deduceably abstract -class Thing(object): - valid_values = None - - def __init__(self): - self._init_values() - - def validate(self, value): - if self.valid_values is None: - return True - else: - # error should not be emitted here - return value in self.valid_values - - def _init_values(self): - raise NotImplementedError - -# error cases -42 in 42 # [unsupported-membership-test] -42 not in None # [unsupported-membership-test] -42 in 8.5 # [unsupported-membership-test] - -class EmptyClass(object): - pass - -42 not in EmptyClass() # [unsupported-membership-test] -42 in EmptyClass # [unsupported-membership-test] -42 not in count # [unsupported-membership-test] -42 in range # [unsupported-membership-test] diff --git a/tests/functional/m/membership_protocol.txt b/tests/functional/m/membership_protocol.txt deleted file mode 100644 index e021062da..000000000 --- a/tests/functional/m/membership_protocol.txt +++ /dev/null @@ -1,7 +0,0 @@ -unsupported-membership-test:113:6::Value '42' doesn't support membership test -unsupported-membership-test:114:10::Value 'None' doesn't support membership test -unsupported-membership-test:115:6::Value '8.5' doesn't support membership test -unsupported-membership-test:120:10::Value 'EmptyClass()' doesn't support membership test -unsupported-membership-test:121:6::Value 'EmptyClass' doesn't support membership test -unsupported-membership-test:122:10::Value 'count' doesn't support membership test -unsupported-membership-test:123:6::Value 'range' doesn't support membership test diff --git a/tests/functional/m/membership_protocol_py3.py b/tests/functional/m/membership_protocol_py3.py deleted file mode 100644 index 678072354..000000000 --- a/tests/functional/m/membership_protocol_py3.py +++ /dev/null @@ -1,36 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,pointless-statement,expression-not-assigned - -# metaclasses that support membership test protocol -class MetaIterable(type): - def __iter__(cls): - return iter((1, 2, 3)) - -class MetaOldIterable(type): - def __getitem__(cls, key): - if key < 10: - return key ** 2 - - raise IndexError("bad index") - -class MetaContainer(type): - def __contains__(cls, key): - return False - - -class IterableClass(metaclass=MetaOldIterable): - pass - -class OldIterableClass(metaclass=MetaOldIterable): - pass - -class ContainerClass(metaclass=MetaContainer): - pass - - -def test(): - 1 in IterableClass - 1 in OldIterableClass - 1 in ContainerClass - 1 in IterableClass() # [unsupported-membership-test] - 1 in OldIterableClass() # [unsupported-membership-test] - 1 in ContainerClass() # [unsupported-membership-test] diff --git a/tests/functional/m/membership_protocol_py3.rc b/tests/functional/m/membership_protocol_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/m/membership_protocol_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/m/membership_protocol_py3.txt b/tests/functional/m/membership_protocol_py3.txt deleted file mode 100644 index 495cf94db..000000000 --- a/tests/functional/m/membership_protocol_py3.txt +++ /dev/null @@ -1,3 +0,0 @@ -unsupported-membership-test:34:9:test:Value 'IterableClass()' doesn't support membership test -unsupported-membership-test:35:9:test:Value 'OldIterableClass()' doesn't support membership test -unsupported-membership-test:36:9:test:Value 'ContainerClass()' doesn't support membership test diff --git a/tests/functional/m/missing/missing_docstring.py b/tests/functional/m/missing/missing_docstring.py new file mode 100644 index 000000000..72d6762aa --- /dev/null +++ b/tests/functional/m/missing/missing_docstring.py @@ -0,0 +1,58 @@ +# [missing-module-docstring] +# pylint: disable=too-few-public-methods, useless-object-inheritance + +def public_documented(): + """It has a docstring.""" + + +def _private_undocumented(): + # Doesn't need a docstring + pass + + +def _private_documented(): + """It has a docstring.""" + + +class ClassDocumented(object): + """It has a docstring.""" + + +class ClassUndocumented(object): # [missing-class-docstring] + pass + + +def public_undocumented(): # [missing-function-docstring] + pass + + +def __sizeof__(): + # Special + pass + + +def __mangled(): + pass + + +class Property(object): + """Don't warn about setters and deleters.""" + + def __init__(self): + self._value = None + + @property + def test(self): + """Default docstring for setters and deleters.""" + + @test.setter + def test(self, value): + self._value = value + + @test.deleter + def test(self): + pass + + +class DocumentedViaDunderDoc(object): + __doc__ = "This one" diff --git a/tests/functional/m/missing/missing_docstring.txt b/tests/functional/m/missing/missing_docstring.txt new file mode 100644 index 000000000..c9ec52161 --- /dev/null +++ b/tests/functional/m/missing/missing_docstring.txt @@ -0,0 +1,3 @@ +missing-module-docstring:1:0::Missing module docstring +missing-class-docstring:21:0:ClassUndocumented:Missing class docstring +missing-function-docstring:25:0:public_undocumented:Missing function or method docstring diff --git a/tests/functional/m/missing/missing_docstring_new_style.py b/tests/functional/m/missing/missing_docstring_new_style.py new file mode 100644 index 000000000..58c7c1ec8 --- /dev/null +++ b/tests/functional/m/missing/missing_docstring_new_style.py @@ -0,0 +1,47 @@ +# [missing-module-docstring] +# pylint: disable=too-few-public-methods + + +class ClassDocumented: + """It has a docstring.""" + + +class UndocumentedClass: # [missing-class-docstring] + pass + + +# pylint: disable=missing-class-docstring +class ClassUndocumented: + pass + + +# pylint: enable=missing-class-docstring +class OtherClassUndocumented: # [missing-class-docstring] + pass + + +def public_documented(): + """It has a docstring.""" + + +def _private_undocumented(): + # Doesn't need a docstring + pass + + +def _private_documented(): + """It has a docstring.""" + + +def public_undocumented(): # [missing-function-docstring] + pass + + +# pylint: disable=missing-function-docstring +def undocumented_function(): + pass + + +# pylint: enable=missing-function-docstring +def undocumented_other_function(): # [missing-function-docstring] + pass diff --git a/tests/functional/m/missing/missing_docstring_new_style.txt b/tests/functional/m/missing/missing_docstring_new_style.txt new file mode 100644 index 000000000..f194673fe --- /dev/null +++ b/tests/functional/m/missing/missing_docstring_new_style.txt @@ -0,0 +1,5 @@ +missing-module-docstring:1:0::Missing module docstring +missing-class-docstring:9:0:UndocumentedClass:Missing class docstring +missing-class-docstring:19:0:OtherClassUndocumented:Missing class docstring +missing-function-docstring:36:0:public_undocumented:Missing function or method docstring +missing-function-docstring:46:0:undocumented_other_function:Missing function or method docstring diff --git a/tests/functional/m/missing/missing_final_newline.py b/tests/functional/m/missing/missing_final_newline.py new file mode 100644 index 000000000..370f902b7 --- /dev/null +++ b/tests/functional/m/missing/missing_final_newline.py @@ -0,0 +1,4 @@ +"""This file does not have a final newline.""" +from __future__ import print_function +# +1:[missing-final-newline] +print(1) \ No newline at end of file diff --git a/tests/functional/m/missing/missing_final_newline.txt b/tests/functional/m/missing/missing_final_newline.txt new file mode 100644 index 000000000..d7c329b70 --- /dev/null +++ b/tests/functional/m/missing/missing_final_newline.txt @@ -0,0 +1 @@ +missing-final-newline:4:0::Final newline missing diff --git a/tests/functional/m/missing/missing_kwoa_py3.py b/tests/functional/m/missing/missing_kwoa_py3.py new file mode 100644 index 000000000..b4dc604cd --- /dev/null +++ b/tests/functional/m/missing/missing_kwoa_py3.py @@ -0,0 +1,73 @@ +# pylint: disable=missing-docstring,unused-argument,too-few-public-methods +import typing + + +def target(pos, *, keyword): + return pos + keyword + + +def forwarding_kwds(pos, **kwds): + target(pos, **kwds) + + +def forwarding_args(*args, keyword): + target(*args, keyword=keyword) + +def forwarding_conversion(*args, **kwargs): + target(*args, **dict(kwargs)) + + +def not_forwarding_kwargs(*args, **kwargs): + target(*args) # [missing-kwoa] + + +target(1, keyword=2) + +PARAM = 1 +target(2, PARAM) # [too-many-function-args, missing-kwoa] + + +def some_function(*, param): + return param + 2 + + +def other_function(**kwargs): + return some_function(**kwargs) # Does not trigger missing-kwoa + + +other_function(param=2) + + +class Parent: + + @typing.overload + def __init__( self, *, first, second, third): + pass + + @typing.overload + def __init__(self, *, first, second): + pass + + @typing.overload + def __init__(self, *, first): + pass + + def __init__( + self, + *, + first, + second: typing.Optional[str] = None, + third: typing.Optional[str] = None): + self._first = first + self._second = second + self._third = third + + +class Child(Parent): + def __init__( + self, + *, + first, + second): + super().__init__(first=first, second=second) + self._first = first + second diff --git a/tests/functional/m/missing/missing_kwoa_py3.rc b/tests/functional/m/missing/missing_kwoa_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/m/missing/missing_kwoa_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/m/missing/missing_kwoa_py3.txt b/tests/functional/m/missing/missing_kwoa_py3.txt new file mode 100644 index 000000000..710635504 --- /dev/null +++ b/tests/functional/m/missing/missing_kwoa_py3.txt @@ -0,0 +1,3 @@ +missing-kwoa:21:4:not_forwarding_kwargs:Missing mandatory keyword argument 'keyword' in function call +missing-kwoa:27:0::Missing mandatory keyword argument 'keyword' in function call +too-many-function-args:27:0::Too many positional arguments for function call diff --git a/tests/functional/m/missing/missing_module_docstring_disabled.py b/tests/functional/m/missing/missing_module_docstring_disabled.py new file mode 100644 index 000000000..d4d9edf3f --- /dev/null +++ b/tests/functional/m/missing/missing_module_docstring_disabled.py @@ -0,0 +1,5 @@ +# pylint: disable=missing-module-docstring, too-few-public-methods + + +class Documented: + "Something." diff --git a/tests/functional/m/missing/missing_parentheses_for_call_in_test.py b/tests/functional/m/missing/missing_parentheses_for_call_in_test.py new file mode 100644 index 000000000..cd1d76a8d --- /dev/null +++ b/tests/functional/m/missing/missing_parentheses_for_call_in_test.py @@ -0,0 +1,95 @@ +"""Verify if call to function or method inside tests are missing parentheses.""" +# pylint: disable=using-constant-test, missing-docstring, useless-object-inheritance +# pylint: disable=invalid-name, expression-not-assigned + +import collections + + +def bool_function(): + return True + +def nonbool_function(): + return 42 + + +class Class(object): + + @staticmethod + def bool_method(): + return False + + @staticmethod + def nonbool_method(): + return 42 + + +if collections: + pass + +if bool_function: # [missing-parentheses-for-call-in-test] + pass + +if not bool_function(): + pass + +if nonbool_function: # [missing-parentheses-for-call-in-test] + pass + +if nonbool_function() != 42: + pass + +instance = Class() + +if instance.bool_method: # [missing-parentheses-for-call-in-test] + pass + +if not instance.bool_method(): + pass + +if not instance.nonbool_method: + pass +elif instance.bool_method: # [missing-parentheses-for-call-in-test] + pass + +bool_lambda = lambda: True + +if bool_lambda: # [missing-parentheses-for-call-in-test] + pass + +if not bool_lambda(): + pass + +nonbool_lambda = lambda: 42 + +if nonbool_lambda: # [missing-parentheses-for-call-in-test] + pass + +if not nonbool_lambda(): + pass + +MY_VALUE = 42 if bool_function else -1 # [missing-parentheses-for-call-in-test] +MY_2ND_VALUE = 42 if not bool_function() else -1 +MY_THIRD_VALUE = 42 if bool_lambda else -1 # [missing-parentheses-for-call-in-test] +MY_FOURTH_VALUE = 42 if nonbool_lambda else -1 # [missing-parentheses-for-call-in-test] + +[x for x in range(100) if bool_function] # [missing-parentheses-for-call-in-test] +[x for x in range(100) if bool_lambda] # [missing-parentheses-for-call-in-test] +[x for x in range(100) if not bool_function()] +[x for x in range(100) if not bool_lambda()] +[x for x in range(100) if nonbool_lambda] # [missing-parentheses-for-call-in-test] +[x for x in range(100) if nonbool_function] # [missing-parentheses-for-call-in-test] + +def non_const_node_function(): + return (1, 2, 42) + +if non_const_node_function: # [missing-parentheses-for-call-in-test] + pass + +def yielding_function(): + yield 42 + +if yielding_function: # [missing-parentheses-for-call-in-test] + pass + +if not yielding_function(): + pass diff --git a/tests/functional/m/missing/missing_parentheses_for_call_in_test.txt b/tests/functional/m/missing/missing_parentheses_for_call_in_test.txt new file mode 100644 index 000000000..0547c6e30 --- /dev/null +++ b/tests/functional/m/missing/missing_parentheses_for_call_in_test.txt @@ -0,0 +1,15 @@ +missing-parentheses-for-call-in-test:29:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:35:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:43:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:51:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:56:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:64:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:70:11::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:72:17::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:73:18::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:75:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:76:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:79:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:80:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:85:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses +missing-parentheses-for-call-in-test:91:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses diff --git a/tests/functional/m/missing/missing_self_argument.py b/tests/functional/m/missing/missing_self_argument.py new file mode 100644 index 000000000..79ae34879 --- /dev/null +++ b/tests/functional/m/missing/missing_self_argument.py @@ -0,0 +1,21 @@ +"""Checks that missing self in method defs don't crash Pylint.""" +# pylint: disable=useless-object-inheritance + + + +class MyClass(object): + """A class with some methods missing self args.""" + + def __init__(self): + self.var = "var" + + def method(): # [no-method-argument] + """A method without a self argument.""" + + def setup(): # [no-method-argument] + """A method without a self argument, but usage.""" + self.var = 1 # [undefined-variable] + + def correct(self): + """Correct.""" + self.var = "correct" diff --git a/tests/functional/m/missing/missing_self_argument.txt b/tests/functional/m/missing/missing_self_argument.txt new file mode 100644 index 000000000..1b7626244 --- /dev/null +++ b/tests/functional/m/missing/missing_self_argument.txt @@ -0,0 +1,3 @@ +no-method-argument:12:4:MyClass.method:Method has no argument +no-method-argument:15:4:MyClass.setup:Method has no argument +undefined-variable:17:8:MyClass.setup:Undefined variable 'self' diff --git a/tests/functional/m/missing_docstring.py b/tests/functional/m/missing_docstring.py deleted file mode 100644 index 72d6762aa..000000000 --- a/tests/functional/m/missing_docstring.py +++ /dev/null @@ -1,58 +0,0 @@ -# [missing-module-docstring] -# pylint: disable=too-few-public-methods, useless-object-inheritance - -def public_documented(): - """It has a docstring.""" - - -def _private_undocumented(): - # Doesn't need a docstring - pass - - -def _private_documented(): - """It has a docstring.""" - - -class ClassDocumented(object): - """It has a docstring.""" - - -class ClassUndocumented(object): # [missing-class-docstring] - pass - - -def public_undocumented(): # [missing-function-docstring] - pass - - -def __sizeof__(): - # Special - pass - - -def __mangled(): - pass - - -class Property(object): - """Don't warn about setters and deleters.""" - - def __init__(self): - self._value = None - - @property - def test(self): - """Default docstring for setters and deleters.""" - - @test.setter - def test(self, value): - self._value = value - - @test.deleter - def test(self): - pass - - -class DocumentedViaDunderDoc(object): - __doc__ = "This one" diff --git a/tests/functional/m/missing_docstring.txt b/tests/functional/m/missing_docstring.txt deleted file mode 100644 index c9ec52161..000000000 --- a/tests/functional/m/missing_docstring.txt +++ /dev/null @@ -1,3 +0,0 @@ -missing-module-docstring:1:0::Missing module docstring -missing-class-docstring:21:0:ClassUndocumented:Missing class docstring -missing-function-docstring:25:0:public_undocumented:Missing function or method docstring diff --git a/tests/functional/m/missing_docstring_new_style.py b/tests/functional/m/missing_docstring_new_style.py deleted file mode 100644 index 58c7c1ec8..000000000 --- a/tests/functional/m/missing_docstring_new_style.py +++ /dev/null @@ -1,47 +0,0 @@ -# [missing-module-docstring] -# pylint: disable=too-few-public-methods - - -class ClassDocumented: - """It has a docstring.""" - - -class UndocumentedClass: # [missing-class-docstring] - pass - - -# pylint: disable=missing-class-docstring -class ClassUndocumented: - pass - - -# pylint: enable=missing-class-docstring -class OtherClassUndocumented: # [missing-class-docstring] - pass - - -def public_documented(): - """It has a docstring.""" - - -def _private_undocumented(): - # Doesn't need a docstring - pass - - -def _private_documented(): - """It has a docstring.""" - - -def public_undocumented(): # [missing-function-docstring] - pass - - -# pylint: disable=missing-function-docstring -def undocumented_function(): - pass - - -# pylint: enable=missing-function-docstring -def undocumented_other_function(): # [missing-function-docstring] - pass diff --git a/tests/functional/m/missing_docstring_new_style.txt b/tests/functional/m/missing_docstring_new_style.txt deleted file mode 100644 index f194673fe..000000000 --- a/tests/functional/m/missing_docstring_new_style.txt +++ /dev/null @@ -1,5 +0,0 @@ -missing-module-docstring:1:0::Missing module docstring -missing-class-docstring:9:0:UndocumentedClass:Missing class docstring -missing-class-docstring:19:0:OtherClassUndocumented:Missing class docstring -missing-function-docstring:36:0:public_undocumented:Missing function or method docstring -missing-function-docstring:46:0:undocumented_other_function:Missing function or method docstring diff --git a/tests/functional/m/missing_final_newline.py b/tests/functional/m/missing_final_newline.py deleted file mode 100644 index 370f902b7..000000000 --- a/tests/functional/m/missing_final_newline.py +++ /dev/null @@ -1,4 +0,0 @@ -"""This file does not have a final newline.""" -from __future__ import print_function -# +1:[missing-final-newline] -print(1) \ No newline at end of file diff --git a/tests/functional/m/missing_final_newline.txt b/tests/functional/m/missing_final_newline.txt deleted file mode 100644 index d7c329b70..000000000 --- a/tests/functional/m/missing_final_newline.txt +++ /dev/null @@ -1 +0,0 @@ -missing-final-newline:4:0::Final newline missing diff --git a/tests/functional/m/missing_kwoa_py3.py b/tests/functional/m/missing_kwoa_py3.py deleted file mode 100644 index b4dc604cd..000000000 --- a/tests/functional/m/missing_kwoa_py3.py +++ /dev/null @@ -1,73 +0,0 @@ -# pylint: disable=missing-docstring,unused-argument,too-few-public-methods -import typing - - -def target(pos, *, keyword): - return pos + keyword - - -def forwarding_kwds(pos, **kwds): - target(pos, **kwds) - - -def forwarding_args(*args, keyword): - target(*args, keyword=keyword) - -def forwarding_conversion(*args, **kwargs): - target(*args, **dict(kwargs)) - - -def not_forwarding_kwargs(*args, **kwargs): - target(*args) # [missing-kwoa] - - -target(1, keyword=2) - -PARAM = 1 -target(2, PARAM) # [too-many-function-args, missing-kwoa] - - -def some_function(*, param): - return param + 2 - - -def other_function(**kwargs): - return some_function(**kwargs) # Does not trigger missing-kwoa - - -other_function(param=2) - - -class Parent: - - @typing.overload - def __init__( self, *, first, second, third): - pass - - @typing.overload - def __init__(self, *, first, second): - pass - - @typing.overload - def __init__(self, *, first): - pass - - def __init__( - self, - *, - first, - second: typing.Optional[str] = None, - third: typing.Optional[str] = None): - self._first = first - self._second = second - self._third = third - - -class Child(Parent): - def __init__( - self, - *, - first, - second): - super().__init__(first=first, second=second) - self._first = first + second diff --git a/tests/functional/m/missing_kwoa_py3.rc b/tests/functional/m/missing_kwoa_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/m/missing_kwoa_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/m/missing_kwoa_py3.txt b/tests/functional/m/missing_kwoa_py3.txt deleted file mode 100644 index 710635504..000000000 --- a/tests/functional/m/missing_kwoa_py3.txt +++ /dev/null @@ -1,3 +0,0 @@ -missing-kwoa:21:4:not_forwarding_kwargs:Missing mandatory keyword argument 'keyword' in function call -missing-kwoa:27:0::Missing mandatory keyword argument 'keyword' in function call -too-many-function-args:27:0::Too many positional arguments for function call diff --git a/tests/functional/m/missing_module_docstring_disabled.py b/tests/functional/m/missing_module_docstring_disabled.py deleted file mode 100644 index d4d9edf3f..000000000 --- a/tests/functional/m/missing_module_docstring_disabled.py +++ /dev/null @@ -1,5 +0,0 @@ -# pylint: disable=missing-module-docstring, too-few-public-methods - - -class Documented: - "Something." diff --git a/tests/functional/m/missing_parentheses_for_call_in_test.py b/tests/functional/m/missing_parentheses_for_call_in_test.py deleted file mode 100644 index cd1d76a8d..000000000 --- a/tests/functional/m/missing_parentheses_for_call_in_test.py +++ /dev/null @@ -1,95 +0,0 @@ -"""Verify if call to function or method inside tests are missing parentheses.""" -# pylint: disable=using-constant-test, missing-docstring, useless-object-inheritance -# pylint: disable=invalid-name, expression-not-assigned - -import collections - - -def bool_function(): - return True - -def nonbool_function(): - return 42 - - -class Class(object): - - @staticmethod - def bool_method(): - return False - - @staticmethod - def nonbool_method(): - return 42 - - -if collections: - pass - -if bool_function: # [missing-parentheses-for-call-in-test] - pass - -if not bool_function(): - pass - -if nonbool_function: # [missing-parentheses-for-call-in-test] - pass - -if nonbool_function() != 42: - pass - -instance = Class() - -if instance.bool_method: # [missing-parentheses-for-call-in-test] - pass - -if not instance.bool_method(): - pass - -if not instance.nonbool_method: - pass -elif instance.bool_method: # [missing-parentheses-for-call-in-test] - pass - -bool_lambda = lambda: True - -if bool_lambda: # [missing-parentheses-for-call-in-test] - pass - -if not bool_lambda(): - pass - -nonbool_lambda = lambda: 42 - -if nonbool_lambda: # [missing-parentheses-for-call-in-test] - pass - -if not nonbool_lambda(): - pass - -MY_VALUE = 42 if bool_function else -1 # [missing-parentheses-for-call-in-test] -MY_2ND_VALUE = 42 if not bool_function() else -1 -MY_THIRD_VALUE = 42 if bool_lambda else -1 # [missing-parentheses-for-call-in-test] -MY_FOURTH_VALUE = 42 if nonbool_lambda else -1 # [missing-parentheses-for-call-in-test] - -[x for x in range(100) if bool_function] # [missing-parentheses-for-call-in-test] -[x for x in range(100) if bool_lambda] # [missing-parentheses-for-call-in-test] -[x for x in range(100) if not bool_function()] -[x for x in range(100) if not bool_lambda()] -[x for x in range(100) if nonbool_lambda] # [missing-parentheses-for-call-in-test] -[x for x in range(100) if nonbool_function] # [missing-parentheses-for-call-in-test] - -def non_const_node_function(): - return (1, 2, 42) - -if non_const_node_function: # [missing-parentheses-for-call-in-test] - pass - -def yielding_function(): - yield 42 - -if yielding_function: # [missing-parentheses-for-call-in-test] - pass - -if not yielding_function(): - pass diff --git a/tests/functional/m/missing_parentheses_for_call_in_test.txt b/tests/functional/m/missing_parentheses_for_call_in_test.txt deleted file mode 100644 index 0547c6e30..000000000 --- a/tests/functional/m/missing_parentheses_for_call_in_test.txt +++ /dev/null @@ -1,15 +0,0 @@ -missing-parentheses-for-call-in-test:29:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:35:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:43:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:51:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:56:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:64:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:70:11::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:72:17::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:73:18::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:75:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:76:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:79:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:80:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:85:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses -missing-parentheses-for-call-in-test:91:0::Using a conditional statement with potentially wrong function or method call due to missing parentheses diff --git a/tests/functional/m/missing_self_argument.py b/tests/functional/m/missing_self_argument.py deleted file mode 100644 index 79ae34879..000000000 --- a/tests/functional/m/missing_self_argument.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Checks that missing self in method defs don't crash Pylint.""" -# pylint: disable=useless-object-inheritance - - - -class MyClass(object): - """A class with some methods missing self args.""" - - def __init__(self): - self.var = "var" - - def method(): # [no-method-argument] - """A method without a self argument.""" - - def setup(): # [no-method-argument] - """A method without a self argument, but usage.""" - self.var = 1 # [undefined-variable] - - def correct(self): - """Correct.""" - self.var = "correct" diff --git a/tests/functional/m/missing_self_argument.txt b/tests/functional/m/missing_self_argument.txt deleted file mode 100644 index 1b7626244..000000000 --- a/tests/functional/m/missing_self_argument.txt +++ /dev/null @@ -1,3 +0,0 @@ -no-method-argument:12:4:MyClass.method:Method has no argument -no-method-argument:15:4:MyClass.setup:Method has no argument -undefined-variable:17:8:MyClass.setup:Undefined variable 'self' diff --git a/tests/functional/n/name/namePresetCamelCase.py b/tests/functional/n/name/namePresetCamelCase.py new file mode 100644 index 000000000..e048ec4d8 --- /dev/null +++ b/tests/functional/n/name/namePresetCamelCase.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,too-few-public-methods +__version__ = "1.0" +SOME_CONSTANT = 42 # [invalid-name] + + +def sayHello(someArgument): + return [someArgument * someValue for someValue in range(10)] + + +class MyClass: # [invalid-name] + def __init__(self, argX): + self._mySecretX = argX + + @property + def myPublicX(self): + return self._mySecretX * 2 + + def __eq__(self, other): + return isinstance(other, MyClass) and self.myPublicX == other.myPublicX + + +def say_hello(): # [invalid-name] + pass diff --git a/tests/functional/n/name/namePresetCamelCase.rc b/tests/functional/n/name/namePresetCamelCase.rc new file mode 100644 index 000000000..29f44504a --- /dev/null +++ b/tests/functional/n/name/namePresetCamelCase.rc @@ -0,0 +1,13 @@ +[BASIC] +function-naming-style=camelCase +const-naming-style=camelCase +attr-naming-style=camelCase +argument-naming-style=camelCase +module-naming-style=camelCase +method-naming-style=camelCase +variable-naming-style=camelCase +class-attribute-naming-style=camelCase +inlinevar-naming-style=camelCase +class-naming-style=camelCase + +include-naming-hint=yes diff --git a/tests/functional/n/name/namePresetCamelCase.txt b/tests/functional/n/name/namePresetCamelCase.txt new file mode 100644 index 000000000..b24b0a881 --- /dev/null +++ b/tests/functional/n/name/namePresetCamelCase.txt @@ -0,0 +1,3 @@ +invalid-name:3:0::"Constant name ""SOME_CONSTANT"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]*|__.*__)$' pattern)" +invalid-name:10:0:MyClass:"Class name ""MyClass"" doesn't conform to camelCase naming style ('[^\\W\\dA-Z][^\\W_]+$' pattern)" +invalid-name:22:0:say_hello:"Function name ""say_hello"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]{2,}|__[^\\W\\dA-Z_]\\w+__)$' pattern)" diff --git a/tests/functional/n/name/name_good_bad_names_regex.py b/tests/functional/n/name/name_good_bad_names_regex.py new file mode 100644 index 000000000..f1ed4b91b --- /dev/null +++ b/tests/functional/n/name/name_good_bad_names_regex.py @@ -0,0 +1,20 @@ +# pylint: disable=missing-docstring,too-few-public-methods +__version__ = "1.0" +ignored_SOME_CONSTANT = 42 + +explicit_bad_some_constant = 42 # [blacklisted-name] + +snake_case_bad_SOME_CONSTANT = 42 # [invalid-name] + + +class my_class: + def __init__(self, arg_x): + self._my_secret_x = arg_x + + @property + def my_public_x(self): + return self._my_secret_x * 2 + + +def blacklisted_2_snake_case(): # [blacklisted-name] + pass diff --git a/tests/functional/n/name/name_good_bad_names_regex.rc b/tests/functional/n/name/name_good_bad_names_regex.rc new file mode 100644 index 000000000..8246438cd --- /dev/null +++ b/tests/functional/n/name/name_good_bad_names_regex.rc @@ -0,0 +1,15 @@ +[BASIC] +function-naming-style=snake_case +const-naming-style=snake_case +attr-naming-style=snake_case +argument-naming-style=snake_case +module-naming-style=snake_case +method-naming-style=snake_case +variable-naming-style=snake_case +class-attribute-naming-style=snake_case +inlinevar-naming-style=snake_case +class-naming-style=snake_case + +good-names-rgxs=ignored.* +bad-names-rgxs=explicit.*,blacklisted.* +include-naming-hint=yes diff --git a/tests/functional/n/name/name_good_bad_names_regex.txt b/tests/functional/n/name/name_good_bad_names_regex.txt new file mode 100644 index 000000000..08aef7d78 --- /dev/null +++ b/tests/functional/n/name/name_good_bad_names_regex.txt @@ -0,0 +1,3 @@ +blacklisted-name:5:0::Black listed name "explicit_bad_some_constant" +invalid-name:7:0::"Constant name ""snake_case_bad_SOME_CONSTANT"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]*|__.*__)$' pattern)" +blacklisted-name:19:0:blacklisted_2_snake_case:Black listed name "blacklisted_2_snake_case" diff --git a/tests/functional/n/name/name_preset_snake_case.py b/tests/functional/n/name/name_preset_snake_case.py new file mode 100644 index 000000000..75350497e --- /dev/null +++ b/tests/functional/n/name/name_preset_snake_case.py @@ -0,0 +1,35 @@ +# pylint: disable=missing-docstring,too-few-public-methods +from enum import Enum +from typing import ClassVar + +__version__ = "1.0" +SOME_CONSTANT = 42 # [invalid-name] + + +def say_hello(some_argument): + return [some_argument * some_value for some_value in range(10)] + + +class MyClass: # [invalid-name] + def __init__(self, arg_x): + self._my_secret_x = arg_x + + @property + def my_public_x(self): + return self._my_secret_x * 2 + + def __eq__(self, other): + return isinstance(other, MyClass) and self.my_public_x == other.my_public_x + + +def sayHello(): # [invalid-name] + pass + + +class FooEnum(Enum): # [invalid-name] + const_with_snake_case = 42 + another_const = 43 + + +class Bar: # [invalid-name] + const_with_snake_case: ClassVar[int] = 42 diff --git a/tests/functional/n/name/name_preset_snake_case.rc b/tests/functional/n/name/name_preset_snake_case.rc new file mode 100644 index 000000000..2b04af5d4 --- /dev/null +++ b/tests/functional/n/name/name_preset_snake_case.rc @@ -0,0 +1,14 @@ +[BASIC] +function-naming-style=snake_case +const-naming-style=snake_case +attr-naming-style=snake_case +argument-naming-style=snake_case +module-naming-style=snake_case +method-naming-style=snake_case +variable-naming-style=snake_case +class-attribute-naming-style=snake_case +class-const-naming-style=snake_case +inlinevar-naming-style=snake_case +class-naming-style=snake_case + +include-naming-hint=yes diff --git a/tests/functional/n/name/name_preset_snake_case.txt b/tests/functional/n/name/name_preset_snake_case.txt new file mode 100644 index 000000000..c189797e9 --- /dev/null +++ b/tests/functional/n/name/name_preset_snake_case.txt @@ -0,0 +1,5 @@ +invalid-name:6:0::"Constant name ""SOME_CONSTANT"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]*|__.*__)$' pattern)" +invalid-name:13:0:MyClass:"Class name ""MyClass"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)" +invalid-name:25:0:sayHello:"Function name ""sayHello"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]{2,}|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)" +invalid-name:29:0:FooEnum:"Class name ""FooEnum"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)" +invalid-name:34:0:Bar:"Class name ""Bar"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)" diff --git a/tests/functional/n/name/name_styles.py b/tests/functional/n/name/name_styles.py new file mode 100644 index 000000000..394c82826 --- /dev/null +++ b/tests/functional/n/name/name_styles.py @@ -0,0 +1,156 @@ +"""Test for the invalid-name warning.""" +# pylint: disable=no-absolute-import, useless-object-inheritance, unnecessary-pass, unnecessary-comprehension +from __future__ import print_function +import abc +import collections +from enum import Enum +from typing import ClassVar + +GOOD_CONST_NAME = '' +bad_const_name = 0 # [invalid-name] + + +def BADFUNCTION_name(): # [invalid-name] + """Bad function name.""" + BAD_LOCAL_VAR = 1 # [invalid-name] + print(BAD_LOCAL_VAR) + + +def func_bad_argname(NOT_GOOD): # [invalid-name] + """Function with a badly named argument.""" + return NOT_GOOD + + +def no_nested_args(arg1, arg21, arg22): + """Well-formed function.""" + print(arg1, arg21, arg22) + + +class bad_class_name(object): # [invalid-name] + """Class with a bad name.""" + + +class CorrectClassName(object): + """Class with a good name.""" + + def __init__(self): + self._good_private_name = 10 + self.__good_real_private_name = 11 + self.good_attribute_name = 12 + self._Bad_AtTR_name = None # [invalid-name] + self.Bad_PUBLIC_name = None # [invalid-name] + + zz = 'Why Was It Bad Class Attribute?' + GOOD_CLASS_ATTR = 'Good Class Attribute' + + def BadMethodName(self): # [invalid-name] + """A Method with a bad name.""" + + def good_method_name(self): + """A method with a good name.""" + + def __DunDER_IS_not_free_for_all__(self): # [invalid-name] + """Another badly named method.""" + + +class DerivedFromCorrect(CorrectClassName): + """A derived class with an invalid inherited members. + + Derived attributes and methods with invalid names do not trigger warnings. + """ + zz = 'Now a good class attribute' + + def __init__(self): + super().__init__() + self._Bad_AtTR_name = None # Ignored + + def BadMethodName(self): + """Ignored since the method is in the interface.""" + + +V = [WHAT_Ever_inListComp for WHAT_Ever_inListComp in GOOD_CONST_NAME] + +def class_builder(): + """Function returning a class object.""" + + class EmbeddedClass(object): + """Useless class.""" + + return EmbeddedClass + +# +1:[invalid-name] +BAD_NAME_FOR_CLASS = collections.namedtuple('Named', ['tuple']) +NEXT_BAD_NAME_FOR_CLASS = class_builder() # [invalid-name] + +GoodName = collections.namedtuple('Named', ['tuple']) +ToplevelClass = class_builder() + +# Aliases for classes have the same name constraints. +AlsoCorrect = CorrectClassName +NOT_CORRECT = CorrectClassName # [invalid-name] + + +def test_globals(): + """Names in global statements are also checked.""" + global NOT_CORRECT + global AlsoCorrect # [invalid-name] + NOT_CORRECT = 1 + AlsoCorrect = 2 + + +class FooClass(object): + """A test case for property names. + + Since by default, the regex for attributes is the same as the one + for method names, we check the warning messages to contain the + string 'attribute'. + """ + @property + def PROPERTY_NAME(self): # [invalid-name] + """Ignored.""" + pass + + @abc.abstractproperty + def ABSTRACT_PROPERTY_NAME(self): # [invalid-name] + """Ignored.""" + pass + + @PROPERTY_NAME.setter + def PROPERTY_NAME_SETTER(self): # [invalid-name] + """Ignored.""" + pass + + def _nice_and_long_descriptive_private_method_name(self): + """private method with long name""" + pass + + +def good_public_function_name(good_arg_name): + """This is a perfect public function""" + good_variable_name = 1 + return good_variable_name + good_arg_name + + +def _private_scope_function_with_long_descriptive_name(): + """Private scope function are cool with long descriptive names""" + return 12 + +LONG_CONSTANT_NAME_IN_PUBLIC_SCOPE_ARE_OKAY = True +# We don't emit for non-const nodes +good_name_for_funcs = lambda: None +good_name_for_lists = [1, 2, 3] + +class _AnExceptionalExceptionThatOccursVeryVeryRarely(Exception): + """A very exceptional exception with a nice descriptive name""" + pass + +class FooEnum(Enum): + """A test case for enum names.""" + GOOD_ENUM_NAME = 1 + bad_enum_name = 2 # [invalid-name] + +class Bar: + """Class with class constants annotated with ClassVar.""" + CLASS_CONST: ClassVar[int] = 42 + CLASS_CONST2: ClassVar = "const" + variable: ClassVar[str] = "invalid name" # [invalid-name] diff --git a/tests/functional/n/name/name_styles.rc b/tests/functional/n/name/name_styles.rc new file mode 100644 index 000000000..1a63e671b --- /dev/null +++ b/tests/functional/n/name/name_styles.rc @@ -0,0 +1,5 @@ +[testoptions] +min_pyver=2.6 + +[Messages Control] +disable=too-few-public-methods,abstract-class-not-used,global-statement diff --git a/tests/functional/n/name/name_styles.txt b/tests/functional/n/name/name_styles.txt new file mode 100644 index 000000000..ef665c0de --- /dev/null +++ b/tests/functional/n/name/name_styles.txt @@ -0,0 +1,18 @@ +invalid-name:10:0::"Constant name ""bad_const_name"" doesn't conform to UPPER_CASE naming style" +invalid-name:13:0:BADFUNCTION_name:"Function name ""BADFUNCTION_name"" doesn't conform to snake_case naming style" +invalid-name:15:4:BADFUNCTION_name:"Variable name ""BAD_LOCAL_VAR"" doesn't conform to snake_case naming style" +invalid-name:19:0:func_bad_argname:"Argument name ""NOT_GOOD"" doesn't conform to snake_case naming style" +invalid-name:29:0:bad_class_name:"Class name ""bad_class_name"" doesn't conform to PascalCase naming style" +invalid-name:40:8:CorrectClassName.__init__:"Attribute name ""_Bad_AtTR_name"" doesn't conform to snake_case naming style" +invalid-name:41:8:CorrectClassName.__init__:"Attribute name ""Bad_PUBLIC_name"" doesn't conform to snake_case naming style" +invalid-name:46:4:CorrectClassName.BadMethodName:"Method name ""BadMethodName"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:52:4:CorrectClassName.__DunDER_IS_not_free_for_all__:"Method name ""__DunDER_IS_not_free_for_all__"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:82:0::"Class name ""BAD_NAME_FOR_CLASS"" doesn't conform to PascalCase naming style" +invalid-name:83:0::"Class name ""NEXT_BAD_NAME_FOR_CLASS"" doesn't conform to PascalCase naming style" +invalid-name:90:0::"Class name ""NOT_CORRECT"" doesn't conform to PascalCase naming style" +invalid-name:96:4:test_globals:"Constant name ""AlsoCorrect"" doesn't conform to UPPER_CASE naming style" +invalid-name:109:4:FooClass.PROPERTY_NAME:"Attribute name ""PROPERTY_NAME"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:114:4:FooClass.ABSTRACT_PROPERTY_NAME:"Attribute name ""ABSTRACT_PROPERTY_NAME"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:119:4:FooClass.PROPERTY_NAME_SETTER:"Attribute name ""PROPERTY_NAME_SETTER"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:150:4:FooEnum:"Class constant name ""bad_enum_name"" doesn't conform to UPPER_CASE naming style" +invalid-name:156:4:Bar:"Class constant name ""variable"" doesn't conform to UPPER_CASE naming style" diff --git a/tests/functional/n/name/namedtuple_member_inference.py b/tests/functional/n/name/namedtuple_member_inference.py new file mode 100644 index 000000000..4488ceb0a --- /dev/null +++ b/tests/functional/n/name/namedtuple_member_inference.py @@ -0,0 +1,22 @@ +"""Test namedtuple attributes. + +Regression test for: +https://bitbucket.org/logilab/pylint/issue/93/pylint-crashes-on-namedtuple-attribute +""" +from __future__ import absolute_import, print_function +from collections import namedtuple + +__revision__ = None + +Thing = namedtuple('Thing', ()) + +Fantastic = namedtuple('Fantastic', ['foo']) + +def test(): + """Test member access in named tuples.""" + print(Thing.x) # [no-member] + fan = Fantastic(1) + print(fan.foo) + # Should not raise protected-access. + fan2 = fan._replace(foo=2) + print(fan2.foo) diff --git a/tests/functional/n/name/namedtuple_member_inference.txt b/tests/functional/n/name/namedtuple_member_inference.txt new file mode 100644 index 000000000..b754e9be7 --- /dev/null +++ b/tests/functional/n/name/namedtuple_member_inference.txt @@ -0,0 +1 @@ +no-member:17:10:test:Class 'Thing' has no 'x' member:INFERENCE diff --git a/tests/functional/n/name/names_in__all__.py b/tests/functional/n/name/names_in__all__.py new file mode 100644 index 000000000..9b2840acc --- /dev/null +++ b/tests/functional/n/name/names_in__all__.py @@ -0,0 +1,49 @@ +# pylint: disable=too-few-public-methods,no-self-use, no-absolute-import,import-error, useless-object-inheritance, unnecessary-pass +"""Test Pylint's use of __all__. + +* NonExistant is not defined in this module, and it is listed in + __all__. An error is expected. + +* This module imports path and republished it in __all__. No errors + are expected. +""" +from __future__ import print_function +from os import path +from collections import deque +from missing import Missing + +__all__ = [ + 'Dummy', + '', # [undefined-all-variable] + Missing, + SomeUndefined, # [undefined-variable] + 'NonExistant', # [undefined-all-variable] + 'path', + 'func', # [undefined-all-variable] + 'inner', # [undefined-all-variable] + 'InnerKlass', deque.__name__] # [undefined-all-variable] + + +class Dummy(object): + """A class defined in this module.""" + pass + +DUMMY = Dummy() + +def function(): + """Function docstring + """ + pass + +function() + +class Klass(object): + """A klass which contains a function""" + def func(self): + """A klass method""" + inner = None + print(inner) + + class InnerKlass(object): + """An inner klass""" + pass diff --git a/tests/functional/n/name/names_in__all__.txt b/tests/functional/n/name/names_in__all__.txt new file mode 100644 index 000000000..aa9015143 --- /dev/null +++ b/tests/functional/n/name/names_in__all__.txt @@ -0,0 +1,6 @@ +undefined-all-variable:17:4::Undefined variable name '' in __all__ +undefined-variable:19:4::Undefined variable 'SomeUndefined' +undefined-all-variable:20:4::Undefined variable name 'NonExistant' in __all__ +undefined-all-variable:22:4::Undefined variable name 'func' in __all__ +undefined-all-variable:23:4::Undefined variable name 'inner' in __all__ +undefined-all-variable:24:4::Undefined variable name 'InnerKlass' in __all__ diff --git a/tests/functional/n/namePresetCamelCase.py b/tests/functional/n/namePresetCamelCase.py deleted file mode 100644 index e048ec4d8..000000000 --- a/tests/functional/n/namePresetCamelCase.py +++ /dev/null @@ -1,23 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods -__version__ = "1.0" -SOME_CONSTANT = 42 # [invalid-name] - - -def sayHello(someArgument): - return [someArgument * someValue for someValue in range(10)] - - -class MyClass: # [invalid-name] - def __init__(self, argX): - self._mySecretX = argX - - @property - def myPublicX(self): - return self._mySecretX * 2 - - def __eq__(self, other): - return isinstance(other, MyClass) and self.myPublicX == other.myPublicX - - -def say_hello(): # [invalid-name] - pass diff --git a/tests/functional/n/namePresetCamelCase.rc b/tests/functional/n/namePresetCamelCase.rc deleted file mode 100644 index 29f44504a..000000000 --- a/tests/functional/n/namePresetCamelCase.rc +++ /dev/null @@ -1,13 +0,0 @@ -[BASIC] -function-naming-style=camelCase -const-naming-style=camelCase -attr-naming-style=camelCase -argument-naming-style=camelCase -module-naming-style=camelCase -method-naming-style=camelCase -variable-naming-style=camelCase -class-attribute-naming-style=camelCase -inlinevar-naming-style=camelCase -class-naming-style=camelCase - -include-naming-hint=yes diff --git a/tests/functional/n/namePresetCamelCase.txt b/tests/functional/n/namePresetCamelCase.txt deleted file mode 100644 index b24b0a881..000000000 --- a/tests/functional/n/namePresetCamelCase.txt +++ /dev/null @@ -1,3 +0,0 @@ -invalid-name:3:0::"Constant name ""SOME_CONSTANT"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]*|__.*__)$' pattern)" -invalid-name:10:0:MyClass:"Class name ""MyClass"" doesn't conform to camelCase naming style ('[^\\W\\dA-Z][^\\W_]+$' pattern)" -invalid-name:22:0:say_hello:"Function name ""say_hello"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]{2,}|__[^\\W\\dA-Z_]\\w+__)$' pattern)" diff --git a/tests/functional/n/name_good_bad_names_regex.py b/tests/functional/n/name_good_bad_names_regex.py deleted file mode 100644 index f1ed4b91b..000000000 --- a/tests/functional/n/name_good_bad_names_regex.py +++ /dev/null @@ -1,20 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods -__version__ = "1.0" -ignored_SOME_CONSTANT = 42 - -explicit_bad_some_constant = 42 # [blacklisted-name] - -snake_case_bad_SOME_CONSTANT = 42 # [invalid-name] - - -class my_class: - def __init__(self, arg_x): - self._my_secret_x = arg_x - - @property - def my_public_x(self): - return self._my_secret_x * 2 - - -def blacklisted_2_snake_case(): # [blacklisted-name] - pass diff --git a/tests/functional/n/name_good_bad_names_regex.rc b/tests/functional/n/name_good_bad_names_regex.rc deleted file mode 100644 index 8246438cd..000000000 --- a/tests/functional/n/name_good_bad_names_regex.rc +++ /dev/null @@ -1,15 +0,0 @@ -[BASIC] -function-naming-style=snake_case -const-naming-style=snake_case -attr-naming-style=snake_case -argument-naming-style=snake_case -module-naming-style=snake_case -method-naming-style=snake_case -variable-naming-style=snake_case -class-attribute-naming-style=snake_case -inlinevar-naming-style=snake_case -class-naming-style=snake_case - -good-names-rgxs=ignored.* -bad-names-rgxs=explicit.*,blacklisted.* -include-naming-hint=yes diff --git a/tests/functional/n/name_good_bad_names_regex.txt b/tests/functional/n/name_good_bad_names_regex.txt deleted file mode 100644 index 08aef7d78..000000000 --- a/tests/functional/n/name_good_bad_names_regex.txt +++ /dev/null @@ -1,3 +0,0 @@ -blacklisted-name:5:0::Black listed name "explicit_bad_some_constant" -invalid-name:7:0::"Constant name ""snake_case_bad_SOME_CONSTANT"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]*|__.*__)$' pattern)" -blacklisted-name:19:0:blacklisted_2_snake_case:Black listed name "blacklisted_2_snake_case" diff --git a/tests/functional/n/name_preset_snake_case.py b/tests/functional/n/name_preset_snake_case.py deleted file mode 100644 index 75350497e..000000000 --- a/tests/functional/n/name_preset_snake_case.py +++ /dev/null @@ -1,35 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods -from enum import Enum -from typing import ClassVar - -__version__ = "1.0" -SOME_CONSTANT = 42 # [invalid-name] - - -def say_hello(some_argument): - return [some_argument * some_value for some_value in range(10)] - - -class MyClass: # [invalid-name] - def __init__(self, arg_x): - self._my_secret_x = arg_x - - @property - def my_public_x(self): - return self._my_secret_x * 2 - - def __eq__(self, other): - return isinstance(other, MyClass) and self.my_public_x == other.my_public_x - - -def sayHello(): # [invalid-name] - pass - - -class FooEnum(Enum): # [invalid-name] - const_with_snake_case = 42 - another_const = 43 - - -class Bar: # [invalid-name] - const_with_snake_case: ClassVar[int] = 42 diff --git a/tests/functional/n/name_preset_snake_case.rc b/tests/functional/n/name_preset_snake_case.rc deleted file mode 100644 index 2b04af5d4..000000000 --- a/tests/functional/n/name_preset_snake_case.rc +++ /dev/null @@ -1,14 +0,0 @@ -[BASIC] -function-naming-style=snake_case -const-naming-style=snake_case -attr-naming-style=snake_case -argument-naming-style=snake_case -module-naming-style=snake_case -method-naming-style=snake_case -variable-naming-style=snake_case -class-attribute-naming-style=snake_case -class-const-naming-style=snake_case -inlinevar-naming-style=snake_case -class-naming-style=snake_case - -include-naming-hint=yes diff --git a/tests/functional/n/name_preset_snake_case.txt b/tests/functional/n/name_preset_snake_case.txt deleted file mode 100644 index c189797e9..000000000 --- a/tests/functional/n/name_preset_snake_case.txt +++ /dev/null @@ -1,5 +0,0 @@ -invalid-name:6:0::"Constant name ""SOME_CONSTANT"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]*|__.*__)$' pattern)" -invalid-name:13:0:MyClass:"Class name ""MyClass"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)" -invalid-name:25:0:sayHello:"Function name ""sayHello"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]{2,}|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)" -invalid-name:29:0:FooEnum:"Class name ""FooEnum"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)" -invalid-name:34:0:Bar:"Class name ""Bar"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)" diff --git a/tests/functional/n/name_styles.py b/tests/functional/n/name_styles.py deleted file mode 100644 index 394c82826..000000000 --- a/tests/functional/n/name_styles.py +++ /dev/null @@ -1,156 +0,0 @@ -"""Test for the invalid-name warning.""" -# pylint: disable=no-absolute-import, useless-object-inheritance, unnecessary-pass, unnecessary-comprehension -from __future__ import print_function -import abc -import collections -from enum import Enum -from typing import ClassVar - -GOOD_CONST_NAME = '' -bad_const_name = 0 # [invalid-name] - - -def BADFUNCTION_name(): # [invalid-name] - """Bad function name.""" - BAD_LOCAL_VAR = 1 # [invalid-name] - print(BAD_LOCAL_VAR) - - -def func_bad_argname(NOT_GOOD): # [invalid-name] - """Function with a badly named argument.""" - return NOT_GOOD - - -def no_nested_args(arg1, arg21, arg22): - """Well-formed function.""" - print(arg1, arg21, arg22) - - -class bad_class_name(object): # [invalid-name] - """Class with a bad name.""" - - -class CorrectClassName(object): - """Class with a good name.""" - - def __init__(self): - self._good_private_name = 10 - self.__good_real_private_name = 11 - self.good_attribute_name = 12 - self._Bad_AtTR_name = None # [invalid-name] - self.Bad_PUBLIC_name = None # [invalid-name] - - zz = 'Why Was It Bad Class Attribute?' - GOOD_CLASS_ATTR = 'Good Class Attribute' - - def BadMethodName(self): # [invalid-name] - """A Method with a bad name.""" - - def good_method_name(self): - """A method with a good name.""" - - def __DunDER_IS_not_free_for_all__(self): # [invalid-name] - """Another badly named method.""" - - -class DerivedFromCorrect(CorrectClassName): - """A derived class with an invalid inherited members. - - Derived attributes and methods with invalid names do not trigger warnings. - """ - zz = 'Now a good class attribute' - - def __init__(self): - super().__init__() - self._Bad_AtTR_name = None # Ignored - - def BadMethodName(self): - """Ignored since the method is in the interface.""" - - -V = [WHAT_Ever_inListComp for WHAT_Ever_inListComp in GOOD_CONST_NAME] - -def class_builder(): - """Function returning a class object.""" - - class EmbeddedClass(object): - """Useless class.""" - - return EmbeddedClass - -# +1:[invalid-name] -BAD_NAME_FOR_CLASS = collections.namedtuple('Named', ['tuple']) -NEXT_BAD_NAME_FOR_CLASS = class_builder() # [invalid-name] - -GoodName = collections.namedtuple('Named', ['tuple']) -ToplevelClass = class_builder() - -# Aliases for classes have the same name constraints. -AlsoCorrect = CorrectClassName -NOT_CORRECT = CorrectClassName # [invalid-name] - - -def test_globals(): - """Names in global statements are also checked.""" - global NOT_CORRECT - global AlsoCorrect # [invalid-name] - NOT_CORRECT = 1 - AlsoCorrect = 2 - - -class FooClass(object): - """A test case for property names. - - Since by default, the regex for attributes is the same as the one - for method names, we check the warning messages to contain the - string 'attribute'. - """ - @property - def PROPERTY_NAME(self): # [invalid-name] - """Ignored.""" - pass - - @abc.abstractproperty - def ABSTRACT_PROPERTY_NAME(self): # [invalid-name] - """Ignored.""" - pass - - @PROPERTY_NAME.setter - def PROPERTY_NAME_SETTER(self): # [invalid-name] - """Ignored.""" - pass - - def _nice_and_long_descriptive_private_method_name(self): - """private method with long name""" - pass - - -def good_public_function_name(good_arg_name): - """This is a perfect public function""" - good_variable_name = 1 - return good_variable_name + good_arg_name - - -def _private_scope_function_with_long_descriptive_name(): - """Private scope function are cool with long descriptive names""" - return 12 - -LONG_CONSTANT_NAME_IN_PUBLIC_SCOPE_ARE_OKAY = True -# We don't emit for non-const nodes -good_name_for_funcs = lambda: None -good_name_for_lists = [1, 2, 3] - -class _AnExceptionalExceptionThatOccursVeryVeryRarely(Exception): - """A very exceptional exception with a nice descriptive name""" - pass - -class FooEnum(Enum): - """A test case for enum names.""" - GOOD_ENUM_NAME = 1 - bad_enum_name = 2 # [invalid-name] - -class Bar: - """Class with class constants annotated with ClassVar.""" - CLASS_CONST: ClassVar[int] = 42 - CLASS_CONST2: ClassVar = "const" - variable: ClassVar[str] = "invalid name" # [invalid-name] diff --git a/tests/functional/n/name_styles.rc b/tests/functional/n/name_styles.rc deleted file mode 100644 index 1a63e671b..000000000 --- a/tests/functional/n/name_styles.rc +++ /dev/null @@ -1,5 +0,0 @@ -[testoptions] -min_pyver=2.6 - -[Messages Control] -disable=too-few-public-methods,abstract-class-not-used,global-statement diff --git a/tests/functional/n/name_styles.txt b/tests/functional/n/name_styles.txt deleted file mode 100644 index ef665c0de..000000000 --- a/tests/functional/n/name_styles.txt +++ /dev/null @@ -1,18 +0,0 @@ -invalid-name:10:0::"Constant name ""bad_const_name"" doesn't conform to UPPER_CASE naming style" -invalid-name:13:0:BADFUNCTION_name:"Function name ""BADFUNCTION_name"" doesn't conform to snake_case naming style" -invalid-name:15:4:BADFUNCTION_name:"Variable name ""BAD_LOCAL_VAR"" doesn't conform to snake_case naming style" -invalid-name:19:0:func_bad_argname:"Argument name ""NOT_GOOD"" doesn't conform to snake_case naming style" -invalid-name:29:0:bad_class_name:"Class name ""bad_class_name"" doesn't conform to PascalCase naming style" -invalid-name:40:8:CorrectClassName.__init__:"Attribute name ""_Bad_AtTR_name"" doesn't conform to snake_case naming style" -invalid-name:41:8:CorrectClassName.__init__:"Attribute name ""Bad_PUBLIC_name"" doesn't conform to snake_case naming style" -invalid-name:46:4:CorrectClassName.BadMethodName:"Method name ""BadMethodName"" doesn't conform to snake_case naming style":INFERENCE -invalid-name:52:4:CorrectClassName.__DunDER_IS_not_free_for_all__:"Method name ""__DunDER_IS_not_free_for_all__"" doesn't conform to snake_case naming style":INFERENCE -invalid-name:82:0::"Class name ""BAD_NAME_FOR_CLASS"" doesn't conform to PascalCase naming style" -invalid-name:83:0::"Class name ""NEXT_BAD_NAME_FOR_CLASS"" doesn't conform to PascalCase naming style" -invalid-name:90:0::"Class name ""NOT_CORRECT"" doesn't conform to PascalCase naming style" -invalid-name:96:4:test_globals:"Constant name ""AlsoCorrect"" doesn't conform to UPPER_CASE naming style" -invalid-name:109:4:FooClass.PROPERTY_NAME:"Attribute name ""PROPERTY_NAME"" doesn't conform to snake_case naming style":INFERENCE -invalid-name:114:4:FooClass.ABSTRACT_PROPERTY_NAME:"Attribute name ""ABSTRACT_PROPERTY_NAME"" doesn't conform to snake_case naming style":INFERENCE -invalid-name:119:4:FooClass.PROPERTY_NAME_SETTER:"Attribute name ""PROPERTY_NAME_SETTER"" doesn't conform to snake_case naming style":INFERENCE -invalid-name:150:4:FooEnum:"Class constant name ""bad_enum_name"" doesn't conform to UPPER_CASE naming style" -invalid-name:156:4:Bar:"Class constant name ""variable"" doesn't conform to UPPER_CASE naming style" diff --git a/tests/functional/n/namedtuple_member_inference.py b/tests/functional/n/namedtuple_member_inference.py deleted file mode 100644 index 4488ceb0a..000000000 --- a/tests/functional/n/namedtuple_member_inference.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Test namedtuple attributes. - -Regression test for: -https://bitbucket.org/logilab/pylint/issue/93/pylint-crashes-on-namedtuple-attribute -""" -from __future__ import absolute_import, print_function -from collections import namedtuple - -__revision__ = None - -Thing = namedtuple('Thing', ()) - -Fantastic = namedtuple('Fantastic', ['foo']) - -def test(): - """Test member access in named tuples.""" - print(Thing.x) # [no-member] - fan = Fantastic(1) - print(fan.foo) - # Should not raise protected-access. - fan2 = fan._replace(foo=2) - print(fan2.foo) diff --git a/tests/functional/n/namedtuple_member_inference.txt b/tests/functional/n/namedtuple_member_inference.txt deleted file mode 100644 index b754e9be7..000000000 --- a/tests/functional/n/namedtuple_member_inference.txt +++ /dev/null @@ -1 +0,0 @@ -no-member:17:10:test:Class 'Thing' has no 'x' member:INFERENCE diff --git a/tests/functional/n/names_in__all__.py b/tests/functional/n/names_in__all__.py deleted file mode 100644 index 9b2840acc..000000000 --- a/tests/functional/n/names_in__all__.py +++ /dev/null @@ -1,49 +0,0 @@ -# pylint: disable=too-few-public-methods,no-self-use, no-absolute-import,import-error, useless-object-inheritance, unnecessary-pass -"""Test Pylint's use of __all__. - -* NonExistant is not defined in this module, and it is listed in - __all__. An error is expected. - -* This module imports path and republished it in __all__. No errors - are expected. -""" -from __future__ import print_function -from os import path -from collections import deque -from missing import Missing - -__all__ = [ - 'Dummy', - '', # [undefined-all-variable] - Missing, - SomeUndefined, # [undefined-variable] - 'NonExistant', # [undefined-all-variable] - 'path', - 'func', # [undefined-all-variable] - 'inner', # [undefined-all-variable] - 'InnerKlass', deque.__name__] # [undefined-all-variable] - - -class Dummy(object): - """A class defined in this module.""" - pass - -DUMMY = Dummy() - -def function(): - """Function docstring - """ - pass - -function() - -class Klass(object): - """A klass which contains a function""" - def func(self): - """A klass method""" - inner = None - print(inner) - - class InnerKlass(object): - """An inner klass""" - pass diff --git a/tests/functional/n/names_in__all__.txt b/tests/functional/n/names_in__all__.txt deleted file mode 100644 index aa9015143..000000000 --- a/tests/functional/n/names_in__all__.txt +++ /dev/null @@ -1,6 +0,0 @@ -undefined-all-variable:17:4::Undefined variable name '' in __all__ -undefined-variable:19:4::Undefined variable 'SomeUndefined' -undefined-all-variable:20:4::Undefined variable name 'NonExistant' in __all__ -undefined-all-variable:22:4::Undefined variable name 'func' in __all__ -undefined-all-variable:23:4::Undefined variable name 'inner' in __all__ -undefined-all-variable:24:4::Undefined variable name 'InnerKlass' in __all__ diff --git a/tests/functional/n/no/__init__.py b/tests/functional/n/no/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/functional/n/no/no_classmethod_decorator.py b/tests/functional/n/no/no_classmethod_decorator.py new file mode 100644 index 000000000..66cc0b3c0 --- /dev/null +++ b/tests/functional/n/no/no_classmethod_decorator.py @@ -0,0 +1,35 @@ +"""Checks class methods are declared with a decorator if within the class +scope and if classmethod's argument is a member of the class +""" + +# pylint: disable=too-few-public-methods, using-constant-test, no-self-argument, useless-object-inheritance + +class MyClass(object): + """Some class""" + def __init__(self): + pass + + def cmethod(cls): + """class method-to-be""" + cmethod = classmethod(cmethod) # [no-classmethod-decorator] + + if True: + cmethod = classmethod(cmethod) # [no-classmethod-decorator] + + @classmethod + def my_second_method(cls): + """correct class method definition""" + + def other_method(cls): + """some method""" + cmethod2 = classmethod(other_method) # [no-classmethod-decorator] + +def helloworld(): + """says hello""" + + +MyClass.new_class_method = classmethod(helloworld) + +class MyOtherClass(object): + """Some other class""" + _make = classmethod(tuple.__new__) diff --git a/tests/functional/n/no/no_classmethod_decorator.txt b/tests/functional/n/no/no_classmethod_decorator.txt new file mode 100644 index 000000000..90b10f2b1 --- /dev/null +++ b/tests/functional/n/no/no_classmethod_decorator.txt @@ -0,0 +1,3 @@ +no-classmethod-decorator:14:4:MyClass:Consider using a decorator instead of calling classmethod +no-classmethod-decorator:17:8:MyClass:Consider using a decorator instead of calling classmethod +no-classmethod-decorator:25:4:MyClass:Consider using a decorator instead of calling classmethod diff --git a/tests/functional/n/no/no_else_break.py b/tests/functional/n/no/no_else_break.py new file mode 100644 index 000000000..cf23f313a --- /dev/null +++ b/tests/functional/n/no/no_else_break.py @@ -0,0 +1,137 @@ +""" Test that superfluous else return are detected. """ + +# pylint:disable=invalid-name,missing-docstring,unused-variable + + +def foo1(x, y, z): + for i in x: + if i > y: # [no-else-break] + break + else: + a = z + + +def foo2(x, y, w, z): + for i in x: + if i > y: # [no-else-break] + break + elif i > w: + break + else: + a = z + + +def foo3(x, y, z): + for i in x: + if i > y: + a = 1 + if z: # [no-else-break] + b = 2 + break + else: + c = 3 + break + else: + d = 4 + break + + +def foo4(x, y): + for i in x: + if i > x: # [no-else-break] + if y: + a = 4 + else: + b = 2 + break + else: + c = 3 + break + + +def foo5(x, y, z): + for i in x: + if i > y: # [no-else-break] + if y: + a = 4 + else: + b = 2 + break + elif z: + c = 2 + else: + c = 3 + break + + +def foo6(x, y): + for i in x: + if i > x: + if y: # [no-else-break] + a = 4 + break + else: + b = 2 + else: + c = 3 + break + + +def bar1(x, y, z): + for i in x: + if i > y: + break + return z + + +def bar2(w, x, y, z): + for i in w: + if i > x: + break + if z < i: + a = y + else: + break + return + + +def bar3(x, y, z): + for i in x: + if i > y: + if z: + break + else: + return z + return None + + +def bar4(x): + for i in range(10): + if x: # [no-else-break] + break + else: + try: + return + except ValueError: + break + + +def nested1(x, y, z): + for i in x: + if i > x: + for j in y: + if j < z: + break + else: + a = z + + +def nested2(x, y, z): + for i in x: + if i > x: + for j in y: + if j > z: + break + break + else: + a = z diff --git a/tests/functional/n/no/no_else_break.txt b/tests/functional/n/no/no_else_break.txt new file mode 100644 index 000000000..d1a27f73c --- /dev/null +++ b/tests/functional/n/no/no_else_break.txt @@ -0,0 +1,7 @@ +no-else-break:8:8:foo1:"Unnecessary ""else"" after ""break""" +no-else-break:16:8:foo2:"Unnecessary ""elif"" after ""break""" +no-else-break:28:12:foo3:"Unnecessary ""else"" after ""break""" +no-else-break:41:8:foo4:"Unnecessary ""else"" after ""break""" +no-else-break:54:8:foo5:"Unnecessary ""elif"" after ""break""" +no-else-break:70:12:foo6:"Unnecessary ""else"" after ""break""" +no-else-break:110:8:bar4:"Unnecessary ""else"" after ""break""" diff --git a/tests/functional/n/no/no_else_continue.py b/tests/functional/n/no/no_else_continue.py new file mode 100644 index 000000000..37f70f121 --- /dev/null +++ b/tests/functional/n/no/no_else_continue.py @@ -0,0 +1,137 @@ +""" Test that superfluous else return are detected. """ + +# pylint:disable=invalid-name,missing-docstring,unused-variable + + +def foo1(x, y, z): + for i in x: + if i < y: # [no-else-continue] + continue + else: + a = z + + +def foo2(x, y, w, z): + for i in x: + if i < y: # [no-else-continue] + continue + elif i < w: + continue + else: + a = z + + +def foo3(x, y, z): + for i in x: + if i < y: + a = 1 + if z: # [no-else-continue] + b = 2 + continue + else: + c = 3 + continue + else: + d = 4 + continue + + +def foo4(x, y): + for i in x: + if i < x: # [no-else-continue] + if y: + a = 4 + else: + b = 2 + continue + else: + c = 3 + continue + + +def foo5(x, y, z): + for i in x: + if i < y: # [no-else-continue] + if y: + a = 4 + else: + b = 2 + continue + elif z: + c = 2 + else: + c = 3 + continue + + +def foo6(x, y): + for i in x: + if i < x: + if y: # [no-else-continue] + a = 4 + continue + else: + b = 2 + else: + c = 3 + continue + + +def bar1(x, y, z): + for i in x: + if i < y: + continue + return z + + +def bar2(w, x, y, z): + for i in w: + if i < x: + continue + if z < i: + a = y + else: + continue + return + + +def bar3(x, y, z): + for i in x: + if i < y: + if z: + continue + else: + return z + return None + + +def bar4(x): + for i in range(10): + if x: # [no-else-continue] + continue + else: + try: + return + except ValueError: + continue + + +def nested1(x, y, z): + for i in x: + if i < x: + for j in y: + if j < z: + continue + else: + a = z + + +def nested2(x, y, z): + for i in x: + if i < x: + for j in y: + if j < z: + continue + continue + else: + a = z diff --git a/tests/functional/n/no/no_else_continue.txt b/tests/functional/n/no/no_else_continue.txt new file mode 100644 index 000000000..6d659ea28 --- /dev/null +++ b/tests/functional/n/no/no_else_continue.txt @@ -0,0 +1,7 @@ +no-else-continue:8:8:foo1:"Unnecessary ""else"" after ""continue""" +no-else-continue:16:8:foo2:"Unnecessary ""elif"" after ""continue""" +no-else-continue:28:12:foo3:"Unnecessary ""else"" after ""continue""" +no-else-continue:41:8:foo4:"Unnecessary ""else"" after ""continue""" +no-else-continue:54:8:foo5:"Unnecessary ""elif"" after ""continue""" +no-else-continue:70:12:foo6:"Unnecessary ""else"" after ""continue""" +no-else-continue:110:8:bar4:"Unnecessary ""else"" after ""continue""" diff --git a/tests/functional/n/no/no_else_raise.py b/tests/functional/n/no/no_else_raise.py new file mode 100644 index 000000000..ae807fae3 --- /dev/null +++ b/tests/functional/n/no/no_else_raise.py @@ -0,0 +1,110 @@ +""" Test that superfluous else return are detected. """ + +# pylint:disable=invalid-name,missing-docstring,unused-variable,raise-missing-from + +def foo1(x, y, z): + if x: # [no-else-raise] + a = 1 + raise Exception(y) + else: + b = 2 + raise Exception(z) + + +def foo2(x, y, w, z): + if x: # [no-else-raise] + a = 1 + raise Exception(y) + elif z: + b = 2 + raise Exception(w) + else: + c = 3 + raise Exception(z) + + +def foo3(x, y, z): + if x: + a = 1 + if y: # [no-else-raise] + b = 2 + raise Exception(y) + else: + c = 3 + raise Exception(x) + else: + d = 4 + raise Exception(z) + + +def foo4(x, y): + if x: # [no-else-raise] + if y: + a = 4 + else: + b = 2 + raise Exception(x) + else: + c = 3 + raise Exception(y) + + +def foo5(x, y, z): + if x: # [no-else-raise] + if y: + a = 4 + else: + b = 2 + raise Exception(x) + elif z: + raise Exception(y) + else: + c = 3 + raise Exception(z) + + +def foo6(x, y): + if x: + if y: # [no-else-raise] + a = 4 + raise Exception(x) + else: + b = 2 + else: + c = 3 + raise Exception(y) + + +def bar1(x, y, z): + if x: + raise Exception(y) + raise Exception(z) + + +def bar2(w, x, y, z): + if x: + raise Exception(y) + if z: + a = 1 + else: + raise Exception(w) + raise Exception(None) + + +def bar3(x, y, z): + if x: + if z: + raise Exception(y) + else: + raise Exception(z) + raise Exception(None) + + +def bar4(x): + if x: # [no-else-raise] + raise Exception(True) + else: + try: + raise Exception(False) + except ValueError: + raise Exception(None) diff --git a/tests/functional/n/no/no_else_raise.txt b/tests/functional/n/no/no_else_raise.txt new file mode 100644 index 000000000..b41f7132f --- /dev/null +++ b/tests/functional/n/no/no_else_raise.txt @@ -0,0 +1,7 @@ +no-else-raise:6:4:foo1:"Unnecessary ""else"" after ""raise""" +no-else-raise:15:4:foo2:"Unnecessary ""elif"" after ""raise""" +no-else-raise:29:8:foo3:"Unnecessary ""else"" after ""raise""" +no-else-raise:41:4:foo4:"Unnecessary ""else"" after ""raise""" +no-else-raise:53:4:foo5:"Unnecessary ""elif"" after ""raise""" +no-else-raise:68:8:foo6:"Unnecessary ""else"" after ""raise""" +no-else-raise:104:4:bar4:"Unnecessary ""else"" after ""raise""" diff --git a/tests/functional/n/no/no_else_return.py b/tests/functional/n/no/no_else_return.py new file mode 100644 index 000000000..0a87551fa --- /dev/null +++ b/tests/functional/n/no/no_else_return.py @@ -0,0 +1,110 @@ +""" Test that superfluous else return are detected. """ + + +# pylint:disable=invalid-name,missing-docstring,unused-variable +def foo1(x, y, z): + if x: # [no-else-return] + a = 1 + return y + else: + b = 2 + return z + + +def foo2(x, y, w, z): + if x: # [no-else-return] + a = 1 + return y + elif z: + b = 2 + return w + else: + c = 3 + return z + + +def foo3(x, y, z): + if x: + a = 1 + if y: # [no-else-return] + b = 2 + return y + else: + c = 3 + return x + else: + d = 4 + return z + + +def foo4(x, y): + if x: # [no-else-return] + if y: + a = 4 + else: + b = 2 + return + else: + c = 3 + return + + +def foo5(x, y, z): + if x: # [no-else-return] + if y: + a = 4 + else: + b = 2 + return + elif z: + c = 2 + else: + c = 3 + return + + +def foo6(x, y): + if x: + if y: # [no-else-return] + a = 4 + return + else: + b = 2 + else: + c = 3 + return + + +def bar1(x, y, z): + if x: + return y + return z + + +def bar2(w, x, y, z): + if x: + return y + if z: + a = 1 + else: + return w + return None + + +def bar3(x, y, z): + if x: + if z: + return y + else: + return z + return None + + +def bar4(x): + if x: # [no-else-return] + return True + else: + try: + return False + except ValueError: + return None diff --git a/tests/functional/n/no/no_else_return.txt b/tests/functional/n/no/no_else_return.txt new file mode 100644 index 000000000..4560f7490 --- /dev/null +++ b/tests/functional/n/no/no_else_return.txt @@ -0,0 +1,7 @@ +no-else-return:6:4:foo1:"Unnecessary ""else"" after ""return""" +no-else-return:15:4:foo2:"Unnecessary ""elif"" after ""return""" +no-else-return:29:8:foo3:"Unnecessary ""else"" after ""return""" +no-else-return:41:4:foo4:"Unnecessary ""else"" after ""return""" +no-else-return:53:4:foo5:"Unnecessary ""elif"" after ""return""" +no-else-return:68:8:foo6:"Unnecessary ""else"" after ""return""" +no-else-return:104:4:bar4:"Unnecessary ""else"" after ""return""" diff --git a/tests/functional/n/no/no_method_argument_py38.py b/tests/functional/n/no/no_method_argument_py38.py new file mode 100644 index 000000000..c67453288 --- /dev/null +++ b/tests/functional/n/no/no_method_argument_py38.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring,too-few-public-methods + + +class Cls: + def __init__(self, obj, /): + self.obj = obj diff --git a/tests/functional/n/no/no_method_argument_py38.rc b/tests/functional/n/no/no_method_argument_py38.rc new file mode 100644 index 000000000..85fc502b3 --- /dev/null +++ b/tests/functional/n/no/no_method_argument_py38.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.8 diff --git a/tests/functional/n/no/no_name_in_module.py b/tests/functional/n/no/no_name_in_module.py new file mode 100644 index 000000000..73ad2db93 --- /dev/null +++ b/tests/functional/n/no/no_name_in_module.py @@ -0,0 +1,66 @@ +#pylint: disable=W0401,W0611,no-absolute-import,invalid-name,import-error,bare-except,broad-except,wrong-import-order,ungrouped-imports,wrong-import-position +"""check unexistant names imported are reported""" +from __future__ import print_function + +import collections.tutu # [no-name-in-module] +from collections import toto # [no-name-in-module] +toto.yo() + +from xml.etree import ElementTree +ElementTree.nonexistant_function() # [no-member] +ElementTree.another.nonexistant.function() # [no-member] + + +import sys +print(sys.stdout, 'hello world') +print(sys.stdoout, 'bye bye world') # [no-member] + + +import re +re.finditer('*', 'yo') + +from rie import * +from re import findiiter, compiile # [no-name-in-module,no-name-in-module] + +import os +'SOMEVAR' in os.environ # [pointless-statement] + +try: + from collections import something +except ImportError: + something = None + +try: + from collections import anything # [no-name-in-module] +except ValueError: + anything = None + +try: + import collections.missing +except ImportError: + pass + +try: + import collections.indeed_missing # [no-name-in-module] +except ValueError: + pass + +try: + import collections.emit # [no-name-in-module] +except Exception: + pass + +try: + import collections.emit1 +except ImportError: + pass + +try: + if something: + import collections.emit2 # [no-name-in-module] +except Exception: + pass + +from .no_self_use import Super +from .no_self_use import lala # [no-name-in-module] +from .no_self_use.bla import lala1 # [no-name-in-module] diff --git a/tests/functional/n/no/no_name_in_module.txt b/tests/functional/n/no/no_name_in_module.txt new file mode 100644 index 000000000..883e6b5d7 --- /dev/null +++ b/tests/functional/n/no/no_name_in_module.txt @@ -0,0 +1,14 @@ +no-name-in-module:5:0::No name 'tutu' in module 'collections' +no-name-in-module:6:0::No name 'toto' in module 'collections' +no-member:10:0::Module 'xml.etree.ElementTree' has no 'nonexistant_function' member:INFERENCE +no-member:11:0::Module 'xml.etree.ElementTree' has no 'another' member:INFERENCE +no-member:16:6::Module 'sys' has no 'stdoout' member; maybe 'stdout'?:INFERENCE +no-name-in-module:23:0::No name 'compiile' in module 're' +no-name-in-module:23:0::No name 'findiiter' in module 're' +pointless-statement:26:0::Statement seems to have no effect +no-name-in-module:34:4::No name 'anything' in module 'collections' +no-name-in-module:44:4::No name 'indeed_missing' in module 'collections' +no-name-in-module:49:4::No name 'emit' in module 'collections' +no-name-in-module:60:8::No name 'emit2' in module 'collections' +no-name-in-module:65:0::No name 'lala' in module 'functional.n.no.no_self_use' +no-name-in-module:66:0::No name 'bla' in module 'functional.n.no.no_self_use' diff --git a/tests/functional/n/no/no_self_argument_py37.py b/tests/functional/n/no/no_self_argument_py37.py new file mode 100644 index 000000000..8e6d6fc34 --- /dev/null +++ b/tests/functional/n/no/no_self_argument_py37.py @@ -0,0 +1,15 @@ +"""Test detection of self as argument of first method in Python 3.7 and above.""" + +# pylint: disable=missing-docstring,too-few-public-methods,useless-object-inheritance + + +class Toto(object): + + def __class_getitem__(cls, params): + # This is actually a special method which is always a class method. + # See https://www.python.org/dev/peps/pep-0560/#class-getitem + pass + + def __class_other__(cls, params): # [no-self-argument] + # This is not a special case and as such is an instance method. + pass diff --git a/tests/functional/n/no/no_self_argument_py37.rc b/tests/functional/n/no/no_self_argument_py37.rc new file mode 100644 index 000000000..a17bb22da --- /dev/null +++ b/tests/functional/n/no/no_self_argument_py37.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 diff --git a/tests/functional/n/no/no_self_argument_py37.txt b/tests/functional/n/no/no_self_argument_py37.txt new file mode 100644 index 000000000..d0aba8476 --- /dev/null +++ b/tests/functional/n/no/no_self_argument_py37.txt @@ -0,0 +1 @@ +no-self-argument:13:4:Toto.__class_other__:"Method should have ""self"" as first argument" diff --git a/tests/functional/n/no/no_self_use.py b/tests/functional/n/no/no_self_use.py new file mode 100644 index 000000000..3d3cda1f2 --- /dev/null +++ b/tests/functional/n/no/no_self_use.py @@ -0,0 +1,78 @@ +# pylint: disable=R0903,W0232,missing-docstring, useless-object-inheritance +"""test detection of method which could be a function""" + +from __future__ import print_function + +class Toto(object): + """bla bal abl""" + + def __init__(self): + self.aaa = 2 + + def regular_method(self): + """this method is a real method since it access to self""" + self.function_method() + + def function_method(self): # [no-self-use] + """this method isn' a real method since it doesn't need self""" + print('hello') + + +class Base(object): + """an abstract class""" + + def __init__(self): + self.aaa = 2 + + def check(self, arg): + """an abstract method, could not be a function""" + raise NotImplementedError + + +class Sub(Base): + """a concrete class""" + + def check(self, arg): + """a concrete method, could not be a function since it need + polymorphism benefits + """ + return arg == 0 + +class Super(object): + """same as before without abstract""" + attr = 1 + def method(self): + """regular""" + print(self.attr) + +class Sub1(Super): + """override method with need for self""" + def method(self): + """no i can not be a function""" + print(42) + + def __len__(self): + """no i can not be a function""" + print(42) + + def __cmp__(self, other): + """no i can not be a function""" + print(42) + + def __copy__(self): + return 24 + + def __getstate__(self): + return 42 + + +class Prop(object): + + @property + def count(self): + """Don't emit no-self-use for properties. + + They can't be functions and they can be part of an + API specification. + """ + return 42 diff --git a/tests/functional/n/no/no_self_use.txt b/tests/functional/n/no/no_self_use.txt new file mode 100644 index 000000000..b14ee9e03 --- /dev/null +++ b/tests/functional/n/no/no_self_use.txt @@ -0,0 +1 @@ +no-self-use:16:4:Toto.function_method:Method could be a function diff --git a/tests/functional/n/no/no_self_use_py3.py b/tests/functional/n/no/no_self_use_py3.py new file mode 100644 index 000000000..f40150835 --- /dev/null +++ b/tests/functional/n/no/no_self_use_py3.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring,no-init,unused-argument,invalid-name,too-few-public-methods + +class A: + def __init__(self): + self.store = {} + + def get(self, key, default=None): + return self.store.get(key, default) + +class B(A): + def get_memo(self, obj): + return super().get(obj) diff --git a/tests/functional/n/no/no_self_use_py3.rc b/tests/functional/n/no/no_self_use_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/n/no/no_self_use_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/n/no/no_staticmethod_decorator.py b/tests/functional/n/no/no_staticmethod_decorator.py new file mode 100644 index 000000000..d0e0effa4 --- /dev/null +++ b/tests/functional/n/no/no_staticmethod_decorator.py @@ -0,0 +1,35 @@ +"""Checks static methods are declared with a decorator if within the class +scope and if static method's argument is a member of the class +""" + +# pylint: disable=too-few-public-methods, using-constant-test, no-method-argument, useless-object-inheritance + +class MyClass(object): + """Some class""" + def __init__(self): + pass + + def smethod(): + """static method-to-be""" + smethod = staticmethod(smethod) # [no-staticmethod-decorator] + + if True: + smethod = staticmethod(smethod) # [no-staticmethod-decorator] + + @staticmethod + def my_second_method(): + """correct static method definition""" + + def other_method(): + """some method""" + smethod2 = staticmethod(other_method) # [no-staticmethod-decorator] + +def helloworld(): + """says hello""" + + +MyClass.new_static_method = staticmethod(helloworld) + +class MyOtherClass(object): + """Some other class""" + _make = staticmethod(tuple.__new__) diff --git a/tests/functional/n/no/no_staticmethod_decorator.txt b/tests/functional/n/no/no_staticmethod_decorator.txt new file mode 100644 index 000000000..df897666a --- /dev/null +++ b/tests/functional/n/no/no_staticmethod_decorator.txt @@ -0,0 +1,3 @@ +no-staticmethod-decorator:14:4:MyClass:Consider using a decorator instead of calling staticmethod +no-staticmethod-decorator:17:8:MyClass:Consider using a decorator instead of calling staticmethod +no-staticmethod-decorator:25:4:MyClass:Consider using a decorator instead of calling staticmethod diff --git a/tests/functional/n/no_classmethod_decorator.py b/tests/functional/n/no_classmethod_decorator.py deleted file mode 100644 index 66cc0b3c0..000000000 --- a/tests/functional/n/no_classmethod_decorator.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Checks class methods are declared with a decorator if within the class -scope and if classmethod's argument is a member of the class -""" - -# pylint: disable=too-few-public-methods, using-constant-test, no-self-argument, useless-object-inheritance - -class MyClass(object): - """Some class""" - def __init__(self): - pass - - def cmethod(cls): - """class method-to-be""" - cmethod = classmethod(cmethod) # [no-classmethod-decorator] - - if True: - cmethod = classmethod(cmethod) # [no-classmethod-decorator] - - @classmethod - def my_second_method(cls): - """correct class method definition""" - - def other_method(cls): - """some method""" - cmethod2 = classmethod(other_method) # [no-classmethod-decorator] - -def helloworld(): - """says hello""" - - -MyClass.new_class_method = classmethod(helloworld) - -class MyOtherClass(object): - """Some other class""" - _make = classmethod(tuple.__new__) diff --git a/tests/functional/n/no_classmethod_decorator.txt b/tests/functional/n/no_classmethod_decorator.txt deleted file mode 100644 index 90b10f2b1..000000000 --- a/tests/functional/n/no_classmethod_decorator.txt +++ /dev/null @@ -1,3 +0,0 @@ -no-classmethod-decorator:14:4:MyClass:Consider using a decorator instead of calling classmethod -no-classmethod-decorator:17:8:MyClass:Consider using a decorator instead of calling classmethod -no-classmethod-decorator:25:4:MyClass:Consider using a decorator instead of calling classmethod diff --git a/tests/functional/n/no_else_break.py b/tests/functional/n/no_else_break.py deleted file mode 100644 index cf23f313a..000000000 --- a/tests/functional/n/no_else_break.py +++ /dev/null @@ -1,137 +0,0 @@ -""" Test that superfluous else return are detected. """ - -# pylint:disable=invalid-name,missing-docstring,unused-variable - - -def foo1(x, y, z): - for i in x: - if i > y: # [no-else-break] - break - else: - a = z - - -def foo2(x, y, w, z): - for i in x: - if i > y: # [no-else-break] - break - elif i > w: - break - else: - a = z - - -def foo3(x, y, z): - for i in x: - if i > y: - a = 1 - if z: # [no-else-break] - b = 2 - break - else: - c = 3 - break - else: - d = 4 - break - - -def foo4(x, y): - for i in x: - if i > x: # [no-else-break] - if y: - a = 4 - else: - b = 2 - break - else: - c = 3 - break - - -def foo5(x, y, z): - for i in x: - if i > y: # [no-else-break] - if y: - a = 4 - else: - b = 2 - break - elif z: - c = 2 - else: - c = 3 - break - - -def foo6(x, y): - for i in x: - if i > x: - if y: # [no-else-break] - a = 4 - break - else: - b = 2 - else: - c = 3 - break - - -def bar1(x, y, z): - for i in x: - if i > y: - break - return z - - -def bar2(w, x, y, z): - for i in w: - if i > x: - break - if z < i: - a = y - else: - break - return - - -def bar3(x, y, z): - for i in x: - if i > y: - if z: - break - else: - return z - return None - - -def bar4(x): - for i in range(10): - if x: # [no-else-break] - break - else: - try: - return - except ValueError: - break - - -def nested1(x, y, z): - for i in x: - if i > x: - for j in y: - if j < z: - break - else: - a = z - - -def nested2(x, y, z): - for i in x: - if i > x: - for j in y: - if j > z: - break - break - else: - a = z diff --git a/tests/functional/n/no_else_break.txt b/tests/functional/n/no_else_break.txt deleted file mode 100644 index d1a27f73c..000000000 --- a/tests/functional/n/no_else_break.txt +++ /dev/null @@ -1,7 +0,0 @@ -no-else-break:8:8:foo1:"Unnecessary ""else"" after ""break""" -no-else-break:16:8:foo2:"Unnecessary ""elif"" after ""break""" -no-else-break:28:12:foo3:"Unnecessary ""else"" after ""break""" -no-else-break:41:8:foo4:"Unnecessary ""else"" after ""break""" -no-else-break:54:8:foo5:"Unnecessary ""elif"" after ""break""" -no-else-break:70:12:foo6:"Unnecessary ""else"" after ""break""" -no-else-break:110:8:bar4:"Unnecessary ""else"" after ""break""" diff --git a/tests/functional/n/no_else_continue.py b/tests/functional/n/no_else_continue.py deleted file mode 100644 index 37f70f121..000000000 --- a/tests/functional/n/no_else_continue.py +++ /dev/null @@ -1,137 +0,0 @@ -""" Test that superfluous else return are detected. """ - -# pylint:disable=invalid-name,missing-docstring,unused-variable - - -def foo1(x, y, z): - for i in x: - if i < y: # [no-else-continue] - continue - else: - a = z - - -def foo2(x, y, w, z): - for i in x: - if i < y: # [no-else-continue] - continue - elif i < w: - continue - else: - a = z - - -def foo3(x, y, z): - for i in x: - if i < y: - a = 1 - if z: # [no-else-continue] - b = 2 - continue - else: - c = 3 - continue - else: - d = 4 - continue - - -def foo4(x, y): - for i in x: - if i < x: # [no-else-continue] - if y: - a = 4 - else: - b = 2 - continue - else: - c = 3 - continue - - -def foo5(x, y, z): - for i in x: - if i < y: # [no-else-continue] - if y: - a = 4 - else: - b = 2 - continue - elif z: - c = 2 - else: - c = 3 - continue - - -def foo6(x, y): - for i in x: - if i < x: - if y: # [no-else-continue] - a = 4 - continue - else: - b = 2 - else: - c = 3 - continue - - -def bar1(x, y, z): - for i in x: - if i < y: - continue - return z - - -def bar2(w, x, y, z): - for i in w: - if i < x: - continue - if z < i: - a = y - else: - continue - return - - -def bar3(x, y, z): - for i in x: - if i < y: - if z: - continue - else: - return z - return None - - -def bar4(x): - for i in range(10): - if x: # [no-else-continue] - continue - else: - try: - return - except ValueError: - continue - - -def nested1(x, y, z): - for i in x: - if i < x: - for j in y: - if j < z: - continue - else: - a = z - - -def nested2(x, y, z): - for i in x: - if i < x: - for j in y: - if j < z: - continue - continue - else: - a = z diff --git a/tests/functional/n/no_else_continue.txt b/tests/functional/n/no_else_continue.txt deleted file mode 100644 index 6d659ea28..000000000 --- a/tests/functional/n/no_else_continue.txt +++ /dev/null @@ -1,7 +0,0 @@ -no-else-continue:8:8:foo1:"Unnecessary ""else"" after ""continue""" -no-else-continue:16:8:foo2:"Unnecessary ""elif"" after ""continue""" -no-else-continue:28:12:foo3:"Unnecessary ""else"" after ""continue""" -no-else-continue:41:8:foo4:"Unnecessary ""else"" after ""continue""" -no-else-continue:54:8:foo5:"Unnecessary ""elif"" after ""continue""" -no-else-continue:70:12:foo6:"Unnecessary ""else"" after ""continue""" -no-else-continue:110:8:bar4:"Unnecessary ""else"" after ""continue""" diff --git a/tests/functional/n/no_else_raise.py b/tests/functional/n/no_else_raise.py deleted file mode 100644 index ae807fae3..000000000 --- a/tests/functional/n/no_else_raise.py +++ /dev/null @@ -1,110 +0,0 @@ -""" Test that superfluous else return are detected. """ - -# pylint:disable=invalid-name,missing-docstring,unused-variable,raise-missing-from - -def foo1(x, y, z): - if x: # [no-else-raise] - a = 1 - raise Exception(y) - else: - b = 2 - raise Exception(z) - - -def foo2(x, y, w, z): - if x: # [no-else-raise] - a = 1 - raise Exception(y) - elif z: - b = 2 - raise Exception(w) - else: - c = 3 - raise Exception(z) - - -def foo3(x, y, z): - if x: - a = 1 - if y: # [no-else-raise] - b = 2 - raise Exception(y) - else: - c = 3 - raise Exception(x) - else: - d = 4 - raise Exception(z) - - -def foo4(x, y): - if x: # [no-else-raise] - if y: - a = 4 - else: - b = 2 - raise Exception(x) - else: - c = 3 - raise Exception(y) - - -def foo5(x, y, z): - if x: # [no-else-raise] - if y: - a = 4 - else: - b = 2 - raise Exception(x) - elif z: - raise Exception(y) - else: - c = 3 - raise Exception(z) - - -def foo6(x, y): - if x: - if y: # [no-else-raise] - a = 4 - raise Exception(x) - else: - b = 2 - else: - c = 3 - raise Exception(y) - - -def bar1(x, y, z): - if x: - raise Exception(y) - raise Exception(z) - - -def bar2(w, x, y, z): - if x: - raise Exception(y) - if z: - a = 1 - else: - raise Exception(w) - raise Exception(None) - - -def bar3(x, y, z): - if x: - if z: - raise Exception(y) - else: - raise Exception(z) - raise Exception(None) - - -def bar4(x): - if x: # [no-else-raise] - raise Exception(True) - else: - try: - raise Exception(False) - except ValueError: - raise Exception(None) diff --git a/tests/functional/n/no_else_raise.txt b/tests/functional/n/no_else_raise.txt deleted file mode 100644 index b41f7132f..000000000 --- a/tests/functional/n/no_else_raise.txt +++ /dev/null @@ -1,7 +0,0 @@ -no-else-raise:6:4:foo1:"Unnecessary ""else"" after ""raise""" -no-else-raise:15:4:foo2:"Unnecessary ""elif"" after ""raise""" -no-else-raise:29:8:foo3:"Unnecessary ""else"" after ""raise""" -no-else-raise:41:4:foo4:"Unnecessary ""else"" after ""raise""" -no-else-raise:53:4:foo5:"Unnecessary ""elif"" after ""raise""" -no-else-raise:68:8:foo6:"Unnecessary ""else"" after ""raise""" -no-else-raise:104:4:bar4:"Unnecessary ""else"" after ""raise""" diff --git a/tests/functional/n/no_else_return.py b/tests/functional/n/no_else_return.py deleted file mode 100644 index 0a87551fa..000000000 --- a/tests/functional/n/no_else_return.py +++ /dev/null @@ -1,110 +0,0 @@ -""" Test that superfluous else return are detected. """ - - -# pylint:disable=invalid-name,missing-docstring,unused-variable -def foo1(x, y, z): - if x: # [no-else-return] - a = 1 - return y - else: - b = 2 - return z - - -def foo2(x, y, w, z): - if x: # [no-else-return] - a = 1 - return y - elif z: - b = 2 - return w - else: - c = 3 - return z - - -def foo3(x, y, z): - if x: - a = 1 - if y: # [no-else-return] - b = 2 - return y - else: - c = 3 - return x - else: - d = 4 - return z - - -def foo4(x, y): - if x: # [no-else-return] - if y: - a = 4 - else: - b = 2 - return - else: - c = 3 - return - - -def foo5(x, y, z): - if x: # [no-else-return] - if y: - a = 4 - else: - b = 2 - return - elif z: - c = 2 - else: - c = 3 - return - - -def foo6(x, y): - if x: - if y: # [no-else-return] - a = 4 - return - else: - b = 2 - else: - c = 3 - return - - -def bar1(x, y, z): - if x: - return y - return z - - -def bar2(w, x, y, z): - if x: - return y - if z: - a = 1 - else: - return w - return None - - -def bar3(x, y, z): - if x: - if z: - return y - else: - return z - return None - - -def bar4(x): - if x: # [no-else-return] - return True - else: - try: - return False - except ValueError: - return None diff --git a/tests/functional/n/no_else_return.txt b/tests/functional/n/no_else_return.txt deleted file mode 100644 index 4560f7490..000000000 --- a/tests/functional/n/no_else_return.txt +++ /dev/null @@ -1,7 +0,0 @@ -no-else-return:6:4:foo1:"Unnecessary ""else"" after ""return""" -no-else-return:15:4:foo2:"Unnecessary ""elif"" after ""return""" -no-else-return:29:8:foo3:"Unnecessary ""else"" after ""return""" -no-else-return:41:4:foo4:"Unnecessary ""else"" after ""return""" -no-else-return:53:4:foo5:"Unnecessary ""elif"" after ""return""" -no-else-return:68:8:foo6:"Unnecessary ""else"" after ""return""" -no-else-return:104:4:bar4:"Unnecessary ""else"" after ""return""" diff --git a/tests/functional/n/no_method_argument_py38.py b/tests/functional/n/no_method_argument_py38.py deleted file mode 100644 index c67453288..000000000 --- a/tests/functional/n/no_method_argument_py38.py +++ /dev/null @@ -1,6 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods - - -class Cls: - def __init__(self, obj, /): - self.obj = obj diff --git a/tests/functional/n/no_method_argument_py38.rc b/tests/functional/n/no_method_argument_py38.rc deleted file mode 100644 index 85fc502b3..000000000 --- a/tests/functional/n/no_method_argument_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.8 diff --git a/tests/functional/n/no_name_in_module.py b/tests/functional/n/no_name_in_module.py deleted file mode 100644 index 73ad2db93..000000000 --- a/tests/functional/n/no_name_in_module.py +++ /dev/null @@ -1,66 +0,0 @@ -#pylint: disable=W0401,W0611,no-absolute-import,invalid-name,import-error,bare-except,broad-except,wrong-import-order,ungrouped-imports,wrong-import-position -"""check unexistant names imported are reported""" -from __future__ import print_function - -import collections.tutu # [no-name-in-module] -from collections import toto # [no-name-in-module] -toto.yo() - -from xml.etree import ElementTree -ElementTree.nonexistant_function() # [no-member] -ElementTree.another.nonexistant.function() # [no-member] - - -import sys -print(sys.stdout, 'hello world') -print(sys.stdoout, 'bye bye world') # [no-member] - - -import re -re.finditer('*', 'yo') - -from rie import * -from re import findiiter, compiile # [no-name-in-module,no-name-in-module] - -import os -'SOMEVAR' in os.environ # [pointless-statement] - -try: - from collections import something -except ImportError: - something = None - -try: - from collections import anything # [no-name-in-module] -except ValueError: - anything = None - -try: - import collections.missing -except ImportError: - pass - -try: - import collections.indeed_missing # [no-name-in-module] -except ValueError: - pass - -try: - import collections.emit # [no-name-in-module] -except Exception: - pass - -try: - import collections.emit1 -except ImportError: - pass - -try: - if something: - import collections.emit2 # [no-name-in-module] -except Exception: - pass - -from .no_self_use import Super -from .no_self_use import lala # [no-name-in-module] -from .no_self_use.bla import lala1 # [no-name-in-module] diff --git a/tests/functional/n/no_name_in_module.txt b/tests/functional/n/no_name_in_module.txt deleted file mode 100644 index ea83ac6f8..000000000 --- a/tests/functional/n/no_name_in_module.txt +++ /dev/null @@ -1,14 +0,0 @@ -no-name-in-module:5:0::No name 'tutu' in module 'collections' -no-name-in-module:6:0::No name 'toto' in module 'collections' -no-member:10:0::Module 'xml.etree.ElementTree' has no 'nonexistant_function' member:INFERENCE -no-member:11:0::Module 'xml.etree.ElementTree' has no 'another' member:INFERENCE -no-member:16:6::Module 'sys' has no 'stdoout' member; maybe 'stdout'?:INFERENCE -no-name-in-module:23:0::No name 'compiile' in module 're' -no-name-in-module:23:0::No name 'findiiter' in module 're' -pointless-statement:26:0::Statement seems to have no effect -no-name-in-module:34:4::No name 'anything' in module 'collections' -no-name-in-module:44:4::No name 'indeed_missing' in module 'collections' -no-name-in-module:49:4::No name 'emit' in module 'collections' -no-name-in-module:60:8::No name 'emit2' in module 'collections' -no-name-in-module:65:0::No name 'lala' in module 'functional.n.no_self_use' -no-name-in-module:66:0::No name 'bla' in module 'functional.n.no_self_use' diff --git a/tests/functional/n/no_self_argument_py37.py b/tests/functional/n/no_self_argument_py37.py deleted file mode 100644 index 8e6d6fc34..000000000 --- a/tests/functional/n/no_self_argument_py37.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Test detection of self as argument of first method in Python 3.7 and above.""" - -# pylint: disable=missing-docstring,too-few-public-methods,useless-object-inheritance - - -class Toto(object): - - def __class_getitem__(cls, params): - # This is actually a special method which is always a class method. - # See https://www.python.org/dev/peps/pep-0560/#class-getitem - pass - - def __class_other__(cls, params): # [no-self-argument] - # This is not a special case and as such is an instance method. - pass diff --git a/tests/functional/n/no_self_argument_py37.rc b/tests/functional/n/no_self_argument_py37.rc deleted file mode 100644 index a17bb22da..000000000 --- a/tests/functional/n/no_self_argument_py37.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.7 diff --git a/tests/functional/n/no_self_argument_py37.txt b/tests/functional/n/no_self_argument_py37.txt deleted file mode 100644 index d0aba8476..000000000 --- a/tests/functional/n/no_self_argument_py37.txt +++ /dev/null @@ -1 +0,0 @@ -no-self-argument:13:4:Toto.__class_other__:"Method should have ""self"" as first argument" diff --git a/tests/functional/n/no_self_use.py b/tests/functional/n/no_self_use.py deleted file mode 100644 index 3d3cda1f2..000000000 --- a/tests/functional/n/no_self_use.py +++ /dev/null @@ -1,78 +0,0 @@ -# pylint: disable=R0903,W0232,missing-docstring, useless-object-inheritance -"""test detection of method which could be a function""" - -from __future__ import print_function - -class Toto(object): - """bla bal abl""" - - def __init__(self): - self.aaa = 2 - - def regular_method(self): - """this method is a real method since it access to self""" - self.function_method() - - def function_method(self): # [no-self-use] - """this method isn' a real method since it doesn't need self""" - print('hello') - - -class Base(object): - """an abstract class""" - - def __init__(self): - self.aaa = 2 - - def check(self, arg): - """an abstract method, could not be a function""" - raise NotImplementedError - - -class Sub(Base): - """a concrete class""" - - def check(self, arg): - """a concrete method, could not be a function since it need - polymorphism benefits - """ - return arg == 0 - -class Super(object): - """same as before without abstract""" - attr = 1 - def method(self): - """regular""" - print(self.attr) - -class Sub1(Super): - """override method with need for self""" - def method(self): - """no i can not be a function""" - print(42) - - def __len__(self): - """no i can not be a function""" - print(42) - - def __cmp__(self, other): - """no i can not be a function""" - print(42) - - def __copy__(self): - return 24 - - def __getstate__(self): - return 42 - - -class Prop(object): - - @property - def count(self): - """Don't emit no-self-use for properties. - - They can't be functions and they can be part of an - API specification. - """ - return 42 diff --git a/tests/functional/n/no_self_use.txt b/tests/functional/n/no_self_use.txt deleted file mode 100644 index b14ee9e03..000000000 --- a/tests/functional/n/no_self_use.txt +++ /dev/null @@ -1 +0,0 @@ -no-self-use:16:4:Toto.function_method:Method could be a function diff --git a/tests/functional/n/no_self_use_py3.py b/tests/functional/n/no_self_use_py3.py deleted file mode 100644 index f40150835..000000000 --- a/tests/functional/n/no_self_use_py3.py +++ /dev/null @@ -1,12 +0,0 @@ -# pylint: disable=missing-docstring,no-init,unused-argument,invalid-name,too-few-public-methods - -class A: - def __init__(self): - self.store = {} - - def get(self, key, default=None): - return self.store.get(key, default) - -class B(A): - def get_memo(self, obj): - return super().get(obj) diff --git a/tests/functional/n/no_self_use_py3.rc b/tests/functional/n/no_self_use_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/n/no_self_use_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/n/no_staticmethod_decorator.py b/tests/functional/n/no_staticmethod_decorator.py deleted file mode 100644 index d0e0effa4..000000000 --- a/tests/functional/n/no_staticmethod_decorator.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Checks static methods are declared with a decorator if within the class -scope and if static method's argument is a member of the class -""" - -# pylint: disable=too-few-public-methods, using-constant-test, no-method-argument, useless-object-inheritance - -class MyClass(object): - """Some class""" - def __init__(self): - pass - - def smethod(): - """static method-to-be""" - smethod = staticmethod(smethod) # [no-staticmethod-decorator] - - if True: - smethod = staticmethod(smethod) # [no-staticmethod-decorator] - - @staticmethod - def my_second_method(): - """correct static method definition""" - - def other_method(): - """some method""" - smethod2 = staticmethod(other_method) # [no-staticmethod-decorator] - -def helloworld(): - """says hello""" - - -MyClass.new_static_method = staticmethod(helloworld) - -class MyOtherClass(object): - """Some other class""" - _make = staticmethod(tuple.__new__) diff --git a/tests/functional/n/no_staticmethod_decorator.txt b/tests/functional/n/no_staticmethod_decorator.txt deleted file mode 100644 index df897666a..000000000 --- a/tests/functional/n/no_staticmethod_decorator.txt +++ /dev/null @@ -1,3 +0,0 @@ -no-staticmethod-decorator:14:4:MyClass:Consider using a decorator instead of calling staticmethod -no-staticmethod-decorator:17:8:MyClass:Consider using a decorator instead of calling staticmethod -no-staticmethod-decorator:25:4:MyClass:Consider using a decorator instead of calling staticmethod diff --git a/tests/functional/r/raise/raise_missing_from.py b/tests/functional/r/raise/raise_missing_from.py new file mode 100644 index 000000000..d23cefb5e --- /dev/null +++ b/tests/functional/r/raise/raise_missing_from.py @@ -0,0 +1,157 @@ +# pylint:disable=missing-docstring, unreachable, using-constant-test, invalid-name, bare-except +# pylint:disable=try-except-raise, undefined-variable, too-few-public-methods, superfluous-parens + +################################################################################ +# Positives: + +try: + 1 / 0 +except ZeroDivisionError: + # +1: [raise-missing-from] + raise KeyError + +try: + 1 / 0 +except ZeroDivisionError: + # Our algorithm doesn't have to be careful about the complicated expression below, because + # the exception above wasn't bound to a name. + # +1: [raise-missing-from] + raise (foo + bar).baz + +try: + 1 / 0 +except ZeroDivisionError as e: + # +1: [raise-missing-from] + raise KeyError + +try: + 1 / 0 +except ZeroDivisionError as e: + # +1: [raise-missing-from] + raise KeyError +else: + pass +finally: + pass + +try: + 1 / 0 +except ZeroDivisionError as e: + if 1: + if 1: + with whatever: + try: + # +1: [raise-missing-from] + raise KeyError + except: + pass + +try: + 1 / 0 +except ZeroDivisionError as e: + # +1: [raise-missing-from] + raise KeyError() + +try: + 1 / 0 +except ZeroDivisionError as e: + # +1: [raise-missing-from] + raise KeyError(whatever, whatever=whatever) + + +################################################################################ +# Negatives (Same cases as above, except with `from`): + +try: + 1 / 0 +except ZeroDivisionError: + raise KeyError from foo + +try: + 1 / 0 +except ZeroDivisionError: + raise (foo + bar).baz from foo + +try: + 1 / 0 +except ZeroDivisionError as e: + raise KeyError from foo + +try: + 1 / 0 +except ZeroDivisionError as e: + raise KeyError from foo +else: + pass +finally: + pass + +try: + 1 / 0 +except ZeroDivisionError as e: + if 1: + if 1: + with whatever: + try: + raise KeyError from foo + except: + pass + +try: + 1 / 0 +except ZeroDivisionError as e: + raise KeyError() from foo + +try: + 1 / 0 +except ZeroDivisionError as e: + raise KeyError(whatever, whatever=whatever) from foo + + +################################################################################ +# Other negatives: + +try: + 1 / 0 +except ZeroDivisionError: + raise + +try: + 1 / 0 +except ZeroDivisionError as e: + raise + +try: + 1 / 0 +except ZeroDivisionError as e: + raise e + +try: + 1 / 0 +except ZeroDivisionError as e: + if 1: + if 1: + if 1: + raise e + +try: + 1 / 0 +except ZeroDivisionError as e: + raise e.with_traceback(e.__traceback__) + +try: + 1 / 0 +except ZeroDivisionError as e: + raise (e + 7) + +try: + 1 / 0 +except ZeroDivisionError as e: + def f(): + raise KeyError + +try: + 1 / 0 +except ZeroDivisionError as e: + class Foo: + raise KeyError diff --git a/tests/functional/r/raise/raise_missing_from.txt b/tests/functional/r/raise/raise_missing_from.txt new file mode 100644 index 000000000..15138705a --- /dev/null +++ b/tests/functional/r/raise/raise_missing_from.txt @@ -0,0 +1,7 @@ +raise-missing-from:11:4::Consider explicitly re-raising using the 'from' keyword +raise-missing-from:19:4::Consider explicitly re-raising using the 'from' keyword +raise-missing-from:25:4::Consider explicitly re-raising using the 'from' keyword +raise-missing-from:31:4::Consider explicitly re-raising using the 'from' keyword +raise-missing-from:45:20::Consider explicitly re-raising using the 'from' keyword +raise-missing-from:53:4::Consider explicitly re-raising using the 'from' keyword +raise-missing-from:59:4::Consider explicitly re-raising using the 'from' keyword diff --git a/tests/functional/r/raise/raising_format_tuple.py b/tests/functional/r/raise/raising_format_tuple.py new file mode 100644 index 000000000..0f3a3349a --- /dev/null +++ b/tests/functional/r/raise/raising_format_tuple.py @@ -0,0 +1,51 @@ +''' +Complain about multi-argument exception constructors where the first argument +contains a percent sign, thus suggesting a % string formatting was intended +instead. The same holds for a string containing {...} suggesting str.format() +was intended. +''' + +def bad_percent(arg): + '''Raising a percent-formatted string and an argument''' + raise KeyError('Bad key: %r', arg) # [raising-format-tuple] + +def good_percent(arg): + '''Instead of passing multiple arguments, format the message''' + raise KeyError('Bad key: %r' % arg) + +def bad_multiarg(name, value): + '''Raising a formatted string and multiple additional arguments''' + raise ValueError('%s measures %.2f', name, value) # [raising-format-tuple] + +def good_multiarg(name, value): + '''The arguments have to be written as a tuple for formatting''' + raise ValueError('%s measures %.2f' % (name, value)) + +def bad_braces(arg): + '''Curly braces as placeholders''' + raise KeyError('Bad key: {:r}', arg) # [raising-format-tuple] + +def good_braces(arg): + '''Call str.format() instead''' + raise KeyError('Bad key: {:r}'.format(arg)) + +def bad_multistring(arg): + '''Multiple adjacent string literals''' + raise AssertionError( # [raising-format-tuple] + 'Long message about %s ' + "split over several adjacent literals", arg) + +def bad_triplequote(arg): + '''String literals with triple quotes''' + raise AssertionError( # [raising-format-tuple] + '''Long message about %s + split over several adjacent literals''', arg) + +def bad_unicode(arg): + '''Unicode string literal''' + raise ValueError(u'Bad %s', arg) # [raising-format-tuple] + +def raise_something_without_name(arg): + '''Regression test for nodes without .node attribute''' + import standard_exceptions # pylint: disable=import-error,import-outside-toplevel + raise standard_exceptions.MyException(u'An %s', arg) # [raising-format-tuple] diff --git a/tests/functional/r/raise/raising_format_tuple.txt b/tests/functional/r/raise/raising_format_tuple.txt new file mode 100644 index 000000000..756fd1092 --- /dev/null +++ b/tests/functional/r/raise/raising_format_tuple.txt @@ -0,0 +1,7 @@ +raising-format-tuple:10:4:bad_percent:Exception arguments suggest string formatting might be intended +raising-format-tuple:18:4:bad_multiarg:Exception arguments suggest string formatting might be intended +raising-format-tuple:26:4:bad_braces:Exception arguments suggest string formatting might be intended +raising-format-tuple:34:4:bad_multistring:Exception arguments suggest string formatting might be intended +raising-format-tuple:40:4:bad_triplequote:Exception arguments suggest string formatting might be intended +raising-format-tuple:46:4:bad_unicode:Exception arguments suggest string formatting might be intended +raising-format-tuple:51:4:raise_something_without_name:Exception arguments suggest string formatting might be intended diff --git a/tests/functional/r/raise/raising_non_exception_py3.py b/tests/functional/r/raise/raising_non_exception_py3.py new file mode 100644 index 000000000..7961c5220 --- /dev/null +++ b/tests/functional/r/raise/raising_non_exception_py3.py @@ -0,0 +1,13 @@ +"""The following code should emit a raising-non-exception. + +Previously, it didn't, due to a bug in the check for bad-exception-context, +which prevented further checking on the Raise node. +""" +# pylint: disable=import-error, too-few-public-methods, useless-object-inheritance + +from missing_module import missing + +class Exc(object): + """Not an actual exception.""" + +raise Exc from missing # [raising-non-exception] diff --git a/tests/functional/r/raise/raising_non_exception_py3.rc b/tests/functional/r/raise/raising_non_exception_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/r/raise/raising_non_exception_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/r/raise/raising_non_exception_py3.txt b/tests/functional/r/raise/raising_non_exception_py3.txt new file mode 100644 index 000000000..9a2e494f1 --- /dev/null +++ b/tests/functional/r/raise/raising_non_exception_py3.txt @@ -0,0 +1 @@ +raising-non-exception:13:0::Raising a new style class which doesn't inherit from BaseException diff --git a/tests/functional/r/raise/raising_self.py b/tests/functional/r/raise/raising_self.py new file mode 100644 index 000000000..16f244ba5 --- /dev/null +++ b/tests/functional/r/raise/raising_self.py @@ -0,0 +1,10 @@ +# pylint: disable=missing-docstring + +class MultiException(Exception): + def __init__(self): + Exception.__init__(self) + def return_self(self): + return self + + +raise MultiException().return_self() diff --git a/tests/functional/r/raise_missing_from.py b/tests/functional/r/raise_missing_from.py deleted file mode 100644 index d23cefb5e..000000000 --- a/tests/functional/r/raise_missing_from.py +++ /dev/null @@ -1,157 +0,0 @@ -# pylint:disable=missing-docstring, unreachable, using-constant-test, invalid-name, bare-except -# pylint:disable=try-except-raise, undefined-variable, too-few-public-methods, superfluous-parens - -################################################################################ -# Positives: - -try: - 1 / 0 -except ZeroDivisionError: - # +1: [raise-missing-from] - raise KeyError - -try: - 1 / 0 -except ZeroDivisionError: - # Our algorithm doesn't have to be careful about the complicated expression below, because - # the exception above wasn't bound to a name. - # +1: [raise-missing-from] - raise (foo + bar).baz - -try: - 1 / 0 -except ZeroDivisionError as e: - # +1: [raise-missing-from] - raise KeyError - -try: - 1 / 0 -except ZeroDivisionError as e: - # +1: [raise-missing-from] - raise KeyError -else: - pass -finally: - pass - -try: - 1 / 0 -except ZeroDivisionError as e: - if 1: - if 1: - with whatever: - try: - # +1: [raise-missing-from] - raise KeyError - except: - pass - -try: - 1 / 0 -except ZeroDivisionError as e: - # +1: [raise-missing-from] - raise KeyError() - -try: - 1 / 0 -except ZeroDivisionError as e: - # +1: [raise-missing-from] - raise KeyError(whatever, whatever=whatever) - - -################################################################################ -# Negatives (Same cases as above, except with `from`): - -try: - 1 / 0 -except ZeroDivisionError: - raise KeyError from foo - -try: - 1 / 0 -except ZeroDivisionError: - raise (foo + bar).baz from foo - -try: - 1 / 0 -except ZeroDivisionError as e: - raise KeyError from foo - -try: - 1 / 0 -except ZeroDivisionError as e: - raise KeyError from foo -else: - pass -finally: - pass - -try: - 1 / 0 -except ZeroDivisionError as e: - if 1: - if 1: - with whatever: - try: - raise KeyError from foo - except: - pass - -try: - 1 / 0 -except ZeroDivisionError as e: - raise KeyError() from foo - -try: - 1 / 0 -except ZeroDivisionError as e: - raise KeyError(whatever, whatever=whatever) from foo - - -################################################################################ -# Other negatives: - -try: - 1 / 0 -except ZeroDivisionError: - raise - -try: - 1 / 0 -except ZeroDivisionError as e: - raise - -try: - 1 / 0 -except ZeroDivisionError as e: - raise e - -try: - 1 / 0 -except ZeroDivisionError as e: - if 1: - if 1: - if 1: - raise e - -try: - 1 / 0 -except ZeroDivisionError as e: - raise e.with_traceback(e.__traceback__) - -try: - 1 / 0 -except ZeroDivisionError as e: - raise (e + 7) - -try: - 1 / 0 -except ZeroDivisionError as e: - def f(): - raise KeyError - -try: - 1 / 0 -except ZeroDivisionError as e: - class Foo: - raise KeyError diff --git a/tests/functional/r/raise_missing_from.txt b/tests/functional/r/raise_missing_from.txt deleted file mode 100644 index 15138705a..000000000 --- a/tests/functional/r/raise_missing_from.txt +++ /dev/null @@ -1,7 +0,0 @@ -raise-missing-from:11:4::Consider explicitly re-raising using the 'from' keyword -raise-missing-from:19:4::Consider explicitly re-raising using the 'from' keyword -raise-missing-from:25:4::Consider explicitly re-raising using the 'from' keyword -raise-missing-from:31:4::Consider explicitly re-raising using the 'from' keyword -raise-missing-from:45:20::Consider explicitly re-raising using the 'from' keyword -raise-missing-from:53:4::Consider explicitly re-raising using the 'from' keyword -raise-missing-from:59:4::Consider explicitly re-raising using the 'from' keyword diff --git a/tests/functional/r/raising_format_tuple.py b/tests/functional/r/raising_format_tuple.py deleted file mode 100644 index 0f3a3349a..000000000 --- a/tests/functional/r/raising_format_tuple.py +++ /dev/null @@ -1,51 +0,0 @@ -''' -Complain about multi-argument exception constructors where the first argument -contains a percent sign, thus suggesting a % string formatting was intended -instead. The same holds for a string containing {...} suggesting str.format() -was intended. -''' - -def bad_percent(arg): - '''Raising a percent-formatted string and an argument''' - raise KeyError('Bad key: %r', arg) # [raising-format-tuple] - -def good_percent(arg): - '''Instead of passing multiple arguments, format the message''' - raise KeyError('Bad key: %r' % arg) - -def bad_multiarg(name, value): - '''Raising a formatted string and multiple additional arguments''' - raise ValueError('%s measures %.2f', name, value) # [raising-format-tuple] - -def good_multiarg(name, value): - '''The arguments have to be written as a tuple for formatting''' - raise ValueError('%s measures %.2f' % (name, value)) - -def bad_braces(arg): - '''Curly braces as placeholders''' - raise KeyError('Bad key: {:r}', arg) # [raising-format-tuple] - -def good_braces(arg): - '''Call str.format() instead''' - raise KeyError('Bad key: {:r}'.format(arg)) - -def bad_multistring(arg): - '''Multiple adjacent string literals''' - raise AssertionError( # [raising-format-tuple] - 'Long message about %s ' - "split over several adjacent literals", arg) - -def bad_triplequote(arg): - '''String literals with triple quotes''' - raise AssertionError( # [raising-format-tuple] - '''Long message about %s - split over several adjacent literals''', arg) - -def bad_unicode(arg): - '''Unicode string literal''' - raise ValueError(u'Bad %s', arg) # [raising-format-tuple] - -def raise_something_without_name(arg): - '''Regression test for nodes without .node attribute''' - import standard_exceptions # pylint: disable=import-error,import-outside-toplevel - raise standard_exceptions.MyException(u'An %s', arg) # [raising-format-tuple] diff --git a/tests/functional/r/raising_format_tuple.txt b/tests/functional/r/raising_format_tuple.txt deleted file mode 100644 index 756fd1092..000000000 --- a/tests/functional/r/raising_format_tuple.txt +++ /dev/null @@ -1,7 +0,0 @@ -raising-format-tuple:10:4:bad_percent:Exception arguments suggest string formatting might be intended -raising-format-tuple:18:4:bad_multiarg:Exception arguments suggest string formatting might be intended -raising-format-tuple:26:4:bad_braces:Exception arguments suggest string formatting might be intended -raising-format-tuple:34:4:bad_multistring:Exception arguments suggest string formatting might be intended -raising-format-tuple:40:4:bad_triplequote:Exception arguments suggest string formatting might be intended -raising-format-tuple:46:4:bad_unicode:Exception arguments suggest string formatting might be intended -raising-format-tuple:51:4:raise_something_without_name:Exception arguments suggest string formatting might be intended diff --git a/tests/functional/r/raising_non_exception_py3.py b/tests/functional/r/raising_non_exception_py3.py deleted file mode 100644 index 7961c5220..000000000 --- a/tests/functional/r/raising_non_exception_py3.py +++ /dev/null @@ -1,13 +0,0 @@ -"""The following code should emit a raising-non-exception. - -Previously, it didn't, due to a bug in the check for bad-exception-context, -which prevented further checking on the Raise node. -""" -# pylint: disable=import-error, too-few-public-methods, useless-object-inheritance - -from missing_module import missing - -class Exc(object): - """Not an actual exception.""" - -raise Exc from missing # [raising-non-exception] diff --git a/tests/functional/r/raising_non_exception_py3.rc b/tests/functional/r/raising_non_exception_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/r/raising_non_exception_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/r/raising_non_exception_py3.txt b/tests/functional/r/raising_non_exception_py3.txt deleted file mode 100644 index 9a2e494f1..000000000 --- a/tests/functional/r/raising_non_exception_py3.txt +++ /dev/null @@ -1 +0,0 @@ -raising-non-exception:13:0::Raising a new style class which doesn't inherit from BaseException diff --git a/tests/functional/r/raising_self.py b/tests/functional/r/raising_self.py deleted file mode 100644 index 16f244ba5..000000000 --- a/tests/functional/r/raising_self.py +++ /dev/null @@ -1,10 +0,0 @@ -# pylint: disable=missing-docstring - -class MultiException(Exception): - def __init__(self): - Exception.__init__(self) - def return_self(self): - return self - - -raise MultiException().return_self() diff --git a/tests/functional/r/recursion/recursion_error_2667.py b/tests/functional/r/recursion/recursion_error_2667.py new file mode 100644 index 000000000..585cf7f2f --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_2667.py @@ -0,0 +1,9 @@ +"""Add regression test for https://github.com/PyCQA/pylint/issues/2667""" +# pylint: disable=missing-docstring, too-few-public-methods + +class MyClass: + def __init__(self): + self._slice = slice(0, 10) + + def incr(self): + self._slice = slice(0, self._slice.stop + 1) diff --git a/tests/functional/r/recursion/recursion_error_2836.py b/tests/functional/r/recursion/recursion_error_2836.py new file mode 100644 index 000000000..9be68b265 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_2836.py @@ -0,0 +1,18 @@ +# pylint: disable=missing-docstring +class Data: + def __init__(self): + self.shape = [None, 17] + + @property + def ndim(self): + return len(self.shape) + + def copy_move_axis(self, old_axis): + if old_axis < 0: + old_axis += self.ndim + assert old_axis >= 0 + assert 0 <= old_axis < self.ndim + + new_shape = [None] * self.ndim + self.shape = new_shape + return self diff --git a/tests/functional/r/recursion/recursion_error_2861.py b/tests/functional/r/recursion/recursion_error_2861.py new file mode 100644 index 000000000..03e0a5444 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_2861.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring,redefined-builtin,unsubscriptable-object +# pylint: disable=invalid-name,too-few-public-methods,attribute-defined-outside-init +class Repository: + def _transfer(self, bytes=-1): + self._bytesTransfered = 0 + bufff = True + while bufff and (bytes < 0 or self._bytesTransfered < bytes): + bufff = bufff[: bytes - self._bytesTransfered] + self._bytesTransfered += len(bufff) diff --git a/tests/functional/r/recursion/recursion_error_2899.py b/tests/functional/r/recursion/recursion_error_2899.py new file mode 100644 index 000000000..aa01f2aca --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_2899.py @@ -0,0 +1,9 @@ +# pylint: disable=global-statement,missing-docstring,blacklisted-name +foo = "test" + + +def broken(): + global foo + + bar = len(foo) + foo = foo[bar] diff --git a/tests/functional/r/recursion/recursion_error_2906.py b/tests/functional/r/recursion/recursion_error_2906.py new file mode 100644 index 000000000..062109672 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_2906.py @@ -0,0 +1,14 @@ +"""Recursion error for https://github.com/PyCQA/pylint/issues/2906""" +# pylint: disable=blacklisted-name,global-statement,invalid-name,missing-docstring +lst = [] + + +def foo(): + lst.append(0) + + +def bar(): + global lst + + length = len(lst) + lst += [length] diff --git a/tests/functional/r/recursion/recursion_error_3152.py b/tests/functional/r/recursion/recursion_error_3152.py new file mode 100644 index 000000000..97ec190e8 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_3152.py @@ -0,0 +1,7 @@ +"""Check that we do not crash with a recursion error""" +import setuptools + + +# pylint: disable=missing-docstring,too-few-public-methods +class Custom(setuptools.Command): + pass diff --git a/tests/functional/r/recursion/recursion_error_3159.py b/tests/functional/r/recursion/recursion_error_3159.py new file mode 100644 index 000000000..086cce769 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_3159.py @@ -0,0 +1,26 @@ +"""Check that we do not crash with a recursion error + +https://github.com/PyCQA/pylint/issues/3159 +""" +# pylint: disable=missing-docstring +from setuptools import Command, find_packages, setup + + +class AnyCommand(Command): + def initialize_options(self): + pass + + def finalize_options(self): + pass + + @staticmethod + def run(): + print("Do anything") + + +setup( + name="Thing", + version="1.0", + packages=find_packages(), + cmdclass={"anycommand": AnyCommand}, +) diff --git a/tests/functional/r/recursion/recursion_error_940.py b/tests/functional/r/recursion/recursion_error_940.py new file mode 100644 index 000000000..4a9f346cb --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_940.py @@ -0,0 +1,13 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance +import datetime + + +class NewDate(datetime.date): + @classmethod + def today(cls): + return cls(2010, 1, 1) + + +class Next(object): + def __init__(self): + datetime.date = NewDate diff --git a/tests/functional/r/recursion/recursion_error_crash.py b/tests/functional/r/recursion/recursion_error_crash.py new file mode 100644 index 000000000..208bc2e7a --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_crash.py @@ -0,0 +1,9 @@ +"""Test that a recursion error does not happen + +https://github.com/PyCQA/pylint/issues/2463 +""" +import os + +ABC = os.path.realpath('abc') +DEF = os.path.realpath(ABC + 'def') +GHI = os.path.join(DEF, 'ghi') diff --git a/tests/functional/r/recursion/recursion_error_crash_2683.py b/tests/functional/r/recursion/recursion_error_crash_2683.py new file mode 100644 index 000000000..05978a355 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_crash_2683.py @@ -0,0 +1,13 @@ +"""Test for https://github.com/PyCQA/pylint/issues/2683""" +# pylint: disable=missing-docstring,too-few-public-methods + +class Cls: + def __init__(self): + self.count = 5 + + def method(self): + records = [] + for _ in []: + records += [] + records = records[:self.count] + records.sort() diff --git a/tests/functional/r/recursion/recursion_error_crash_astroid_623.py b/tests/functional/r/recursion/recursion_error_crash_astroid_623.py new file mode 100644 index 000000000..662da6145 --- /dev/null +++ b/tests/functional/r/recursion/recursion_error_crash_astroid_623.py @@ -0,0 +1,10 @@ +"""Test that a recursion error does not happen + +https://github.com/PyCQA/astroid/issues/623 +""" +from os import path + +FIRST = path.normpath(path.dirname(path.realpath(__file__))) +SECOND = path.normpath(path.abspath(path.join(FIRST, ".."))) +THIRD = path.normpath(path.abspath(path.join(SECOND, ".."))) +FOURTH = path.join(THIRD) diff --git a/tests/functional/r/recursion/recursion_regression_2960.py b/tests/functional/r/recursion/recursion_regression_2960.py new file mode 100644 index 000000000..96e0fbf74 --- /dev/null +++ b/tests/functional/r/recursion/recursion_regression_2960.py @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring +from runpy import run_path + +_STH = run_path('hello.py') diff --git a/tests/functional/r/recursion_error_2667.py b/tests/functional/r/recursion_error_2667.py deleted file mode 100644 index 585cf7f2f..000000000 --- a/tests/functional/r/recursion_error_2667.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Add regression test for https://github.com/PyCQA/pylint/issues/2667""" -# pylint: disable=missing-docstring, too-few-public-methods - -class MyClass: - def __init__(self): - self._slice = slice(0, 10) - - def incr(self): - self._slice = slice(0, self._slice.stop + 1) diff --git a/tests/functional/r/recursion_error_2836.py b/tests/functional/r/recursion_error_2836.py deleted file mode 100644 index 9be68b265..000000000 --- a/tests/functional/r/recursion_error_2836.py +++ /dev/null @@ -1,18 +0,0 @@ -# pylint: disable=missing-docstring -class Data: - def __init__(self): - self.shape = [None, 17] - - @property - def ndim(self): - return len(self.shape) - - def copy_move_axis(self, old_axis): - if old_axis < 0: - old_axis += self.ndim - assert old_axis >= 0 - assert 0 <= old_axis < self.ndim - - new_shape = [None] * self.ndim - self.shape = new_shape - return self diff --git a/tests/functional/r/recursion_error_2861.py b/tests/functional/r/recursion_error_2861.py deleted file mode 100644 index 03e0a5444..000000000 --- a/tests/functional/r/recursion_error_2861.py +++ /dev/null @@ -1,9 +0,0 @@ -# pylint: disable=missing-docstring,redefined-builtin,unsubscriptable-object -# pylint: disable=invalid-name,too-few-public-methods,attribute-defined-outside-init -class Repository: - def _transfer(self, bytes=-1): - self._bytesTransfered = 0 - bufff = True - while bufff and (bytes < 0 or self._bytesTransfered < bytes): - bufff = bufff[: bytes - self._bytesTransfered] - self._bytesTransfered += len(bufff) diff --git a/tests/functional/r/recursion_error_2899.py b/tests/functional/r/recursion_error_2899.py deleted file mode 100644 index aa01f2aca..000000000 --- a/tests/functional/r/recursion_error_2899.py +++ /dev/null @@ -1,9 +0,0 @@ -# pylint: disable=global-statement,missing-docstring,blacklisted-name -foo = "test" - - -def broken(): - global foo - - bar = len(foo) - foo = foo[bar] diff --git a/tests/functional/r/recursion_error_2906.py b/tests/functional/r/recursion_error_2906.py deleted file mode 100644 index 062109672..000000000 --- a/tests/functional/r/recursion_error_2906.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Recursion error for https://github.com/PyCQA/pylint/issues/2906""" -# pylint: disable=blacklisted-name,global-statement,invalid-name,missing-docstring -lst = [] - - -def foo(): - lst.append(0) - - -def bar(): - global lst - - length = len(lst) - lst += [length] diff --git a/tests/functional/r/recursion_error_3152.py b/tests/functional/r/recursion_error_3152.py deleted file mode 100644 index 97ec190e8..000000000 --- a/tests/functional/r/recursion_error_3152.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Check that we do not crash with a recursion error""" -import setuptools - - -# pylint: disable=missing-docstring,too-few-public-methods -class Custom(setuptools.Command): - pass diff --git a/tests/functional/r/recursion_error_3159.py b/tests/functional/r/recursion_error_3159.py deleted file mode 100644 index 086cce769..000000000 --- a/tests/functional/r/recursion_error_3159.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Check that we do not crash with a recursion error - -https://github.com/PyCQA/pylint/issues/3159 -""" -# pylint: disable=missing-docstring -from setuptools import Command, find_packages, setup - - -class AnyCommand(Command): - def initialize_options(self): - pass - - def finalize_options(self): - pass - - @staticmethod - def run(): - print("Do anything") - - -setup( - name="Thing", - version="1.0", - packages=find_packages(), - cmdclass={"anycommand": AnyCommand}, -) diff --git a/tests/functional/r/recursion_error_940.py b/tests/functional/r/recursion_error_940.py deleted file mode 100644 index 4a9f346cb..000000000 --- a/tests/functional/r/recursion_error_940.py +++ /dev/null @@ -1,13 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance -import datetime - - -class NewDate(datetime.date): - @classmethod - def today(cls): - return cls(2010, 1, 1) - - -class Next(object): - def __init__(self): - datetime.date = NewDate diff --git a/tests/functional/r/recursion_error_crash.py b/tests/functional/r/recursion_error_crash.py deleted file mode 100644 index 208bc2e7a..000000000 --- a/tests/functional/r/recursion_error_crash.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Test that a recursion error does not happen - -https://github.com/PyCQA/pylint/issues/2463 -""" -import os - -ABC = os.path.realpath('abc') -DEF = os.path.realpath(ABC + 'def') -GHI = os.path.join(DEF, 'ghi') diff --git a/tests/functional/r/recursion_error_crash_2683.py b/tests/functional/r/recursion_error_crash_2683.py deleted file mode 100644 index 05978a355..000000000 --- a/tests/functional/r/recursion_error_crash_2683.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Test for https://github.com/PyCQA/pylint/issues/2683""" -# pylint: disable=missing-docstring,too-few-public-methods - -class Cls: - def __init__(self): - self.count = 5 - - def method(self): - records = [] - for _ in []: - records += [] - records = records[:self.count] - records.sort() diff --git a/tests/functional/r/recursion_error_crash_astroid_623.py b/tests/functional/r/recursion_error_crash_astroid_623.py deleted file mode 100644 index 662da6145..000000000 --- a/tests/functional/r/recursion_error_crash_astroid_623.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Test that a recursion error does not happen - -https://github.com/PyCQA/astroid/issues/623 -""" -from os import path - -FIRST = path.normpath(path.dirname(path.realpath(__file__))) -SECOND = path.normpath(path.abspath(path.join(FIRST, ".."))) -THIRD = path.normpath(path.abspath(path.join(SECOND, ".."))) -FOURTH = path.join(THIRD) diff --git a/tests/functional/r/recursion_regression_2960.py b/tests/functional/r/recursion_regression_2960.py deleted file mode 100644 index 96e0fbf74..000000000 --- a/tests/functional/r/recursion_regression_2960.py +++ /dev/null @@ -1,4 +0,0 @@ -# pylint: disable=missing-docstring -from runpy import run_path - -_STH = run_path('hello.py') diff --git a/tests/functional/r/regression/regression_1326_crash_uninferable.py b/tests/functional/r/regression/regression_1326_crash_uninferable.py new file mode 100644 index 000000000..a42d44ac3 --- /dev/null +++ b/tests/functional/r/regression/regression_1326_crash_uninferable.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring + +import socket + +RETRYABLE_EXCEPTIONS = (socket.error,) + +# pylint: disable=wrong-exception-operation +def exception_handler(): + try: + yield 1 + except RETRYABLE_EXCEPTIONS + tuple(): + yield 2 diff --git a/tests/functional/r/regression/regression_2443_duplicate_bases.py b/tests/functional/r/regression/regression_2443_duplicate_bases.py new file mode 100644 index 000000000..f32490c44 --- /dev/null +++ b/tests/functional/r/regression/regression_2443_duplicate_bases.py @@ -0,0 +1,28 @@ +# pylint: disable=missing-docstring, too-many-ancestors,too-few-public-methods +from typing import Generic, TypeVar + +IN = TypeVar('IN', contravariant=True) +OUT = TypeVar('OUT', covariant=True) + + +class Service: + pass + + +class ConsumingMixin(Generic[IN]): + pass + + +class ProducingMixin(Generic[OUT]): + pass + + +class StreamingMixin(Generic[IN, OUT], ConsumingMixin[IN], ProducingMixin[OUT]): + pass + + +class Example(StreamingMixin[str, int], Service): + pass + + +print(Example.__mro__) diff --git a/tests/functional/r/regression/regression_2443_duplicate_bases.rc b/tests/functional/r/regression/regression_2443_duplicate_bases.rc new file mode 100644 index 000000000..0ba2b6333 --- /dev/null +++ b/tests/functional/r/regression/regression_2443_duplicate_bases.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/tests/functional/r/regression/regression_2937_ifexp.py b/tests/functional/r/regression/regression_2937_ifexp.py new file mode 100644 index 000000000..55b240440 --- /dev/null +++ b/tests/functional/r/regression/regression_2937_ifexp.py @@ -0,0 +1,20 @@ +# pylint: disable=missing-docstring,no-else-return,using-constant-test +def get_list(): + return [1] if True else [2] + + +def find_int(): + return int(get_list()[0]) + + +def func(): + if True: + return find_int() + else: + return find_int() + + +def test(): + resp = func() + assert resp / resp > 0 + return resp diff --git a/tests/functional/r/regression/regression_3091.py b/tests/functional/r/regression/regression_3091.py new file mode 100644 index 000000000..8196db12d --- /dev/null +++ b/tests/functional/r/regression/regression_3091.py @@ -0,0 +1,6 @@ +# pylint: disable=too-few-public-methods,invalid-name,missing-docstring +class MyClass(): + fun = lambda self, x: x * 2 + def __init__(self): + x = self.fun(1) # Crashes pylint 2.3.1 + print(x) diff --git a/tests/functional/r/regression/regression_3231_no_member_property.py b/tests/functional/r/regression/regression_3231_no_member_property.py new file mode 100644 index 000000000..6cc9cd71c --- /dev/null +++ b/tests/functional/r/regression/regression_3231_no_member_property.py @@ -0,0 +1,20 @@ +# pylint: disable=missing-docstring +from abc import ABCMeta, abstractmethod + + +class Cls(metaclass=ABCMeta): + def __init__(self): + pass + + @property + @abstractmethod + def values(self): + pass + + @classmethod + def some_method(cls): + return cls.values.issubset({2, 3}) + + +class Subcls(Cls): + values = {1, 2, 3} diff --git a/tests/functional/r/regression/regression_3416_unused_argument_raise.py b/tests/functional/r/regression/regression_3416_unused_argument_raise.py new file mode 100644 index 000000000..9bc761701 --- /dev/null +++ b/tests/functional/r/regression/regression_3416_unused_argument_raise.py @@ -0,0 +1,14 @@ +"""Test that we emit unused-argument when a function uses `raise + +https://github.com/PyCQA/pylint/issues/3416 +""" + +# pylint:disable=raise-missing-from + +# +1: [unused-argument, unused-argument, unused-argument] +def fun(arg_a, arg_b, arg_c) -> None: + """Routine docstring""" + try: + pass + except Exception: + raise RuntimeError("") diff --git a/tests/functional/r/regression/regression_3416_unused_argument_raise.txt b/tests/functional/r/regression/regression_3416_unused_argument_raise.txt new file mode 100644 index 000000000..44d7a6230 --- /dev/null +++ b/tests/functional/r/regression/regression_3416_unused_argument_raise.txt @@ -0,0 +1,3 @@ +unused-argument:9:8:fun:Unused argument 'arg_a' +unused-argument:9:15:fun:Unused argument 'arg_b' +unused-argument:9:22:fun:Unused argument 'arg_c' diff --git a/tests/functional/r/regression/regression_infer_call_result_3690.py b/tests/functional/r/regression/regression_infer_call_result_3690.py new file mode 100644 index 000000000..0949d9439 --- /dev/null +++ b/tests/functional/r/regression/regression_infer_call_result_3690.py @@ -0,0 +1,11 @@ +# pylint: disable-msg=missing-docstring,too-few-public-methods,using-constant-test + +class Class: + @property + @classmethod + def func(cls): + pass + + +if Class.func: + pass diff --git a/tests/functional/r/regression/regression_no_member_1078.py b/tests/functional/r/regression/regression_no_member_1078.py new file mode 100644 index 000000000..b7be27d3c --- /dev/null +++ b/tests/functional/r/regression/regression_no_member_1078.py @@ -0,0 +1,14 @@ +"""Make sure no-member is not emitted when modifying __doc__ via augmented assignment + +https://github.com/PyCQA/pylint/issues/1078 +""" +# pylint: disable=too-few-public-methods,missing-class-docstring +class Cls: + def test(self): + "a" + + test.__doc__ += "b" + + +print(Cls().test.__doc__) +print(Cls.test.__doc__) diff --git a/tests/functional/r/regression/regression_no_value_for_parameter.py b/tests/functional/r/regression/regression_no_value_for_parameter.py new file mode 100644 index 000000000..6dd2ea491 --- /dev/null +++ b/tests/functional/r/regression/regression_no_value_for_parameter.py @@ -0,0 +1,42 @@ +# pylint: disable=missing-docstring,import-error +import os + +from Unknown import Unknown + + +class ConfigManager(Unknown): + + + RENAMED_SECTIONS = { + 'permissions': 'content' + } + + def test(self): + self.RENAMED_SECTIONS.items() #@ + + def items(self, sectname, raw=True): + pass + + +def func(*, key=None): + return key + + +def varargs_good(*parts): + """All good""" + return os.path.join(*parts) + + +def varargs_no_expr(*parts): + """False positive below this line""" + ret = os.path.join(*parts) + return ret + + +def kwargs_good(**kwargs): + return func(**kwargs) + + +def kwargs_no_expr(**kwargs): + ret = func(**kwargs) + return ret diff --git a/tests/functional/r/regression/regression_posonly_args.py b/tests/functional/r/regression/regression_posonly_args.py new file mode 100644 index 000000000..750b1f951 --- /dev/null +++ b/tests/functional/r/regression/regression_posonly_args.py @@ -0,0 +1,21 @@ +"""Test linting. + +This is only intended to test pylint support for python 3.8's +positional-only arguments (PEP 570). +""" + + +class Foobar: + """Class for frobulating the Foobar.""" + + @classmethod + def buildme(cls, /, value): + """Construct object using alternate method.""" + return cls(value).abc + + def runme(self, qrs, /, xyz=None): + """Do something funcy.""" + if self.abc and qrs and xyz: + print("found something else") + + abc = 42 diff --git a/tests/functional/r/regression/regression_posonly_args.rc b/tests/functional/r/regression/regression_posonly_args.rc new file mode 100644 index 000000000..85fc502b3 --- /dev/null +++ b/tests/functional/r/regression/regression_posonly_args.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.8 diff --git a/tests/functional/r/regression/regression_property_no_member_2641.py b/tests/functional/r/regression/regression_property_no_member_2641.py new file mode 100644 index 000000000..083f78bdc --- /dev/null +++ b/tests/functional/r/regression/regression_property_no_member_2641.py @@ -0,0 +1,40 @@ +# pylint: disable=missing-docstring,unused-argument,too-few-public-methods +# https://github.com/PyCQA/pylint/issues/2641 +from abc import ABCMeta, abstractmethod + + +class Person(metaclass=ABCMeta): + @abstractmethod + def __init__(self, name, age): + self.name = name + self.age = age + + @property + def name(self): + return self.__name + + @name.setter + def name(self, value): + self.__name = value + + +class Myself(Person): + def __init__(self, name, age, tel): + super().__init__(name, age) + self.tel = tel + + @Person.name.setter + def name(self, value): + super(self.__class__, self.__class__).name.fset(self, "override") + + +class Wife(Person): + def __init__(self, name, age, tel): + super().__init__(name, age) + self.tel = tel + + +ms = Myself("Matheus Saraiva", 36, "988070350") +wi = Wife("Joice Saraiva", 34, "999923554") + +print(wi.name) diff --git a/tests/functional/r/regression/regression_property_no_member_3269.py b/tests/functional/r/regression/regression_property_no_member_3269.py new file mode 100644 index 000000000..784dd90d4 --- /dev/null +++ b/tests/functional/r/regression/regression_property_no_member_3269.py @@ -0,0 +1,23 @@ +"""Calling a super property""" +# pylint: disable=too-few-public-methods,invalid-name + +class A: + """A parent class""" + + @property + def test(self): + """A property""" + return "test" + + +class B: + """A child class""" + + @property + def test(self): + """Overriding implementation of prop which calls the parent""" + return A.test.fget(self) + " overriden" + + +if __name__ == "__main__": + print(B().test) diff --git a/tests/functional/r/regression/regression_property_no_member_844.py b/tests/functional/r/regression/regression_property_no_member_844.py new file mode 100644 index 000000000..759b7bfe3 --- /dev/null +++ b/tests/functional/r/regression/regression_property_no_member_844.py @@ -0,0 +1,18 @@ +# pylint: disable=missing-docstring,too-few-public-methods,invalid-overridden-method +# https://github.com/PyCQA/pylint/issues/844 +class Parent: + def __init__(self): + self.__thing = 'foo' + + @property + def thing(self): + return self.__thing + + +class Child(Parent): + @Parent.thing.getter + def thing(self): + return super().thing + '!' + + +print(Child().thing) diff --git a/tests/functional/r/regression/regression_property_no_member_870.py b/tests/functional/r/regression/regression_property_no_member_870.py new file mode 100644 index 000000000..e89ae169e --- /dev/null +++ b/tests/functional/r/regression/regression_property_no_member_870.py @@ -0,0 +1,15 @@ +# pylint: disable=too-few-public-methods,invalid-name,missing-docstring +# https://github.com/PyCQA/pylint/issues/870 + +class X: + def __init__(self, val=None): + self._val = val + @property + def val(self): + return self._val + @val.setter + def val(self, value): + self._val = value + +if __name__ == '__main__': + print(X([]).val.append) diff --git a/tests/functional/r/regression/regression_property_slots_2439.py b/tests/functional/r/regression/regression_property_slots_2439.py new file mode 100644 index 000000000..91cf86cfd --- /dev/null +++ b/tests/functional/r/regression/regression_property_slots_2439.py @@ -0,0 +1,22 @@ +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods +# https://github.com/PyCQA/pylint/issues/2439 +class TestClass: + __slots__ = ["_i"] + + def __init__(self): + self._i = 0 + + @property + def i(self): + return self._i + + @i.setter + def i(self, v): + self._i = v + + other = i + + +instance = TestClass() +instance.other = 42 +print(instance.i) diff --git a/tests/functional/r/regression/regression_too_many_arguments_2335.py b/tests/functional/r/regression/regression_too_many_arguments_2335.py new file mode 100644 index 000000000..d2759adfe --- /dev/null +++ b/tests/functional/r/regression/regression_too_many_arguments_2335.py @@ -0,0 +1,11 @@ +"""Test that `abc.ABCMeta.__new__` does not trigger too-many-function-arguments when referred + +https://github.com/PyCQA/pylint/issues/2335 +""" +# pylint: disable=missing-class-docstring,unused-argument,arguments-differ +from abc import ABCMeta + + +class NodeCheckMetaClass(ABCMeta): + def __new__(cls, name, bases, namespace, **kwargs): + return ABCMeta.__new__(cls, name, bases, namespace) diff --git a/tests/functional/r/regression_1326_crash_uninferable.py b/tests/functional/r/regression_1326_crash_uninferable.py deleted file mode 100644 index a42d44ac3..000000000 --- a/tests/functional/r/regression_1326_crash_uninferable.py +++ /dev/null @@ -1,12 +0,0 @@ -# pylint: disable=missing-docstring - -import socket - -RETRYABLE_EXCEPTIONS = (socket.error,) - -# pylint: disable=wrong-exception-operation -def exception_handler(): - try: - yield 1 - except RETRYABLE_EXCEPTIONS + tuple(): - yield 2 diff --git a/tests/functional/r/regression_2443_duplicate_bases.py b/tests/functional/r/regression_2443_duplicate_bases.py deleted file mode 100644 index f32490c44..000000000 --- a/tests/functional/r/regression_2443_duplicate_bases.py +++ /dev/null @@ -1,28 +0,0 @@ -# pylint: disable=missing-docstring, too-many-ancestors,too-few-public-methods -from typing import Generic, TypeVar - -IN = TypeVar('IN', contravariant=True) -OUT = TypeVar('OUT', covariant=True) - - -class Service: - pass - - -class ConsumingMixin(Generic[IN]): - pass - - -class ProducingMixin(Generic[OUT]): - pass - - -class StreamingMixin(Generic[IN, OUT], ConsumingMixin[IN], ProducingMixin[OUT]): - pass - - -class Example(StreamingMixin[str, int], Service): - pass - - -print(Example.__mro__) diff --git a/tests/functional/r/regression_2443_duplicate_bases.rc b/tests/functional/r/regression_2443_duplicate_bases.rc deleted file mode 100644 index 0ba2b6333..000000000 --- a/tests/functional/r/regression_2443_duplicate_bases.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.6 diff --git a/tests/functional/r/regression_2937_ifexp.py b/tests/functional/r/regression_2937_ifexp.py deleted file mode 100644 index 55b240440..000000000 --- a/tests/functional/r/regression_2937_ifexp.py +++ /dev/null @@ -1,20 +0,0 @@ -# pylint: disable=missing-docstring,no-else-return,using-constant-test -def get_list(): - return [1] if True else [2] - - -def find_int(): - return int(get_list()[0]) - - -def func(): - if True: - return find_int() - else: - return find_int() - - -def test(): - resp = func() - assert resp / resp > 0 - return resp diff --git a/tests/functional/r/regression_3091.py b/tests/functional/r/regression_3091.py deleted file mode 100644 index 8196db12d..000000000 --- a/tests/functional/r/regression_3091.py +++ /dev/null @@ -1,6 +0,0 @@ -# pylint: disable=too-few-public-methods,invalid-name,missing-docstring -class MyClass(): - fun = lambda self, x: x * 2 - def __init__(self): - x = self.fun(1) # Crashes pylint 2.3.1 - print(x) diff --git a/tests/functional/r/regression_3231_no_member_property.py b/tests/functional/r/regression_3231_no_member_property.py deleted file mode 100644 index 6cc9cd71c..000000000 --- a/tests/functional/r/regression_3231_no_member_property.py +++ /dev/null @@ -1,20 +0,0 @@ -# pylint: disable=missing-docstring -from abc import ABCMeta, abstractmethod - - -class Cls(metaclass=ABCMeta): - def __init__(self): - pass - - @property - @abstractmethod - def values(self): - pass - - @classmethod - def some_method(cls): - return cls.values.issubset({2, 3}) - - -class Subcls(Cls): - values = {1, 2, 3} diff --git a/tests/functional/r/regression_3416_unused_argument_raise.py b/tests/functional/r/regression_3416_unused_argument_raise.py deleted file mode 100644 index 9bc761701..000000000 --- a/tests/functional/r/regression_3416_unused_argument_raise.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Test that we emit unused-argument when a function uses `raise - -https://github.com/PyCQA/pylint/issues/3416 -""" - -# pylint:disable=raise-missing-from - -# +1: [unused-argument, unused-argument, unused-argument] -def fun(arg_a, arg_b, arg_c) -> None: - """Routine docstring""" - try: - pass - except Exception: - raise RuntimeError("") diff --git a/tests/functional/r/regression_3416_unused_argument_raise.txt b/tests/functional/r/regression_3416_unused_argument_raise.txt deleted file mode 100644 index 44d7a6230..000000000 --- a/tests/functional/r/regression_3416_unused_argument_raise.txt +++ /dev/null @@ -1,3 +0,0 @@ -unused-argument:9:8:fun:Unused argument 'arg_a' -unused-argument:9:15:fun:Unused argument 'arg_b' -unused-argument:9:22:fun:Unused argument 'arg_c' diff --git a/tests/functional/r/regression_infer_call_result_3690.py b/tests/functional/r/regression_infer_call_result_3690.py deleted file mode 100644 index 0949d9439..000000000 --- a/tests/functional/r/regression_infer_call_result_3690.py +++ /dev/null @@ -1,11 +0,0 @@ -# pylint: disable-msg=missing-docstring,too-few-public-methods,using-constant-test - -class Class: - @property - @classmethod - def func(cls): - pass - - -if Class.func: - pass diff --git a/tests/functional/r/regression_no_member_1078.py b/tests/functional/r/regression_no_member_1078.py deleted file mode 100644 index b7be27d3c..000000000 --- a/tests/functional/r/regression_no_member_1078.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Make sure no-member is not emitted when modifying __doc__ via augmented assignment - -https://github.com/PyCQA/pylint/issues/1078 -""" -# pylint: disable=too-few-public-methods,missing-class-docstring -class Cls: - def test(self): - "a" - - test.__doc__ += "b" - - -print(Cls().test.__doc__) -print(Cls.test.__doc__) diff --git a/tests/functional/r/regression_no_value_for_parameter.py b/tests/functional/r/regression_no_value_for_parameter.py deleted file mode 100644 index 6dd2ea491..000000000 --- a/tests/functional/r/regression_no_value_for_parameter.py +++ /dev/null @@ -1,42 +0,0 @@ -# pylint: disable=missing-docstring,import-error -import os - -from Unknown import Unknown - - -class ConfigManager(Unknown): - - - RENAMED_SECTIONS = { - 'permissions': 'content' - } - - def test(self): - self.RENAMED_SECTIONS.items() #@ - - def items(self, sectname, raw=True): - pass - - -def func(*, key=None): - return key - - -def varargs_good(*parts): - """All good""" - return os.path.join(*parts) - - -def varargs_no_expr(*parts): - """False positive below this line""" - ret = os.path.join(*parts) - return ret - - -def kwargs_good(**kwargs): - return func(**kwargs) - - -def kwargs_no_expr(**kwargs): - ret = func(**kwargs) - return ret diff --git a/tests/functional/r/regression_posonly_args.py b/tests/functional/r/regression_posonly_args.py deleted file mode 100644 index 750b1f951..000000000 --- a/tests/functional/r/regression_posonly_args.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Test linting. - -This is only intended to test pylint support for python 3.8's -positional-only arguments (PEP 570). -""" - - -class Foobar: - """Class for frobulating the Foobar.""" - - @classmethod - def buildme(cls, /, value): - """Construct object using alternate method.""" - return cls(value).abc - - def runme(self, qrs, /, xyz=None): - """Do something funcy.""" - if self.abc and qrs and xyz: - print("found something else") - - abc = 42 diff --git a/tests/functional/r/regression_posonly_args.rc b/tests/functional/r/regression_posonly_args.rc deleted file mode 100644 index 85fc502b3..000000000 --- a/tests/functional/r/regression_posonly_args.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.8 diff --git a/tests/functional/r/regression_property_no_member_2641.py b/tests/functional/r/regression_property_no_member_2641.py deleted file mode 100644 index 083f78bdc..000000000 --- a/tests/functional/r/regression_property_no_member_2641.py +++ /dev/null @@ -1,40 +0,0 @@ -# pylint: disable=missing-docstring,unused-argument,too-few-public-methods -# https://github.com/PyCQA/pylint/issues/2641 -from abc import ABCMeta, abstractmethod - - -class Person(metaclass=ABCMeta): - @abstractmethod - def __init__(self, name, age): - self.name = name - self.age = age - - @property - def name(self): - return self.__name - - @name.setter - def name(self, value): - self.__name = value - - -class Myself(Person): - def __init__(self, name, age, tel): - super().__init__(name, age) - self.tel = tel - - @Person.name.setter - def name(self, value): - super(self.__class__, self.__class__).name.fset(self, "override") - - -class Wife(Person): - def __init__(self, name, age, tel): - super().__init__(name, age) - self.tel = tel - - -ms = Myself("Matheus Saraiva", 36, "988070350") -wi = Wife("Joice Saraiva", 34, "999923554") - -print(wi.name) diff --git a/tests/functional/r/regression_property_no_member_3269.py b/tests/functional/r/regression_property_no_member_3269.py deleted file mode 100644 index 784dd90d4..000000000 --- a/tests/functional/r/regression_property_no_member_3269.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Calling a super property""" -# pylint: disable=too-few-public-methods,invalid-name - -class A: - """A parent class""" - - @property - def test(self): - """A property""" - return "test" - - -class B: - """A child class""" - - @property - def test(self): - """Overriding implementation of prop which calls the parent""" - return A.test.fget(self) + " overriden" - - -if __name__ == "__main__": - print(B().test) diff --git a/tests/functional/r/regression_property_no_member_844.py b/tests/functional/r/regression_property_no_member_844.py deleted file mode 100644 index 759b7bfe3..000000000 --- a/tests/functional/r/regression_property_no_member_844.py +++ /dev/null @@ -1,18 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods,invalid-overridden-method -# https://github.com/PyCQA/pylint/issues/844 -class Parent: - def __init__(self): - self.__thing = 'foo' - - @property - def thing(self): - return self.__thing - - -class Child(Parent): - @Parent.thing.getter - def thing(self): - return super().thing + '!' - - -print(Child().thing) diff --git a/tests/functional/r/regression_property_no_member_870.py b/tests/functional/r/regression_property_no_member_870.py deleted file mode 100644 index e89ae169e..000000000 --- a/tests/functional/r/regression_property_no_member_870.py +++ /dev/null @@ -1,15 +0,0 @@ -# pylint: disable=too-few-public-methods,invalid-name,missing-docstring -# https://github.com/PyCQA/pylint/issues/870 - -class X: - def __init__(self, val=None): - self._val = val - @property - def val(self): - return self._val - @val.setter - def val(self, value): - self._val = value - -if __name__ == '__main__': - print(X([]).val.append) diff --git a/tests/functional/r/regression_property_slots_2439.py b/tests/functional/r/regression_property_slots_2439.py deleted file mode 100644 index 91cf86cfd..000000000 --- a/tests/functional/r/regression_property_slots_2439.py +++ /dev/null @@ -1,22 +0,0 @@ -# pylint: disable=missing-docstring,invalid-name,too-few-public-methods -# https://github.com/PyCQA/pylint/issues/2439 -class TestClass: - __slots__ = ["_i"] - - def __init__(self): - self._i = 0 - - @property - def i(self): - return self._i - - @i.setter - def i(self, v): - self._i = v - - other = i - - -instance = TestClass() -instance.other = 42 -print(instance.i) diff --git a/tests/functional/r/regression_too_many_arguments_2335.py b/tests/functional/r/regression_too_many_arguments_2335.py deleted file mode 100644 index d2759adfe..000000000 --- a/tests/functional/r/regression_too_many_arguments_2335.py +++ /dev/null @@ -1,11 +0,0 @@ -"""Test that `abc.ABCMeta.__new__` does not trigger too-many-function-arguments when referred - -https://github.com/PyCQA/pylint/issues/2335 -""" -# pylint: disable=missing-class-docstring,unused-argument,arguments-differ -from abc import ABCMeta - - -class NodeCheckMetaClass(ABCMeta): - def __new__(cls, name, bases, namespace, **kwargs): - return ABCMeta.__new__(cls, name, bases, namespace) diff --git a/tests/functional/s/simplifiable/simplifiable_condition.py b/tests/functional/s/simplifiable/simplifiable_condition.py new file mode 100644 index 000000000..32bf36aca --- /dev/null +++ b/tests/functional/s/simplifiable/simplifiable_condition.py @@ -0,0 +1,36 @@ +"""Test that boolean conditions can be simplified""" +# pylint: disable=pointless-statement + + +def func(_): + """Pointless function""" + + +CONSTANT = 100 +OTHER = 200 + +# Simplifies any boolean expression that is coerced into a True/False value +bool(CONSTANT or False) # [simplifiable-condition] +assert CONSTANT or False # [simplifiable-condition] +if CONSTANT and True: # [simplifiable-condition] + pass +elif CONSTANT and True: # [simplifiable-condition] + pass +while CONSTANT and True: # [simplifiable-condition] + break +1 if CONSTANT or False else 2 # [simplifiable-condition] +z = [x for x in range(10) if x or False] # [simplifiable-condition] + +# Simplifies recursively +assert CONSTANT or (True and False) # [simplifiable-condition] +assert True and CONSTANT and OTHER # [simplifiable-condition] +assert (CONSTANT or False) and (OTHER or True) # [simplifiable-condition] + +# Will try to infer the truthiness of an expression as long as it doesn't contain any variables +assert [] or CONSTANT # [simplifiable-condition] +assert {} or CONSTANT # [simplifiable-condition] + +# Expressions not in one of the above situations will not emit a message +CONSTANT or True +bool(CONSTANT or OTHER) +bool(func(CONSTANT or True)) diff --git a/tests/functional/s/simplifiable/simplifiable_condition.txt b/tests/functional/s/simplifiable/simplifiable_condition.txt new file mode 100644 index 000000000..b3552b50f --- /dev/null +++ b/tests/functional/s/simplifiable/simplifiable_condition.txt @@ -0,0 +1,12 @@ +simplifiable-condition:13:5::Boolean condition 'CONSTANT or False' may be simplified to 'CONSTANT' +simplifiable-condition:14:7::Boolean condition 'CONSTANT or False' may be simplified to 'CONSTANT' +simplifiable-condition:15:3::Boolean condition 'CONSTANT and True' may be simplified to 'CONSTANT' +simplifiable-condition:17:5::Boolean condition 'CONSTANT and True' may be simplified to 'CONSTANT' +simplifiable-condition:19:6::Boolean condition 'CONSTANT and True' may be simplified to 'CONSTANT' +simplifiable-condition:21:5::Boolean condition 'CONSTANT or False' may be simplified to 'CONSTANT' +simplifiable-condition:22:29::Boolean condition 'x or False' may be simplified to 'x' +simplifiable-condition:25:7::Boolean condition 'CONSTANT or True and False' may be simplified to 'CONSTANT' +simplifiable-condition:26:7::Boolean condition 'True and CONSTANT and OTHER' may be simplified to 'CONSTANT and OTHER' +simplifiable-condition:27:7::Boolean condition '(CONSTANT or False) and (OTHER or True)' may be simplified to 'CONSTANT' +simplifiable-condition:30:7::Boolean condition '[] or CONSTANT' may be simplified to 'CONSTANT' +simplifiable-condition:31:7::Boolean condition '{} or CONSTANT' may be simplified to 'CONSTANT' diff --git a/tests/functional/s/simplifiable/simplifiable_if_expression.py b/tests/functional/s/simplifiable/simplifiable_if_expression.py new file mode 100644 index 000000000..bcfdf890b --- /dev/null +++ b/tests/functional/s/simplifiable/simplifiable_if_expression.py @@ -0,0 +1,27 @@ +"""Test that some if expressions can be simplified.""" + +# pylint: disable=missing-docstring, invalid-name + + +def test_simplifiable_1(arg): + # Simple test that can be replaced by bool(arg) + return True if arg else False # [simplifiable-if-expression] + +def test_simplifiable_2(arg): + # Simple test that can be replaced by not arg + return False if arg else True # [simplifiable-if-expression] + +def test_simplifiable_3(arg): + # Simple test that can be replaced by arg == 1 + return True if arg == 1 else False # [simplifiable-if-expression] + +def test_simplifiable_4(arg): + # Simple test that can be replaced by not (arg == 1) + return False if arg == 1 else True # [simplifiable-if-expression] + +def test_not_simplifiable(arg): + x = True if arg else True + y = 0 if arg else 1 + t = False if arg != 1 else False + t2 = None if arg > 3 else False + return x, y, t, t2 diff --git a/tests/functional/s/simplifiable/simplifiable_if_expression.txt b/tests/functional/s/simplifiable/simplifiable_if_expression.txt new file mode 100644 index 000000000..872df8c25 --- /dev/null +++ b/tests/functional/s/simplifiable/simplifiable_if_expression.txt @@ -0,0 +1,4 @@ +simplifiable-if-expression:8:11:test_simplifiable_1:The if expression can be replaced with 'bool(test)' +simplifiable-if-expression:12:11:test_simplifiable_2:The if expression can be replaced with 'not test' +simplifiable-if-expression:16:11:test_simplifiable_3:The if expression can be replaced with 'test' +simplifiable-if-expression:20:11:test_simplifiable_4:The if expression can be replaced with 'not test' diff --git a/tests/functional/s/simplifiable/simplifiable_if_statement.py b/tests/functional/s/simplifiable/simplifiable_if_statement.py new file mode 100644 index 000000000..4d4c8b5d4 --- /dev/null +++ b/tests/functional/s/simplifiable/simplifiable_if_statement.py @@ -0,0 +1,146 @@ +"""Test that some if statement tests can be simplified.""" + +# pylint: disable=missing-docstring, invalid-name, no-else-return, arguments-out-of-order + + +def test_simplifiable_1(arg): + # Simple test that can be replaced by bool(arg) + if arg: # [simplifiable-if-statement] + return True + else: + return False + + +def test_simplifiable_2(arg, arg2): + # Can be reduced to bool(arg and not arg2) + if arg and not arg2: # [simplifiable-if-statement] + return True + else: + return False + + +def test_simplifiable_3(arg, arg2): + # Can be reduced to bool(arg and not arg2) + if arg and not arg2: # [simplifiable-if-statement] + var = True + else: + var = False + return var + + +def test_simplifiable_4(arg): + if arg: + var = True + else: + if arg == "arg1": # [simplifiable-if-statement] + return True + else: + return False + return var + + +def test_not_necessarily_simplifiable_1(arg, arg2): + # Can be reduced to bool(not arg and not arg2) or to + # `not all(N)`, which is a bit harder to understand + # than `any(N)` when var should be False. + if arg or arg2: + var = False + else: + var = True + return var + + +def test_not_necessarily_simplifiabile_2(arg): + # This could theoretically be reduced to `not arg or arg > 3` + # but the net result is that now the condition is harder to understand, + # because it requires understanding of an extra clause: + # * first, there is the negation of truthness with `not arg` + # * the second clause is `arg > 3`, which occurs when arg has a + # a truth value, but it implies that `arg > 3` is equivalent + # with `arg and arg > 3`, which means that the user must + # think about this assumption when evaluating `arg > 3`. + # The original form is easier to grasp. + if arg and arg <= 3: + return False + else: + return True + + +def test_not_simplifiable_3(arg): + if arg: + test_not_necessarily_simplifiabile_2(arg) + test_not_necessarily_simplifiable_1(arg, arg) + return False + else: + if arg < 3: + test_simplifiable_3(arg, 42) + return True + + +def test_not_simplifiable_4(arg): + # Not interested in multiple elifs + if arg == "any": + return True + elif test_not_simplifiable_3(arg) == arg: + return True + else: + return False + + +def test_not_simplifiable_5(arg): + # Different actions in each branch + if arg == "any": + return True + else: + var = 42 + return var + + +def test_not_simplifiable_6(arg): + # Different actions in each branch + if arg == "any": + var = 42 + else: + return True + return var + +def test_not_simplifiable_7(arg): + # Returning something different + if arg == "any": + return 4 + else: + return 5 + + +def test_not_simplifiable_8(arg): + # Only one of the branch returns something boolean + if arg == "any": + return True + else: + return 0 + + +def test_not_simplifiable_9(): + # Not the same targets + first = True + second = 1 + third = [1] + fourth = False + fifth = False + + if first and second in third: + fourth = True + else: + fifth = True + return fourth + fifth + + +def test_not_simplifiable_10(): + # Subscripts are not considered + object_type = 'read' + filter_kwargs = {} + if object_type == 'read': + filter_kwargs['a'] = True + else: + filter_kwargs['b'] = True + return filter_kwargs diff --git a/tests/functional/s/simplifiable/simplifiable_if_statement.txt b/tests/functional/s/simplifiable/simplifiable_if_statement.txt new file mode 100644 index 000000000..aa61f4993 --- /dev/null +++ b/tests/functional/s/simplifiable/simplifiable_if_statement.txt @@ -0,0 +1,4 @@ +simplifiable-if-statement:8:4:test_simplifiable_1:The if statement can be replaced with 'return bool(test)' +simplifiable-if-statement:16:4:test_simplifiable_2:The if statement can be replaced with 'return bool(test)' +simplifiable-if-statement:24:4:test_simplifiable_3:The if statement can be replaced with 'var = bool(test)' +simplifiable-if-statement:35:8:test_simplifiable_4:The if statement can be replaced with 'return bool(test)' diff --git a/tests/functional/s/simplifiable/simplify_chained_comparison.py b/tests/functional/s/simplifiable/simplify_chained_comparison.py new file mode 100644 index 000000000..4be9fbe3d --- /dev/null +++ b/tests/functional/s/simplifiable/simplify_chained_comparison.py @@ -0,0 +1,89 @@ +"""Test that some boolean expression statement tests can be simplified.""" + +# pylint: disable=missing-docstring, invalid-name, no-else-return, too-many-branches + + +def test_simplify_chained_comparison_1(): + a = 1 + b = 2 + c = 3 + return a < b and b < c # [chained-comparison] + + +def test_simplify_chained_comparison_2(): + a = 1 + return a < 10 and a > 1 # [chained-comparison] + + +def test_simplify_chained_comparison_3(): + a = 1 + b = 2 + c = 3 + d = 4 + if a < 10 and a > 1: # [chained-comparison] + pass + elif a > 1 and a < 10: # [chained-comparison] + pass + elif a > 1 and a <= 10: # [chained-comparison] + pass + elif a > 1 and a < 10 and b == 2: # [chained-comparison] + pass + elif a > 1 and c == b and a < 10: # [chained-comparison] + pass + elif a > 100 and c == b and a < 10: # [chained-comparison] + # In this comparison we are not checking whether left bound is actually + # lower than right bound or not. + pass + elif a < b and b < c: # [chained-comparison] + pass + elif a > b and b > c: # [chained-comparison] + pass + elif a < b and a == 1 and b < c: # [chained-comparison] + pass + elif a < b and b < c and c == 786: # [chained-comparison] + pass + elif a < b and b < 0 and c == 786: # [chained-comparison] + pass + elif a < b and c == 786 and b < 0: # [chained-comparison] + pass + elif c == 786 and b < 0 and a < b: # [chained-comparison] + pass + elif a < b < c and c < d: # [chained-comparison] + pass + elif b < c < d and a < b: # [chained-comparison] + pass + elif a < b < c and a < b and b < c: # [chained-comparison] + pass + + +def test_not_simplify_chained_comparison_1(): + a = 1 + b = 2 + c = 3 + d = 4 + if a < 10 and b > 1: + pass + elif a > 1 and b < 10: + pass + elif a > 1 and a == 10: + pass + elif a == 1 and b == 2: + pass + elif a > 1 and a > 10: + pass + elif a < 100 and a < 10: + pass + elif a < b and a < c: + pass + elif a < b and a == 1 and a < c: + pass + elif a < b and a < c and c == 786: + pass + elif a < b < c and b < d: + pass + elif a < b < c and a < d: + pass + elif b < c < d and a < c: + pass + elif b < c < d and a < d: + pass diff --git a/tests/functional/s/simplifiable/simplify_chained_comparison.txt b/tests/functional/s/simplifiable/simplify_chained_comparison.txt new file mode 100644 index 000000000..fe8d3c384 --- /dev/null +++ b/tests/functional/s/simplifiable/simplify_chained_comparison.txt @@ -0,0 +1,18 @@ +chained-comparison:10:11:test_simplify_chained_comparison_1:Simplify chained comparison between the operands +chained-comparison:15:11:test_simplify_chained_comparison_2:Simplify chained comparison between the operands +chained-comparison:23:7:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:25:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:27:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:29:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:31:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:33:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:37:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:39:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:41:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:43:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:45:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:47:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:49:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:51:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:53:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:55:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands diff --git a/tests/functional/s/simplifiable_condition.py b/tests/functional/s/simplifiable_condition.py deleted file mode 100644 index 32bf36aca..000000000 --- a/tests/functional/s/simplifiable_condition.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Test that boolean conditions can be simplified""" -# pylint: disable=pointless-statement - - -def func(_): - """Pointless function""" - - -CONSTANT = 100 -OTHER = 200 - -# Simplifies any boolean expression that is coerced into a True/False value -bool(CONSTANT or False) # [simplifiable-condition] -assert CONSTANT or False # [simplifiable-condition] -if CONSTANT and True: # [simplifiable-condition] - pass -elif CONSTANT and True: # [simplifiable-condition] - pass -while CONSTANT and True: # [simplifiable-condition] - break -1 if CONSTANT or False else 2 # [simplifiable-condition] -z = [x for x in range(10) if x or False] # [simplifiable-condition] - -# Simplifies recursively -assert CONSTANT or (True and False) # [simplifiable-condition] -assert True and CONSTANT and OTHER # [simplifiable-condition] -assert (CONSTANT or False) and (OTHER or True) # [simplifiable-condition] - -# Will try to infer the truthiness of an expression as long as it doesn't contain any variables -assert [] or CONSTANT # [simplifiable-condition] -assert {} or CONSTANT # [simplifiable-condition] - -# Expressions not in one of the above situations will not emit a message -CONSTANT or True -bool(CONSTANT or OTHER) -bool(func(CONSTANT or True)) diff --git a/tests/functional/s/simplifiable_condition.txt b/tests/functional/s/simplifiable_condition.txt deleted file mode 100644 index b3552b50f..000000000 --- a/tests/functional/s/simplifiable_condition.txt +++ /dev/null @@ -1,12 +0,0 @@ -simplifiable-condition:13:5::Boolean condition 'CONSTANT or False' may be simplified to 'CONSTANT' -simplifiable-condition:14:7::Boolean condition 'CONSTANT or False' may be simplified to 'CONSTANT' -simplifiable-condition:15:3::Boolean condition 'CONSTANT and True' may be simplified to 'CONSTANT' -simplifiable-condition:17:5::Boolean condition 'CONSTANT and True' may be simplified to 'CONSTANT' -simplifiable-condition:19:6::Boolean condition 'CONSTANT and True' may be simplified to 'CONSTANT' -simplifiable-condition:21:5::Boolean condition 'CONSTANT or False' may be simplified to 'CONSTANT' -simplifiable-condition:22:29::Boolean condition 'x or False' may be simplified to 'x' -simplifiable-condition:25:7::Boolean condition 'CONSTANT or True and False' may be simplified to 'CONSTANT' -simplifiable-condition:26:7::Boolean condition 'True and CONSTANT and OTHER' may be simplified to 'CONSTANT and OTHER' -simplifiable-condition:27:7::Boolean condition '(CONSTANT or False) and (OTHER or True)' may be simplified to 'CONSTANT' -simplifiable-condition:30:7::Boolean condition '[] or CONSTANT' may be simplified to 'CONSTANT' -simplifiable-condition:31:7::Boolean condition '{} or CONSTANT' may be simplified to 'CONSTANT' diff --git a/tests/functional/s/simplifiable_if_expression.py b/tests/functional/s/simplifiable_if_expression.py deleted file mode 100644 index bcfdf890b..000000000 --- a/tests/functional/s/simplifiable_if_expression.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Test that some if expressions can be simplified.""" - -# pylint: disable=missing-docstring, invalid-name - - -def test_simplifiable_1(arg): - # Simple test that can be replaced by bool(arg) - return True if arg else False # [simplifiable-if-expression] - -def test_simplifiable_2(arg): - # Simple test that can be replaced by not arg - return False if arg else True # [simplifiable-if-expression] - -def test_simplifiable_3(arg): - # Simple test that can be replaced by arg == 1 - return True if arg == 1 else False # [simplifiable-if-expression] - -def test_simplifiable_4(arg): - # Simple test that can be replaced by not (arg == 1) - return False if arg == 1 else True # [simplifiable-if-expression] - -def test_not_simplifiable(arg): - x = True if arg else True - y = 0 if arg else 1 - t = False if arg != 1 else False - t2 = None if arg > 3 else False - return x, y, t, t2 diff --git a/tests/functional/s/simplifiable_if_expression.txt b/tests/functional/s/simplifiable_if_expression.txt deleted file mode 100644 index 872df8c25..000000000 --- a/tests/functional/s/simplifiable_if_expression.txt +++ /dev/null @@ -1,4 +0,0 @@ -simplifiable-if-expression:8:11:test_simplifiable_1:The if expression can be replaced with 'bool(test)' -simplifiable-if-expression:12:11:test_simplifiable_2:The if expression can be replaced with 'not test' -simplifiable-if-expression:16:11:test_simplifiable_3:The if expression can be replaced with 'test' -simplifiable-if-expression:20:11:test_simplifiable_4:The if expression can be replaced with 'not test' diff --git a/tests/functional/s/simplifiable_if_statement.py b/tests/functional/s/simplifiable_if_statement.py deleted file mode 100644 index 4d4c8b5d4..000000000 --- a/tests/functional/s/simplifiable_if_statement.py +++ /dev/null @@ -1,146 +0,0 @@ -"""Test that some if statement tests can be simplified.""" - -# pylint: disable=missing-docstring, invalid-name, no-else-return, arguments-out-of-order - - -def test_simplifiable_1(arg): - # Simple test that can be replaced by bool(arg) - if arg: # [simplifiable-if-statement] - return True - else: - return False - - -def test_simplifiable_2(arg, arg2): - # Can be reduced to bool(arg and not arg2) - if arg and not arg2: # [simplifiable-if-statement] - return True - else: - return False - - -def test_simplifiable_3(arg, arg2): - # Can be reduced to bool(arg and not arg2) - if arg and not arg2: # [simplifiable-if-statement] - var = True - else: - var = False - return var - - -def test_simplifiable_4(arg): - if arg: - var = True - else: - if arg == "arg1": # [simplifiable-if-statement] - return True - else: - return False - return var - - -def test_not_necessarily_simplifiable_1(arg, arg2): - # Can be reduced to bool(not arg and not arg2) or to - # `not all(N)`, which is a bit harder to understand - # than `any(N)` when var should be False. - if arg or arg2: - var = False - else: - var = True - return var - - -def test_not_necessarily_simplifiabile_2(arg): - # This could theoretically be reduced to `not arg or arg > 3` - # but the net result is that now the condition is harder to understand, - # because it requires understanding of an extra clause: - # * first, there is the negation of truthness with `not arg` - # * the second clause is `arg > 3`, which occurs when arg has a - # a truth value, but it implies that `arg > 3` is equivalent - # with `arg and arg > 3`, which means that the user must - # think about this assumption when evaluating `arg > 3`. - # The original form is easier to grasp. - if arg and arg <= 3: - return False - else: - return True - - -def test_not_simplifiable_3(arg): - if arg: - test_not_necessarily_simplifiabile_2(arg) - test_not_necessarily_simplifiable_1(arg, arg) - return False - else: - if arg < 3: - test_simplifiable_3(arg, 42) - return True - - -def test_not_simplifiable_4(arg): - # Not interested in multiple elifs - if arg == "any": - return True - elif test_not_simplifiable_3(arg) == arg: - return True - else: - return False - - -def test_not_simplifiable_5(arg): - # Different actions in each branch - if arg == "any": - return True - else: - var = 42 - return var - - -def test_not_simplifiable_6(arg): - # Different actions in each branch - if arg == "any": - var = 42 - else: - return True - return var - -def test_not_simplifiable_7(arg): - # Returning something different - if arg == "any": - return 4 - else: - return 5 - - -def test_not_simplifiable_8(arg): - # Only one of the branch returns something boolean - if arg == "any": - return True - else: - return 0 - - -def test_not_simplifiable_9(): - # Not the same targets - first = True - second = 1 - third = [1] - fourth = False - fifth = False - - if first and second in third: - fourth = True - else: - fifth = True - return fourth + fifth - - -def test_not_simplifiable_10(): - # Subscripts are not considered - object_type = 'read' - filter_kwargs = {} - if object_type == 'read': - filter_kwargs['a'] = True - else: - filter_kwargs['b'] = True - return filter_kwargs diff --git a/tests/functional/s/simplifiable_if_statement.txt b/tests/functional/s/simplifiable_if_statement.txt deleted file mode 100644 index aa61f4993..000000000 --- a/tests/functional/s/simplifiable_if_statement.txt +++ /dev/null @@ -1,4 +0,0 @@ -simplifiable-if-statement:8:4:test_simplifiable_1:The if statement can be replaced with 'return bool(test)' -simplifiable-if-statement:16:4:test_simplifiable_2:The if statement can be replaced with 'return bool(test)' -simplifiable-if-statement:24:4:test_simplifiable_3:The if statement can be replaced with 'var = bool(test)' -simplifiable-if-statement:35:8:test_simplifiable_4:The if statement can be replaced with 'return bool(test)' diff --git a/tests/functional/s/simplify_chained_comparison.py b/tests/functional/s/simplify_chained_comparison.py deleted file mode 100644 index 4be9fbe3d..000000000 --- a/tests/functional/s/simplify_chained_comparison.py +++ /dev/null @@ -1,89 +0,0 @@ -"""Test that some boolean expression statement tests can be simplified.""" - -# pylint: disable=missing-docstring, invalid-name, no-else-return, too-many-branches - - -def test_simplify_chained_comparison_1(): - a = 1 - b = 2 - c = 3 - return a < b and b < c # [chained-comparison] - - -def test_simplify_chained_comparison_2(): - a = 1 - return a < 10 and a > 1 # [chained-comparison] - - -def test_simplify_chained_comparison_3(): - a = 1 - b = 2 - c = 3 - d = 4 - if a < 10 and a > 1: # [chained-comparison] - pass - elif a > 1 and a < 10: # [chained-comparison] - pass - elif a > 1 and a <= 10: # [chained-comparison] - pass - elif a > 1 and a < 10 and b == 2: # [chained-comparison] - pass - elif a > 1 and c == b and a < 10: # [chained-comparison] - pass - elif a > 100 and c == b and a < 10: # [chained-comparison] - # In this comparison we are not checking whether left bound is actually - # lower than right bound or not. - pass - elif a < b and b < c: # [chained-comparison] - pass - elif a > b and b > c: # [chained-comparison] - pass - elif a < b and a == 1 and b < c: # [chained-comparison] - pass - elif a < b and b < c and c == 786: # [chained-comparison] - pass - elif a < b and b < 0 and c == 786: # [chained-comparison] - pass - elif a < b and c == 786 and b < 0: # [chained-comparison] - pass - elif c == 786 and b < 0 and a < b: # [chained-comparison] - pass - elif a < b < c and c < d: # [chained-comparison] - pass - elif b < c < d and a < b: # [chained-comparison] - pass - elif a < b < c and a < b and b < c: # [chained-comparison] - pass - - -def test_not_simplify_chained_comparison_1(): - a = 1 - b = 2 - c = 3 - d = 4 - if a < 10 and b > 1: - pass - elif a > 1 and b < 10: - pass - elif a > 1 and a == 10: - pass - elif a == 1 and b == 2: - pass - elif a > 1 and a > 10: - pass - elif a < 100 and a < 10: - pass - elif a < b and a < c: - pass - elif a < b and a == 1 and a < c: - pass - elif a < b and a < c and c == 786: - pass - elif a < b < c and b < d: - pass - elif a < b < c and a < d: - pass - elif b < c < d and a < c: - pass - elif b < c < d and a < d: - pass diff --git a/tests/functional/s/simplify_chained_comparison.txt b/tests/functional/s/simplify_chained_comparison.txt deleted file mode 100644 index fe8d3c384..000000000 --- a/tests/functional/s/simplify_chained_comparison.txt +++ /dev/null @@ -1,18 +0,0 @@ -chained-comparison:10:11:test_simplify_chained_comparison_1:Simplify chained comparison between the operands -chained-comparison:15:11:test_simplify_chained_comparison_2:Simplify chained comparison between the operands -chained-comparison:23:7:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:25:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:27:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:29:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:31:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:33:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:37:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:39:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:41:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:43:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:45:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:47:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:49:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:51:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:53:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands -chained-comparison:55:9:test_simplify_chained_comparison_3:Simplify chained comparison between the operands diff --git a/tests/functional/s/string/string_formatting.py b/tests/functional/s/string/string_formatting.py new file mode 100644 index 000000000..8e49d28b4 --- /dev/null +++ b/tests/functional/s/string/string_formatting.py @@ -0,0 +1,197 @@ +"""test for Python 3 string formatting error +""" +# pylint: disable=too-few-public-methods, import-error, unused-argument, line-too-long, no-absolute-import, useless-object-inheritance +import os +import sys +from missing import Missing + + +class Custom(object): + """ Has a __getattr__ """ + def __getattr__(self, _): + return self + +class Test(object): + """ test format attribute access """ + custom = Custom() + ids = [1, 2, 3, [4, 5, 6]] + +class Getitem(object): + """ test custom getitem for lookup access """ + def __getitem__(self, index): + return 42 + +class ReturnYes(object): + """ can't be properly infered """ + missing = Missing() + +def log(message, message_type="error"): + """ Test """ + return message + +def print_good(): + """ Good format strings """ + "{0} {1}".format(1, 2) + "{0!r:20}".format("Hello") + "{!r:20}".format("Hello") + "{a!r:20}".format(a="Hello") + "{pid}".format(pid=os.getpid()) + str("{}").format(2) + "{0.missing.length}".format(ReturnYes()) + "{1.missing.length}".format(ReturnYes()) + "{a.ids[3][1]}".format(a=Test()) + "{a[0][0]}".format(a=[[1]]) + "{[0][0]}".format({0: {0: 1}}) + "{a.test}".format(a=Custom()) + "{a.__len__}".format(a=[]) + "{a.ids.__len__}".format(a=Test()) + "{a[0]}".format(a=Getitem()) + "{a[0][0]}".format(a=[Getitem()]) + "{[0][0]}".format(["test"]) + # these are skipped + "{0} {1}".format(*[1, 2]) + "{a} {b}".format(**{'a': 1, 'b': 2}) + "{a}".format(a=Missing()) + +def pprint_bad(): + """Test string format """ + "{{}}".format(1) # [too-many-format-args] + "{} {".format() # [bad-format-string] + "{} }".format() # [bad-format-string] + "{0} {}".format(1, 2) # [format-combined-specification] + # +1: [missing-format-argument-key, unused-format-string-argument] + "{a} {b}".format(a=1, c=2) + "{} {a}".format(1, 2) # [missing-format-argument-key] + "{} {}".format(1) # [too-few-format-args] + "{} {}".format(1, 2, 3) # [too-many-format-args] + # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key] + "{a} {b} {c}".format() + "{} {}".format(a=1, b=2) # [too-few-format-args] + # +1: [missing-format-argument-key, missing-format-argument-key] + "{a} {b}".format(1, 2) + "{0} {1} {a}".format(1, 2, 3) # [missing-format-argument-key] + # +1: [missing-format-attribute] + "{a.ids.__len__.length}".format(a=Test()) + "{a.ids[3][400]}".format(a=Test()) # [invalid-format-index] + "{a.ids[3]['string']}".format(a=Test()) # [invalid-format-index] + "{[0][1]}".format(["a"]) # [invalid-format-index] + "{[0][0]}".format(((1, ))) # [invalid-format-index] + # +1: [missing-format-argument-key, unused-format-string-argument] + "{b[0]}".format(a=23) + "{a[0]}".format(a=object) # [invalid-format-index] + log("{}".format(2, "info")) # [too-many-format-args] + "{0.missing}".format(2) # [missing-format-attribute] + "{0} {1} {2}".format(1, 2) # [too-few-format-args] + "{0} {1}".format(1, 2, 3) # [too-many-format-args] + "{0} {a}".format(a=4) # [too-few-format-args] + "{[0]} {}".format([4]) # [too-few-format-args] + "{[0]} {}".format([4], 5, 6) # [too-many-format-args] + +def good_issue288(*args, **kwargs): + """ Test that using kwargs does not emit a false + positive. + """ + 'Hello John Doe {0[0]}'.format(args) + 'Hello {0[name]}'.format(kwargs) + +def good_issue287(): + """ Test that the string format checker skips + format nodes which don't have a string as a parent + (but a subscript, name etc). + """ + name = 'qwerty' + ret = {'comment': ''} + ret['comment'] = 'MySQL grant {0} is set to be revoked' + ret['comment'] = ret['comment'].format(name) + return ret, name + +def nested_issue294(): + """ Test nested format fields. """ + '{0:>{1}}'.format(42, 24) + '{0:{a[1]}} {a}'.format(1, a=[1, 2]) + '{:>{}}'.format(42, 24) + '{0:>{1}}'.format(42) # [too-few-format-args] + '{0:>{1}}'.format(42, 24, 54) # [too-many-format-args] + '{0:{a[1]}}'.format(1) # [missing-format-argument-key] + '{0:{a.x}}'.format(1, a=2) # [missing-format-attribute] + +def issue310(): + """ Test a regression using duplicate manual position arguments. """ + '{0} {1} {0}'.format(1, 2) + '{0} {1} {0}'.format(1) # [too-few-format-args] + +def issue322(): + """ Test a regression using mixed manual position arguments + and attribute access arguments. + """ + '{0}{1[FOO]}'.format(123, {'FOO': 456}) + '{0}{1[FOO]}'.format(123, {'FOO': 456}, 321) # [too-many-format-args] + '{0}{1[FOO]}'.format(123) # [too-few-format-args] + +def issue338(): + """ + Check that using a namedtuple subclass doesn't crash when + trying to infer EmptyNodes (resulted after mocking the + members of namedtuples). + """ + from collections import namedtuple # pylint: disable=import-outside-toplevel + + class Crash(namedtuple("C", "foo bar")): + """ Looking for attributes in __str__ will crash, + because EmptyNodes can't be infered. + """ + def __str__(self): + return "{0.foo}: {0.bar}".format(self) + return Crash + +def issue351(): + """ + Check that the format method can be assigned to a variable, ie: + """ + fmt = 'test {} {}'.format + fmt('arg1') # [too-few-format-args] + fmt('arg1', 'arg2') + fmt('arg1', 'arg2', 'arg3') # [too-many-format-args] + +def issue373(): + """ + Ignore any object coming from an argument. + """ + class SomeClass(object): + """ empty docstring. """ + def __init__(self, opts=None): + self.opts = opts + + def dunc(self, arg): + """Don't try to analyze this.""" + return "A{0}{1}".format(arg, self.opts) + + def func(self): + """Don't try to analyze the following string.""" + return 'AAA{0[iface]}BBB{0[port]}'.format(self.opts) + + return SomeClass + +def issue_463(): + """ + Mix positional arguments, `{0}`, with positional + arguments with attribute access, `{0.__x__}`. + """ + data = "{0.__class__.__name__}: {0}".format(42) + data2 = "{0[0]}: {0}".format([1]) + return (data, data2) + + +def avoid_empty_attribute(): + """The following string is invalid, avoid crashing.""" + + return "There are {.:2f} undiscovered errors.".format(1) # [bad-format-string] + + +def invalid_format_index_on_inference_ambiguity(): + """Test inference bug for invalid-format-index""" + if len(sys.argv) > 1: + options = [["Woof!"]] + else: + options = [["Barf!"]] + return 'Why is this bad? {options[0][0]}'.format(options=options) diff --git a/tests/functional/s/string/string_formatting.txt b/tests/functional/s/string/string_formatting.txt new file mode 100644 index 000000000..ac67ae47c --- /dev/null +++ b/tests/functional/s/string/string_formatting.txt @@ -0,0 +1,41 @@ +too-many-format-args:58:4:pprint_bad:Too many arguments for format string +bad-format-string:59:4:pprint_bad:Invalid format string +bad-format-string:60:4:pprint_bad:Invalid format string +format-combined-specification:61:4:pprint_bad:Format string contains both automatic field numbering and manual field specification +missing-format-argument-key:63:4:pprint_bad:Missing keyword argument 'b' for format string +unused-format-string-argument:63:4:pprint_bad:Unused format argument 'c' +missing-format-argument-key:64:4:pprint_bad:Missing keyword argument 'a' for format string +too-few-format-args:65:4:pprint_bad:Not enough arguments for format string +too-many-format-args:66:4:pprint_bad:Too many arguments for format string +missing-format-argument-key:68:4:pprint_bad:Missing keyword argument 'a' for format string +missing-format-argument-key:68:4:pprint_bad:Missing keyword argument 'b' for format string +missing-format-argument-key:68:4:pprint_bad:Missing keyword argument 'c' for format string +too-few-format-args:69:4:pprint_bad:Not enough arguments for format string +missing-format-argument-key:71:4:pprint_bad:Missing keyword argument 'a' for format string +missing-format-argument-key:71:4:pprint_bad:Missing keyword argument 'b' for format string +missing-format-argument-key:72:4:pprint_bad:Missing keyword argument 'a' for format string +missing-format-attribute:74:4:pprint_bad:Missing format attribute 'length' in format specifier 'a.ids.__len__.length' +invalid-format-index:75:4:pprint_bad:Using invalid lookup key 400 in format specifier 'a.ids[3][400]' +invalid-format-index:76:4:pprint_bad:"Using invalid lookup key ""'string'"" in format specifier 'a.ids[3][""\'string\'""]'" +invalid-format-index:77:4:pprint_bad:Using invalid lookup key 1 in format specifier '0[0][1]' +invalid-format-index:78:4:pprint_bad:Using invalid lookup key 0 in format specifier '0[0][0]' +missing-format-argument-key:80:4:pprint_bad:Missing keyword argument 'b' for format string +unused-format-string-argument:80:4:pprint_bad:Unused format argument 'a' +invalid-format-index:81:4:pprint_bad:Using invalid lookup key 0 in format specifier 'a[0]' +too-many-format-args:82:8:pprint_bad:Too many arguments for format string +missing-format-attribute:83:4:pprint_bad:Missing format attribute 'missing' in format specifier '0.missing' +too-few-format-args:84:4:pprint_bad:Not enough arguments for format string +too-many-format-args:85:4:pprint_bad:Too many arguments for format string +too-few-format-args:86:4:pprint_bad:Not enough arguments for format string +too-few-format-args:87:4:pprint_bad:Not enough arguments for format string +too-many-format-args:88:4:pprint_bad:Too many arguments for format string +too-few-format-args:113:4:nested_issue294:Not enough arguments for format string +too-many-format-args:114:4:nested_issue294:Too many arguments for format string +missing-format-argument-key:115:4:nested_issue294:Missing keyword argument 'a' for format string +missing-format-attribute:116:4:nested_issue294:Missing format attribute 'x' in format specifier 'a.x' +too-few-format-args:121:4:issue310:Not enough arguments for format string +too-many-format-args:128:4:issue322:Too many arguments for format string +too-few-format-args:129:4:issue322:Not enough arguments for format string +too-few-format-args:152:4:issue351:Not enough arguments for format string +too-many-format-args:154:4:issue351:Too many arguments for format string +bad-format-string:188:11:avoid_empty_attribute:Invalid format string diff --git a/tests/functional/s/string/string_formatting_disable.py b/tests/functional/s/string/string_formatting_disable.py new file mode 100644 index 000000000..88f3dcf03 --- /dev/null +++ b/tests/functional/s/string/string_formatting_disable.py @@ -0,0 +1 @@ +"a {} {".format(1) # [bad-format-string] diff --git a/tests/functional/s/string/string_formatting_disable.rc b/tests/functional/s/string/string_formatting_disable.rc new file mode 100644 index 000000000..0193339de --- /dev/null +++ b/tests/functional/s/string/string_formatting_disable.rc @@ -0,0 +1,3 @@ +[Messages Control] +disable=all +enable=bad-format-string diff --git a/tests/functional/s/string/string_formatting_disable.txt b/tests/functional/s/string/string_formatting_disable.txt new file mode 100644 index 000000000..f6e390f00 --- /dev/null +++ b/tests/functional/s/string/string_formatting_disable.txt @@ -0,0 +1 @@ +bad-format-string:1:0::Invalid format string diff --git a/tests/functional/s/string/string_formatting_failed_inference.py b/tests/functional/s/string/string_formatting_failed_inference.py new file mode 100644 index 000000000..c5add58c8 --- /dev/null +++ b/tests/functional/s/string/string_formatting_failed_inference.py @@ -0,0 +1,4 @@ +""" Testing string format with a failed inference. This should not crash. """ +# pylint: disable=using-constant-test +import collections +"{dict[0]}".format(dict=collections.defaultdict(int)) diff --git a/tests/functional/s/string/string_formatting_failed_inference_py35.py b/tests/functional/s/string/string_formatting_failed_inference_py35.py new file mode 100644 index 000000000..a511ff80e --- /dev/null +++ b/tests/functional/s/string/string_formatting_failed_inference_py35.py @@ -0,0 +1,6 @@ +""" Testing string format with a failed inference. This should not crash. """ +# pylint: disable=using-constant-test +import collections +"{dict[0]}".format(dict=collections.defaultdict(int)) + +COMMENT = "message %s %s %s" % (0, *(1 if "cond" else 2,) * 2) diff --git a/tests/functional/s/string/string_formatting_failed_inference_py35.rc b/tests/functional/s/string/string_formatting_failed_inference_py35.rc new file mode 100644 index 000000000..71de8b630 --- /dev/null +++ b/tests/functional/s/string/string_formatting_failed_inference_py35.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 diff --git a/tests/functional/s/string/string_formatting_py3.py b/tests/functional/s/string/string_formatting_py3.py new file mode 100644 index 000000000..3cdd60eb2 --- /dev/null +++ b/tests/functional/s/string/string_formatting_py3.py @@ -0,0 +1,21 @@ +# pylint: disable=missing-docstring,import-error + + +def issue_957_good(): + meat = ['spam', 'ham'] + print('%s%s%s' % ('eggs', *meat)) + + +def issue_957_bad1(): + meat = ['spam', 'ham', 'monty python'] + print('%s%s%s' % ('eggs', *meat)) # [too-many-format-args] + + +def issue_957_bad2(): + meat = ['spam'] + print('%s%s%s' % ('eggs', *meat)) # [too-few-format-args] + + +def issue_957_uninferable(): + from butchery import meat # pylint: disable=import-outside-toplevel + print('%s%s%s' % ('eggs', *meat)) diff --git a/tests/functional/s/string/string_formatting_py3.rc b/tests/functional/s/string/string_formatting_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/s/string/string_formatting_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/s/string/string_formatting_py3.txt b/tests/functional/s/string/string_formatting_py3.txt new file mode 100644 index 000000000..bf90e016b --- /dev/null +++ b/tests/functional/s/string/string_formatting_py3.txt @@ -0,0 +1,2 @@ +too-many-format-args:11:10:issue_957_bad1:Too many arguments for format string +too-few-format-args:16:10:issue_957_bad2:Not enough arguments for format string diff --git a/tests/functional/s/string_formatting.py b/tests/functional/s/string_formatting.py deleted file mode 100644 index 8e49d28b4..000000000 --- a/tests/functional/s/string_formatting.py +++ /dev/null @@ -1,197 +0,0 @@ -"""test for Python 3 string formatting error -""" -# pylint: disable=too-few-public-methods, import-error, unused-argument, line-too-long, no-absolute-import, useless-object-inheritance -import os -import sys -from missing import Missing - - -class Custom(object): - """ Has a __getattr__ """ - def __getattr__(self, _): - return self - -class Test(object): - """ test format attribute access """ - custom = Custom() - ids = [1, 2, 3, [4, 5, 6]] - -class Getitem(object): - """ test custom getitem for lookup access """ - def __getitem__(self, index): - return 42 - -class ReturnYes(object): - """ can't be properly infered """ - missing = Missing() - -def log(message, message_type="error"): - """ Test """ - return message - -def print_good(): - """ Good format strings """ - "{0} {1}".format(1, 2) - "{0!r:20}".format("Hello") - "{!r:20}".format("Hello") - "{a!r:20}".format(a="Hello") - "{pid}".format(pid=os.getpid()) - str("{}").format(2) - "{0.missing.length}".format(ReturnYes()) - "{1.missing.length}".format(ReturnYes()) - "{a.ids[3][1]}".format(a=Test()) - "{a[0][0]}".format(a=[[1]]) - "{[0][0]}".format({0: {0: 1}}) - "{a.test}".format(a=Custom()) - "{a.__len__}".format(a=[]) - "{a.ids.__len__}".format(a=Test()) - "{a[0]}".format(a=Getitem()) - "{a[0][0]}".format(a=[Getitem()]) - "{[0][0]}".format(["test"]) - # these are skipped - "{0} {1}".format(*[1, 2]) - "{a} {b}".format(**{'a': 1, 'b': 2}) - "{a}".format(a=Missing()) - -def pprint_bad(): - """Test string format """ - "{{}}".format(1) # [too-many-format-args] - "{} {".format() # [bad-format-string] - "{} }".format() # [bad-format-string] - "{0} {}".format(1, 2) # [format-combined-specification] - # +1: [missing-format-argument-key, unused-format-string-argument] - "{a} {b}".format(a=1, c=2) - "{} {a}".format(1, 2) # [missing-format-argument-key] - "{} {}".format(1) # [too-few-format-args] - "{} {}".format(1, 2, 3) # [too-many-format-args] - # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key] - "{a} {b} {c}".format() - "{} {}".format(a=1, b=2) # [too-few-format-args] - # +1: [missing-format-argument-key, missing-format-argument-key] - "{a} {b}".format(1, 2) - "{0} {1} {a}".format(1, 2, 3) # [missing-format-argument-key] - # +1: [missing-format-attribute] - "{a.ids.__len__.length}".format(a=Test()) - "{a.ids[3][400]}".format(a=Test()) # [invalid-format-index] - "{a.ids[3]['string']}".format(a=Test()) # [invalid-format-index] - "{[0][1]}".format(["a"]) # [invalid-format-index] - "{[0][0]}".format(((1, ))) # [invalid-format-index] - # +1: [missing-format-argument-key, unused-format-string-argument] - "{b[0]}".format(a=23) - "{a[0]}".format(a=object) # [invalid-format-index] - log("{}".format(2, "info")) # [too-many-format-args] - "{0.missing}".format(2) # [missing-format-attribute] - "{0} {1} {2}".format(1, 2) # [too-few-format-args] - "{0} {1}".format(1, 2, 3) # [too-many-format-args] - "{0} {a}".format(a=4) # [too-few-format-args] - "{[0]} {}".format([4]) # [too-few-format-args] - "{[0]} {}".format([4], 5, 6) # [too-many-format-args] - -def good_issue288(*args, **kwargs): - """ Test that using kwargs does not emit a false - positive. - """ - 'Hello John Doe {0[0]}'.format(args) - 'Hello {0[name]}'.format(kwargs) - -def good_issue287(): - """ Test that the string format checker skips - format nodes which don't have a string as a parent - (but a subscript, name etc). - """ - name = 'qwerty' - ret = {'comment': ''} - ret['comment'] = 'MySQL grant {0} is set to be revoked' - ret['comment'] = ret['comment'].format(name) - return ret, name - -def nested_issue294(): - """ Test nested format fields. """ - '{0:>{1}}'.format(42, 24) - '{0:{a[1]}} {a}'.format(1, a=[1, 2]) - '{:>{}}'.format(42, 24) - '{0:>{1}}'.format(42) # [too-few-format-args] - '{0:>{1}}'.format(42, 24, 54) # [too-many-format-args] - '{0:{a[1]}}'.format(1) # [missing-format-argument-key] - '{0:{a.x}}'.format(1, a=2) # [missing-format-attribute] - -def issue310(): - """ Test a regression using duplicate manual position arguments. """ - '{0} {1} {0}'.format(1, 2) - '{0} {1} {0}'.format(1) # [too-few-format-args] - -def issue322(): - """ Test a regression using mixed manual position arguments - and attribute access arguments. - """ - '{0}{1[FOO]}'.format(123, {'FOO': 456}) - '{0}{1[FOO]}'.format(123, {'FOO': 456}, 321) # [too-many-format-args] - '{0}{1[FOO]}'.format(123) # [too-few-format-args] - -def issue338(): - """ - Check that using a namedtuple subclass doesn't crash when - trying to infer EmptyNodes (resulted after mocking the - members of namedtuples). - """ - from collections import namedtuple # pylint: disable=import-outside-toplevel - - class Crash(namedtuple("C", "foo bar")): - """ Looking for attributes in __str__ will crash, - because EmptyNodes can't be infered. - """ - def __str__(self): - return "{0.foo}: {0.bar}".format(self) - return Crash - -def issue351(): - """ - Check that the format method can be assigned to a variable, ie: - """ - fmt = 'test {} {}'.format - fmt('arg1') # [too-few-format-args] - fmt('arg1', 'arg2') - fmt('arg1', 'arg2', 'arg3') # [too-many-format-args] - -def issue373(): - """ - Ignore any object coming from an argument. - """ - class SomeClass(object): - """ empty docstring. """ - def __init__(self, opts=None): - self.opts = opts - - def dunc(self, arg): - """Don't try to analyze this.""" - return "A{0}{1}".format(arg, self.opts) - - def func(self): - """Don't try to analyze the following string.""" - return 'AAA{0[iface]}BBB{0[port]}'.format(self.opts) - - return SomeClass - -def issue_463(): - """ - Mix positional arguments, `{0}`, with positional - arguments with attribute access, `{0.__x__}`. - """ - data = "{0.__class__.__name__}: {0}".format(42) - data2 = "{0[0]}: {0}".format([1]) - return (data, data2) - - -def avoid_empty_attribute(): - """The following string is invalid, avoid crashing.""" - - return "There are {.:2f} undiscovered errors.".format(1) # [bad-format-string] - - -def invalid_format_index_on_inference_ambiguity(): - """Test inference bug for invalid-format-index""" - if len(sys.argv) > 1: - options = [["Woof!"]] - else: - options = [["Barf!"]] - return 'Why is this bad? {options[0][0]}'.format(options=options) diff --git a/tests/functional/s/string_formatting.txt b/tests/functional/s/string_formatting.txt deleted file mode 100644 index ac67ae47c..000000000 --- a/tests/functional/s/string_formatting.txt +++ /dev/null @@ -1,41 +0,0 @@ -too-many-format-args:58:4:pprint_bad:Too many arguments for format string -bad-format-string:59:4:pprint_bad:Invalid format string -bad-format-string:60:4:pprint_bad:Invalid format string -format-combined-specification:61:4:pprint_bad:Format string contains both automatic field numbering and manual field specification -missing-format-argument-key:63:4:pprint_bad:Missing keyword argument 'b' for format string -unused-format-string-argument:63:4:pprint_bad:Unused format argument 'c' -missing-format-argument-key:64:4:pprint_bad:Missing keyword argument 'a' for format string -too-few-format-args:65:4:pprint_bad:Not enough arguments for format string -too-many-format-args:66:4:pprint_bad:Too many arguments for format string -missing-format-argument-key:68:4:pprint_bad:Missing keyword argument 'a' for format string -missing-format-argument-key:68:4:pprint_bad:Missing keyword argument 'b' for format string -missing-format-argument-key:68:4:pprint_bad:Missing keyword argument 'c' for format string -too-few-format-args:69:4:pprint_bad:Not enough arguments for format string -missing-format-argument-key:71:4:pprint_bad:Missing keyword argument 'a' for format string -missing-format-argument-key:71:4:pprint_bad:Missing keyword argument 'b' for format string -missing-format-argument-key:72:4:pprint_bad:Missing keyword argument 'a' for format string -missing-format-attribute:74:4:pprint_bad:Missing format attribute 'length' in format specifier 'a.ids.__len__.length' -invalid-format-index:75:4:pprint_bad:Using invalid lookup key 400 in format specifier 'a.ids[3][400]' -invalid-format-index:76:4:pprint_bad:"Using invalid lookup key ""'string'"" in format specifier 'a.ids[3][""\'string\'""]'" -invalid-format-index:77:4:pprint_bad:Using invalid lookup key 1 in format specifier '0[0][1]' -invalid-format-index:78:4:pprint_bad:Using invalid lookup key 0 in format specifier '0[0][0]' -missing-format-argument-key:80:4:pprint_bad:Missing keyword argument 'b' for format string -unused-format-string-argument:80:4:pprint_bad:Unused format argument 'a' -invalid-format-index:81:4:pprint_bad:Using invalid lookup key 0 in format specifier 'a[0]' -too-many-format-args:82:8:pprint_bad:Too many arguments for format string -missing-format-attribute:83:4:pprint_bad:Missing format attribute 'missing' in format specifier '0.missing' -too-few-format-args:84:4:pprint_bad:Not enough arguments for format string -too-many-format-args:85:4:pprint_bad:Too many arguments for format string -too-few-format-args:86:4:pprint_bad:Not enough arguments for format string -too-few-format-args:87:4:pprint_bad:Not enough arguments for format string -too-many-format-args:88:4:pprint_bad:Too many arguments for format string -too-few-format-args:113:4:nested_issue294:Not enough arguments for format string -too-many-format-args:114:4:nested_issue294:Too many arguments for format string -missing-format-argument-key:115:4:nested_issue294:Missing keyword argument 'a' for format string -missing-format-attribute:116:4:nested_issue294:Missing format attribute 'x' in format specifier 'a.x' -too-few-format-args:121:4:issue310:Not enough arguments for format string -too-many-format-args:128:4:issue322:Too many arguments for format string -too-few-format-args:129:4:issue322:Not enough arguments for format string -too-few-format-args:152:4:issue351:Not enough arguments for format string -too-many-format-args:154:4:issue351:Too many arguments for format string -bad-format-string:188:11:avoid_empty_attribute:Invalid format string diff --git a/tests/functional/s/string_formatting_disable.py b/tests/functional/s/string_formatting_disable.py deleted file mode 100644 index 88f3dcf03..000000000 --- a/tests/functional/s/string_formatting_disable.py +++ /dev/null @@ -1 +0,0 @@ -"a {} {".format(1) # [bad-format-string] diff --git a/tests/functional/s/string_formatting_disable.rc b/tests/functional/s/string_formatting_disable.rc deleted file mode 100644 index 0193339de..000000000 --- a/tests/functional/s/string_formatting_disable.rc +++ /dev/null @@ -1,3 +0,0 @@ -[Messages Control] -disable=all -enable=bad-format-string diff --git a/tests/functional/s/string_formatting_disable.txt b/tests/functional/s/string_formatting_disable.txt deleted file mode 100644 index f6e390f00..000000000 --- a/tests/functional/s/string_formatting_disable.txt +++ /dev/null @@ -1 +0,0 @@ -bad-format-string:1:0::Invalid format string diff --git a/tests/functional/s/string_formatting_failed_inference.py b/tests/functional/s/string_formatting_failed_inference.py deleted file mode 100644 index c5add58c8..000000000 --- a/tests/functional/s/string_formatting_failed_inference.py +++ /dev/null @@ -1,4 +0,0 @@ -""" Testing string format with a failed inference. This should not crash. """ -# pylint: disable=using-constant-test -import collections -"{dict[0]}".format(dict=collections.defaultdict(int)) diff --git a/tests/functional/s/string_formatting_failed_inference_py35.py b/tests/functional/s/string_formatting_failed_inference_py35.py deleted file mode 100644 index a511ff80e..000000000 --- a/tests/functional/s/string_formatting_failed_inference_py35.py +++ /dev/null @@ -1,6 +0,0 @@ -""" Testing string format with a failed inference. This should not crash. """ -# pylint: disable=using-constant-test -import collections -"{dict[0]}".format(dict=collections.defaultdict(int)) - -COMMENT = "message %s %s %s" % (0, *(1 if "cond" else 2,) * 2) diff --git a/tests/functional/s/string_formatting_failed_inference_py35.rc b/tests/functional/s/string_formatting_failed_inference_py35.rc deleted file mode 100644 index 71de8b630..000000000 --- a/tests/functional/s/string_formatting_failed_inference_py35.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.5 diff --git a/tests/functional/s/string_formatting_py3.py b/tests/functional/s/string_formatting_py3.py deleted file mode 100644 index 3cdd60eb2..000000000 --- a/tests/functional/s/string_formatting_py3.py +++ /dev/null @@ -1,21 +0,0 @@ -# pylint: disable=missing-docstring,import-error - - -def issue_957_good(): - meat = ['spam', 'ham'] - print('%s%s%s' % ('eggs', *meat)) - - -def issue_957_bad1(): - meat = ['spam', 'ham', 'monty python'] - print('%s%s%s' % ('eggs', *meat)) # [too-many-format-args] - - -def issue_957_bad2(): - meat = ['spam'] - print('%s%s%s' % ('eggs', *meat)) # [too-few-format-args] - - -def issue_957_uninferable(): - from butchery import meat # pylint: disable=import-outside-toplevel - print('%s%s%s' % ('eggs', *meat)) diff --git a/tests/functional/s/string_formatting_py3.rc b/tests/functional/s/string_formatting_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/s/string_formatting_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/s/string_formatting_py3.txt b/tests/functional/s/string_formatting_py3.txt deleted file mode 100644 index bf90e016b..000000000 --- a/tests/functional/s/string_formatting_py3.txt +++ /dev/null @@ -1,2 +0,0 @@ -too-many-format-args:11:10:issue_957_bad1:Too many arguments for format string -too-few-format-args:16:10:issue_957_bad2:Not enough arguments for format string diff --git a/tests/functional/s/super/super_checks.py b/tests/functional/s/super/super_checks.py new file mode 100644 index 000000000..3f132dff1 --- /dev/null +++ b/tests/functional/s/super/super_checks.py @@ -0,0 +1,125 @@ +# pylint: disable=too-few-public-methods,import-error, no-absolute-import,missing-docstring, useless-object-inheritance +# pylint: disable=useless-super-delegation,wrong-import-position,invalid-name, wrong-import-order +# pylint: disable=super-with-arguments +from unknown import Missing + +class Aaaa: + """old style""" + def hop(self): + """hop""" + super(Aaaa, self).hop() # >=3.0:[no-member] + + def __init__(self): + super(Aaaa, self).__init__() + +class NewAaaa(object): + """old style""" + def hop(self): + """hop""" + super(NewAaaa, self).hop() # [no-member] + + def __init__(self): + super(Aaaa, self).__init__() # [bad-super-call] + +class Py3kAaaa(NewAaaa): + """new style""" + def __init__(self): + super().__init__() # <3.0:[missing-super-argument] + +class Py3kWrongSuper(Py3kAaaa): + """new style""" + def __init__(self): + super(NewAaaa, self).__init__() # [bad-super-call] + +class WrongNameRegression(Py3kAaaa): + """ test a regression with the message """ + def __init__(self): + super(Missing, self).__init__() # [bad-super-call] + +class Getattr(object): + """ crash """ + name = NewAaaa + +class CrashSuper(object): + """ test a crash with this checker """ + def __init__(self): + super(Getattr.name, self).__init__() # [bad-super-call] + +class Empty(object): + """Just an empty class.""" + +class SuperDifferentScope(object): + """Don'emit bad-super-call when the super call is in another scope. + For reference, see https://bitbucket.org/logilab/pylint/issue/403. + """ + @staticmethod + def test(): + """Test that a bad-super-call is not emitted for this case.""" + class FalsePositive(Empty): + """The following super is in another scope than `test`.""" + def __init__(self, arg): + super(FalsePositive, self).__init__(arg) + super(object, 1).__init__() # [bad-super-call] + + +class UnknownBases(Missing): + """Don't emit if we don't know all the bases.""" + def __init__(self): + super(UnknownBases, self).__init__() + super(UnknownBases, self).test() + super(Missing, self).test() # [bad-super-call] + + +# Test that we are detecting proper super errors. + +class BaseClass(object): + + not_a_method = 42 + + def function(self, param): + return param + self.not_a_method + + def __getattr__(self, attr): + return attr + + +class InvalidSuperChecks(BaseClass): + + def __init__(self): + super(InvalidSuperChecks, self).not_a_method() # [not-callable] + super(InvalidSuperChecks, self).attribute_error() # [no-member] + super(InvalidSuperChecks, self).function(42) + super(InvalidSuperChecks, self).function() # [no-value-for-parameter] + super(InvalidSuperChecks, self).function(42, 24, 24) # [too-many-function-args] + # +1: [unexpected-keyword-arg,no-value-for-parameter] + super(InvalidSuperChecks, self).function(lala=42) + # Even though BaseClass has a __getattr__, that won't + # be called. + super(InvalidSuperChecks, self).attribute_error() # [no-member] + + + +# Regression for PyCQA/pylint/issues/773 +import subprocess + +# The problem was related to astroid not filtering statements +# at scope level properly, basically not doing strong updates. +try: + TimeoutExpired = subprocess.TimeoutExpired +except AttributeError: + class TimeoutExpired(subprocess.CalledProcessError): + def __init__(self): + returncode = -1 + self.timeout = -1 + super(TimeoutExpired, self).__init__("", returncode) + + +class SuperWithType(object): + """type(self) may lead to recursion loop in derived classes""" + def __init__(self): + super(type(self), self).__init__() # [bad-super-call] + +class SuperWithSelfClass(object): + """self.__class__ may lead to recursion loop in derived classes""" + def __init__(self): + super(self.__class__, self).__init__() # [bad-super-call] diff --git a/tests/functional/s/super/super_checks.txt b/tests/functional/s/super/super_checks.txt new file mode 100644 index 000000000..bd360c831 --- /dev/null +++ b/tests/functional/s/super/super_checks.txt @@ -0,0 +1,17 @@ +no-member:10:8:Aaaa.hop:Super of 'Aaaa' has no 'hop' member:INFERENCE +no-member:19:8:NewAaaa.hop:Super of 'NewAaaa' has no 'hop' member:INFERENCE +bad-super-call:22:8:NewAaaa.__init__:Bad first argument 'Aaaa' given to super() +bad-super-call:32:8:Py3kWrongSuper.__init__:Bad first argument 'NewAaaa' given to super() +bad-super-call:37:8:WrongNameRegression.__init__:Bad first argument 'Missing' given to super() +bad-super-call:46:8:CrashSuper.__init__:Bad first argument 'NewAaaa' given to super() +bad-super-call:62:8:SuperDifferentScope.test:Bad first argument 'object' given to super() +bad-super-call:70:8:UnknownBases.__init__:Bad first argument 'Missing' given to super() +not-callable:89:8:InvalidSuperChecks.__init__:super(InvalidSuperChecks, self).not_a_method is not callable +no-member:90:8:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE +no-value-for-parameter:92:8:InvalidSuperChecks.__init__:No value for argument 'param' in method call +too-many-function-args:93:8:InvalidSuperChecks.__init__:Too many positional arguments for method call +no-value-for-parameter:95:8:InvalidSuperChecks.__init__:No value for argument 'param' in method call +unexpected-keyword-arg:95:8:InvalidSuperChecks.__init__:Unexpected keyword argument 'lala' in method call +no-member:98:8:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE +bad-super-call:120:8:SuperWithType.__init__:Bad first argument 'type' given to super() +bad-super-call:125:8:SuperWithSelfClass.__init__:Bad first argument 'self.__class__' given to super() diff --git a/tests/functional/s/super/super_with_arguments.py b/tests/functional/s/super/super_with_arguments.py new file mode 100644 index 000000000..8ab7c4d71 --- /dev/null +++ b/tests/functional/s/super/super_with_arguments.py @@ -0,0 +1,35 @@ +class Foo: + pass + + +class Bar(Foo): + def __init__(self): + super(Bar, self).__init__() # [super-with-arguments] + + +class Baz(Foo): + def __init__(self): + super().__init__() + + +class Qux(Foo): + def __init__(self): + super(Bar, self).__init__() + + +class NotSuperCall(Foo): + def __init__(self): + super.test(Bar, self).__init__() + + +class InvalidSuperCall(Foo): + def __init__(self): + super(InvalidSuperCall.__class__, self).__init__() + + +def method_accepting_cls(cls, self): + # Using plain `super()` is not valid here, since there's no `__class__` cell found + # (Exact exception would be 'RuntimeError: super(): __class__ cell not found') + # Instead, we expect to *not* see a warning about `super-with-arguments`. + # Explicitly passing `cls`, and `self` to `super()` is what's required. + super(cls, self).__init__() diff --git a/tests/functional/s/super/super_with_arguments.rc b/tests/functional/s/super/super_with_arguments.rc new file mode 100644 index 000000000..0e70163ee --- /dev/null +++ b/tests/functional/s/super/super_with_arguments.rc @@ -0,0 +1,3 @@ +[Messages Control] +disable=all +enable=super-with-arguments diff --git a/tests/functional/s/super/super_with_arguments.txt b/tests/functional/s/super/super_with_arguments.txt new file mode 100644 index 000000000..f882848f8 --- /dev/null +++ b/tests/functional/s/super/super_with_arguments.txt @@ -0,0 +1 @@ +super-with-arguments:7:8:Bar.__init__:Consider using Python 3 style super() without arguments diff --git a/tests/functional/s/super_checks.py b/tests/functional/s/super_checks.py deleted file mode 100644 index 3f132dff1..000000000 --- a/tests/functional/s/super_checks.py +++ /dev/null @@ -1,125 +0,0 @@ -# pylint: disable=too-few-public-methods,import-error, no-absolute-import,missing-docstring, useless-object-inheritance -# pylint: disable=useless-super-delegation,wrong-import-position,invalid-name, wrong-import-order -# pylint: disable=super-with-arguments -from unknown import Missing - -class Aaaa: - """old style""" - def hop(self): - """hop""" - super(Aaaa, self).hop() # >=3.0:[no-member] - - def __init__(self): - super(Aaaa, self).__init__() - -class NewAaaa(object): - """old style""" - def hop(self): - """hop""" - super(NewAaaa, self).hop() # [no-member] - - def __init__(self): - super(Aaaa, self).__init__() # [bad-super-call] - -class Py3kAaaa(NewAaaa): - """new style""" - def __init__(self): - super().__init__() # <3.0:[missing-super-argument] - -class Py3kWrongSuper(Py3kAaaa): - """new style""" - def __init__(self): - super(NewAaaa, self).__init__() # [bad-super-call] - -class WrongNameRegression(Py3kAaaa): - """ test a regression with the message """ - def __init__(self): - super(Missing, self).__init__() # [bad-super-call] - -class Getattr(object): - """ crash """ - name = NewAaaa - -class CrashSuper(object): - """ test a crash with this checker """ - def __init__(self): - super(Getattr.name, self).__init__() # [bad-super-call] - -class Empty(object): - """Just an empty class.""" - -class SuperDifferentScope(object): - """Don'emit bad-super-call when the super call is in another scope. - For reference, see https://bitbucket.org/logilab/pylint/issue/403. - """ - @staticmethod - def test(): - """Test that a bad-super-call is not emitted for this case.""" - class FalsePositive(Empty): - """The following super is in another scope than `test`.""" - def __init__(self, arg): - super(FalsePositive, self).__init__(arg) - super(object, 1).__init__() # [bad-super-call] - - -class UnknownBases(Missing): - """Don't emit if we don't know all the bases.""" - def __init__(self): - super(UnknownBases, self).__init__() - super(UnknownBases, self).test() - super(Missing, self).test() # [bad-super-call] - - -# Test that we are detecting proper super errors. - -class BaseClass(object): - - not_a_method = 42 - - def function(self, param): - return param + self.not_a_method - - def __getattr__(self, attr): - return attr - - -class InvalidSuperChecks(BaseClass): - - def __init__(self): - super(InvalidSuperChecks, self).not_a_method() # [not-callable] - super(InvalidSuperChecks, self).attribute_error() # [no-member] - super(InvalidSuperChecks, self).function(42) - super(InvalidSuperChecks, self).function() # [no-value-for-parameter] - super(InvalidSuperChecks, self).function(42, 24, 24) # [too-many-function-args] - # +1: [unexpected-keyword-arg,no-value-for-parameter] - super(InvalidSuperChecks, self).function(lala=42) - # Even though BaseClass has a __getattr__, that won't - # be called. - super(InvalidSuperChecks, self).attribute_error() # [no-member] - - - -# Regression for PyCQA/pylint/issues/773 -import subprocess - -# The problem was related to astroid not filtering statements -# at scope level properly, basically not doing strong updates. -try: - TimeoutExpired = subprocess.TimeoutExpired -except AttributeError: - class TimeoutExpired(subprocess.CalledProcessError): - def __init__(self): - returncode = -1 - self.timeout = -1 - super(TimeoutExpired, self).__init__("", returncode) - - -class SuperWithType(object): - """type(self) may lead to recursion loop in derived classes""" - def __init__(self): - super(type(self), self).__init__() # [bad-super-call] - -class SuperWithSelfClass(object): - """self.__class__ may lead to recursion loop in derived classes""" - def __init__(self): - super(self.__class__, self).__init__() # [bad-super-call] diff --git a/tests/functional/s/super_checks.txt b/tests/functional/s/super_checks.txt deleted file mode 100644 index bd360c831..000000000 --- a/tests/functional/s/super_checks.txt +++ /dev/null @@ -1,17 +0,0 @@ -no-member:10:8:Aaaa.hop:Super of 'Aaaa' has no 'hop' member:INFERENCE -no-member:19:8:NewAaaa.hop:Super of 'NewAaaa' has no 'hop' member:INFERENCE -bad-super-call:22:8:NewAaaa.__init__:Bad first argument 'Aaaa' given to super() -bad-super-call:32:8:Py3kWrongSuper.__init__:Bad first argument 'NewAaaa' given to super() -bad-super-call:37:8:WrongNameRegression.__init__:Bad first argument 'Missing' given to super() -bad-super-call:46:8:CrashSuper.__init__:Bad first argument 'NewAaaa' given to super() -bad-super-call:62:8:SuperDifferentScope.test:Bad first argument 'object' given to super() -bad-super-call:70:8:UnknownBases.__init__:Bad first argument 'Missing' given to super() -not-callable:89:8:InvalidSuperChecks.__init__:super(InvalidSuperChecks, self).not_a_method is not callable -no-member:90:8:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE -no-value-for-parameter:92:8:InvalidSuperChecks.__init__:No value for argument 'param' in method call -too-many-function-args:93:8:InvalidSuperChecks.__init__:Too many positional arguments for method call -no-value-for-parameter:95:8:InvalidSuperChecks.__init__:No value for argument 'param' in method call -unexpected-keyword-arg:95:8:InvalidSuperChecks.__init__:Unexpected keyword argument 'lala' in method call -no-member:98:8:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE -bad-super-call:120:8:SuperWithType.__init__:Bad first argument 'type' given to super() -bad-super-call:125:8:SuperWithSelfClass.__init__:Bad first argument 'self.__class__' given to super() diff --git a/tests/functional/s/super_with_arguments.py b/tests/functional/s/super_with_arguments.py deleted file mode 100644 index 8ab7c4d71..000000000 --- a/tests/functional/s/super_with_arguments.py +++ /dev/null @@ -1,35 +0,0 @@ -class Foo: - pass - - -class Bar(Foo): - def __init__(self): - super(Bar, self).__init__() # [super-with-arguments] - - -class Baz(Foo): - def __init__(self): - super().__init__() - - -class Qux(Foo): - def __init__(self): - super(Bar, self).__init__() - - -class NotSuperCall(Foo): - def __init__(self): - super.test(Bar, self).__init__() - - -class InvalidSuperCall(Foo): - def __init__(self): - super(InvalidSuperCall.__class__, self).__init__() - - -def method_accepting_cls(cls, self): - # Using plain `super()` is not valid here, since there's no `__class__` cell found - # (Exact exception would be 'RuntimeError: super(): __class__ cell not found') - # Instead, we expect to *not* see a warning about `super-with-arguments`. - # Explicitly passing `cls`, and `self` to `super()` is what's required. - super(cls, self).__init__() diff --git a/tests/functional/s/super_with_arguments.rc b/tests/functional/s/super_with_arguments.rc deleted file mode 100644 index 0e70163ee..000000000 --- a/tests/functional/s/super_with_arguments.rc +++ /dev/null @@ -1,3 +0,0 @@ -[Messages Control] -disable=all -enable=super-with-arguments diff --git a/tests/functional/s/super_with_arguments.txt b/tests/functional/s/super_with_arguments.txt deleted file mode 100644 index f882848f8..000000000 --- a/tests/functional/s/super_with_arguments.txt +++ /dev/null @@ -1 +0,0 @@ -super-with-arguments:7:8:Bar.__init__:Consider using Python 3 style super() without arguments diff --git a/tests/functional/t/too/__init__.py b/tests/functional/t/too/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/functional/t/too/too_few_public_methods.py b/tests/functional/t/too/too_few_public_methods.py new file mode 100644 index 000000000..5ba528f79 --- /dev/null +++ b/tests/functional/t/too/too_few_public_methods.py @@ -0,0 +1,50 @@ +# pylint: disable=missing-docstring, useless-object-inheritance +from __future__ import print_function + + +from enum import Enum + + +class Aaaa(object): # [too-few-public-methods] + + def __init__(self): + pass + + def meth1(self): + print(self) + + def _dontcount(self): + print(self) + + +# Don't emit for these cases. +class Klass(object): + """docstring""" + + def meth1(self): + """first""" + + def meth2(self): + """second""" + + +class EnoughPublicMethods(Klass): + """We shouldn't emit too-few-public-methods for this.""" + + +class BossMonster(Enum): + """An enum does not need methods to be useful.""" + MEGASHARK = 1 + OCTOPUS = 2 + + +class DumbList: + """A class can define only special methods.""" + def __init__(self, iterable): + self._list = list(iterable) + + def __len__(self): + return len(self._list) + + def __getitem__(self, index): + return self._list[index] diff --git a/tests/functional/t/too/too_few_public_methods.txt b/tests/functional/t/too/too_few_public_methods.txt new file mode 100644 index 000000000..a86ba6d81 --- /dev/null +++ b/tests/functional/t/too/too_few_public_methods.txt @@ -0,0 +1 @@ +too-few-public-methods:8:0:Aaaa:Too few public methods (1/2) diff --git a/tests/functional/t/too/too_few_public_methods_37.py b/tests/functional/t/too/too_few_public_methods_37.py new file mode 100644 index 000000000..55fc54484 --- /dev/null +++ b/tests/functional/t/too/too_few_public_methods_37.py @@ -0,0 +1,37 @@ +# pylint: disable=missing-docstring +import dataclasses +import typing +from dataclasses import dataclass + + +@dataclasses.dataclass +class ScheduledTxSearchModel: + date_from = None + date_to = None + + +@dataclass +class ScheduledTxSearchModelOne: + date = None + + +@dataclass(frozen=True) +class Test: + some_integer: int + + +class Example(typing.NamedTuple): + some_int: int + + +@dataclasses.dataclass(frozen=True) +class Point: + """A three dimensional point with x, y and z components.""" + + attr1: float + attr2: float + attr3: float + + def to_array(self): + """Convert to a NumPy array `np.array((x, y, z))`.""" + return self.attr1 diff --git a/tests/functional/t/too/too_few_public_methods_37.rc b/tests/functional/t/too/too_few_public_methods_37.rc new file mode 100644 index 000000000..a17bb22da --- /dev/null +++ b/tests/functional/t/too/too_few_public_methods_37.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 diff --git a/tests/functional/t/too/too_many_ancestors.py b/tests/functional/t/too/too_many_ancestors.py new file mode 100644 index 000000000..a0ae18a02 --- /dev/null +++ b/tests/functional/t/too/too_many_ancestors.py @@ -0,0 +1,24 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance + +class Aaaa(object): + pass +class Bbbb(object): + pass +class Cccc(object): + pass +class Dddd(object): + pass +class Eeee(object): + pass +class Ffff(object): + pass +class Gggg(object): + pass +class Hhhh(object): + pass + +class Iiii(Aaaa, Bbbb, Cccc, Dddd, Eeee, Ffff, Gggg, Hhhh): # [too-many-ancestors] + pass + +class Jjjj(Iiii): # [too-many-ancestors] + pass diff --git a/tests/functional/t/too/too_many_ancestors.txt b/tests/functional/t/too/too_many_ancestors.txt new file mode 100644 index 000000000..97c954368 --- /dev/null +++ b/tests/functional/t/too/too_many_ancestors.txt @@ -0,0 +1,2 @@ +too-many-ancestors:20:0:Iiii:Too many ancestors (9/7) +too-many-ancestors:23:0:Jjjj:Too many ancestors (10/7) diff --git a/tests/functional/t/too/too_many_arguments.py b/tests/functional/t/too/too_many_arguments.py new file mode 100644 index 000000000..689745e27 --- /dev/null +++ b/tests/functional/t/too/too_many_arguments.py @@ -0,0 +1,32 @@ +# pylint: disable=missing-docstring,wrong-import-position + +def stupid_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9): # [too-many-arguments] + return arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + + +class MyClass: + text = "MyText" + + def mymethod1(self): + return self.text + + def mymethod2(self): + return self.mymethod1.__get__(self, MyClass) + + +MyClass().mymethod2()() + + +# Check a false positive does not occur +from functools import partial + + +def root_function(first, second, third): + return first + second + third + + +def func_call(): + """Test we don't emit a FP for https://github.com/PyCQA/pylint/issues/2588""" + partial_func = partial(root_function, 1, 2, 3) + partial_func() + return root_function(1, 2, 3) diff --git a/tests/functional/t/too/too_many_arguments.txt b/tests/functional/t/too/too_many_arguments.txt new file mode 100644 index 000000000..d4f551634 --- /dev/null +++ b/tests/functional/t/too/too_many_arguments.txt @@ -0,0 +1 @@ +too-many-arguments:3:0:stupid_function:Too many arguments (9/5) diff --git a/tests/functional/t/too/too_many_arguments_issue_1045.py b/tests/functional/t/too/too_many_arguments_issue_1045.py new file mode 100644 index 000000000..e5aa76d75 --- /dev/null +++ b/tests/functional/t/too/too_many_arguments_issue_1045.py @@ -0,0 +1,13 @@ +# pylint: disable=missing-docstring + +# pylint: disable=unused-import, undefined-variable; false positives :-( + +import functools + + +@functools.lru_cache() +def func(): + pass + + +func.cache_clear() diff --git a/tests/functional/t/too/too_many_arguments_issue_1045.rc b/tests/functional/t/too/too_many_arguments_issue_1045.rc new file mode 100644 index 000000000..d425e7c47 --- /dev/null +++ b/tests/functional/t/too/too_many_arguments_issue_1045.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.2 diff --git a/tests/functional/t/too/too_many_arguments_overload.py b/tests/functional/t/too/too_many_arguments_overload.py new file mode 100644 index 000000000..1155deb0c --- /dev/null +++ b/tests/functional/t/too/too_many_arguments_overload.py @@ -0,0 +1,38 @@ +# pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring +# pylint: disable=too-few-public-methods +from typing import overload + + +class ClassA: + @classmethod + @overload + def method(cls, arg1): + pass + + @classmethod + @overload + def method(cls, arg1, arg2): + pass + + @classmethod + def method(cls, arg1, arg2=None): + pass + + +ClassA.method(1, 2) + + +class ClassB: + @overload + def method(self, arg1): + pass + + @overload + def method(self, arg1, arg2): + pass + + def method(self, arg1, arg2=None): + pass + + +ClassB().method(1, arg2=2) diff --git a/tests/functional/t/too/too_many_boolean_expressions.py b/tests/functional/t/too/too_many_boolean_expressions.py new file mode 100644 index 000000000..e8753859c --- /dev/null +++ b/tests/functional/t/too/too_many_boolean_expressions.py @@ -0,0 +1,20 @@ +"""Checks for if statements containing too many boolean expressions""" + +# pylint: disable=invalid-name, comparison-with-itself, chained-comparison, condition-evals-to-constant + +x = y = z = 5 +if x > -5 and x < 5 and y > -5 and y < 5 and z > -5 and z < 5: # [too-many-boolean-expressions] + pass +elif True and False and 1 and 2 and 3: + pass +elif True and False and 1 and 2 and 3 and 4 and 5: # [too-many-boolean-expressions] + pass +elif True and (True and True) and (x == 5 or True or True): # [too-many-boolean-expressions] + pass +elif True and (True or (x > -5 and x < 5 and (z > -5 or z < 5))): # [too-many-boolean-expressions] + pass +elif True == True == True == True == True == True: + pass + +if True and False and 1 and 2 and 3: + pass diff --git a/tests/functional/t/too/too_many_boolean_expressions.txt b/tests/functional/t/too/too_many_boolean_expressions.txt new file mode 100644 index 000000000..6055e7437 --- /dev/null +++ b/tests/functional/t/too/too_many_boolean_expressions.txt @@ -0,0 +1,4 @@ +too-many-boolean-expressions:6:3::Too many boolean expressions in if statement (6/5) +too-many-boolean-expressions:10:5::Too many boolean expressions in if statement (7/5) +too-many-boolean-expressions:12:5::Too many boolean expressions in if statement (6/5) +too-many-boolean-expressions:14:5::Too many boolean expressions in if statement (6/5) diff --git a/tests/functional/t/too/too_many_branches.py b/tests/functional/t/too/too_many_branches.py new file mode 100644 index 000000000..7b0b068ad --- /dev/null +++ b/tests/functional/t/too/too_many_branches.py @@ -0,0 +1,69 @@ +""" Test for too many branches. """ +# pylint: disable=using-constant-test +def wrong(): # [too-many-branches] + """ Has too many branches. """ + if 1: + pass + elif 1: + pass + elif 1: + pass + elif 1: + pass + elif 1: + pass + elif 1: + pass + try: + pass + finally: + pass + if 2: + pass + while True: + pass + if 1: + pass + elif 2: + pass + elif 3: + pass + +def good(): + """ Too many branches only if we take + into consideration the nested functions. + """ + def nested_1(): + """ empty """ + if 1: + pass + elif 2: + pass + elif 3: + pass + elif 4: + pass + + nested_1() + try: + pass + finally: + pass + try: + pass + finally: + pass + if 1: + pass + elif 2: + pass + elif 3: + pass + elif 4: + pass + elif 5: + pass + elif 6: + pass + elif 7: + pass diff --git a/tests/functional/t/too/too_many_branches.txt b/tests/functional/t/too/too_many_branches.txt new file mode 100644 index 000000000..e5bfd4d49 --- /dev/null +++ b/tests/functional/t/too/too_many_branches.txt @@ -0,0 +1 @@ +too-many-branches:3:0:wrong:Too many branches (13/12) diff --git a/tests/functional/t/too/too_many_instance_attributes.py b/tests/functional/t/too/too_many_instance_attributes.py new file mode 100644 index 000000000..f6703e0b7 --- /dev/null +++ b/tests/functional/t/too/too_many_instance_attributes.py @@ -0,0 +1,26 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance + +class Aaaa(object): # [too-many-instance-attributes] + + def __init__(self): + self.aaaa = 1 + self.bbbb = 2 + self.cccc = 3 + self.dddd = 4 + self.eeee = 5 + self.ffff = 6 + self.gggg = 7 + self.hhhh = 8 + self.iiii = 9 + self.jjjj = 10 + self._aaaa = 1 + self._bbbb = 2 + self._cccc = 3 + self._dddd = 4 + self._eeee = 5 + self._ffff = 6 + self._gggg = 7 + self._hhhh = 8 + self._iiii = 9 + self._jjjj = 10 + self.tomuch = None diff --git a/tests/functional/t/too/too_many_instance_attributes.txt b/tests/functional/t/too/too_many_instance_attributes.txt new file mode 100644 index 000000000..42c85493c --- /dev/null +++ b/tests/functional/t/too/too_many_instance_attributes.txt @@ -0,0 +1 @@ +too-many-instance-attributes:3:0:Aaaa:Too many instance attributes (21/7) diff --git a/tests/functional/t/too/too_many_lines.py b/tests/functional/t/too/too_many_lines.py new file mode 100644 index 000000000..78e568c23 --- /dev/null +++ b/tests/functional/t/too/too_many_lines.py @@ -0,0 +1,1015 @@ +# pylint: disable=missing-docstring +# -1: [too-many-lines] +__revision__ = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ZERFZAER = 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +HEHEHE = 2 diff --git a/tests/functional/t/too/too_many_lines.txt b/tests/functional/t/too/too_many_lines.txt new file mode 100644 index 000000000..5c228ac49 --- /dev/null +++ b/tests/functional/t/too/too_many_lines.txt @@ -0,0 +1 @@ +too-many-lines:1:0::Too many lines in module (1015/1000) diff --git a/tests/functional/t/too/too_many_lines_disabled.py b/tests/functional/t/too/too_many_lines_disabled.py new file mode 100644 index 000000000..1b0866db2 --- /dev/null +++ b/tests/functional/t/too/too_many_lines_disabled.py @@ -0,0 +1,1018 @@ +"""Test that disabling too-many-lines on any line works.""" + + + +# pylint: disable=too-many-lines +__revision__ = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ZERFZAER = 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +HEHEHE = 2 diff --git a/tests/functional/t/too/too_many_locals.py b/tests/functional/t/too/too_many_locals.py new file mode 100644 index 000000000..ac38a9e01 --- /dev/null +++ b/tests/functional/t/too/too_many_locals.py @@ -0,0 +1,60 @@ +# pylint: disable=missing-docstring +from __future__ import print_function + +def function(arg1, arg2, arg3, arg4, arg5): # [too-many-locals] + arg6, arg7, arg8, arg9 = arg1, arg2, arg3, arg4 + print(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + loc1, loc2, loc3, loc4, loc5, loc6, loc7 = arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 + print(loc1, loc2, loc3, loc4, loc5, loc6, loc7) + + +def too_many_locals_function(): # [too-many-locals] + """pylint will complains about too many local variables""" + args0 = 0 + args1 = args0 * 1 + args2 = args1 * 2 + args3 = args2 * 3 + args4 = args3 * 4 + args5 = args4 * 5 + args6 = args5 * 6 + args7 = args6 * 7 + args8 = args7 * 8 + args9 = args8 * 9 + args10 = args9 * 10 + args11 = args10 * 11 + args12 = args11 * 12 + args13 = args12 * 13 + args14 = args13 * 14 + args15 = args14 * 15 + return args15 + +def too_many_arguments_function(arga, argu, argi, arge, argt, args): # [too-many-arguments] + """pylint will complains about too many arguments.""" + arga = argu + arga += argi + arga += arge + arga += argt + arga += args + return arga + +def ignored_arguments_function(arga, argu, argi, + _arge=0, _argt=1, _args=None): + """pylint will ignore _arge, _argt, _args. + + Consequently pylint will only coun 13 arguments. + """ + arg0 = 0 + arg1 = arg0 * 1 + arga + arg2 = arg1 * 2 + argu + arg3 = arg2 * 3 + argi + arg4 = arg3 * 4 + _arge + arg5 = arg4 * 5 + _argt + arg6 = arg5 * 6 + arg7 = arg6 * 7 + arg8 = arg7 * 8 + arg9 = arg8 * 9 + arg9 += arg0 + if _args: + arg9 += sum(_args) + return arg9 diff --git a/tests/functional/t/too/too_many_locals.txt b/tests/functional/t/too/too_many_locals.txt new file mode 100644 index 000000000..4af7f0307 --- /dev/null +++ b/tests/functional/t/too/too_many_locals.txt @@ -0,0 +1,3 @@ +too-many-locals:4:0:function:Too many local variables (16/15) +too-many-locals:12:0:too_many_locals_function:Too many local variables (16/15) +too-many-arguments:32:0:too_many_arguments_function:Too many arguments (6/5) diff --git a/tests/functional/t/too/too_many_nested_blocks.py b/tests/functional/t/too/too_many_nested_blocks.py new file mode 100644 index 000000000..e7c007957 --- /dev/null +++ b/tests/functional/t/too/too_many_nested_blocks.py @@ -0,0 +1,97 @@ +"""Checks the maximum block level is smaller than 6 in function definitions""" + +#pylint: disable=using-constant-test, missing-docstring, too-many-return-statements,no-else-return + +def my_function(): + if 1: # [too-many-nested-blocks] + for i in range(10): + if i == 2: + while True: + try: + if True: + i += 1 + except IOError: + pass + + if 1: + for i in range(10): + if i == 2: + while True: + try: + i += 1 + except IOError: + pass + + def nested_func(): + if True: + for i in range(10): + while True: + if True: + if True: + yield i + + nested_func() + +def more_complex_function(): + attr1 = attr2 = attr3 = [1, 2, 3] + if attr1: + for i in attr1: + if attr2: + return i + else: + return 'duh' + elif attr2: + for i in attr2: + if attr2: + return i + else: + return 'duh' + else: + for i in range(15): + if attr3: + return i + else: + return 'doh' + return None + +def elif_function(): + arg = None + if arg == 1: + return 1 + elif arg == 2: + return 2 + elif arg == 3: + return 3 + elif arg == 4: + return 4 + elif arg == 5: + return 5 + elif arg == 6: + return 6 + elif arg == 7: + return 7 + return None + +def else_if_function(): + arg = None + if arg == 1: # [too-many-nested-blocks] + return 1 + else: + if arg == 2: + return 2 + else: + if arg == 3: + return 3 + else: + if arg == 4: + return 4 + else: + if arg == 5: + return 5 + else: + if arg == 6: + return 6 + else: + if arg == 7: + return 7 + return None diff --git a/tests/functional/t/too/too_many_nested_blocks.txt b/tests/functional/t/too/too_many_nested_blocks.txt new file mode 100644 index 000000000..6232b9ff0 --- /dev/null +++ b/tests/functional/t/too/too_many_nested_blocks.txt @@ -0,0 +1,2 @@ +too-many-nested-blocks:6:4:my_function:Too many nested blocks (6/5) +too-many-nested-blocks:77:4:else_if_function:Too many nested blocks (7/5) diff --git a/tests/functional/t/too/too_many_public_methods.py b/tests/functional/t/too/too_many_public_methods.py new file mode 100644 index 000000000..11b4b367d --- /dev/null +++ b/tests/functional/t/too/too_many_public_methods.py @@ -0,0 +1,79 @@ +# pylint: disable=missing-docstring, useless-object-inheritance + +class Aaaa(object): # [too-many-public-methods] + + def __init__(self): + pass + + def meth1(self): + """hehehe""" + + def meth2(self): + """hehehe""" + + def meth3(self): + """hehehe""" + + def meth4(self): + """hehehe""" + + def meth5(self): + """hehehe""" + + def meth6(self): + """hehehe""" + + def meth7(self): + """hehehe""" + + def meth8(self): + """hehehe""" + + def meth9(self): + """hehehe""" + + def meth10(self): + """hehehe""" + + def meth11(self): + """hehehe""" + + def meth12(self): + """hehehe""" + + def meth13(self): + """hehehe""" + + def meth14(self): + """hehehe""" + + def meth15(self): + """hehehe""" + + def meth16(self): + """hehehe""" + + def meth17(self): + """hehehe""" + + def meth18(self): + """hehehe""" + + def meth19(self): + """hehehe""" + + def meth20(self): + """hehehe""" + + def meth21(self): + """hehehe""" + + def _dontcount(self): + """not public""" + +class BBB(Aaaa): + """Don't emit for methods defined in the parent.""" + def meth1(self): + """trop""" + def meth2(self): + """tzop""" diff --git a/tests/functional/t/too/too_many_public_methods.txt b/tests/functional/t/too/too_many_public_methods.txt new file mode 100644 index 000000000..61e47e8eb --- /dev/null +++ b/tests/functional/t/too/too_many_public_methods.txt @@ -0,0 +1 @@ +too-many-public-methods:3:0:Aaaa:Too many public methods (21/20) diff --git a/tests/functional/t/too/too_many_return_statements.py b/tests/functional/t/too/too_many_return_statements.py new file mode 100644 index 000000000..66a85da40 --- /dev/null +++ b/tests/functional/t/too/too_many_return_statements.py @@ -0,0 +1,40 @@ +# pylint: disable=missing-docstring + +def stupid_function(arg): # [too-many-return-statements] + if arg == 1: + return 1 + if arg == 2: + return 2 + if arg == 3: + return 3 + if arg == 4: + return 4 + if arg == 5: + return 5 + if arg == 6: + return 6 + if arg == 7: + return 7 + if arg == 8: + return 8 + if arg == 9: + return 9 + if arg == 10: + return 10 + return None + + +def many_yield(text): + """Not a problem""" + if text: + yield " line 1: %s\n" % text + yield " line 2\n" + yield " line 3\n" + yield " line 4\n" + yield " line 5\n" + else: + yield " line 6\n" + yield " line 7\n" + yield " line 8\n" + yield " line 9\n" + yield " line 10\n" diff --git a/tests/functional/t/too/too_many_return_statements.txt b/tests/functional/t/too/too_many_return_statements.txt new file mode 100644 index 000000000..5abbb71b3 --- /dev/null +++ b/tests/functional/t/too/too_many_return_statements.txt @@ -0,0 +1 @@ +too-many-return-statements:3:0:stupid_function:Too many return statements (11/6) diff --git a/tests/functional/t/too/too_many_star_expressions.py b/tests/functional/t/too/too_many_star_expressions.py new file mode 100644 index 000000000..c1bbfb9d3 --- /dev/null +++ b/tests/functional/t/too/too_many_star_expressions.py @@ -0,0 +1,7 @@ +"""Test for too-many-star-expressions.""" +# pylint: disable=unbalanced-tuple-unpacking +*FIRST, *SECOND = [1, 2, 3] # [too-many-star-expressions] +(FIRST, *SECOND), *THIRD = ((1, 2, 3), 4, 5) +*FIRST_1, SECOND = (1, 2, 3) +(*FIRST, *SECOND), THIRD = [...] # [too-many-star-expressions] +((*FIRST, SECOND), *THIRD), *FOURTH = [...] diff --git a/tests/functional/t/too/too_many_star_expressions.rc b/tests/functional/t/too/too_many_star_expressions.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/t/too/too_many_star_expressions.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/t/too/too_many_star_expressions.txt b/tests/functional/t/too/too_many_star_expressions.txt new file mode 100644 index 000000000..d1e74b624 --- /dev/null +++ b/tests/functional/t/too/too_many_star_expressions.txt @@ -0,0 +1,2 @@ +too-many-star-expressions:3:0::More than one starred expression in assignment +too-many-star-expressions:6:0::More than one starred expression in assignment diff --git a/tests/functional/t/too/too_many_statements.py b/tests/functional/t/too/too_many_statements.py new file mode 100644 index 000000000..b3e2fd796 --- /dev/null +++ b/tests/functional/t/too/too_many_statements.py @@ -0,0 +1,125 @@ +# pylint: disable=missing-docstring + +from __future__ import print_function + +def stupid_function(arg): # [too-many-statements] + if arg == 1: + print(1) + elif arg == 2: + print(1) + elif arg == 3: + print(1) + elif arg == 4: + print(1) + elif arg == 5: + print(1) + elif arg == 6: + print(1) + elif arg == 7: + print(1) + elif arg == 8: + print(1) + elif arg == 9: + print(1) + elif arg == 10: + print(1) + elif arg < 1: + print(1) + print(1) + arg = 0 + for _ in range(arg): + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + +def long_function_with_inline_def(fake): # [too-many-statements] + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + def an_inline_function(var): + return var + var + fake = an_inline_function(fake) + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 diff --git a/tests/functional/t/too/too_many_statements.txt b/tests/functional/t/too/too_many_statements.txt new file mode 100644 index 000000000..c48f14e50 --- /dev/null +++ b/tests/functional/t/too/too_many_statements.txt @@ -0,0 +1,2 @@ +too-many-statements:5:0:stupid_function:Too many statements (55/50) +too-many-statements:62:0:long_function_with_inline_def:Too many statements (62/50) diff --git a/tests/functional/too/__init__.py b/tests/functional/too/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/functional/too/too_few_public_methods.py b/tests/functional/too/too_few_public_methods.py deleted file mode 100644 index 5ba528f79..000000000 --- a/tests/functional/too/too_few_public_methods.py +++ /dev/null @@ -1,50 +0,0 @@ -# pylint: disable=missing-docstring, useless-object-inheritance -from __future__ import print_function - - -from enum import Enum - - -class Aaaa(object): # [too-few-public-methods] - - def __init__(self): - pass - - def meth1(self): - print(self) - - def _dontcount(self): - print(self) - - -# Don't emit for these cases. -class Klass(object): - """docstring""" - - def meth1(self): - """first""" - - def meth2(self): - """second""" - - -class EnoughPublicMethods(Klass): - """We shouldn't emit too-few-public-methods for this.""" - - -class BossMonster(Enum): - """An enum does not need methods to be useful.""" - MEGASHARK = 1 - OCTOPUS = 2 - - -class DumbList: - """A class can define only special methods.""" - def __init__(self, iterable): - self._list = list(iterable) - - def __len__(self): - return len(self._list) - - def __getitem__(self, index): - return self._list[index] diff --git a/tests/functional/too/too_few_public_methods.txt b/tests/functional/too/too_few_public_methods.txt deleted file mode 100644 index a86ba6d81..000000000 --- a/tests/functional/too/too_few_public_methods.txt +++ /dev/null @@ -1 +0,0 @@ -too-few-public-methods:8:0:Aaaa:Too few public methods (1/2) diff --git a/tests/functional/too/too_few_public_methods_37.py b/tests/functional/too/too_few_public_methods_37.py deleted file mode 100644 index 55fc54484..000000000 --- a/tests/functional/too/too_few_public_methods_37.py +++ /dev/null @@ -1,37 +0,0 @@ -# pylint: disable=missing-docstring -import dataclasses -import typing -from dataclasses import dataclass - - -@dataclasses.dataclass -class ScheduledTxSearchModel: - date_from = None - date_to = None - - -@dataclass -class ScheduledTxSearchModelOne: - date = None - - -@dataclass(frozen=True) -class Test: - some_integer: int - - -class Example(typing.NamedTuple): - some_int: int - - -@dataclasses.dataclass(frozen=True) -class Point: - """A three dimensional point with x, y and z components.""" - - attr1: float - attr2: float - attr3: float - - def to_array(self): - """Convert to a NumPy array `np.array((x, y, z))`.""" - return self.attr1 diff --git a/tests/functional/too/too_few_public_methods_37.rc b/tests/functional/too/too_few_public_methods_37.rc deleted file mode 100644 index a17bb22da..000000000 --- a/tests/functional/too/too_few_public_methods_37.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.7 diff --git a/tests/functional/too/too_many_ancestors.py b/tests/functional/too/too_many_ancestors.py deleted file mode 100644 index a0ae18a02..000000000 --- a/tests/functional/too/too_many_ancestors.py +++ /dev/null @@ -1,24 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance - -class Aaaa(object): - pass -class Bbbb(object): - pass -class Cccc(object): - pass -class Dddd(object): - pass -class Eeee(object): - pass -class Ffff(object): - pass -class Gggg(object): - pass -class Hhhh(object): - pass - -class Iiii(Aaaa, Bbbb, Cccc, Dddd, Eeee, Ffff, Gggg, Hhhh): # [too-many-ancestors] - pass - -class Jjjj(Iiii): # [too-many-ancestors] - pass diff --git a/tests/functional/too/too_many_ancestors.txt b/tests/functional/too/too_many_ancestors.txt deleted file mode 100644 index 97c954368..000000000 --- a/tests/functional/too/too_many_ancestors.txt +++ /dev/null @@ -1,2 +0,0 @@ -too-many-ancestors:20:0:Iiii:Too many ancestors (9/7) -too-many-ancestors:23:0:Jjjj:Too many ancestors (10/7) diff --git a/tests/functional/too/too_many_arguments.py b/tests/functional/too/too_many_arguments.py deleted file mode 100644 index 689745e27..000000000 --- a/tests/functional/too/too_many_arguments.py +++ /dev/null @@ -1,32 +0,0 @@ -# pylint: disable=missing-docstring,wrong-import-position - -def stupid_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9): # [too-many-arguments] - return arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 - - -class MyClass: - text = "MyText" - - def mymethod1(self): - return self.text - - def mymethod2(self): - return self.mymethod1.__get__(self, MyClass) - - -MyClass().mymethod2()() - - -# Check a false positive does not occur -from functools import partial - - -def root_function(first, second, third): - return first + second + third - - -def func_call(): - """Test we don't emit a FP for https://github.com/PyCQA/pylint/issues/2588""" - partial_func = partial(root_function, 1, 2, 3) - partial_func() - return root_function(1, 2, 3) diff --git a/tests/functional/too/too_many_arguments.txt b/tests/functional/too/too_many_arguments.txt deleted file mode 100644 index d4f551634..000000000 --- a/tests/functional/too/too_many_arguments.txt +++ /dev/null @@ -1 +0,0 @@ -too-many-arguments:3:0:stupid_function:Too many arguments (9/5) diff --git a/tests/functional/too/too_many_arguments_issue_1045.py b/tests/functional/too/too_many_arguments_issue_1045.py deleted file mode 100644 index e5aa76d75..000000000 --- a/tests/functional/too/too_many_arguments_issue_1045.py +++ /dev/null @@ -1,13 +0,0 @@ -# pylint: disable=missing-docstring - -# pylint: disable=unused-import, undefined-variable; false positives :-( - -import functools - - -@functools.lru_cache() -def func(): - pass - - -func.cache_clear() diff --git a/tests/functional/too/too_many_arguments_issue_1045.rc b/tests/functional/too/too_many_arguments_issue_1045.rc deleted file mode 100644 index d425e7c47..000000000 --- a/tests/functional/too/too_many_arguments_issue_1045.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.2 diff --git a/tests/functional/too/too_many_arguments_overload.py b/tests/functional/too/too_many_arguments_overload.py deleted file mode 100644 index 1155deb0c..000000000 --- a/tests/functional/too/too_many_arguments_overload.py +++ /dev/null @@ -1,38 +0,0 @@ -# pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring -# pylint: disable=too-few-public-methods -from typing import overload - - -class ClassA: - @classmethod - @overload - def method(cls, arg1): - pass - - @classmethod - @overload - def method(cls, arg1, arg2): - pass - - @classmethod - def method(cls, arg1, arg2=None): - pass - - -ClassA.method(1, 2) - - -class ClassB: - @overload - def method(self, arg1): - pass - - @overload - def method(self, arg1, arg2): - pass - - def method(self, arg1, arg2=None): - pass - - -ClassB().method(1, arg2=2) diff --git a/tests/functional/too/too_many_boolean_expressions.py b/tests/functional/too/too_many_boolean_expressions.py deleted file mode 100644 index e8753859c..000000000 --- a/tests/functional/too/too_many_boolean_expressions.py +++ /dev/null @@ -1,20 +0,0 @@ -"""Checks for if statements containing too many boolean expressions""" - -# pylint: disable=invalid-name, comparison-with-itself, chained-comparison, condition-evals-to-constant - -x = y = z = 5 -if x > -5 and x < 5 and y > -5 and y < 5 and z > -5 and z < 5: # [too-many-boolean-expressions] - pass -elif True and False and 1 and 2 and 3: - pass -elif True and False and 1 and 2 and 3 and 4 and 5: # [too-many-boolean-expressions] - pass -elif True and (True and True) and (x == 5 or True or True): # [too-many-boolean-expressions] - pass -elif True and (True or (x > -5 and x < 5 and (z > -5 or z < 5))): # [too-many-boolean-expressions] - pass -elif True == True == True == True == True == True: - pass - -if True and False and 1 and 2 and 3: - pass diff --git a/tests/functional/too/too_many_boolean_expressions.txt b/tests/functional/too/too_many_boolean_expressions.txt deleted file mode 100644 index 6055e7437..000000000 --- a/tests/functional/too/too_many_boolean_expressions.txt +++ /dev/null @@ -1,4 +0,0 @@ -too-many-boolean-expressions:6:3::Too many boolean expressions in if statement (6/5) -too-many-boolean-expressions:10:5::Too many boolean expressions in if statement (7/5) -too-many-boolean-expressions:12:5::Too many boolean expressions in if statement (6/5) -too-many-boolean-expressions:14:5::Too many boolean expressions in if statement (6/5) diff --git a/tests/functional/too/too_many_branches.py b/tests/functional/too/too_many_branches.py deleted file mode 100644 index 7b0b068ad..000000000 --- a/tests/functional/too/too_many_branches.py +++ /dev/null @@ -1,69 +0,0 @@ -""" Test for too many branches. """ -# pylint: disable=using-constant-test -def wrong(): # [too-many-branches] - """ Has too many branches. """ - if 1: - pass - elif 1: - pass - elif 1: - pass - elif 1: - pass - elif 1: - pass - elif 1: - pass - try: - pass - finally: - pass - if 2: - pass - while True: - pass - if 1: - pass - elif 2: - pass - elif 3: - pass - -def good(): - """ Too many branches only if we take - into consideration the nested functions. - """ - def nested_1(): - """ empty """ - if 1: - pass - elif 2: - pass - elif 3: - pass - elif 4: - pass - - nested_1() - try: - pass - finally: - pass - try: - pass - finally: - pass - if 1: - pass - elif 2: - pass - elif 3: - pass - elif 4: - pass - elif 5: - pass - elif 6: - pass - elif 7: - pass diff --git a/tests/functional/too/too_many_branches.txt b/tests/functional/too/too_many_branches.txt deleted file mode 100644 index e5bfd4d49..000000000 --- a/tests/functional/too/too_many_branches.txt +++ /dev/null @@ -1 +0,0 @@ -too-many-branches:3:0:wrong:Too many branches (13/12) diff --git a/tests/functional/too/too_many_instance_attributes.py b/tests/functional/too/too_many_instance_attributes.py deleted file mode 100644 index f6703e0b7..000000000 --- a/tests/functional/too/too_many_instance_attributes.py +++ /dev/null @@ -1,26 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance - -class Aaaa(object): # [too-many-instance-attributes] - - def __init__(self): - self.aaaa = 1 - self.bbbb = 2 - self.cccc = 3 - self.dddd = 4 - self.eeee = 5 - self.ffff = 6 - self.gggg = 7 - self.hhhh = 8 - self.iiii = 9 - self.jjjj = 10 - self._aaaa = 1 - self._bbbb = 2 - self._cccc = 3 - self._dddd = 4 - self._eeee = 5 - self._ffff = 6 - self._gggg = 7 - self._hhhh = 8 - self._iiii = 9 - self._jjjj = 10 - self.tomuch = None diff --git a/tests/functional/too/too_many_instance_attributes.txt b/tests/functional/too/too_many_instance_attributes.txt deleted file mode 100644 index 42c85493c..000000000 --- a/tests/functional/too/too_many_instance_attributes.txt +++ /dev/null @@ -1 +0,0 @@ -too-many-instance-attributes:3:0:Aaaa:Too many instance attributes (21/7) diff --git a/tests/functional/too/too_many_lines.py b/tests/functional/too/too_many_lines.py deleted file mode 100644 index 78e568c23..000000000 --- a/tests/functional/too/too_many_lines.py +++ /dev/null @@ -1,1015 +0,0 @@ -# pylint: disable=missing-docstring -# -1: [too-many-lines] -__revision__ = 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ZERFZAER = 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -HEHEHE = 2 diff --git a/tests/functional/too/too_many_lines.txt b/tests/functional/too/too_many_lines.txt deleted file mode 100644 index 5c228ac49..000000000 --- a/tests/functional/too/too_many_lines.txt +++ /dev/null @@ -1 +0,0 @@ -too-many-lines:1:0::Too many lines in module (1015/1000) diff --git a/tests/functional/too/too_many_lines_disabled.py b/tests/functional/too/too_many_lines_disabled.py deleted file mode 100644 index 1b0866db2..000000000 --- a/tests/functional/too/too_many_lines_disabled.py +++ /dev/null @@ -1,1018 +0,0 @@ -"""Test that disabling too-many-lines on any line works.""" - - - -# pylint: disable=too-many-lines -__revision__ = 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ZERFZAER = 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -HEHEHE = 2 diff --git a/tests/functional/too/too_many_locals.py b/tests/functional/too/too_many_locals.py deleted file mode 100644 index ac38a9e01..000000000 --- a/tests/functional/too/too_many_locals.py +++ /dev/null @@ -1,60 +0,0 @@ -# pylint: disable=missing-docstring -from __future__ import print_function - -def function(arg1, arg2, arg3, arg4, arg5): # [too-many-locals] - arg6, arg7, arg8, arg9 = arg1, arg2, arg3, arg4 - print(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) - loc1, loc2, loc3, loc4, loc5, loc6, loc7 = arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 - print(loc1, loc2, loc3, loc4, loc5, loc6, loc7) - - -def too_many_locals_function(): # [too-many-locals] - """pylint will complains about too many local variables""" - args0 = 0 - args1 = args0 * 1 - args2 = args1 * 2 - args3 = args2 * 3 - args4 = args3 * 4 - args5 = args4 * 5 - args6 = args5 * 6 - args7 = args6 * 7 - args8 = args7 * 8 - args9 = args8 * 9 - args10 = args9 * 10 - args11 = args10 * 11 - args12 = args11 * 12 - args13 = args12 * 13 - args14 = args13 * 14 - args15 = args14 * 15 - return args15 - -def too_many_arguments_function(arga, argu, argi, arge, argt, args): # [too-many-arguments] - """pylint will complains about too many arguments.""" - arga = argu - arga += argi - arga += arge - arga += argt - arga += args - return arga - -def ignored_arguments_function(arga, argu, argi, - _arge=0, _argt=1, _args=None): - """pylint will ignore _arge, _argt, _args. - - Consequently pylint will only coun 13 arguments. - """ - arg0 = 0 - arg1 = arg0 * 1 + arga - arg2 = arg1 * 2 + argu - arg3 = arg2 * 3 + argi - arg4 = arg3 * 4 + _arge - arg5 = arg4 * 5 + _argt - arg6 = arg5 * 6 - arg7 = arg6 * 7 - arg8 = arg7 * 8 - arg9 = arg8 * 9 - arg9 += arg0 - if _args: - arg9 += sum(_args) - return arg9 diff --git a/tests/functional/too/too_many_locals.txt b/tests/functional/too/too_many_locals.txt deleted file mode 100644 index 4af7f0307..000000000 --- a/tests/functional/too/too_many_locals.txt +++ /dev/null @@ -1,3 +0,0 @@ -too-many-locals:4:0:function:Too many local variables (16/15) -too-many-locals:12:0:too_many_locals_function:Too many local variables (16/15) -too-many-arguments:32:0:too_many_arguments_function:Too many arguments (6/5) diff --git a/tests/functional/too/too_many_nested_blocks.py b/tests/functional/too/too_many_nested_blocks.py deleted file mode 100644 index e7c007957..000000000 --- a/tests/functional/too/too_many_nested_blocks.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Checks the maximum block level is smaller than 6 in function definitions""" - -#pylint: disable=using-constant-test, missing-docstring, too-many-return-statements,no-else-return - -def my_function(): - if 1: # [too-many-nested-blocks] - for i in range(10): - if i == 2: - while True: - try: - if True: - i += 1 - except IOError: - pass - - if 1: - for i in range(10): - if i == 2: - while True: - try: - i += 1 - except IOError: - pass - - def nested_func(): - if True: - for i in range(10): - while True: - if True: - if True: - yield i - - nested_func() - -def more_complex_function(): - attr1 = attr2 = attr3 = [1, 2, 3] - if attr1: - for i in attr1: - if attr2: - return i - else: - return 'duh' - elif attr2: - for i in attr2: - if attr2: - return i - else: - return 'duh' - else: - for i in range(15): - if attr3: - return i - else: - return 'doh' - return None - -def elif_function(): - arg = None - if arg == 1: - return 1 - elif arg == 2: - return 2 - elif arg == 3: - return 3 - elif arg == 4: - return 4 - elif arg == 5: - return 5 - elif arg == 6: - return 6 - elif arg == 7: - return 7 - return None - -def else_if_function(): - arg = None - if arg == 1: # [too-many-nested-blocks] - return 1 - else: - if arg == 2: - return 2 - else: - if arg == 3: - return 3 - else: - if arg == 4: - return 4 - else: - if arg == 5: - return 5 - else: - if arg == 6: - return 6 - else: - if arg == 7: - return 7 - return None diff --git a/tests/functional/too/too_many_nested_blocks.txt b/tests/functional/too/too_many_nested_blocks.txt deleted file mode 100644 index 6232b9ff0..000000000 --- a/tests/functional/too/too_many_nested_blocks.txt +++ /dev/null @@ -1,2 +0,0 @@ -too-many-nested-blocks:6:4:my_function:Too many nested blocks (6/5) -too-many-nested-blocks:77:4:else_if_function:Too many nested blocks (7/5) diff --git a/tests/functional/too/too_many_public_methods.py b/tests/functional/too/too_many_public_methods.py deleted file mode 100644 index 11b4b367d..000000000 --- a/tests/functional/too/too_many_public_methods.py +++ /dev/null @@ -1,79 +0,0 @@ -# pylint: disable=missing-docstring, useless-object-inheritance - -class Aaaa(object): # [too-many-public-methods] - - def __init__(self): - pass - - def meth1(self): - """hehehe""" - - def meth2(self): - """hehehe""" - - def meth3(self): - """hehehe""" - - def meth4(self): - """hehehe""" - - def meth5(self): - """hehehe""" - - def meth6(self): - """hehehe""" - - def meth7(self): - """hehehe""" - - def meth8(self): - """hehehe""" - - def meth9(self): - """hehehe""" - - def meth10(self): - """hehehe""" - - def meth11(self): - """hehehe""" - - def meth12(self): - """hehehe""" - - def meth13(self): - """hehehe""" - - def meth14(self): - """hehehe""" - - def meth15(self): - """hehehe""" - - def meth16(self): - """hehehe""" - - def meth17(self): - """hehehe""" - - def meth18(self): - """hehehe""" - - def meth19(self): - """hehehe""" - - def meth20(self): - """hehehe""" - - def meth21(self): - """hehehe""" - - def _dontcount(self): - """not public""" - -class BBB(Aaaa): - """Don't emit for methods defined in the parent.""" - def meth1(self): - """trop""" - def meth2(self): - """tzop""" diff --git a/tests/functional/too/too_many_public_methods.txt b/tests/functional/too/too_many_public_methods.txt deleted file mode 100644 index 61e47e8eb..000000000 --- a/tests/functional/too/too_many_public_methods.txt +++ /dev/null @@ -1 +0,0 @@ -too-many-public-methods:3:0:Aaaa:Too many public methods (21/20) diff --git a/tests/functional/too/too_many_return_statements.py b/tests/functional/too/too_many_return_statements.py deleted file mode 100644 index 66a85da40..000000000 --- a/tests/functional/too/too_many_return_statements.py +++ /dev/null @@ -1,40 +0,0 @@ -# pylint: disable=missing-docstring - -def stupid_function(arg): # [too-many-return-statements] - if arg == 1: - return 1 - if arg == 2: - return 2 - if arg == 3: - return 3 - if arg == 4: - return 4 - if arg == 5: - return 5 - if arg == 6: - return 6 - if arg == 7: - return 7 - if arg == 8: - return 8 - if arg == 9: - return 9 - if arg == 10: - return 10 - return None - - -def many_yield(text): - """Not a problem""" - if text: - yield " line 1: %s\n" % text - yield " line 2\n" - yield " line 3\n" - yield " line 4\n" - yield " line 5\n" - else: - yield " line 6\n" - yield " line 7\n" - yield " line 8\n" - yield " line 9\n" - yield " line 10\n" diff --git a/tests/functional/too/too_many_return_statements.txt b/tests/functional/too/too_many_return_statements.txt deleted file mode 100644 index 5abbb71b3..000000000 --- a/tests/functional/too/too_many_return_statements.txt +++ /dev/null @@ -1 +0,0 @@ -too-many-return-statements:3:0:stupid_function:Too many return statements (11/6) diff --git a/tests/functional/too/too_many_star_expressions.py b/tests/functional/too/too_many_star_expressions.py deleted file mode 100644 index c1bbfb9d3..000000000 --- a/tests/functional/too/too_many_star_expressions.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Test for too-many-star-expressions.""" -# pylint: disable=unbalanced-tuple-unpacking -*FIRST, *SECOND = [1, 2, 3] # [too-many-star-expressions] -(FIRST, *SECOND), *THIRD = ((1, 2, 3), 4, 5) -*FIRST_1, SECOND = (1, 2, 3) -(*FIRST, *SECOND), THIRD = [...] # [too-many-star-expressions] -((*FIRST, SECOND), *THIRD), *FOURTH = [...] diff --git a/tests/functional/too/too_many_star_expressions.rc b/tests/functional/too/too_many_star_expressions.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/too/too_many_star_expressions.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/too/too_many_star_expressions.txt b/tests/functional/too/too_many_star_expressions.txt deleted file mode 100644 index d1e74b624..000000000 --- a/tests/functional/too/too_many_star_expressions.txt +++ /dev/null @@ -1,2 +0,0 @@ -too-many-star-expressions:3:0::More than one starred expression in assignment -too-many-star-expressions:6:0::More than one starred expression in assignment diff --git a/tests/functional/too/too_many_statements.py b/tests/functional/too/too_many_statements.py deleted file mode 100644 index b3e2fd796..000000000 --- a/tests/functional/too/too_many_statements.py +++ /dev/null @@ -1,125 +0,0 @@ -# pylint: disable=missing-docstring - -from __future__ import print_function - -def stupid_function(arg): # [too-many-statements] - if arg == 1: - print(1) - elif arg == 2: - print(1) - elif arg == 3: - print(1) - elif arg == 4: - print(1) - elif arg == 5: - print(1) - elif arg == 6: - print(1) - elif arg == 7: - print(1) - elif arg == 8: - print(1) - elif arg == 9: - print(1) - elif arg == 10: - print(1) - elif arg < 1: - print(1) - print(1) - arg = 0 - for _ in range(arg): - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - print(1) - -def long_function_with_inline_def(fake): # [too-many-statements] - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - def an_inline_function(var): - return var + var - fake = an_inline_function(fake) - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 - fake += 1 diff --git a/tests/functional/too/too_many_statements.txt b/tests/functional/too/too_many_statements.txt deleted file mode 100644 index c48f14e50..000000000 --- a/tests/functional/too/too_many_statements.txt +++ /dev/null @@ -1,2 +0,0 @@ -too-many-statements:5:0:stupid_function:Too many statements (55/50) -too-many-statements:62:0:long_function_with_inline_def:Too many statements (62/50) diff --git a/tests/functional/u/undefined/undefined_loop_variable.py b/tests/functional/u/undefined/undefined_loop_variable.py new file mode 100644 index 000000000..a984898f8 --- /dev/null +++ b/tests/functional/u/undefined/undefined_loop_variable.py @@ -0,0 +1,75 @@ +# pylint: disable=missing-docstring,redefined-builtin + +def do_stuff(some_random_list): + for var in some_random_list: + pass + return var # [undefined-loop-variable] + + +def do_else(some_random_list): + for var in some_random_list: + if var == 42: + break + else: + var = 84 + return var + +__revision__ = 'yo' + +TEST_LC = [C for C in __revision__ if C.isalpha()] +B = [B for B in __revision__ if B.isalpha()] +VAR2 = B # nor this one + +for var1, var2 in TEST_LC: + var1 = var2 + 4 +VAR3 = var1 # [undefined-loop-variable] + +for note in __revision__: + note.something() +for line in __revision__: + for note in line: + A = note.anotherthing() + + +for x in []: + pass +for x in range(3): + VAR5 = (lambda: x)() + + +def do_stuff_with_a_list(): + for var in [1, 2, 3]: + pass + return var + + +def do_stuff_with_a_set(): + for var in {1, 2, 3}: + pass + return var + + +def do_stuff_with_a_dict(): + for var in {1: 2, 3: 4}: + pass + return var + + +def do_stuff_with_a_tuple(): + for var in (1, 2, 3): + pass + return var + + +def do_stuff_with_a_range(): + for var in range(1, 2): + pass + return var + + +def do_stuff_with_redefined_range(): + def range(key): + yield from [1, key] + for var in range(3): + pass + return var # [undefined-loop-variable] diff --git a/tests/functional/u/undefined/undefined_loop_variable.txt b/tests/functional/u/undefined/undefined_loop_variable.txt new file mode 100644 index 000000000..ea194e769 --- /dev/null +++ b/tests/functional/u/undefined/undefined_loop_variable.txt @@ -0,0 +1,3 @@ +undefined-loop-variable:6:11:do_stuff:Using possibly undefined loop variable 'var' +undefined-loop-variable:25:7::Using possibly undefined loop variable 'var1' +undefined-loop-variable:75:11:do_stuff_with_redefined_range:Using possibly undefined loop variable 'var' diff --git a/tests/functional/u/undefined/undefined_variable.py b/tests/functional/u/undefined/undefined_variable.py new file mode 100644 index 000000000..7fe205cc9 --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable.py @@ -0,0 +1,296 @@ +# pylint: disable=missing-docstring, multiple-statements, useless-object-inheritance,import-outside-toplevel +# pylint: disable=too-few-public-methods, no-init, no-self-use,bare-except,broad-except, import-error +from __future__ import print_function + +# pylint: disable=wrong-import-position +from typing import TYPE_CHECKING + +DEFINED = 1 + +if DEFINED != 1: + if DEFINED in (unknown, DEFINED): # [undefined-variable] + DEFINED += 1 + + +def in_method(var): + """method doc""" + var = nomoreknown # [undefined-variable] + assert var + +DEFINED = {DEFINED:__revision__} # [undefined-variable] +# +1:[undefined-variable] +DEFINED[__revision__] = OTHER = 'move this is astroid test' + +OTHER += '$' + +def bad_default(var, default=unknown2): # [undefined-variable] + """function with defaut arg's value set to an unexistant name""" + print(var, default) + print(xxxx) # [undefined-variable] + augvar += 1 # [undefined-variable] + del vardel # [undefined-variable] + +LMBD = lambda x, y=doesnotexist: x+y # [undefined-variable] +LMBD2 = lambda x, y: x+z # [undefined-variable] + +try: + POUET # don't catch me +except NameError: + POUET = 'something' + +try: + POUETT # [used-before-assignment] +except Exception: # pylint:disable = broad-except + POUETT = 'something' + +try: + POUETTT # don't catch me +except: # pylint:disable = bare-except + POUETTT = 'something' + +print(POUET, POUETT, POUETTT) + + +try: + PLOUF # [used-before-assignment] +except ValueError: + PLOUF = 'something' + +print(PLOUF) + +def if_branch_test(something): + """hop""" + if something == 0: + if xxx == 1: # [used-before-assignment] + pass + else: + print(xxx) + xxx = 3 + + +def decorator(arg): + """Decorator with one argument.""" + return lambda: list(arg) + + +@decorator(arg=[i * 2 for i in range(15)]) +def func1(): + """A function with a decorator that contains a listcomp.""" + +@decorator(arg=(i * 2 for i in range(15))) +def func2(): + """A function with a decorator that contains a genexpr.""" + +@decorator(lambda x: x > 0) +def main(): + """A function with a decorator that contains a lambda.""" + +# Test shared scope. + +def test_arguments(arg=TestClass): # [used-before-assignment] + """ TestClass isn't defined yet. """ + return arg + +class TestClass(Ancestor): # [used-before-assignment] + """ contains another class, which uses an undefined ancestor. """ + + class MissingAncestor(Ancestor1): # [used-before-assignment] + """ no op """ + + def test1(self): + """ It should trigger here, because the two classes + have the same scope. + """ + class UsingBeforeDefinition(Empty): # [used-before-assignment] + """ uses Empty before definition """ + class Empty(object): + """ no op """ + return UsingBeforeDefinition + + def test(self): + """ Ancestor isn't defined yet, but we don't care. """ + class MissingAncestor1(Ancestor): + """ no op """ + return MissingAncestor1 + +class Self(object): + """ Detect when using the same name inside the class scope. """ + obj = Self # [undefined-variable] + +class Self1(object): + """ No error should be raised here. """ + + def test(self): + """ empty """ + return Self1 + + +class Ancestor(object): + """ No op """ + +class Ancestor1(object): + """ No op """ + +NANA = BAT # [undefined-variable] +del BAT + + +class KeywordArgument(object): + """Test keyword arguments.""" + + enable = True + def test(self, is_enabled=enable): + """do nothing.""" + + def test1(self, is_enabled=enabled): # [used-before-assignment] + """enabled is undefined at this point, but it is used before assignment.""" + + def test2(self, is_disabled=disabled): # [undefined-variable] + """disabled is undefined""" + + enabled = True + + func = lambda arg=arg: arg * arg # [undefined-variable] + + arg2 = 0 + func2 = lambda arg2=arg2: arg2 * arg2 + +# Don't emit if the code is protected by NameError +try: + unicode_1 +except NameError: + pass + +try: + unicode_2 # [undefined-variable] +except Exception: + pass + +try: + unicode_3 # [undefined-variable] +except ValueError: + pass + +# See https://bitbucket.org/logilab/pylint/issue/111/ +try: raise IOError(1, "a") +except IOError as err: print(err) + + +def test_conditional_comprehension(): + methods = ['a', 'b', '_c', '_d'] + my_methods = sum(1 for method in methods + if not method.startswith('_')) + return my_methods + + +class MyError(object): + pass + + +class MyClass(object): + class MyError(MyError): + pass + + +def dec(inp): + def inner(func): + print(inp) + return func + return inner + +# Make sure lambdas with expressions +# referencing parent class do not raise undefined variable +# because at the time of their calling, the class name will +# be populated +# See https://github.com/PyCQA/pylint/issues/704 +class LambdaClass: + myattr = 1 + mylambda = lambda: LambdaClass.myattr + +# Need different classes to make sure +# consumed variables don't get in the way +class LambdaClass2: + myattr = 1 + # Different base_scope scope but still applies + mylambda2 = lambda: [LambdaClass2.myattr for _ in [1, 2]] + +class LambdaClass3: + myattr = 1 + # Nested default argument in lambda + # Should not raise error + mylambda3 = lambda: lambda a=LambdaClass3: a + +class LambdaClass4: + myattr = 1 + mylambda4 = lambda a=LambdaClass4: lambda: a # [undefined-variable] + +# Make sure the first lambda does not consume the LambdaClass5 class +# name although the expression is is valid +# Consuming the class would cause the subsequent undefined-variable to be masked +class LambdaClass5: + myattr = 1 + mylambda = lambda: LambdaClass5.myattr + mylambda4 = lambda a=LambdaClass5: lambda: a # [undefined-variable] + + +def nonlocal_in_ifexp(): + import matplotlib.pyplot as plt + def onclick(event): + if event: + nonlocal i + i += 1 + print(i) + i = 0 + fig = plt.figure() + fig.canvas.mpl_connect('button_press_event', onclick) + plt.show(block=True) + + + +if TYPE_CHECKING: + from datetime import datetime + + +def func_should_fail(_dt: datetime): # [used-before-assignment] + pass + + +# The following should not emit an error. +# pylint: disable=invalid-name +if TYPE_CHECKING: + from typing_extensions import Literal + + AllowedValues = Literal['hello', 'world'] + + +if TYPE_CHECKING: + from collections import Counter + from collections import OrderedDict +else: + Counter = object + OrderedDict = object + + +def tick(counter: Counter, name: str, dictionary: OrderedDict) -> OrderedDict: + counter[name] += 1 + return dictionary + + +# pylint: disable=unused-argument +def not_using_loop_variable_accordingly(iterator): + for iteree in iteree: # [undefined-variable] + yield iteree +# pylint: enable=unused-argument + + +class DunderClass: + def method(self): + # This name is not defined in the AST but it's present at runtime + return __class__ + + +def undefined_annotation(a:x): # [undefined-variable] + if x == 2: # [used-before-assignment] + for x in [1, 2]: + pass + return a diff --git a/tests/functional/u/undefined/undefined_variable.txt b/tests/functional/u/undefined/undefined_variable.txt new file mode 100644 index 000000000..384a3a306 --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable.txt @@ -0,0 +1,30 @@ +undefined-variable:11:19::Undefined variable 'unknown' +undefined-variable:17:10:in_method:Undefined variable 'nomoreknown' +undefined-variable:20:19::Undefined variable '__revision__' +undefined-variable:22:8::Undefined variable '__revision__' +undefined-variable:26:29:bad_default:Undefined variable 'unknown2' +undefined-variable:29:10:bad_default:Undefined variable 'xxxx' +undefined-variable:30:4:bad_default:Undefined variable 'augvar' +undefined-variable:31:8:bad_default:Undefined variable 'vardel' +undefined-variable:33:19::Undefined variable 'doesnotexist' +undefined-variable:34:23::Undefined variable 'z' +used-before-assignment:42:4::Using variable 'POUETT' before assignment +used-before-assignment:55:4::Using variable 'PLOUF' before assignment +used-before-assignment:64:11:if_branch_test:Using variable 'xxx' before assignment +used-before-assignment:90:23:test_arguments:Using variable 'TestClass' before assignment +used-before-assignment:94:16:TestClass:Using variable 'Ancestor' before assignment +used-before-assignment:97:26:TestClass.MissingAncestor:Using variable 'Ancestor1' before assignment +used-before-assignment:104:36:TestClass.test1.UsingBeforeDefinition:Using variable 'Empty' before assignment +undefined-variable:118:10:Self:Undefined variable 'Self' +undefined-variable:134:7::Undefined variable 'BAT' +used-before-assignment:145:31:KeywordArgument.test1:Using variable 'enabled' before assignment +undefined-variable:148:32:KeywordArgument.test2:Undefined variable 'disabled' +undefined-variable:153:22:KeywordArgument.:Undefined variable 'arg' +undefined-variable:165:4::Undefined variable 'unicode_2' +undefined-variable:170:4::Undefined variable 'unicode_3' +undefined-variable:225:25:LambdaClass4.:Undefined variable 'LambdaClass4' +undefined-variable:233:25:LambdaClass5.:Undefined variable 'LambdaClass5' +used-before-assignment:254:26:func_should_fail:Using variable 'datetime' before assignment +undefined-variable:281:18:not_using_loop_variable_accordingly:Undefined variable 'iteree' +undefined-variable:292:27:undefined_annotation:Undefined variable 'x' +used-before-assignment:293:7:undefined_annotation:Using variable 'x' before assignment diff --git a/tests/functional/u/undefined/undefined_variable_crash_on_attribute.py b/tests/functional/u/undefined/undefined_variable_crash_on_attribute.py new file mode 100644 index 000000000..571efab1c --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable_crash_on_attribute.py @@ -0,0 +1,6 @@ +# pylint: disable=import-error,missing-module-docstring,missing-class-docstring,too-few-public-methods +import unknown + + +class Cls(metaclass=unknown.path.MetaFoo): + pass diff --git a/tests/functional/u/undefined/undefined_variable_py30.py b/tests/functional/u/undefined/undefined_variable_py30.py new file mode 100644 index 000000000..78d6dd3ea --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable_py30.py @@ -0,0 +1,86 @@ +"""Test warnings about access to undefined variables +for various Python 3 constructs. """ +# pylint: disable=too-few-public-methods, no-init, no-self-use, import-error +# pylint: disable=wrong-import-position, invalid-metaclass, useless-object-inheritance +class Undefined: + """ test various annotation problems. """ + + def test(self)->Undefined: # [undefined-variable] + """ used Undefined, which is Undefined in this scope. """ + + Undefined = True + + def test1(self)->Undefined: + """ This Undefined exists at local scope. """ + + def test2(self): + """ This should not emit. """ + def func()->Undefined: + """ empty """ + return 2 + return func + + +class Undefined1: + """ Other annotation problems. """ + + Undef = 42 + ABC = 42 + + class InnerScope: + """ Test inner scope definition. """ + + def test_undefined(self)->Undef: # [undefined-variable] + """ Looking at a higher scope is impossible. """ + + def test1(self)->ABC: # [undefined-variable] + """ Triggers undefined-variable. """ + + +class FalsePositive342(object): + # pylint: disable=line-too-long + """ Fix some false positives found in + https://bitbucket.org/logilab/pylint/issue/342/spurious-undefined-variable-for-class + """ + + top = 42 + + def test_good(self, bac: top): + """ top is defined at this moment. """ + + def test_bad(self, bac: trop): # [undefined-variable] + """ trop is undefined at this moment. """ + + def test_bad1(self, *args: trop1): # [undefined-variable] + """ trop1 is undefined at this moment. """ + + def test_bad2(self, **bac: trop2): # [undefined-variable] + """ trop2 is undefined at this moment. """ + +import abc +from abc import ABCMeta + +class Bad(metaclass=ABCMet): # [undefined-variable] + """ Notice the typo """ + +class SecondBad(metaclass=ab.ABCMeta): # [undefined-variable] + """ Notice the `ab` module. """ + +class Good(metaclass=int): + """ int is not a proper metaclass, but it is defined. """ + +class SecondGood(metaclass=Good): + """ empty """ + +class ThirdGood(metaclass=ABCMeta): + """ empty """ + +class FourthGood(ThirdGood): + """ This should not trigger anything. """ + +class FifthGood(metaclass=abc.Metaclass): + """Metaclasses can come from imported modules.""" + +# The following used to raise used-before-assignment +# pylint: disable=missing-docstring, multiple-statements +def used_before_assignment(*, arg): return arg + 1 diff --git a/tests/functional/u/undefined/undefined_variable_py30.rc b/tests/functional/u/undefined/undefined_variable_py30.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable_py30.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/u/undefined/undefined_variable_py30.txt b/tests/functional/u/undefined/undefined_variable_py30.txt new file mode 100644 index 000000000..e40ecd1bc --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable_py30.txt @@ -0,0 +1,8 @@ +undefined-variable:8:20:Undefined.test:Undefined variable 'Undefined' +undefined-variable:33:34:Undefined1.InnerScope.test_undefined:Undefined variable 'Undef' +undefined-variable:36:25:Undefined1.InnerScope.test1:Undefined variable 'ABC' +undefined-variable:51:28:FalsePositive342.test_bad:Undefined variable 'trop' +undefined-variable:54:31:FalsePositive342.test_bad1:Undefined variable 'trop1' +undefined-variable:57:31:FalsePositive342.test_bad2:Undefined variable 'trop2' +undefined-variable:63:0:Bad:Undefined variable 'ABCMet' +undefined-variable:66:0:SecondBad:Undefined variable 'ab' diff --git a/tests/functional/u/undefined_loop_variable.py b/tests/functional/u/undefined_loop_variable.py deleted file mode 100644 index a984898f8..000000000 --- a/tests/functional/u/undefined_loop_variable.py +++ /dev/null @@ -1,75 +0,0 @@ -# pylint: disable=missing-docstring,redefined-builtin - -def do_stuff(some_random_list): - for var in some_random_list: - pass - return var # [undefined-loop-variable] - - -def do_else(some_random_list): - for var in some_random_list: - if var == 42: - break - else: - var = 84 - return var - -__revision__ = 'yo' - -TEST_LC = [C for C in __revision__ if C.isalpha()] -B = [B for B in __revision__ if B.isalpha()] -VAR2 = B # nor this one - -for var1, var2 in TEST_LC: - var1 = var2 + 4 -VAR3 = var1 # [undefined-loop-variable] - -for note in __revision__: - note.something() -for line in __revision__: - for note in line: - A = note.anotherthing() - - -for x in []: - pass -for x in range(3): - VAR5 = (lambda: x)() - - -def do_stuff_with_a_list(): - for var in [1, 2, 3]: - pass - return var - - -def do_stuff_with_a_set(): - for var in {1, 2, 3}: - pass - return var - - -def do_stuff_with_a_dict(): - for var in {1: 2, 3: 4}: - pass - return var - - -def do_stuff_with_a_tuple(): - for var in (1, 2, 3): - pass - return var - - -def do_stuff_with_a_range(): - for var in range(1, 2): - pass - return var - - -def do_stuff_with_redefined_range(): - def range(key): - yield from [1, key] - for var in range(3): - pass - return var # [undefined-loop-variable] diff --git a/tests/functional/u/undefined_loop_variable.txt b/tests/functional/u/undefined_loop_variable.txt deleted file mode 100644 index ea194e769..000000000 --- a/tests/functional/u/undefined_loop_variable.txt +++ /dev/null @@ -1,3 +0,0 @@ -undefined-loop-variable:6:11:do_stuff:Using possibly undefined loop variable 'var' -undefined-loop-variable:25:7::Using possibly undefined loop variable 'var1' -undefined-loop-variable:75:11:do_stuff_with_redefined_range:Using possibly undefined loop variable 'var' diff --git a/tests/functional/u/undefined_variable.py b/tests/functional/u/undefined_variable.py deleted file mode 100644 index 7fe205cc9..000000000 --- a/tests/functional/u/undefined_variable.py +++ /dev/null @@ -1,296 +0,0 @@ -# pylint: disable=missing-docstring, multiple-statements, useless-object-inheritance,import-outside-toplevel -# pylint: disable=too-few-public-methods, no-init, no-self-use,bare-except,broad-except, import-error -from __future__ import print_function - -# pylint: disable=wrong-import-position -from typing import TYPE_CHECKING - -DEFINED = 1 - -if DEFINED != 1: - if DEFINED in (unknown, DEFINED): # [undefined-variable] - DEFINED += 1 - - -def in_method(var): - """method doc""" - var = nomoreknown # [undefined-variable] - assert var - -DEFINED = {DEFINED:__revision__} # [undefined-variable] -# +1:[undefined-variable] -DEFINED[__revision__] = OTHER = 'move this is astroid test' - -OTHER += '$' - -def bad_default(var, default=unknown2): # [undefined-variable] - """function with defaut arg's value set to an unexistant name""" - print(var, default) - print(xxxx) # [undefined-variable] - augvar += 1 # [undefined-variable] - del vardel # [undefined-variable] - -LMBD = lambda x, y=doesnotexist: x+y # [undefined-variable] -LMBD2 = lambda x, y: x+z # [undefined-variable] - -try: - POUET # don't catch me -except NameError: - POUET = 'something' - -try: - POUETT # [used-before-assignment] -except Exception: # pylint:disable = broad-except - POUETT = 'something' - -try: - POUETTT # don't catch me -except: # pylint:disable = bare-except - POUETTT = 'something' - -print(POUET, POUETT, POUETTT) - - -try: - PLOUF # [used-before-assignment] -except ValueError: - PLOUF = 'something' - -print(PLOUF) - -def if_branch_test(something): - """hop""" - if something == 0: - if xxx == 1: # [used-before-assignment] - pass - else: - print(xxx) - xxx = 3 - - -def decorator(arg): - """Decorator with one argument.""" - return lambda: list(arg) - - -@decorator(arg=[i * 2 for i in range(15)]) -def func1(): - """A function with a decorator that contains a listcomp.""" - -@decorator(arg=(i * 2 for i in range(15))) -def func2(): - """A function with a decorator that contains a genexpr.""" - -@decorator(lambda x: x > 0) -def main(): - """A function with a decorator that contains a lambda.""" - -# Test shared scope. - -def test_arguments(arg=TestClass): # [used-before-assignment] - """ TestClass isn't defined yet. """ - return arg - -class TestClass(Ancestor): # [used-before-assignment] - """ contains another class, which uses an undefined ancestor. """ - - class MissingAncestor(Ancestor1): # [used-before-assignment] - """ no op """ - - def test1(self): - """ It should trigger here, because the two classes - have the same scope. - """ - class UsingBeforeDefinition(Empty): # [used-before-assignment] - """ uses Empty before definition """ - class Empty(object): - """ no op """ - return UsingBeforeDefinition - - def test(self): - """ Ancestor isn't defined yet, but we don't care. """ - class MissingAncestor1(Ancestor): - """ no op """ - return MissingAncestor1 - -class Self(object): - """ Detect when using the same name inside the class scope. """ - obj = Self # [undefined-variable] - -class Self1(object): - """ No error should be raised here. """ - - def test(self): - """ empty """ - return Self1 - - -class Ancestor(object): - """ No op """ - -class Ancestor1(object): - """ No op """ - -NANA = BAT # [undefined-variable] -del BAT - - -class KeywordArgument(object): - """Test keyword arguments.""" - - enable = True - def test(self, is_enabled=enable): - """do nothing.""" - - def test1(self, is_enabled=enabled): # [used-before-assignment] - """enabled is undefined at this point, but it is used before assignment.""" - - def test2(self, is_disabled=disabled): # [undefined-variable] - """disabled is undefined""" - - enabled = True - - func = lambda arg=arg: arg * arg # [undefined-variable] - - arg2 = 0 - func2 = lambda arg2=arg2: arg2 * arg2 - -# Don't emit if the code is protected by NameError -try: - unicode_1 -except NameError: - pass - -try: - unicode_2 # [undefined-variable] -except Exception: - pass - -try: - unicode_3 # [undefined-variable] -except ValueError: - pass - -# See https://bitbucket.org/logilab/pylint/issue/111/ -try: raise IOError(1, "a") -except IOError as err: print(err) - - -def test_conditional_comprehension(): - methods = ['a', 'b', '_c', '_d'] - my_methods = sum(1 for method in methods - if not method.startswith('_')) - return my_methods - - -class MyError(object): - pass - - -class MyClass(object): - class MyError(MyError): - pass - - -def dec(inp): - def inner(func): - print(inp) - return func - return inner - -# Make sure lambdas with expressions -# referencing parent class do not raise undefined variable -# because at the time of their calling, the class name will -# be populated -# See https://github.com/PyCQA/pylint/issues/704 -class LambdaClass: - myattr = 1 - mylambda = lambda: LambdaClass.myattr - -# Need different classes to make sure -# consumed variables don't get in the way -class LambdaClass2: - myattr = 1 - # Different base_scope scope but still applies - mylambda2 = lambda: [LambdaClass2.myattr for _ in [1, 2]] - -class LambdaClass3: - myattr = 1 - # Nested default argument in lambda - # Should not raise error - mylambda3 = lambda: lambda a=LambdaClass3: a - -class LambdaClass4: - myattr = 1 - mylambda4 = lambda a=LambdaClass4: lambda: a # [undefined-variable] - -# Make sure the first lambda does not consume the LambdaClass5 class -# name although the expression is is valid -# Consuming the class would cause the subsequent undefined-variable to be masked -class LambdaClass5: - myattr = 1 - mylambda = lambda: LambdaClass5.myattr - mylambda4 = lambda a=LambdaClass5: lambda: a # [undefined-variable] - - -def nonlocal_in_ifexp(): - import matplotlib.pyplot as plt - def onclick(event): - if event: - nonlocal i - i += 1 - print(i) - i = 0 - fig = plt.figure() - fig.canvas.mpl_connect('button_press_event', onclick) - plt.show(block=True) - - - -if TYPE_CHECKING: - from datetime import datetime - - -def func_should_fail(_dt: datetime): # [used-before-assignment] - pass - - -# The following should not emit an error. -# pylint: disable=invalid-name -if TYPE_CHECKING: - from typing_extensions import Literal - - AllowedValues = Literal['hello', 'world'] - - -if TYPE_CHECKING: - from collections import Counter - from collections import OrderedDict -else: - Counter = object - OrderedDict = object - - -def tick(counter: Counter, name: str, dictionary: OrderedDict) -> OrderedDict: - counter[name] += 1 - return dictionary - - -# pylint: disable=unused-argument -def not_using_loop_variable_accordingly(iterator): - for iteree in iteree: # [undefined-variable] - yield iteree -# pylint: enable=unused-argument - - -class DunderClass: - def method(self): - # This name is not defined in the AST but it's present at runtime - return __class__ - - -def undefined_annotation(a:x): # [undefined-variable] - if x == 2: # [used-before-assignment] - for x in [1, 2]: - pass - return a diff --git a/tests/functional/u/undefined_variable.txt b/tests/functional/u/undefined_variable.txt deleted file mode 100644 index 384a3a306..000000000 --- a/tests/functional/u/undefined_variable.txt +++ /dev/null @@ -1,30 +0,0 @@ -undefined-variable:11:19::Undefined variable 'unknown' -undefined-variable:17:10:in_method:Undefined variable 'nomoreknown' -undefined-variable:20:19::Undefined variable '__revision__' -undefined-variable:22:8::Undefined variable '__revision__' -undefined-variable:26:29:bad_default:Undefined variable 'unknown2' -undefined-variable:29:10:bad_default:Undefined variable 'xxxx' -undefined-variable:30:4:bad_default:Undefined variable 'augvar' -undefined-variable:31:8:bad_default:Undefined variable 'vardel' -undefined-variable:33:19::Undefined variable 'doesnotexist' -undefined-variable:34:23::Undefined variable 'z' -used-before-assignment:42:4::Using variable 'POUETT' before assignment -used-before-assignment:55:4::Using variable 'PLOUF' before assignment -used-before-assignment:64:11:if_branch_test:Using variable 'xxx' before assignment -used-before-assignment:90:23:test_arguments:Using variable 'TestClass' before assignment -used-before-assignment:94:16:TestClass:Using variable 'Ancestor' before assignment -used-before-assignment:97:26:TestClass.MissingAncestor:Using variable 'Ancestor1' before assignment -used-before-assignment:104:36:TestClass.test1.UsingBeforeDefinition:Using variable 'Empty' before assignment -undefined-variable:118:10:Self:Undefined variable 'Self' -undefined-variable:134:7::Undefined variable 'BAT' -used-before-assignment:145:31:KeywordArgument.test1:Using variable 'enabled' before assignment -undefined-variable:148:32:KeywordArgument.test2:Undefined variable 'disabled' -undefined-variable:153:22:KeywordArgument.:Undefined variable 'arg' -undefined-variable:165:4::Undefined variable 'unicode_2' -undefined-variable:170:4::Undefined variable 'unicode_3' -undefined-variable:225:25:LambdaClass4.:Undefined variable 'LambdaClass4' -undefined-variable:233:25:LambdaClass5.:Undefined variable 'LambdaClass5' -used-before-assignment:254:26:func_should_fail:Using variable 'datetime' before assignment -undefined-variable:281:18:not_using_loop_variable_accordingly:Undefined variable 'iteree' -undefined-variable:292:27:undefined_annotation:Undefined variable 'x' -used-before-assignment:293:7:undefined_annotation:Using variable 'x' before assignment diff --git a/tests/functional/u/undefined_variable_crash_on_attribute.py b/tests/functional/u/undefined_variable_crash_on_attribute.py deleted file mode 100644 index 571efab1c..000000000 --- a/tests/functional/u/undefined_variable_crash_on_attribute.py +++ /dev/null @@ -1,6 +0,0 @@ -# pylint: disable=import-error,missing-module-docstring,missing-class-docstring,too-few-public-methods -import unknown - - -class Cls(metaclass=unknown.path.MetaFoo): - pass diff --git a/tests/functional/u/undefined_variable_py30.py b/tests/functional/u/undefined_variable_py30.py deleted file mode 100644 index 78d6dd3ea..000000000 --- a/tests/functional/u/undefined_variable_py30.py +++ /dev/null @@ -1,86 +0,0 @@ -"""Test warnings about access to undefined variables -for various Python 3 constructs. """ -# pylint: disable=too-few-public-methods, no-init, no-self-use, import-error -# pylint: disable=wrong-import-position, invalid-metaclass, useless-object-inheritance -class Undefined: - """ test various annotation problems. """ - - def test(self)->Undefined: # [undefined-variable] - """ used Undefined, which is Undefined in this scope. """ - - Undefined = True - - def test1(self)->Undefined: - """ This Undefined exists at local scope. """ - - def test2(self): - """ This should not emit. """ - def func()->Undefined: - """ empty """ - return 2 - return func - - -class Undefined1: - """ Other annotation problems. """ - - Undef = 42 - ABC = 42 - - class InnerScope: - """ Test inner scope definition. """ - - def test_undefined(self)->Undef: # [undefined-variable] - """ Looking at a higher scope is impossible. """ - - def test1(self)->ABC: # [undefined-variable] - """ Triggers undefined-variable. """ - - -class FalsePositive342(object): - # pylint: disable=line-too-long - """ Fix some false positives found in - https://bitbucket.org/logilab/pylint/issue/342/spurious-undefined-variable-for-class - """ - - top = 42 - - def test_good(self, bac: top): - """ top is defined at this moment. """ - - def test_bad(self, bac: trop): # [undefined-variable] - """ trop is undefined at this moment. """ - - def test_bad1(self, *args: trop1): # [undefined-variable] - """ trop1 is undefined at this moment. """ - - def test_bad2(self, **bac: trop2): # [undefined-variable] - """ trop2 is undefined at this moment. """ - -import abc -from abc import ABCMeta - -class Bad(metaclass=ABCMet): # [undefined-variable] - """ Notice the typo """ - -class SecondBad(metaclass=ab.ABCMeta): # [undefined-variable] - """ Notice the `ab` module. """ - -class Good(metaclass=int): - """ int is not a proper metaclass, but it is defined. """ - -class SecondGood(metaclass=Good): - """ empty """ - -class ThirdGood(metaclass=ABCMeta): - """ empty """ - -class FourthGood(ThirdGood): - """ This should not trigger anything. """ - -class FifthGood(metaclass=abc.Metaclass): - """Metaclasses can come from imported modules.""" - -# The following used to raise used-before-assignment -# pylint: disable=missing-docstring, multiple-statements -def used_before_assignment(*, arg): return arg + 1 diff --git a/tests/functional/u/undefined_variable_py30.rc b/tests/functional/u/undefined_variable_py30.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/u/undefined_variable_py30.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/u/undefined_variable_py30.txt b/tests/functional/u/undefined_variable_py30.txt deleted file mode 100644 index e40ecd1bc..000000000 --- a/tests/functional/u/undefined_variable_py30.txt +++ /dev/null @@ -1,8 +0,0 @@ -undefined-variable:8:20:Undefined.test:Undefined variable 'Undefined' -undefined-variable:33:34:Undefined1.InnerScope.test_undefined:Undefined variable 'Undef' -undefined-variable:36:25:Undefined1.InnerScope.test1:Undefined variable 'ABC' -undefined-variable:51:28:FalsePositive342.test_bad:Undefined variable 'trop' -undefined-variable:54:31:FalsePositive342.test_bad1:Undefined variable 'trop1' -undefined-variable:57:31:FalsePositive342.test_bad2:Undefined variable 'trop2' -undefined-variable:63:0:Bad:Undefined variable 'ABCMet' -undefined-variable:66:0:SecondBad:Undefined variable 'ab' diff --git a/tests/functional/u/unnecessary/unnecessary_comprehension.py b/tests/functional/u/unnecessary/unnecessary_comprehension.py new file mode 100644 index 000000000..8e40c5925 --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_comprehension.py @@ -0,0 +1,36 @@ +# pylint: disable=undefined-variable, pointless-statement, missing-docstring, line-too-long +# For name-reference see https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries + +# List comprehensions +[x for x in iterable] # [unnecessary-comprehension] +[y for x in iterable] # expression != target_list +[x for x,y,z in iterable] # expression != target_list +[(x,y,z) for x,y,z in iterable] # [unnecessary-comprehension] +[(x,y,z) for (x,y,z) in iterable] # [unnecessary-comprehension] +[x for x, *y in iterable] # expression != target_list +[x for x in iterable if condition] # exclude comp_if +[y for x in iterable for y in x] # exclude nested comprehensions +[2 * x for x in iterable] # exclude useful comprehensions +[(x, y, 1) for x, y in iterable] # exclude useful comprehensions + +# Set comprehensions +{x for x in iterable} # [unnecessary-comprehension] +{y for x in iterable} # expression != target_list +{x for x,y,z in iterable} # expression != target_list +{(x,y,z) for x,y,z in iterable} # [unnecessary-comprehension] +{(x,y,z) for (x, y, z) in iterable} # [unnecessary-comprehension] +{(x,y,z) for x in iterable} # expression != target_list +{(x,y,(a,b,c)) for x in iterable} # expression != target_list +{x for x, *y in iterable} # expression != target_list +{x for x in iterable if condition} # exclude comp_if +{y for x in iterable for y in x} # exclude nested comprehensions + +# Dictionary comprehensions +{x: y for x, y in iterable} # [unnecessary-comprehension] +{y: x for x, y in iterable} # key value wrong order +{x: y for (x, y) in iterable} # [unnecessary-comprehension] +{x: y for x,y,z in iterable} # expression != target_list +{x: y for x, y in iterable if condition} # exclude comp_if +{y: z for x in iterable for y, z in x} # exclude nested comprehensions +{x: 1 for x in iterable} # expression != target_list +{2 * x: 3 + x for x in iterable} # exclude useful comprehensions diff --git a/tests/functional/u/unnecessary/unnecessary_comprehension.txt b/tests/functional/u/unnecessary/unnecessary_comprehension.txt new file mode 100644 index 000000000..47d6d2b59 --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_comprehension.txt @@ -0,0 +1,8 @@ +unnecessary-comprehension:5:0::Unnecessary use of a comprehension +unnecessary-comprehension:8:0::Unnecessary use of a comprehension +unnecessary-comprehension:9:0::Unnecessary use of a comprehension +unnecessary-comprehension:17:0::Unnecessary use of a comprehension +unnecessary-comprehension:20:0::Unnecessary use of a comprehension +unnecessary-comprehension:21:0::Unnecessary use of a comprehension +unnecessary-comprehension:29:0::Unnecessary use of a comprehension +unnecessary-comprehension:31:0::Unnecessary use of a comprehension diff --git a/tests/functional/u/unnecessary/unnecessary_lambda.py b/tests/functional/u/unnecessary/unnecessary_lambda.py new file mode 100644 index 000000000..f0bd775f3 --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_lambda.py @@ -0,0 +1,53 @@ +# pylint: disable=undefined-variable +"""test suspicious lambda expressions +""" + +__revision__ = '' + +# Some simple examples of the most commonly encountered forms. +# +1: [unnecessary-lambda] +_ = lambda: list() # replaceable with "list" +# +1: [unnecessary-lambda] +_ = lambda x: hash(x) # replaceable with "hash" +# +1: [unnecessary-lambda] +_ = lambda x, y: min(x, y) # replaceable with "min" + +# A function that can take any arguments given to it. +_ANYARGS = lambda *args, **kwargs: 'completely arbitrary return value' + +# Some more complex forms of unnecessary lambda expressions. +# +1: [unnecessary-lambda] +_ = lambda *args: _ANYARGS(*args) +# +1: [unnecessary-lambda] +_ = lambda **kwargs: _ANYARGS(**kwargs) +# +1: [unnecessary-lambda] +_ = lambda *args, **kwargs: _ANYARGS(*args, **kwargs) +# +1: [unnecessary-lambda] +_ = lambda x, y, z, *args, **kwargs: _ANYARGS(x, y, z, *args, **kwargs) + +# Lambdas that are *not* unnecessary and should *not* trigger warnings. +_ = lambda x: x +_ = lambda x: x() +_ = lambda x=4: hash(x) +_ = lambda x, y: list(range(y, x)) +_ = lambda x: list(range(5, x)) +_ = lambda x, y: list(range(x, 5)) +_ = lambda x, y, z: x.y(z) +_ = lambda: 5 +_ = lambda **kwargs: _ANYARGS() +_ = lambda **kwargs: _ANYARGS(**dict([('three', 3)])) +_ = lambda **kwargs: _ANYARGS(**{'three': 3}) +_ = lambda dict_arg, **kwargs: _ANYARGS(kwargs, **dict_arg) +_ = lambda *args: _ANYARGS() +_ = lambda *args: _ANYARGS(*list([3, 4])) +_ = lambda *args: _ANYARGS(*[3, 4]) +_ = lambda list_arg, *args: _ANYARGS(args, *list_arg) +_ = lambda: _ANYARGS(*[3]) +_ = lambda: _ANYARGS(**{'three': 3}) +_ = lambda: _ANYARGS(*[3], **{'three': 3}) +_ = lambda: _ANYARGS(func=42) + +# Don't warn about this. +_ = lambda: code().analysis() + +_ = lambda **kwargs: dict(bar=42, **kwargs) diff --git a/tests/functional/u/unnecessary/unnecessary_lambda.txt b/tests/functional/u/unnecessary/unnecessary_lambda.txt new file mode 100644 index 000000000..c3983b195 --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_lambda.txt @@ -0,0 +1,7 @@ +unnecessary-lambda:9:4::Lambda may not be necessary +unnecessary-lambda:11:4::Lambda may not be necessary +unnecessary-lambda:13:4::Lambda may not be necessary +unnecessary-lambda:20:4::Lambda may not be necessary +unnecessary-lambda:22:4::Lambda may not be necessary +unnecessary-lambda:24:4::Lambda may not be necessary +unnecessary-lambda:26:4::Lambda may not be necessary diff --git a/tests/functional/u/unnecessary/unnecessary_not.py b/tests/functional/u/unnecessary/unnecessary_not.py new file mode 100644 index 000000000..97acecd73 --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_not.py @@ -0,0 +1,63 @@ +"""Check exceeding negations in boolean expressions trigger warnings""" + +# pylint: disable=singleton-comparison,too-many-branches,too-few-public-methods,undefined-variable +# pylint: disable=literal-comparison, comparison-with-itself, useless-object-inheritance +def unneeded_not(): + """This is not ok + """ + bool_var = True + someint = 2 + if not not bool_var: # [unneeded-not] + pass + if not someint == 1: # [unneeded-not] + pass + if not someint != 1: # [unneeded-not] + pass + if not someint < 1: # [unneeded-not] + pass + if not someint > 1: # [unneeded-not] + pass + if not someint <= 1: # [unneeded-not] + pass + if not someint >= 1: # [unneeded-not] + pass + if not not someint: # [unneeded-not] + pass + if not bool_var == True: # [unneeded-not] + pass + if not bool_var == False: # [unneeded-not] + pass + if not bool_var != True: # [unneeded-not] + pass + if not True == True: # [unneeded-not] + pass + if not 2 in [3, 4]: # [unneeded-not] + pass + if not someint is 'test': # [unneeded-not] + pass + + +def tolerated_statements(): + """This is ok""" + bool_var = True + someint = 2 + if not(bool_var == False and someint == 1): + pass + if 2 not in [3, 4]: + pass + if not someint == bool_var == 2: + pass + if not 2 <= someint < 3 < 4: + pass + if not set('bar') <= set('foobaz'): + pass + if not set(something) <= 3: + pass + if not frozenset(something) <= 3: + pass + + +class Klass(object): + """This is also ok""" + def __ne__(self, other): + return not self == other diff --git a/tests/functional/u/unnecessary/unnecessary_not.txt b/tests/functional/u/unnecessary/unnecessary_not.txt new file mode 100644 index 000000000..722f26d40 --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_not.txt @@ -0,0 +1,14 @@ +unneeded-not:10:7:unneeded_not:"Consider changing ""not not bool_var"" to ""bool_var""" +unneeded-not:12:7:unneeded_not:"Consider changing ""not someint == 1"" to ""someint != 1""" +unneeded-not:14:7:unneeded_not:"Consider changing ""not someint != 1"" to ""someint == 1""" +unneeded-not:16:7:unneeded_not:"Consider changing ""not someint < 1"" to ""someint >= 1""" +unneeded-not:18:7:unneeded_not:"Consider changing ""not someint > 1"" to ""someint <= 1""" +unneeded-not:20:7:unneeded_not:"Consider changing ""not someint <= 1"" to ""someint > 1""" +unneeded-not:22:7:unneeded_not:"Consider changing ""not someint >= 1"" to ""someint < 1""" +unneeded-not:24:7:unneeded_not:"Consider changing ""not not someint"" to ""someint""" +unneeded-not:26:7:unneeded_not:"Consider changing ""not bool_var == True"" to ""bool_var != True""" +unneeded-not:28:7:unneeded_not:"Consider changing ""not bool_var == False"" to ""bool_var != False""" +unneeded-not:30:7:unneeded_not:"Consider changing ""not bool_var != True"" to ""bool_var == True""" +unneeded-not:32:7:unneeded_not:"Consider changing ""not True == True"" to ""True != True""" +unneeded-not:34:7:unneeded_not:"Consider changing ""not 2 in [3, 4]"" to ""2 not in [3, 4]""" +unneeded-not:36:7:unneeded_not:"Consider changing ""not someint is 'test'"" to ""someint is not 'test'""" diff --git a/tests/functional/u/unnecessary/unnecessary_pass.py b/tests/functional/u/unnecessary/unnecessary_pass.py new file mode 100644 index 000000000..c2733096a --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_pass.py @@ -0,0 +1,49 @@ +# pylint: disable=missing-docstring, too-few-public-methods + +try: + A = 2 +except ValueError: + A = 24 + pass # [unnecessary-pass] + +def docstring_only(): + '''In Python, stubbed functions often have a body that contains just a + single `pass` statement, indicating that the function doesn't do + anything. However, a stubbed function can also have just a + docstring, and function with a docstring and no body also does + nothing. + ''' + + +# This function has no docstring, so it needs a `pass` statement. +def pass_only(): + pass + + +def docstring_and_pass(): + '''This function doesn't do anything, but it has a docstring, so its + `pass` statement is useless clutter. + + NEW CHECK: useless-pass + + This would check for stubs with both docstrings and `pass` + statements, suggesting the removal of the useless `pass` + statements + ''' + pass # [unnecessary-pass] + + +class DocstringOnly: + '''The same goes for class stubs: docstring, or `pass`, but not both. + ''' + + +# No problem +class PassOnly: + pass + + +class DocstringAndPass: + '''Whoops! Mark this one as bad too. + ''' + pass # [unnecessary-pass] diff --git a/tests/functional/u/unnecessary/unnecessary_pass.txt b/tests/functional/u/unnecessary/unnecessary_pass.txt new file mode 100644 index 000000000..6eabcf5bd --- /dev/null +++ b/tests/functional/u/unnecessary/unnecessary_pass.txt @@ -0,0 +1,3 @@ +unnecessary-pass:7:4::Unnecessary pass statement +unnecessary-pass:33:4:docstring_and_pass:Unnecessary pass statement +unnecessary-pass:49:4:DocstringAndPass:Unnecessary pass statement diff --git a/tests/functional/u/unnecessary_comprehension.py b/tests/functional/u/unnecessary_comprehension.py deleted file mode 100644 index 8e40c5925..000000000 --- a/tests/functional/u/unnecessary_comprehension.py +++ /dev/null @@ -1,36 +0,0 @@ -# pylint: disable=undefined-variable, pointless-statement, missing-docstring, line-too-long -# For name-reference see https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries - -# List comprehensions -[x for x in iterable] # [unnecessary-comprehension] -[y for x in iterable] # expression != target_list -[x for x,y,z in iterable] # expression != target_list -[(x,y,z) for x,y,z in iterable] # [unnecessary-comprehension] -[(x,y,z) for (x,y,z) in iterable] # [unnecessary-comprehension] -[x for x, *y in iterable] # expression != target_list -[x for x in iterable if condition] # exclude comp_if -[y for x in iterable for y in x] # exclude nested comprehensions -[2 * x for x in iterable] # exclude useful comprehensions -[(x, y, 1) for x, y in iterable] # exclude useful comprehensions - -# Set comprehensions -{x for x in iterable} # [unnecessary-comprehension] -{y for x in iterable} # expression != target_list -{x for x,y,z in iterable} # expression != target_list -{(x,y,z) for x,y,z in iterable} # [unnecessary-comprehension] -{(x,y,z) for (x, y, z) in iterable} # [unnecessary-comprehension] -{(x,y,z) for x in iterable} # expression != target_list -{(x,y,(a,b,c)) for x in iterable} # expression != target_list -{x for x, *y in iterable} # expression != target_list -{x for x in iterable if condition} # exclude comp_if -{y for x in iterable for y in x} # exclude nested comprehensions - -# Dictionary comprehensions -{x: y for x, y in iterable} # [unnecessary-comprehension] -{y: x for x, y in iterable} # key value wrong order -{x: y for (x, y) in iterable} # [unnecessary-comprehension] -{x: y for x,y,z in iterable} # expression != target_list -{x: y for x, y in iterable if condition} # exclude comp_if -{y: z for x in iterable for y, z in x} # exclude nested comprehensions -{x: 1 for x in iterable} # expression != target_list -{2 * x: 3 + x for x in iterable} # exclude useful comprehensions diff --git a/tests/functional/u/unnecessary_comprehension.txt b/tests/functional/u/unnecessary_comprehension.txt deleted file mode 100644 index 47d6d2b59..000000000 --- a/tests/functional/u/unnecessary_comprehension.txt +++ /dev/null @@ -1,8 +0,0 @@ -unnecessary-comprehension:5:0::Unnecessary use of a comprehension -unnecessary-comprehension:8:0::Unnecessary use of a comprehension -unnecessary-comprehension:9:0::Unnecessary use of a comprehension -unnecessary-comprehension:17:0::Unnecessary use of a comprehension -unnecessary-comprehension:20:0::Unnecessary use of a comprehension -unnecessary-comprehension:21:0::Unnecessary use of a comprehension -unnecessary-comprehension:29:0::Unnecessary use of a comprehension -unnecessary-comprehension:31:0::Unnecessary use of a comprehension diff --git a/tests/functional/u/unnecessary_lambda.py b/tests/functional/u/unnecessary_lambda.py deleted file mode 100644 index f0bd775f3..000000000 --- a/tests/functional/u/unnecessary_lambda.py +++ /dev/null @@ -1,53 +0,0 @@ -# pylint: disable=undefined-variable -"""test suspicious lambda expressions -""" - -__revision__ = '' - -# Some simple examples of the most commonly encountered forms. -# +1: [unnecessary-lambda] -_ = lambda: list() # replaceable with "list" -# +1: [unnecessary-lambda] -_ = lambda x: hash(x) # replaceable with "hash" -# +1: [unnecessary-lambda] -_ = lambda x, y: min(x, y) # replaceable with "min" - -# A function that can take any arguments given to it. -_ANYARGS = lambda *args, **kwargs: 'completely arbitrary return value' - -# Some more complex forms of unnecessary lambda expressions. -# +1: [unnecessary-lambda] -_ = lambda *args: _ANYARGS(*args) -# +1: [unnecessary-lambda] -_ = lambda **kwargs: _ANYARGS(**kwargs) -# +1: [unnecessary-lambda] -_ = lambda *args, **kwargs: _ANYARGS(*args, **kwargs) -# +1: [unnecessary-lambda] -_ = lambda x, y, z, *args, **kwargs: _ANYARGS(x, y, z, *args, **kwargs) - -# Lambdas that are *not* unnecessary and should *not* trigger warnings. -_ = lambda x: x -_ = lambda x: x() -_ = lambda x=4: hash(x) -_ = lambda x, y: list(range(y, x)) -_ = lambda x: list(range(5, x)) -_ = lambda x, y: list(range(x, 5)) -_ = lambda x, y, z: x.y(z) -_ = lambda: 5 -_ = lambda **kwargs: _ANYARGS() -_ = lambda **kwargs: _ANYARGS(**dict([('three', 3)])) -_ = lambda **kwargs: _ANYARGS(**{'three': 3}) -_ = lambda dict_arg, **kwargs: _ANYARGS(kwargs, **dict_arg) -_ = lambda *args: _ANYARGS() -_ = lambda *args: _ANYARGS(*list([3, 4])) -_ = lambda *args: _ANYARGS(*[3, 4]) -_ = lambda list_arg, *args: _ANYARGS(args, *list_arg) -_ = lambda: _ANYARGS(*[3]) -_ = lambda: _ANYARGS(**{'three': 3}) -_ = lambda: _ANYARGS(*[3], **{'three': 3}) -_ = lambda: _ANYARGS(func=42) - -# Don't warn about this. -_ = lambda: code().analysis() - -_ = lambda **kwargs: dict(bar=42, **kwargs) diff --git a/tests/functional/u/unnecessary_lambda.txt b/tests/functional/u/unnecessary_lambda.txt deleted file mode 100644 index c3983b195..000000000 --- a/tests/functional/u/unnecessary_lambda.txt +++ /dev/null @@ -1,7 +0,0 @@ -unnecessary-lambda:9:4::Lambda may not be necessary -unnecessary-lambda:11:4::Lambda may not be necessary -unnecessary-lambda:13:4::Lambda may not be necessary -unnecessary-lambda:20:4::Lambda may not be necessary -unnecessary-lambda:22:4::Lambda may not be necessary -unnecessary-lambda:24:4::Lambda may not be necessary -unnecessary-lambda:26:4::Lambda may not be necessary diff --git a/tests/functional/u/unnecessary_pass.py b/tests/functional/u/unnecessary_pass.py deleted file mode 100644 index c2733096a..000000000 --- a/tests/functional/u/unnecessary_pass.py +++ /dev/null @@ -1,49 +0,0 @@ -# pylint: disable=missing-docstring, too-few-public-methods - -try: - A = 2 -except ValueError: - A = 24 - pass # [unnecessary-pass] - -def docstring_only(): - '''In Python, stubbed functions often have a body that contains just a - single `pass` statement, indicating that the function doesn't do - anything. However, a stubbed function can also have just a - docstring, and function with a docstring and no body also does - nothing. - ''' - - -# This function has no docstring, so it needs a `pass` statement. -def pass_only(): - pass - - -def docstring_and_pass(): - '''This function doesn't do anything, but it has a docstring, so its - `pass` statement is useless clutter. - - NEW CHECK: useless-pass - - This would check for stubs with both docstrings and `pass` - statements, suggesting the removal of the useless `pass` - statements - ''' - pass # [unnecessary-pass] - - -class DocstringOnly: - '''The same goes for class stubs: docstring, or `pass`, but not both. - ''' - - -# No problem -class PassOnly: - pass - - -class DocstringAndPass: - '''Whoops! Mark this one as bad too. - ''' - pass # [unnecessary-pass] diff --git a/tests/functional/u/unnecessary_pass.txt b/tests/functional/u/unnecessary_pass.txt deleted file mode 100644 index 6eabcf5bd..000000000 --- a/tests/functional/u/unnecessary_pass.txt +++ /dev/null @@ -1,3 +0,0 @@ -unnecessary-pass:7:4::Unnecessary pass statement -unnecessary-pass:33:4:docstring_and_pass:Unnecessary pass statement -unnecessary-pass:49:4:DocstringAndPass:Unnecessary pass statement diff --git a/tests/functional/u/unneeded_not.py b/tests/functional/u/unneeded_not.py deleted file mode 100644 index 97acecd73..000000000 --- a/tests/functional/u/unneeded_not.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Check exceeding negations in boolean expressions trigger warnings""" - -# pylint: disable=singleton-comparison,too-many-branches,too-few-public-methods,undefined-variable -# pylint: disable=literal-comparison, comparison-with-itself, useless-object-inheritance -def unneeded_not(): - """This is not ok - """ - bool_var = True - someint = 2 - if not not bool_var: # [unneeded-not] - pass - if not someint == 1: # [unneeded-not] - pass - if not someint != 1: # [unneeded-not] - pass - if not someint < 1: # [unneeded-not] - pass - if not someint > 1: # [unneeded-not] - pass - if not someint <= 1: # [unneeded-not] - pass - if not someint >= 1: # [unneeded-not] - pass - if not not someint: # [unneeded-not] - pass - if not bool_var == True: # [unneeded-not] - pass - if not bool_var == False: # [unneeded-not] - pass - if not bool_var != True: # [unneeded-not] - pass - if not True == True: # [unneeded-not] - pass - if not 2 in [3, 4]: # [unneeded-not] - pass - if not someint is 'test': # [unneeded-not] - pass - - -def tolerated_statements(): - """This is ok""" - bool_var = True - someint = 2 - if not(bool_var == False and someint == 1): - pass - if 2 not in [3, 4]: - pass - if not someint == bool_var == 2: - pass - if not 2 <= someint < 3 < 4: - pass - if not set('bar') <= set('foobaz'): - pass - if not set(something) <= 3: - pass - if not frozenset(something) <= 3: - pass - - -class Klass(object): - """This is also ok""" - def __ne__(self, other): - return not self == other diff --git a/tests/functional/u/unneeded_not.txt b/tests/functional/u/unneeded_not.txt deleted file mode 100644 index 722f26d40..000000000 --- a/tests/functional/u/unneeded_not.txt +++ /dev/null @@ -1,14 +0,0 @@ -unneeded-not:10:7:unneeded_not:"Consider changing ""not not bool_var"" to ""bool_var""" -unneeded-not:12:7:unneeded_not:"Consider changing ""not someint == 1"" to ""someint != 1""" -unneeded-not:14:7:unneeded_not:"Consider changing ""not someint != 1"" to ""someint == 1""" -unneeded-not:16:7:unneeded_not:"Consider changing ""not someint < 1"" to ""someint >= 1""" -unneeded-not:18:7:unneeded_not:"Consider changing ""not someint > 1"" to ""someint <= 1""" -unneeded-not:20:7:unneeded_not:"Consider changing ""not someint <= 1"" to ""someint > 1""" -unneeded-not:22:7:unneeded_not:"Consider changing ""not someint >= 1"" to ""someint < 1""" -unneeded-not:24:7:unneeded_not:"Consider changing ""not not someint"" to ""someint""" -unneeded-not:26:7:unneeded_not:"Consider changing ""not bool_var == True"" to ""bool_var != True""" -unneeded-not:28:7:unneeded_not:"Consider changing ""not bool_var == False"" to ""bool_var != False""" -unneeded-not:30:7:unneeded_not:"Consider changing ""not bool_var != True"" to ""bool_var == True""" -unneeded-not:32:7:unneeded_not:"Consider changing ""not True == True"" to ""True != True""" -unneeded-not:34:7:unneeded_not:"Consider changing ""not 2 in [3, 4]"" to ""2 not in [3, 4]""" -unneeded-not:36:7:unneeded_not:"Consider changing ""not someint is 'test'"" to ""someint is not 'test'""" diff --git a/tests/functional/u/unsupported/unsupported_assignment_operation.py b/tests/functional/u/unsupported/unsupported_assignment_operation.py new file mode 100644 index 000000000..c0b58668a --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_assignment_operation.py @@ -0,0 +1,94 @@ +""" +Checks that value used in a subscript support assignments +(i.e. defines __setitem__ method). +""" +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position,unnecessary-comprehension +# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance +import six + +# primitives +numbers = [1, 2, 3] +numbers[0] = 42 + + +bytearray(b"123")[0] = 42 +dict(a=1, b=2)['a'] = 42 +(1, 2, 3)[0] = 42 # [unsupported-assignment-operation] + +# list/dict comprehensions are fine +[x for x in range(10)][0] = 42 +{x: 10 - x for x in range(10)}[0] = 42 + + +# instances +class NonSubscriptable(object): + pass + +class Subscriptable(object): + def __setitem__(self, key, value): + return key + value + +NonSubscriptable()[0] = 24 # [unsupported-assignment-operation] +NonSubscriptable[0] = 24 # [unsupported-assignment-operation] +Subscriptable()[0] = 24 +Subscriptable[0] = 24 # [unsupported-assignment-operation] + +# generators are not subscriptable +def powers_of_two(): + k = 0 + while k < 10: + yield 2 ** k + k += 1 + +powers_of_two()[0] = 42 # [unsupported-assignment-operation] +powers_of_two[0] = 42 # [unsupported-assignment-operation] + + +# check that primitive non subscriptable types are caught +True[0] = 24 # [unsupported-assignment-operation] +None[0] = 42 # [unsupported-assignment-operation] +8.5[0] = 24 # [unsupported-assignment-operation] +10[0] = 24 # [unsupported-assignment-operation] + +# sets are not subscriptable +{x ** 2 for x in range(10)}[0] = 24 # [unsupported-assignment-operation] +set(numbers)[0] = 24 # [unsupported-assignment-operation] +frozenset(numbers)[0] = 42 # [unsupported-assignment-operation] + +# skip instances with unknown base classes +from some_missing_module import LibSubscriptable + +class MaybeSubscriptable(LibSubscriptable): + pass + +MaybeSubscriptable()[0] = 42 + +# subscriptable classes (through metaclasses) + +class MetaSubscriptable(type): + def __setitem__(cls, key, value): + return key + value + +class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): + pass + +SubscriptableClass[0] = 24 +SubscriptableClass()[0] = 24 # [unsupported-assignment-operation] + +# functions are not subscriptable +def test(*args, **kwargs): + return args, kwargs + +test()[0] = 24 # [unsupported-assignment-operation] +test[0] = 24 # [unsupported-assignment-operation] + +# deque +from collections import deque +deq = deque(maxlen=10) +deq.append(42) +deq[0] = 42 + +# tuples assignment +values = [1, 2, 3, 4] +(values[0], values[1]) = 3, 4 +(values[0], SubscriptableClass()[0]) = 42, 42 # [unsupported-assignment-operation] diff --git a/tests/functional/u/unsupported/unsupported_assignment_operation.rc b/tests/functional/u/unsupported/unsupported_assignment_operation.rc new file mode 100644 index 000000000..6a8ee96ca --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_assignment_operation.rc @@ -0,0 +1,2 @@ +[testoptions] +requires = six diff --git a/tests/functional/u/unsupported/unsupported_assignment_operation.txt b/tests/functional/u/unsupported/unsupported_assignment_operation.txt new file mode 100644 index 000000000..854e8bfec --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_assignment_operation.txt @@ -0,0 +1,17 @@ +unsupported-assignment-operation:16:0::'(1, 2, 3)' does not support item assignment +unsupported-assignment-operation:31:0::'NonSubscriptable()' does not support item assignment +unsupported-assignment-operation:32:0::'NonSubscriptable' does not support item assignment +unsupported-assignment-operation:34:0::'Subscriptable' does not support item assignment +unsupported-assignment-operation:43:0::'powers_of_two()' does not support item assignment +unsupported-assignment-operation:44:0::'powers_of_two' does not support item assignment +unsupported-assignment-operation:48:0::'True' does not support item assignment +unsupported-assignment-operation:49:0::'None' does not support item assignment +unsupported-assignment-operation:50:0::'8.5' does not support item assignment +unsupported-assignment-operation:51:0::'10' does not support item assignment +unsupported-assignment-operation:54:0::'{x**2 for x in range(10)}' does not support item assignment +unsupported-assignment-operation:55:0::'set(numbers)' does not support item assignment +unsupported-assignment-operation:56:0::'frozenset(numbers)' does not support item assignment +unsupported-assignment-operation:76:0::'SubscriptableClass()' does not support item assignment +unsupported-assignment-operation:82:0::'test()' does not support item assignment +unsupported-assignment-operation:83:0::'test' does not support item assignment +unsupported-assignment-operation:94:12::'SubscriptableClass()' does not support item assignment diff --git a/tests/functional/u/unsupported/unsupported_binary_operation.py b/tests/functional/u/unsupported/unsupported_binary_operation.py new file mode 100644 index 000000000..0bfe1d16a --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_binary_operation.py @@ -0,0 +1,66 @@ +"""Test for unsupported-binary-operation.""" +# pylint: disable=missing-docstring,too-few-public-methods,pointless-statement +# pylint: disable=expression-not-assigned, invalid-name, useless-object-inheritance + + +import collections + + +1 + "a" # [unsupported-binary-operation] +1 - [] # [unsupported-binary-operation] +1 * {} # [unsupported-binary-operation] +1 / collections # [unsupported-binary-operation] +1 ** (lambda x: x) # [unsupported-binary-operation] +{} * {} # [unsupported-binary-operation] +{} - {} # [unsupported-binary-operation] +{} | {} # [unsupported-binary-operation] +{} >> {} # [unsupported-binary-operation] +[] + () # [unsupported-binary-operation] +() + [] # [unsupported-binary-operation] +[] * 2.0 # [unsupported-binary-operation] +() * 2.0 # [unsupported-binary-operation] +2.0 >> 2.0 # [unsupported-binary-operation] +class A(object): + pass +class B(object): + pass +A() + B() # [unsupported-binary-operation] +class A1(object): + def __add__(self, other): + return NotImplemented + +A1() + A1() # [unsupported-binary-operation] + +class A2(object): + def __add__(self, other): + return NotImplemented +class B2(object): + def __radd__(self, other): + return NotImplemented +A2() + B2() # [unsupported-binary-operation] + +class Parent(object): + pass +class Child(Parent): + def __add__(self, other): + return NotImplemented +Child() + Parent() # [unsupported-binary-operation] +class A3(object): + def __add__(self, other): + return NotImplemented +class B3(A3): + def __radd__(self, other): + return NotImplemented +A3() + B3() # [unsupported-binary-operation] +# Augmented +FFF = 1 +FFF += A() # [unsupported-binary-operation] +TTT = 1 +TTT += [] # [unsupported-binary-operation] + + +# Don't emit for this case since we don't know what unknown is. +from unknown import Unknown +class Base(Unknown): + pass +Base() * 23 diff --git a/tests/functional/u/unsupported/unsupported_binary_operation.rc b/tests/functional/u/unsupported/unsupported_binary_operation.rc new file mode 100644 index 000000000..401ccfe27 --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_binary_operation.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=4.0 diff --git a/tests/functional/u/unsupported/unsupported_binary_operation.txt b/tests/functional/u/unsupported/unsupported_binary_operation.txt new file mode 100644 index 000000000..00e43cbdc --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_binary_operation.txt @@ -0,0 +1,21 @@ +unsupported-binary-operation:9::"unsupported operand type(s) for +: 'int' and 'str'" +unsupported-binary-operation:10::"unsupported operand type(s) for -: 'int' and 'list'" +unsupported-binary-operation:11::"unsupported operand type(s) for *: 'int' and 'dict'" +unsupported-binary-operation:12::"unsupported operand type(s) for /: 'int' and 'module'" +unsupported-binary-operation:13::"unsupported operand type(s) for **: 'int' and 'function'" +unsupported-binary-operation:14::"unsupported operand type(s) for *: 'dict' and 'dict'" +unsupported-binary-operation:15::"unsupported operand type(s) for -: 'dict' and 'dict'" +unsupported-binary-operation:16::"unsupported operand type(s) for |: 'dict' and 'dict'" +unsupported-binary-operation:17::"unsupported operand type(s) for >>: 'dict' and 'dict'" +unsupported-binary-operation:18::"unsupported operand type(s) for +: 'list' and 'tuple'" +unsupported-binary-operation:19::"unsupported operand type(s) for +: 'tuple' and 'list'" +unsupported-binary-operation:20::"unsupported operand type(s) for *: 'list' and 'float'" +unsupported-binary-operation:21::"unsupported operand type(s) for *: 'tuple' and 'float'" +unsupported-binary-operation:22::"unsupported operand type(s) for >>: 'float' and 'float'" +unsupported-binary-operation:27::"unsupported operand type(s) for +: 'A' and 'B'" +unsupported-binary-operation:32::"unsupported operand type(s) for +: 'A1' and 'A1'" +unsupported-binary-operation:40::"unsupported operand type(s) for +: 'A2' and 'B2'" +unsupported-binary-operation:47::"unsupported operand type(s) for +: 'Child' and 'Parent'" +unsupported-binary-operation:54::"unsupported operand type(s) for +: 'A3' and 'B3'" +unsupported-binary-operation:57::"unsupported operand type(s) for +=: 'int' and 'A'" +unsupported-binary-operation:59::"unsupported operand type(s) for +=: 'int' and 'list'" diff --git a/tests/functional/u/unsupported/unsupported_delete_operation.py b/tests/functional/u/unsupported/unsupported_delete_operation.py new file mode 100644 index 000000000..3c2882a64 --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_delete_operation.py @@ -0,0 +1,94 @@ +""" +Checks that value used in a subscript support deletion +(i.e. defines __delitem__ method). +""" +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position,unnecessary-comprehension +# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance +import six + +# primitives +numbers = [1, 2, 3] +del numbers[0] + + +del bytearray(b"123")[0] +del dict(a=1, b=2)['a'] +del (1, 2, 3)[0] # [unsupported-delete-operation] + +# list/dict comprehensions are fine +del [x for x in range(10)][0] +del {x: 10 - x for x in range(10)}[0] + + +# instances +class NonSubscriptable(object): + pass + +class Subscriptable(object): + def __delitem__(self, key): + pass + +del NonSubscriptable()[0] # [unsupported-delete-operation] +del NonSubscriptable[0] # [unsupported-delete-operation] +del Subscriptable()[0] +del Subscriptable[0] # [unsupported-delete-operation] + +# generators are not subscriptable +def powers_of_two(): + k = 0 + while k < 10: + yield 2 ** k + k += 1 + +del powers_of_two()[0] # [unsupported-delete-operation] +del powers_of_two[0] # [unsupported-delete-operation] + + +# check that primitive non subscriptable types are caught +del True[0] # [unsupported-delete-operation] +del None[0] # [unsupported-delete-operation] +del 8.5[0] # [unsupported-delete-operation] +del 10[0] # [unsupported-delete-operation] + +# sets are not subscriptable +del {x ** 2 for x in range(10)}[0] # [unsupported-delete-operation] +del set(numbers)[0] # [unsupported-delete-operation] +del frozenset(numbers)[0] # [unsupported-delete-operation] + +# skip instances with unknown base classes +from some_missing_module import LibSubscriptable + +class MaybeSubscriptable(LibSubscriptable): + pass + +del MaybeSubscriptable()[0] + +# subscriptable classes (through metaclasses) + +class MetaSubscriptable(type): + def __delitem__(cls, key): + pass + +class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): + pass + +del SubscriptableClass[0] +del SubscriptableClass()[0] # [unsupported-delete-operation] + +# functions are not subscriptable +def test(*args, **kwargs): + return args, kwargs + +del test()[0] # [unsupported-delete-operation] +del test[0] # [unsupported-delete-operation] + +# deque +from collections import deque +deq = deque(maxlen=10) +deq.append(42) +del deq[0] + +# tuples assignment +values = [1, 2, 3, 4] +del (values[0], values[1]) +del (values[0], SubscriptableClass()[0]) # [unsupported-delete-operation] diff --git a/tests/functional/u/unsupported/unsupported_delete_operation.rc b/tests/functional/u/unsupported/unsupported_delete_operation.rc new file mode 100644 index 000000000..6a8ee96ca --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_delete_operation.rc @@ -0,0 +1,2 @@ +[testoptions] +requires = six diff --git a/tests/functional/u/unsupported/unsupported_delete_operation.txt b/tests/functional/u/unsupported/unsupported_delete_operation.txt new file mode 100644 index 000000000..6ad92eb33 --- /dev/null +++ b/tests/functional/u/unsupported/unsupported_delete_operation.txt @@ -0,0 +1,17 @@ +unsupported-delete-operation:16:4::'(1, 2, 3)' does not support item deletion +unsupported-delete-operation:31:4::'NonSubscriptable()' does not support item deletion +unsupported-delete-operation:32:4::'NonSubscriptable' does not support item deletion +unsupported-delete-operation:34:4::'Subscriptable' does not support item deletion +unsupported-delete-operation:43:4::'powers_of_two()' does not support item deletion +unsupported-delete-operation:44:4::'powers_of_two' does not support item deletion +unsupported-delete-operation:48:4::'True' does not support item deletion +unsupported-delete-operation:49:4::'None' does not support item deletion +unsupported-delete-operation:50:4::'8.5' does not support item deletion +unsupported-delete-operation:51:4::'10' does not support item deletion +unsupported-delete-operation:54:4::'{x**2 for x in range(10)}' does not support item deletion +unsupported-delete-operation:55:4::'set(numbers)' does not support item deletion +unsupported-delete-operation:56:4::'frozenset(numbers)' does not support item deletion +unsupported-delete-operation:76:4::'SubscriptableClass()' does not support item deletion +unsupported-delete-operation:82:4::'test()' does not support item deletion +unsupported-delete-operation:83:4::'test' does not support item deletion +unsupported-delete-operation:94:16::'SubscriptableClass()' does not support item deletion diff --git a/tests/functional/u/unsupported_assignment_operation.py b/tests/functional/u/unsupported_assignment_operation.py deleted file mode 100644 index c0b58668a..000000000 --- a/tests/functional/u/unsupported_assignment_operation.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Checks that value used in a subscript support assignments -(i.e. defines __setitem__ method). -""" -# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position,unnecessary-comprehension -# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance -import six - -# primitives -numbers = [1, 2, 3] -numbers[0] = 42 - - -bytearray(b"123")[0] = 42 -dict(a=1, b=2)['a'] = 42 -(1, 2, 3)[0] = 42 # [unsupported-assignment-operation] - -# list/dict comprehensions are fine -[x for x in range(10)][0] = 42 -{x: 10 - x for x in range(10)}[0] = 42 - - -# instances -class NonSubscriptable(object): - pass - -class Subscriptable(object): - def __setitem__(self, key, value): - return key + value - -NonSubscriptable()[0] = 24 # [unsupported-assignment-operation] -NonSubscriptable[0] = 24 # [unsupported-assignment-operation] -Subscriptable()[0] = 24 -Subscriptable[0] = 24 # [unsupported-assignment-operation] - -# generators are not subscriptable -def powers_of_two(): - k = 0 - while k < 10: - yield 2 ** k - k += 1 - -powers_of_two()[0] = 42 # [unsupported-assignment-operation] -powers_of_two[0] = 42 # [unsupported-assignment-operation] - - -# check that primitive non subscriptable types are caught -True[0] = 24 # [unsupported-assignment-operation] -None[0] = 42 # [unsupported-assignment-operation] -8.5[0] = 24 # [unsupported-assignment-operation] -10[0] = 24 # [unsupported-assignment-operation] - -# sets are not subscriptable -{x ** 2 for x in range(10)}[0] = 24 # [unsupported-assignment-operation] -set(numbers)[0] = 24 # [unsupported-assignment-operation] -frozenset(numbers)[0] = 42 # [unsupported-assignment-operation] - -# skip instances with unknown base classes -from some_missing_module import LibSubscriptable - -class MaybeSubscriptable(LibSubscriptable): - pass - -MaybeSubscriptable()[0] = 42 - -# subscriptable classes (through metaclasses) - -class MetaSubscriptable(type): - def __setitem__(cls, key, value): - return key + value - -class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): - pass - -SubscriptableClass[0] = 24 -SubscriptableClass()[0] = 24 # [unsupported-assignment-operation] - -# functions are not subscriptable -def test(*args, **kwargs): - return args, kwargs - -test()[0] = 24 # [unsupported-assignment-operation] -test[0] = 24 # [unsupported-assignment-operation] - -# deque -from collections import deque -deq = deque(maxlen=10) -deq.append(42) -deq[0] = 42 - -# tuples assignment -values = [1, 2, 3, 4] -(values[0], values[1]) = 3, 4 -(values[0], SubscriptableClass()[0]) = 42, 42 # [unsupported-assignment-operation] diff --git a/tests/functional/u/unsupported_assignment_operation.rc b/tests/functional/u/unsupported_assignment_operation.rc deleted file mode 100644 index 6a8ee96ca..000000000 --- a/tests/functional/u/unsupported_assignment_operation.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -requires = six diff --git a/tests/functional/u/unsupported_assignment_operation.txt b/tests/functional/u/unsupported_assignment_operation.txt deleted file mode 100644 index 854e8bfec..000000000 --- a/tests/functional/u/unsupported_assignment_operation.txt +++ /dev/null @@ -1,17 +0,0 @@ -unsupported-assignment-operation:16:0::'(1, 2, 3)' does not support item assignment -unsupported-assignment-operation:31:0::'NonSubscriptable()' does not support item assignment -unsupported-assignment-operation:32:0::'NonSubscriptable' does not support item assignment -unsupported-assignment-operation:34:0::'Subscriptable' does not support item assignment -unsupported-assignment-operation:43:0::'powers_of_two()' does not support item assignment -unsupported-assignment-operation:44:0::'powers_of_two' does not support item assignment -unsupported-assignment-operation:48:0::'True' does not support item assignment -unsupported-assignment-operation:49:0::'None' does not support item assignment -unsupported-assignment-operation:50:0::'8.5' does not support item assignment -unsupported-assignment-operation:51:0::'10' does not support item assignment -unsupported-assignment-operation:54:0::'{x**2 for x in range(10)}' does not support item assignment -unsupported-assignment-operation:55:0::'set(numbers)' does not support item assignment -unsupported-assignment-operation:56:0::'frozenset(numbers)' does not support item assignment -unsupported-assignment-operation:76:0::'SubscriptableClass()' does not support item assignment -unsupported-assignment-operation:82:0::'test()' does not support item assignment -unsupported-assignment-operation:83:0::'test' does not support item assignment -unsupported-assignment-operation:94:12::'SubscriptableClass()' does not support item assignment diff --git a/tests/functional/u/unsupported_binary_operation.py b/tests/functional/u/unsupported_binary_operation.py deleted file mode 100644 index 0bfe1d16a..000000000 --- a/tests/functional/u/unsupported_binary_operation.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Test for unsupported-binary-operation.""" -# pylint: disable=missing-docstring,too-few-public-methods,pointless-statement -# pylint: disable=expression-not-assigned, invalid-name, useless-object-inheritance - - -import collections - - -1 + "a" # [unsupported-binary-operation] -1 - [] # [unsupported-binary-operation] -1 * {} # [unsupported-binary-operation] -1 / collections # [unsupported-binary-operation] -1 ** (lambda x: x) # [unsupported-binary-operation] -{} * {} # [unsupported-binary-operation] -{} - {} # [unsupported-binary-operation] -{} | {} # [unsupported-binary-operation] -{} >> {} # [unsupported-binary-operation] -[] + () # [unsupported-binary-operation] -() + [] # [unsupported-binary-operation] -[] * 2.0 # [unsupported-binary-operation] -() * 2.0 # [unsupported-binary-operation] -2.0 >> 2.0 # [unsupported-binary-operation] -class A(object): - pass -class B(object): - pass -A() + B() # [unsupported-binary-operation] -class A1(object): - def __add__(self, other): - return NotImplemented - -A1() + A1() # [unsupported-binary-operation] - -class A2(object): - def __add__(self, other): - return NotImplemented -class B2(object): - def __radd__(self, other): - return NotImplemented -A2() + B2() # [unsupported-binary-operation] - -class Parent(object): - pass -class Child(Parent): - def __add__(self, other): - return NotImplemented -Child() + Parent() # [unsupported-binary-operation] -class A3(object): - def __add__(self, other): - return NotImplemented -class B3(A3): - def __radd__(self, other): - return NotImplemented -A3() + B3() # [unsupported-binary-operation] -# Augmented -FFF = 1 -FFF += A() # [unsupported-binary-operation] -TTT = 1 -TTT += [] # [unsupported-binary-operation] - - -# Don't emit for this case since we don't know what unknown is. -from unknown import Unknown -class Base(Unknown): - pass -Base() * 23 diff --git a/tests/functional/u/unsupported_binary_operation.rc b/tests/functional/u/unsupported_binary_operation.rc deleted file mode 100644 index 401ccfe27..000000000 --- a/tests/functional/u/unsupported_binary_operation.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=4.0 diff --git a/tests/functional/u/unsupported_binary_operation.txt b/tests/functional/u/unsupported_binary_operation.txt deleted file mode 100644 index 00e43cbdc..000000000 --- a/tests/functional/u/unsupported_binary_operation.txt +++ /dev/null @@ -1,21 +0,0 @@ -unsupported-binary-operation:9::"unsupported operand type(s) for +: 'int' and 'str'" -unsupported-binary-operation:10::"unsupported operand type(s) for -: 'int' and 'list'" -unsupported-binary-operation:11::"unsupported operand type(s) for *: 'int' and 'dict'" -unsupported-binary-operation:12::"unsupported operand type(s) for /: 'int' and 'module'" -unsupported-binary-operation:13::"unsupported operand type(s) for **: 'int' and 'function'" -unsupported-binary-operation:14::"unsupported operand type(s) for *: 'dict' and 'dict'" -unsupported-binary-operation:15::"unsupported operand type(s) for -: 'dict' and 'dict'" -unsupported-binary-operation:16::"unsupported operand type(s) for |: 'dict' and 'dict'" -unsupported-binary-operation:17::"unsupported operand type(s) for >>: 'dict' and 'dict'" -unsupported-binary-operation:18::"unsupported operand type(s) for +: 'list' and 'tuple'" -unsupported-binary-operation:19::"unsupported operand type(s) for +: 'tuple' and 'list'" -unsupported-binary-operation:20::"unsupported operand type(s) for *: 'list' and 'float'" -unsupported-binary-operation:21::"unsupported operand type(s) for *: 'tuple' and 'float'" -unsupported-binary-operation:22::"unsupported operand type(s) for >>: 'float' and 'float'" -unsupported-binary-operation:27::"unsupported operand type(s) for +: 'A' and 'B'" -unsupported-binary-operation:32::"unsupported operand type(s) for +: 'A1' and 'A1'" -unsupported-binary-operation:40::"unsupported operand type(s) for +: 'A2' and 'B2'" -unsupported-binary-operation:47::"unsupported operand type(s) for +: 'Child' and 'Parent'" -unsupported-binary-operation:54::"unsupported operand type(s) for +: 'A3' and 'B3'" -unsupported-binary-operation:57::"unsupported operand type(s) for +=: 'int' and 'A'" -unsupported-binary-operation:59::"unsupported operand type(s) for +=: 'int' and 'list'" diff --git a/tests/functional/u/unsupported_delete_operation.py b/tests/functional/u/unsupported_delete_operation.py deleted file mode 100644 index 3c2882a64..000000000 --- a/tests/functional/u/unsupported_delete_operation.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Checks that value used in a subscript support deletion -(i.e. defines __delitem__ method). -""" -# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position,unnecessary-comprehension -# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance -import six - -# primitives -numbers = [1, 2, 3] -del numbers[0] - - -del bytearray(b"123")[0] -del dict(a=1, b=2)['a'] -del (1, 2, 3)[0] # [unsupported-delete-operation] - -# list/dict comprehensions are fine -del [x for x in range(10)][0] -del {x: 10 - x for x in range(10)}[0] - - -# instances -class NonSubscriptable(object): - pass - -class Subscriptable(object): - def __delitem__(self, key): - pass - -del NonSubscriptable()[0] # [unsupported-delete-operation] -del NonSubscriptable[0] # [unsupported-delete-operation] -del Subscriptable()[0] -del Subscriptable[0] # [unsupported-delete-operation] - -# generators are not subscriptable -def powers_of_two(): - k = 0 - while k < 10: - yield 2 ** k - k += 1 - -del powers_of_two()[0] # [unsupported-delete-operation] -del powers_of_two[0] # [unsupported-delete-operation] - - -# check that primitive non subscriptable types are caught -del True[0] # [unsupported-delete-operation] -del None[0] # [unsupported-delete-operation] -del 8.5[0] # [unsupported-delete-operation] -del 10[0] # [unsupported-delete-operation] - -# sets are not subscriptable -del {x ** 2 for x in range(10)}[0] # [unsupported-delete-operation] -del set(numbers)[0] # [unsupported-delete-operation] -del frozenset(numbers)[0] # [unsupported-delete-operation] - -# skip instances with unknown base classes -from some_missing_module import LibSubscriptable - -class MaybeSubscriptable(LibSubscriptable): - pass - -del MaybeSubscriptable()[0] - -# subscriptable classes (through metaclasses) - -class MetaSubscriptable(type): - def __delitem__(cls, key): - pass - -class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): - pass - -del SubscriptableClass[0] -del SubscriptableClass()[0] # [unsupported-delete-operation] - -# functions are not subscriptable -def test(*args, **kwargs): - return args, kwargs - -del test()[0] # [unsupported-delete-operation] -del test[0] # [unsupported-delete-operation] - -# deque -from collections import deque -deq = deque(maxlen=10) -deq.append(42) -del deq[0] - -# tuples assignment -values = [1, 2, 3, 4] -del (values[0], values[1]) -del (values[0], SubscriptableClass()[0]) # [unsupported-delete-operation] diff --git a/tests/functional/u/unsupported_delete_operation.rc b/tests/functional/u/unsupported_delete_operation.rc deleted file mode 100644 index 6a8ee96ca..000000000 --- a/tests/functional/u/unsupported_delete_operation.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -requires = six diff --git a/tests/functional/u/unsupported_delete_operation.txt b/tests/functional/u/unsupported_delete_operation.txt deleted file mode 100644 index 6ad92eb33..000000000 --- a/tests/functional/u/unsupported_delete_operation.txt +++ /dev/null @@ -1,17 +0,0 @@ -unsupported-delete-operation:16:4::'(1, 2, 3)' does not support item deletion -unsupported-delete-operation:31:4::'NonSubscriptable()' does not support item deletion -unsupported-delete-operation:32:4::'NonSubscriptable' does not support item deletion -unsupported-delete-operation:34:4::'Subscriptable' does not support item deletion -unsupported-delete-operation:43:4::'powers_of_two()' does not support item deletion -unsupported-delete-operation:44:4::'powers_of_two' does not support item deletion -unsupported-delete-operation:48:4::'True' does not support item deletion -unsupported-delete-operation:49:4::'None' does not support item deletion -unsupported-delete-operation:50:4::'8.5' does not support item deletion -unsupported-delete-operation:51:4::'10' does not support item deletion -unsupported-delete-operation:54:4::'{x**2 for x in range(10)}' does not support item deletion -unsupported-delete-operation:55:4::'set(numbers)' does not support item deletion -unsupported-delete-operation:56:4::'frozenset(numbers)' does not support item deletion -unsupported-delete-operation:76:4::'SubscriptableClass()' does not support item deletion -unsupported-delete-operation:82:4::'test()' does not support item deletion -unsupported-delete-operation:83:4::'test' does not support item deletion -unsupported-delete-operation:94:16::'SubscriptableClass()' does not support item deletion diff --git a/tests/functional/u/unused/__init__.py b/tests/functional/u/unused/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/functional/u/unused/unused_argument.py b/tests/functional/u/unused/unused_argument.py new file mode 100644 index 000000000..013d4b3e5 --- /dev/null +++ b/tests/functional/u/unused/unused_argument.py @@ -0,0 +1,48 @@ +# pylint: disable=missing-docstring,too-few-public-methods, useless-object-inheritance + +def test_unused(first, second, _not_used): # [unused-argument, unused-argument] + pass + + +def test_prefixed_with_ignored(first, ignored_second): + first() + + +def test_prefixed_with_unused(first, unused_second): + first() + +# for Sub.inherited, only the warning for "aay" is desired. +# The warnings for "aab" and "aac" are most likely false positives though, +# because there could be another subclass that overrides the same method and does +# use the arguments (eg Sub2) + + +class Base(object): + "parent" + def inherited(self, aaa, aab, aac): + "abstract method" + raise NotImplementedError + +class Sub(Base): + "child 1" + def inherited(self, aaa, aab, aac): + "overridden method, though don't use every argument" + return aaa + + def newmethod(self, aax, aay): # [unused-argument] + "another method, warning for aay desired" + return self, aax + +class Sub2(Base): + "child 1" + + def inherited(self, aaa, aab, aac): + "overridden method, use every argument" + return aaa + aab + aac + +def metadata_from_dict(key): + """ + Should not raise unused-argument message because key is + used inside comprehension dict + """ + return {key: str(value) for key, value in key.items()} diff --git a/tests/functional/u/unused/unused_argument.txt b/tests/functional/u/unused/unused_argument.txt new file mode 100644 index 000000000..a30ff2259 --- /dev/null +++ b/tests/functional/u/unused/unused_argument.txt @@ -0,0 +1,3 @@ +unused-argument:3:16:test_unused:Unused argument 'first' +unused-argument:3:23:test_unused:Unused argument 'second' +unused-argument:32:29:Sub.newmethod:Unused argument 'aay':INFERENCE diff --git a/tests/functional/u/unused/unused_argument_py3.py b/tests/functional/u/unused/unused_argument_py3.py new file mode 100644 index 000000000..4d0fd9adc --- /dev/null +++ b/tests/functional/u/unused/unused_argument_py3.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring + +def func(first, *, second): # [unused-argument, unused-argument] + pass + + +def only_raises(first, second=42): # [unused-argument] + if first == 24: + raise ValueError diff --git a/tests/functional/u/unused/unused_argument_py3.rc b/tests/functional/u/unused/unused_argument_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/u/unused/unused_argument_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/u/unused/unused_argument_py3.txt b/tests/functional/u/unused/unused_argument_py3.txt new file mode 100644 index 000000000..2bddb5184 --- /dev/null +++ b/tests/functional/u/unused/unused_argument_py3.txt @@ -0,0 +1,3 @@ +unused-argument:3:9:func:Unused argument 'first' +unused-argument:3:19:func:Unused argument 'second' +unused-argument:7:23:only_raises:Unused argument 'second' diff --git a/tests/functional/u/unused/unused_global_variable1.py b/tests/functional/u/unused/unused_global_variable1.py new file mode 100644 index 000000000..e630c3337 --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable1.py @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' diff --git a/tests/functional/u/unused/unused_global_variable2.py b/tests/functional/u/unused/unused_global_variable2.py new file mode 100644 index 000000000..62224096e --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable2.py @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' # [unused-variable] diff --git a/tests/functional/u/unused/unused_global_variable2.rc b/tests/functional/u/unused/unused_global_variable2.rc new file mode 100644 index 000000000..5dcd4a84c --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable2.rc @@ -0,0 +1,2 @@ +[variables] +allow-global-unused-variables=no diff --git a/tests/functional/u/unused/unused_global_variable2.txt b/tests/functional/u/unused/unused_global_variable2.txt new file mode 100644 index 000000000..a670aa0e0 --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable2.txt @@ -0,0 +1 @@ +unused-variable:2:0::Unused variable 'VAR' diff --git a/tests/functional/u/unused/unused_global_variable3.py b/tests/functional/u/unused/unused_global_variable3.py new file mode 100644 index 000000000..896789eda --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable3.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' + + +def func(argument): + return VAR + argument diff --git a/tests/functional/u/unused/unused_global_variable4.py b/tests/functional/u/unused/unused_global_variable4.py new file mode 100644 index 000000000..aef49d68c --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable4.py @@ -0,0 +1,3 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' # [unused-variable] +VAR = 'pylint2' # [unused-variable] diff --git a/tests/functional/u/unused/unused_global_variable4.rc b/tests/functional/u/unused/unused_global_variable4.rc new file mode 100644 index 000000000..5dcd4a84c --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable4.rc @@ -0,0 +1,2 @@ +[variables] +allow-global-unused-variables=no diff --git a/tests/functional/u/unused/unused_global_variable4.txt b/tests/functional/u/unused/unused_global_variable4.txt new file mode 100644 index 000000000..67e6da979 --- /dev/null +++ b/tests/functional/u/unused/unused_global_variable4.txt @@ -0,0 +1,2 @@ +unused-variable:2:0::Unused variable 'VAR' +unused-variable:3:0::Unused variable 'VAR' diff --git a/tests/functional/u/unused/unused_import.py b/tests/functional/u/unused/unused_import.py new file mode 100644 index 000000000..752f07ca8 --- /dev/null +++ b/tests/functional/u/unused/unused_import.py @@ -0,0 +1,39 @@ +"""unused import""" +# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring,wrong-import-position, useless-object-inheritance, multiple-imports +import xml.etree # [unused-import] +import xml.sax # [unused-import] +import os.path as test # [unused-import] +from sys import argv as test2 # [unused-import] +from sys import flags # [unused-import] +# +1:[unused-import,unused-import] +from collections import deque, OrderedDict, Counter +import re, html.parser # [unused-import] +DATA = Counter() +# pylint: disable=self-assigning-variable +from fake import SomeName, SomeOtherName # [unused-import] +class SomeClass(object): + SomeName = SomeName # https://bitbucket.org/logilab/pylint/issue/475 + SomeOtherName = 1 + SomeOtherName = SomeOtherName + +from never import __all__ +# pylint: disable=wrong-import-order,ungrouped-imports +import typing +from typing import TYPE_CHECKING + + +if typing.TYPE_CHECKING: + import collections +if TYPE_CHECKING: + import itertools + + +def get_ordered_dict() -> 'collections.OrderedDict': + return [] + + +def get_itertools_obj() -> 'itertools.count': + return [] + +def use_html_parser() -> 'html.parser.HTMLParser': + return html.parser.HTMLParser diff --git a/tests/functional/u/unused/unused_import.txt b/tests/functional/u/unused/unused_import.txt new file mode 100644 index 000000000..2dc892d9e --- /dev/null +++ b/tests/functional/u/unused/unused_import.txt @@ -0,0 +1,9 @@ +unused-import:3:0::Unused import xml.etree +unused-import:4:0::Unused import xml.sax +unused-import:5:0::Unused os.path imported as test +unused-import:6:0::Unused argv imported from sys as test2 +unused-import:7:0::Unused flags imported from sys +unused-import:9:0::Unused OrderedDict imported from collections +unused-import:9:0::Unused deque imported from collections +unused-import:10:0::Unused import re +unused-import:13:0::Unused SomeOtherName imported from fake diff --git a/tests/functional/u/unused/unused_import_assigned_to.py b/tests/functional/u/unused/unused_import_assigned_to.py new file mode 100644 index 000000000..81d3e2ce0 --- /dev/null +++ b/tests/functional/u/unused/unused_import_assigned_to.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring, import-error, invalid-name +# pylint: disable=too-few-public-methods, blacklisted-name, no-member, useless-object-inheritance + +import uuid + +# Note this import doesn't actually exist +import foo + +from .a import x + + +class Y(object): + x = x[0] + + +def test(default=None): + return default + + +class BaseModel(object): + uuid = test(default=uuid.uuid4) + + +class bar(object): + foo = foo.baz diff --git a/tests/functional/u/unused/unused_import_everything_disabled.py b/tests/functional/u/unused/unused_import_everything_disabled.py new file mode 100644 index 000000000..7d6cce74c --- /dev/null +++ b/tests/functional/u/unused/unused_import_everything_disabled.py @@ -0,0 +1,8 @@ +"""Test that unused-import is not emitted here when everything else is disabled + +https://github.com/PyCQA/pylint/issues/3445 +""" +from os import environ + +for k, v in environ.items(): + print(k, v) diff --git a/tests/functional/u/unused/unused_import_everything_disabled.rc b/tests/functional/u/unused/unused_import_everything_disabled.rc new file mode 100644 index 000000000..a9f89cf84 --- /dev/null +++ b/tests/functional/u/unused/unused_import_everything_disabled.rc @@ -0,0 +1,3 @@ +[Messages Control] +disable=all +enable=unused-import diff --git a/tests/functional/u/unused/unused_import_positional_only_py38.py b/tests/functional/u/unused/unused_import_positional_only_py38.py new file mode 100644 index 000000000..693a377d9 --- /dev/null +++ b/tests/functional/u/unused/unused_import_positional_only_py38.py @@ -0,0 +1,10 @@ +"""Test that positional only argument annotations are properly marked as consumed + +https://github.com/PyCQA/pylint/issues/3462 +""" +from typing import AnyStr, Set + + +def func(arg: AnyStr, /, arg2: Set[str]): + """Uses positional only arguments""" + return arg, arg2 diff --git a/tests/functional/u/unused/unused_import_positional_only_py38.rc b/tests/functional/u/unused/unused_import_positional_only_py38.rc new file mode 100644 index 000000000..85fc502b3 --- /dev/null +++ b/tests/functional/u/unused/unused_import_positional_only_py38.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.8 diff --git a/tests/functional/u/unused/unused_typing_imports.py b/tests/functional/u/unused/unused_typing_imports.py new file mode 100644 index 000000000..7de4e411b --- /dev/null +++ b/tests/functional/u/unused/unused_typing_imports.py @@ -0,0 +1,85 @@ +# pylint: disable=missing-docstring +"""Regression test for https://github.com/PyCQA/pylint/issues/1168 + +The problem was that we weren't handling keyword-only arguments annotations, +which means we were never processing them. +""" + +import re +import typing +from collections import Counter as CollectionCounter +from collections import defaultdict +from datetime import datetime +from typing import ( + Any, + Callable, + Iterable, + List, + NamedTuple, + Optional, + Pattern, + Sequence, + Set, + Tuple, +) + + +def func1(arg: Optional[Callable]=None): + return arg + + +def func2(*, arg: Optional[Iterable]=None): + return arg + + +SOME_VALUE = [1] # type: List[Any] +for VALUE in [[1], [2], [3]]: # type: Tuple[Any] + print(VALUE) + + +class ContextManager: + def __enter__(self): + return {1} + + def __exit__(self, *_args): + pass + + +with ContextManager() as SOME_DICT: # type: Set[int] + print(SOME_DICT) + + +def func_test_type_comment(param): + # type: (NamedTuple) -> Tuple[NamedTuple, Pattern] + return param, re.compile('good') + + +def typing_fully_qualified(): + variable = None # type: typing.Optional[str] + other_variable: 'typing.Optional[str]' = None + return variable, other_variable + + +def function(arg1, # type: Iterable + arg2 # type: List + ): + # type: (...) -> Sequence + """docstring""" + print(arg1, arg2) + + +def magic(alpha, beta, gamma): + # type: (str, Optional[str], Optional[datetime]) -> Any + """going strong""" + return alpha, beta, gamma + + +def unused_assignment_import(): + foo_or_bar = 42 # type: defaultdict + return foo_or_bar + + +def unused_reassigned_import(counter): + # type: (CollectionCounter) -> int + print(counter) + return 42 diff --git a/tests/functional/u/unused/unused_typing_imports.rc b/tests/functional/u/unused/unused_typing_imports.rc new file mode 100644 index 000000000..b239d6e2e --- /dev/null +++ b/tests/functional/u/unused/unused_typing_imports.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.6 +except_implementations=PyPy diff --git a/tests/functional/u/unused/unused_variable.py b/tests/functional/u/unused/unused_variable.py new file mode 100644 index 000000000..e57e2abb1 --- /dev/null +++ b/tests/functional/u/unused/unused_variable.py @@ -0,0 +1,67 @@ +# pylint: disable=missing-docstring, invalid-name, too-few-public-methods, no-self-use, useless-object-inheritance,import-outside-toplevel + +def test_regression_737(): + import xml # [unused-import] + +def test_regression_923(): + import unittest.case # [unused-import] + import xml as sql # [unused-import] + +def test_unused_with_prepended_underscore(): + _foo = 42 + _ = 24 + __a = 24 + dummy = 24 + _a_ = 42 # [unused-variable] + __a__ = 24 # [unused-variable] + __never_used = 42 + +def test_local_field_prefixed_with_unused_or_ignored(): + flagged_local_field = 42 # [unused-variable] + unused_local_field = 42 + ignored_local_field = 42 + + +class HasUnusedDunderClass(object): + + def test(self): + __class__ = 42 # [unused-variable] + + def best(self): + self.test() + + +def locals_example_defined_before(): + value = 42 # [possibly-unused-variable] + return locals() + + +def locals_example_defined_after(): + local_variables = locals() + value = 42 # [unused-variable] + return local_variables + + +def locals_does_not_account_for_subscopes(): + value = 42 # [unused-variable] + + def some_other_scope(): + return locals() + return some_other_scope + + +def unused_import_from(): + from functools import wraps as abc # [unused-import] + from collections import namedtuple # [unused-import] + + +def unused_import_in_function(value): + from string import digits, hexdigits # [unused-import] + return value if value in digits else "Nope" + + +def hello(arg): + my_var = 'something' # [unused-variable] + if arg: + return True + raise Exception diff --git a/tests/functional/u/unused/unused_variable.txt b/tests/functional/u/unused/unused_variable.txt new file mode 100644 index 000000000..c11bc0dcc --- /dev/null +++ b/tests/functional/u/unused/unused_variable.txt @@ -0,0 +1,14 @@ +unused-import:4:4:test_regression_737:Unused import xml +unused-import:7:4:test_regression_923:Unused import unittest.case +unused-import:8:4:test_regression_923:Unused xml imported as sql +unused-variable:15:4:test_unused_with_prepended_underscore:Unused variable '_a_' +unused-variable:16:4:test_unused_with_prepended_underscore:Unused variable '__a__' +unused-variable:20:4:test_local_field_prefixed_with_unused_or_ignored:Unused variable 'flagged_local_field' +unused-variable:28:8:HasUnusedDunderClass.test:Unused variable '__class__' +possibly-unused-variable:35:4:locals_example_defined_before:Possibly unused variable 'value' +unused-variable:41:4:locals_example_defined_after:Unused variable 'value' +unused-variable:46:4:locals_does_not_account_for_subscopes:Unused variable 'value' +unused-import:54:4:unused_import_from:Unused wraps imported from functools as abc +unused-import:55:4:unused_import_from:Unused namedtuple imported from collections +unused-import:59:4:unused_import_in_function:Unused hexdigits imported from string +unused-variable:64:4:hello:Unused variable 'my_var' diff --git a/tests/functional/u/unused/unused_variable_py36.py b/tests/functional/u/unused/unused_variable_py36.py new file mode 100644 index 000000000..396d02805 --- /dev/null +++ b/tests/functional/u/unused/unused_variable_py36.py @@ -0,0 +1,13 @@ +# pylint: disable=missing-docstring + +def function(): + ann: int = 0 + assign = 0 + + def inner(): + nonlocal ann, assign + ann += 1 + assign += 1 + return ann + assign + + return inner() diff --git a/tests/functional/u/unused/unused_variable_py36.rc b/tests/functional/u/unused/unused_variable_py36.rc new file mode 100644 index 000000000..0ba2b6333 --- /dev/null +++ b/tests/functional/u/unused/unused_variable_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/tests/functional/u/unused_argument.py b/tests/functional/u/unused_argument.py deleted file mode 100644 index 013d4b3e5..000000000 --- a/tests/functional/u/unused_argument.py +++ /dev/null @@ -1,48 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods, useless-object-inheritance - -def test_unused(first, second, _not_used): # [unused-argument, unused-argument] - pass - - -def test_prefixed_with_ignored(first, ignored_second): - first() - - -def test_prefixed_with_unused(first, unused_second): - first() - -# for Sub.inherited, only the warning for "aay" is desired. -# The warnings for "aab" and "aac" are most likely false positives though, -# because there could be another subclass that overrides the same method and does -# use the arguments (eg Sub2) - - -class Base(object): - "parent" - def inherited(self, aaa, aab, aac): - "abstract method" - raise NotImplementedError - -class Sub(Base): - "child 1" - def inherited(self, aaa, aab, aac): - "overridden method, though don't use every argument" - return aaa - - def newmethod(self, aax, aay): # [unused-argument] - "another method, warning for aay desired" - return self, aax - -class Sub2(Base): - "child 1" - - def inherited(self, aaa, aab, aac): - "overridden method, use every argument" - return aaa + aab + aac - -def metadata_from_dict(key): - """ - Should not raise unused-argument message because key is - used inside comprehension dict - """ - return {key: str(value) for key, value in key.items()} diff --git a/tests/functional/u/unused_argument.txt b/tests/functional/u/unused_argument.txt deleted file mode 100644 index a30ff2259..000000000 --- a/tests/functional/u/unused_argument.txt +++ /dev/null @@ -1,3 +0,0 @@ -unused-argument:3:16:test_unused:Unused argument 'first' -unused-argument:3:23:test_unused:Unused argument 'second' -unused-argument:32:29:Sub.newmethod:Unused argument 'aay':INFERENCE diff --git a/tests/functional/u/unused_argument_py3.py b/tests/functional/u/unused_argument_py3.py deleted file mode 100644 index 4d0fd9adc..000000000 --- a/tests/functional/u/unused_argument_py3.py +++ /dev/null @@ -1,9 +0,0 @@ -# pylint: disable=missing-docstring - -def func(first, *, second): # [unused-argument, unused-argument] - pass - - -def only_raises(first, second=42): # [unused-argument] - if first == 24: - raise ValueError diff --git a/tests/functional/u/unused_argument_py3.rc b/tests/functional/u/unused_argument_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/u/unused_argument_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/u/unused_argument_py3.txt b/tests/functional/u/unused_argument_py3.txt deleted file mode 100644 index 2bddb5184..000000000 --- a/tests/functional/u/unused_argument_py3.txt +++ /dev/null @@ -1,3 +0,0 @@ -unused-argument:3:9:func:Unused argument 'first' -unused-argument:3:19:func:Unused argument 'second' -unused-argument:7:23:only_raises:Unused argument 'second' diff --git a/tests/functional/u/unused_global_variable1.py b/tests/functional/u/unused_global_variable1.py deleted file mode 100644 index e630c3337..000000000 --- a/tests/functional/u/unused_global_variable1.py +++ /dev/null @@ -1,2 +0,0 @@ -# pylint: disable=missing-docstring -VAR = 'pylint' diff --git a/tests/functional/u/unused_global_variable2.py b/tests/functional/u/unused_global_variable2.py deleted file mode 100644 index 62224096e..000000000 --- a/tests/functional/u/unused_global_variable2.py +++ /dev/null @@ -1,2 +0,0 @@ -# pylint: disable=missing-docstring -VAR = 'pylint' # [unused-variable] diff --git a/tests/functional/u/unused_global_variable2.rc b/tests/functional/u/unused_global_variable2.rc deleted file mode 100644 index 5dcd4a84c..000000000 --- a/tests/functional/u/unused_global_variable2.rc +++ /dev/null @@ -1,2 +0,0 @@ -[variables] -allow-global-unused-variables=no diff --git a/tests/functional/u/unused_global_variable2.txt b/tests/functional/u/unused_global_variable2.txt deleted file mode 100644 index a670aa0e0..000000000 --- a/tests/functional/u/unused_global_variable2.txt +++ /dev/null @@ -1 +0,0 @@ -unused-variable:2:0::Unused variable 'VAR' diff --git a/tests/functional/u/unused_global_variable3.py b/tests/functional/u/unused_global_variable3.py deleted file mode 100644 index 896789eda..000000000 --- a/tests/functional/u/unused_global_variable3.py +++ /dev/null @@ -1,6 +0,0 @@ -# pylint: disable=missing-docstring -VAR = 'pylint' - - -def func(argument): - return VAR + argument diff --git a/tests/functional/u/unused_global_variable4.py b/tests/functional/u/unused_global_variable4.py deleted file mode 100644 index aef49d68c..000000000 --- a/tests/functional/u/unused_global_variable4.py +++ /dev/null @@ -1,3 +0,0 @@ -# pylint: disable=missing-docstring -VAR = 'pylint' # [unused-variable] -VAR = 'pylint2' # [unused-variable] diff --git a/tests/functional/u/unused_global_variable4.rc b/tests/functional/u/unused_global_variable4.rc deleted file mode 100644 index 5dcd4a84c..000000000 --- a/tests/functional/u/unused_global_variable4.rc +++ /dev/null @@ -1,2 +0,0 @@ -[variables] -allow-global-unused-variables=no diff --git a/tests/functional/u/unused_global_variable4.txt b/tests/functional/u/unused_global_variable4.txt deleted file mode 100644 index 67e6da979..000000000 --- a/tests/functional/u/unused_global_variable4.txt +++ /dev/null @@ -1,2 +0,0 @@ -unused-variable:2:0::Unused variable 'VAR' -unused-variable:3:0::Unused variable 'VAR' diff --git a/tests/functional/u/unused_import.py b/tests/functional/u/unused_import.py deleted file mode 100644 index 752f07ca8..000000000 --- a/tests/functional/u/unused_import.py +++ /dev/null @@ -1,39 +0,0 @@ -"""unused import""" -# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring,wrong-import-position, useless-object-inheritance, multiple-imports -import xml.etree # [unused-import] -import xml.sax # [unused-import] -import os.path as test # [unused-import] -from sys import argv as test2 # [unused-import] -from sys import flags # [unused-import] -# +1:[unused-import,unused-import] -from collections import deque, OrderedDict, Counter -import re, html.parser # [unused-import] -DATA = Counter() -# pylint: disable=self-assigning-variable -from fake import SomeName, SomeOtherName # [unused-import] -class SomeClass(object): - SomeName = SomeName # https://bitbucket.org/logilab/pylint/issue/475 - SomeOtherName = 1 - SomeOtherName = SomeOtherName - -from never import __all__ -# pylint: disable=wrong-import-order,ungrouped-imports -import typing -from typing import TYPE_CHECKING - - -if typing.TYPE_CHECKING: - import collections -if TYPE_CHECKING: - import itertools - - -def get_ordered_dict() -> 'collections.OrderedDict': - return [] - - -def get_itertools_obj() -> 'itertools.count': - return [] - -def use_html_parser() -> 'html.parser.HTMLParser': - return html.parser.HTMLParser diff --git a/tests/functional/u/unused_import.txt b/tests/functional/u/unused_import.txt deleted file mode 100644 index 2dc892d9e..000000000 --- a/tests/functional/u/unused_import.txt +++ /dev/null @@ -1,9 +0,0 @@ -unused-import:3:0::Unused import xml.etree -unused-import:4:0::Unused import xml.sax -unused-import:5:0::Unused os.path imported as test -unused-import:6:0::Unused argv imported from sys as test2 -unused-import:7:0::Unused flags imported from sys -unused-import:9:0::Unused OrderedDict imported from collections -unused-import:9:0::Unused deque imported from collections -unused-import:10:0::Unused import re -unused-import:13:0::Unused SomeOtherName imported from fake diff --git a/tests/functional/u/unused_import_assigned_to.py b/tests/functional/u/unused_import_assigned_to.py deleted file mode 100644 index 81d3e2ce0..000000000 --- a/tests/functional/u/unused_import_assigned_to.py +++ /dev/null @@ -1,25 +0,0 @@ -# pylint: disable=missing-docstring, import-error, invalid-name -# pylint: disable=too-few-public-methods, blacklisted-name, no-member, useless-object-inheritance - -import uuid - -# Note this import doesn't actually exist -import foo - -from .a import x - - -class Y(object): - x = x[0] - - -def test(default=None): - return default - - -class BaseModel(object): - uuid = test(default=uuid.uuid4) - - -class bar(object): - foo = foo.baz diff --git a/tests/functional/u/unused_import_everything_disabled.py b/tests/functional/u/unused_import_everything_disabled.py deleted file mode 100644 index 7d6cce74c..000000000 --- a/tests/functional/u/unused_import_everything_disabled.py +++ /dev/null @@ -1,8 +0,0 @@ -"""Test that unused-import is not emitted here when everything else is disabled - -https://github.com/PyCQA/pylint/issues/3445 -""" -from os import environ - -for k, v in environ.items(): - print(k, v) diff --git a/tests/functional/u/unused_import_everything_disabled.rc b/tests/functional/u/unused_import_everything_disabled.rc deleted file mode 100644 index a9f89cf84..000000000 --- a/tests/functional/u/unused_import_everything_disabled.rc +++ /dev/null @@ -1,3 +0,0 @@ -[Messages Control] -disable=all -enable=unused-import diff --git a/tests/functional/u/unused_import_positional_only_py38.py b/tests/functional/u/unused_import_positional_only_py38.py deleted file mode 100644 index 693a377d9..000000000 --- a/tests/functional/u/unused_import_positional_only_py38.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Test that positional only argument annotations are properly marked as consumed - -https://github.com/PyCQA/pylint/issues/3462 -""" -from typing import AnyStr, Set - - -def func(arg: AnyStr, /, arg2: Set[str]): - """Uses positional only arguments""" - return arg, arg2 diff --git a/tests/functional/u/unused_import_positional_only_py38.rc b/tests/functional/u/unused_import_positional_only_py38.rc deleted file mode 100644 index 85fc502b3..000000000 --- a/tests/functional/u/unused_import_positional_only_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.8 diff --git a/tests/functional/u/unused_typing_imports.py b/tests/functional/u/unused_typing_imports.py deleted file mode 100644 index 7de4e411b..000000000 --- a/tests/functional/u/unused_typing_imports.py +++ /dev/null @@ -1,85 +0,0 @@ -# pylint: disable=missing-docstring -"""Regression test for https://github.com/PyCQA/pylint/issues/1168 - -The problem was that we weren't handling keyword-only arguments annotations, -which means we were never processing them. -""" - -import re -import typing -from collections import Counter as CollectionCounter -from collections import defaultdict -from datetime import datetime -from typing import ( - Any, - Callable, - Iterable, - List, - NamedTuple, - Optional, - Pattern, - Sequence, - Set, - Tuple, -) - - -def func1(arg: Optional[Callable]=None): - return arg - - -def func2(*, arg: Optional[Iterable]=None): - return arg - - -SOME_VALUE = [1] # type: List[Any] -for VALUE in [[1], [2], [3]]: # type: Tuple[Any] - print(VALUE) - - -class ContextManager: - def __enter__(self): - return {1} - - def __exit__(self, *_args): - pass - - -with ContextManager() as SOME_DICT: # type: Set[int] - print(SOME_DICT) - - -def func_test_type_comment(param): - # type: (NamedTuple) -> Tuple[NamedTuple, Pattern] - return param, re.compile('good') - - -def typing_fully_qualified(): - variable = None # type: typing.Optional[str] - other_variable: 'typing.Optional[str]' = None - return variable, other_variable - - -def function(arg1, # type: Iterable - arg2 # type: List - ): - # type: (...) -> Sequence - """docstring""" - print(arg1, arg2) - - -def magic(alpha, beta, gamma): - # type: (str, Optional[str], Optional[datetime]) -> Any - """going strong""" - return alpha, beta, gamma - - -def unused_assignment_import(): - foo_or_bar = 42 # type: defaultdict - return foo_or_bar - - -def unused_reassigned_import(counter): - # type: (CollectionCounter) -> int - print(counter) - return 42 diff --git a/tests/functional/u/unused_typing_imports.rc b/tests/functional/u/unused_typing_imports.rc deleted file mode 100644 index b239d6e2e..000000000 --- a/tests/functional/u/unused_typing_imports.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -min_pyver=3.6 -except_implementations=PyPy diff --git a/tests/functional/u/unused_variable.py b/tests/functional/u/unused_variable.py deleted file mode 100644 index e57e2abb1..000000000 --- a/tests/functional/u/unused_variable.py +++ /dev/null @@ -1,67 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name, too-few-public-methods, no-self-use, useless-object-inheritance,import-outside-toplevel - -def test_regression_737(): - import xml # [unused-import] - -def test_regression_923(): - import unittest.case # [unused-import] - import xml as sql # [unused-import] - -def test_unused_with_prepended_underscore(): - _foo = 42 - _ = 24 - __a = 24 - dummy = 24 - _a_ = 42 # [unused-variable] - __a__ = 24 # [unused-variable] - __never_used = 42 - -def test_local_field_prefixed_with_unused_or_ignored(): - flagged_local_field = 42 # [unused-variable] - unused_local_field = 42 - ignored_local_field = 42 - - -class HasUnusedDunderClass(object): - - def test(self): - __class__ = 42 # [unused-variable] - - def best(self): - self.test() - - -def locals_example_defined_before(): - value = 42 # [possibly-unused-variable] - return locals() - - -def locals_example_defined_after(): - local_variables = locals() - value = 42 # [unused-variable] - return local_variables - - -def locals_does_not_account_for_subscopes(): - value = 42 # [unused-variable] - - def some_other_scope(): - return locals() - return some_other_scope - - -def unused_import_from(): - from functools import wraps as abc # [unused-import] - from collections import namedtuple # [unused-import] - - -def unused_import_in_function(value): - from string import digits, hexdigits # [unused-import] - return value if value in digits else "Nope" - - -def hello(arg): - my_var = 'something' # [unused-variable] - if arg: - return True - raise Exception diff --git a/tests/functional/u/unused_variable.txt b/tests/functional/u/unused_variable.txt deleted file mode 100644 index c11bc0dcc..000000000 --- a/tests/functional/u/unused_variable.txt +++ /dev/null @@ -1,14 +0,0 @@ -unused-import:4:4:test_regression_737:Unused import xml -unused-import:7:4:test_regression_923:Unused import unittest.case -unused-import:8:4:test_regression_923:Unused xml imported as sql -unused-variable:15:4:test_unused_with_prepended_underscore:Unused variable '_a_' -unused-variable:16:4:test_unused_with_prepended_underscore:Unused variable '__a__' -unused-variable:20:4:test_local_field_prefixed_with_unused_or_ignored:Unused variable 'flagged_local_field' -unused-variable:28:8:HasUnusedDunderClass.test:Unused variable '__class__' -possibly-unused-variable:35:4:locals_example_defined_before:Possibly unused variable 'value' -unused-variable:41:4:locals_example_defined_after:Unused variable 'value' -unused-variable:46:4:locals_does_not_account_for_subscopes:Unused variable 'value' -unused-import:54:4:unused_import_from:Unused wraps imported from functools as abc -unused-import:55:4:unused_import_from:Unused namedtuple imported from collections -unused-import:59:4:unused_import_in_function:Unused hexdigits imported from string -unused-variable:64:4:hello:Unused variable 'my_var' diff --git a/tests/functional/u/unused_variable_py36.py b/tests/functional/u/unused_variable_py36.py deleted file mode 100644 index 396d02805..000000000 --- a/tests/functional/u/unused_variable_py36.py +++ /dev/null @@ -1,13 +0,0 @@ -# pylint: disable=missing-docstring - -def function(): - ann: int = 0 - assign = 0 - - def inner(): - nonlocal ann, assign - ann += 1 - assign += 1 - return ann + assign - - return inner() diff --git a/tests/functional/u/unused_variable_py36.rc b/tests/functional/u/unused_variable_py36.rc deleted file mode 100644 index 0ba2b6333..000000000 --- a/tests/functional/u/unused_variable_py36.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.6 diff --git a/tests/functional/u/use/use_a_generator.py b/tests/functional/u/use/use_a_generator.py new file mode 100644 index 000000000..279deb46f --- /dev/null +++ b/tests/functional/u/use/use_a_generator.py @@ -0,0 +1,11 @@ +# pylint: disable=missing-docstring, invalid-name +# https://github.com/PyCQA/pylint/issues/3165 + +any([]) +all([]) + +any([0 for x in list(range(10))]) # [use-a-generator] +all([0 for y in list(range(10))]) # [use-a-generator] + +any(0 for x in list(range(10))) +all(0 for y in list(range(10))) diff --git a/tests/functional/u/use/use_a_generator.txt b/tests/functional/u/use/use_a_generator.txt new file mode 100644 index 000000000..e7be228f0 --- /dev/null +++ b/tests/functional/u/use/use_a_generator.txt @@ -0,0 +1,2 @@ +use-a-generator:7:0::Use a generator instead 'any(0 for x in list(range(10)))' +use-a-generator:8:0::Use a generator instead 'all(0 for y in list(range(10)))' diff --git a/tests/functional/u/use/used_before_assignment_488.py b/tests/functional/u/use/used_before_assignment_488.py new file mode 100644 index 000000000..efc133c2b --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_488.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring +def func(): + """Test that a variable defined in a finally clause does not trigger a false positive""" + try: + variable = 1 + yield variable + finally: + variable = 2 + yield variable diff --git a/tests/functional/u/use/used_before_assignment_issue1081.py b/tests/functional/u/use/used_before_assignment_issue1081.py new file mode 100644 index 000000000..0c59ccebe --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_issue1081.py @@ -0,0 +1,40 @@ +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods, useless-object-inheritance + +x = 24 + + +def used_before_assignment_1(a): + if x == a: # [used-before-assignment] + for x in [1, 2]: # [redefined-outer-name] + pass + + +def used_before_assignment_2(a): + if x == a: # [used-before-assignment] + pass + x = 2 # [redefined-outer-name] + + +def used_before_assignment_3(a): + if x == a: # [used-before-assignment] + if x > 3: + x = 2 # [redefined-outer-name] + + +def not_used_before_assignment(a): + if x == a: + pass + + +def not_used_before_assignment_2(a): + x = 3 # [redefined-outer-name] + if x == a: + pass + + +def func(something): + return something ** 3 + + +class FalsePositive(object): + x = func(x) diff --git a/tests/functional/u/use/used_before_assignment_issue1081.txt b/tests/functional/u/use/used_before_assignment_issue1081.txt new file mode 100644 index 000000000..4d43c4ad2 --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_issue1081.txt @@ -0,0 +1,7 @@ +used-before-assignment:7:7:used_before_assignment_1:Using variable 'x' before assignment +redefined-outer-name:8:12:used_before_assignment_1:Redefining name 'x' from outer scope (line 3) +used-before-assignment:13:7:used_before_assignment_2:Using variable 'x' before assignment +redefined-outer-name:15:4:used_before_assignment_2:Redefining name 'x' from outer scope (line 3) +used-before-assignment:19:7:used_before_assignment_3:Using variable 'x' before assignment +redefined-outer-name:21:12:used_before_assignment_3:Redefining name 'x' from outer scope (line 3) +redefined-outer-name:30:4:not_used_before_assignment_2:Redefining name 'x' from outer scope (line 3) diff --git a/tests/functional/u/use/used_before_assignment_issue853.py b/tests/functional/u/use/used_before_assignment_issue853.py new file mode 100644 index 000000000..f8b412252 --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_issue853.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,bare-except,pointless-statement,superfluous-parens +def strangeproblem(): + try: + for _ in range(0, 4): + message = object() + print(type(message)) + finally: + message = object() + + +try: + MY_INT = 1 + print("MY_INT = %d" % MY_INT) +finally: + MY_INT = 2 + +try: + pass +except: + FALSE_POSITIVE = 1 + FALSE_POSITIVE # here pylint claims used-before-assignment +finally: + FALSE_POSITIVE = 2 # this line is needed to reproduce the issue diff --git a/tests/functional/u/use/used_before_assignment_nonlocal.py b/tests/functional/u/use/used_before_assignment_nonlocal.py new file mode 100644 index 000000000..5cbdd510c --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_nonlocal.py @@ -0,0 +1,60 @@ +"""Check for nonlocal and used-before-assignment""" +# pylint: disable=missing-docstring, unused-variable, no-init, too-few-public-methods + +__revision__ = 0 + +def test_ok(): + """ uses nonlocal """ + cnt = 1 + def wrap(): + nonlocal cnt + cnt = cnt + 1 + wrap() + +def test_fail(): + """ doesn't use nonlocal """ + cnt = 1 + def wrap(): + cnt = cnt + 1 # [used-before-assignment] + wrap() + +def test_fail2(): + """ use nonlocal, but for other variable """ + cnt = 1 + count = 1 + def wrap(): + nonlocal count + cnt = cnt + 1 # [used-before-assignment] + wrap() + +def test_fail3(arg: test_fail4): # [used-before-assignment] + """ Depends on `test_fail4`, in argument annotation. """ + return arg +# +1: [used-before-assignment, used-before-assignment] +def test_fail4(*args: test_fail5, **kwargs: undefined): + """ Depends on `test_fail5` and `undefined` in + variable and named arguments annotations. + """ + return args, kwargs + +def test_fail5()->undefined1: # [used-before-assignment] + """ Depends on `undefined1` in function return annotation. """ + +def undefined(): + """ no op """ + +def undefined1(): + """ no op """ + + +def nonlocal_in_ifexp(): + """bar""" + bug2 = True + def on_click(event): + """on_click""" + if event: + nonlocal bug2 + bug2 = not bug2 + on_click(True) + +nonlocal_in_ifexp() diff --git a/tests/functional/u/use/used_before_assignment_nonlocal.rc b/tests/functional/u/use/used_before_assignment_nonlocal.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_nonlocal.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/u/use/used_before_assignment_nonlocal.txt b/tests/functional/u/use/used_before_assignment_nonlocal.txt new file mode 100644 index 000000000..59aa0756d --- /dev/null +++ b/tests/functional/u/use/used_before_assignment_nonlocal.txt @@ -0,0 +1,6 @@ +used-before-assignment:18:14:test_fail.wrap:Using variable 'cnt' before assignment +used-before-assignment:27:14:test_fail2.wrap:Using variable 'cnt' before assignment +used-before-assignment:30:20:test_fail3:Using variable 'test_fail4' before assignment +used-before-assignment:34:22:test_fail4:Using variable 'test_fail5' before assignment +used-before-assignment:34:44:test_fail4:Using variable 'undefined' before assignment +used-before-assignment:40:18:test_fail5:Using variable 'undefined1' before assignment diff --git a/tests/functional/u/use/used_prior_global_declaration.py b/tests/functional/u/use/used_prior_global_declaration.py new file mode 100644 index 000000000..079501022 --- /dev/null +++ b/tests/functional/u/use/used_prior_global_declaration.py @@ -0,0 +1,39 @@ +# pylint: disable=missing-docstring, pointless-statement, global-variable-not-assigned, global-statement + + +CONST = 1 + + +def test(): + CONST # [used-prior-global-declaration] + + global CONST + + +def other_test(): + CONST + + global SOMETHING + + +def other_test_1(): + global SOMETHING + + CONST + + +def other_test_2(): + CONST + + def inner(): + global CONST + + return inner + + +def other_test_3(): + def inner(): + return CONST + + global CONST + return inner diff --git a/tests/functional/u/use/used_prior_global_declaration.rc b/tests/functional/u/use/used_prior_global_declaration.rc new file mode 100644 index 000000000..0ba2b6333 --- /dev/null +++ b/tests/functional/u/use/used_prior_global_declaration.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/tests/functional/u/use/used_prior_global_declaration.txt b/tests/functional/u/use/used_prior_global_declaration.txt new file mode 100644 index 000000000..2354e0ef8 --- /dev/null +++ b/tests/functional/u/use/used_prior_global_declaration.txt @@ -0,0 +1 @@ +used-prior-global-declaration:8:4:test:Name 'CONST' is used prior to global declaration diff --git a/tests/functional/u/use/using_constant_test.py b/tests/functional/u/use/using_constant_test.py new file mode 100644 index 000000000..df7b56237 --- /dev/null +++ b/tests/functional/u/use/using_constant_test.py @@ -0,0 +1,141 @@ +"""Verify if constant tests are used inside if statements.""" +# pylint: disable=invalid-name, missing-docstring,too-few-public-methods +# pylint: disable=no-init,expression-not-assigned, useless-object-inheritance +# pylint: disable=missing-parentheses-for-call-in-test, unnecessary-comprehension, condition-evals-to-constant + + +import collections + + +def function(): + yield + + +class Class(object): + + def method(self): + pass + + +instance = Class() + +if collections: # [using-constant-test] + pass + +# GenExpr +if (node for node in range(10)): # [using-constant-test] + pass + +if lambda: None: # [using-constant-test] + pass + +if function: # [using-constant-test] + pass + +if Class: # [using-constant-test] + pass + +if 2: # [using-constant-test] + pass + +if True: # [using-constant-test] + pass + +if '': # [using-constant-test] + pass + +if b'': # [using-constant-test] + pass + +if 2.0: # [using-constant-test] + pass + +if {}: # [using-constant-test] + pass + +if {1, 2, 3}: # [using-constant-test] + pass + +if (1, 2, 3): # [using-constant-test] + pass + +if (): # [using-constant-test] + pass + +# Generator +generator = function() +if generator: # [using-constant-test] + pass + +if 1 if 2 else 3: # [using-constant-test] + pass + +def test_comprehensions(): + [data for data in range(100) if abs] # [using-constant-test] + [data for data in range(100) if 1] # [using-constant-test] + (data for data in range(100) if abs) # [using-constant-test] + (data for data in range(100) if 1) # [using-constant-test] + {data for data in range(100) if abs} # [using-constant-test] + {data: 1 for data in range(100) if abs} # [using-constant-test] + + +# UnboundMethod / Function +if Class.method: # [using-constant-test] + pass + +# BoundMethod +if instance.method: # [using-constant-test] + pass + +# For these, we require to do inference, even though the result can be a +# constant value. For some of them, we could determine that the test +# is constant, such as 2 + 3, but the components of the BinOp +# can be anything else (2 + somefunccall). + +name = 42 +if name: + pass + +if 3 + 4: + pass + +if 3 and 4: + pass + +if not 3: + pass + +if instance.method(): + pass + +# pylint: disable=misplaced-comparison-constant +if 2 < 3: + pass + +if tuple((1, 2, 3)): + pass + +if dict(): + pass + +if tuple(): + pass + +if [1, 2, 3][:1]: + pass + +def test(*args): + if args: + return 42 + return None + +def test_good_comprehension_checks(): + [data for data in range(100)] + [data for data in range(100) if data] + [data for data in range(100) if abs(data)] + (data for data in range(100) if data) + (data for data in range(100) if abs(data)) + {data for data in range(100) if data} + {data for data in range(100) if abs(data)} + {data: 1 for data in range(100) if data} + {data: 1 for data in range(100)} diff --git a/tests/functional/u/use/using_constant_test.txt b/tests/functional/u/use/using_constant_test.txt new file mode 100644 index 000000000..b3047955b --- /dev/null +++ b/tests/functional/u/use/using_constant_test.txt @@ -0,0 +1,24 @@ +using-constant-test:22:0::Using a conditional statement with a constant value +using-constant-test:26:0::Using a conditional statement with a constant value +using-constant-test:29:0::Using a conditional statement with a constant value +using-constant-test:32:0::Using a conditional statement with a constant value +using-constant-test:35:0::Using a conditional statement with a constant value +using-constant-test:38:0::Using a conditional statement with a constant value +using-constant-test:41:0::Using a conditional statement with a constant value +using-constant-test:44:0::Using a conditional statement with a constant value +using-constant-test:47:0::Using a conditional statement with a constant value +using-constant-test:50:0::Using a conditional statement with a constant value +using-constant-test:53:0::Using a conditional statement with a constant value +using-constant-test:56:0::Using a conditional statement with a constant value +using-constant-test:59:0::Using a conditional statement with a constant value +using-constant-test:62:0::Using a conditional statement with a constant value +using-constant-test:67:0::Using a conditional statement with a constant value +using-constant-test:70:3::Using a conditional statement with a constant value +using-constant-test:74:0:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:75:0:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:76:0:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:77:0:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:78:0:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:79:0:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:83:0::Using a conditional statement with a constant value +using-constant-test:87:0::Using a conditional statement with a constant value diff --git a/tests/functional/u/use_a_generator.py b/tests/functional/u/use_a_generator.py deleted file mode 100644 index 279deb46f..000000000 --- a/tests/functional/u/use_a_generator.py +++ /dev/null @@ -1,11 +0,0 @@ -# pylint: disable=missing-docstring, invalid-name -# https://github.com/PyCQA/pylint/issues/3165 - -any([]) -all([]) - -any([0 for x in list(range(10))]) # [use-a-generator] -all([0 for y in list(range(10))]) # [use-a-generator] - -any(0 for x in list(range(10))) -all(0 for y in list(range(10))) diff --git a/tests/functional/u/use_a_generator.txt b/tests/functional/u/use_a_generator.txt deleted file mode 100644 index e7be228f0..000000000 --- a/tests/functional/u/use_a_generator.txt +++ /dev/null @@ -1,2 +0,0 @@ -use-a-generator:7:0::Use a generator instead 'any(0 for x in list(range(10)))' -use-a-generator:8:0::Use a generator instead 'all(0 for y in list(range(10)))' diff --git a/tests/functional/u/used_before_assignment_488.py b/tests/functional/u/used_before_assignment_488.py deleted file mode 100644 index efc133c2b..000000000 --- a/tests/functional/u/used_before_assignment_488.py +++ /dev/null @@ -1,9 +0,0 @@ -# pylint: disable=missing-docstring -def func(): - """Test that a variable defined in a finally clause does not trigger a false positive""" - try: - variable = 1 - yield variable - finally: - variable = 2 - yield variable diff --git a/tests/functional/u/used_before_assignment_issue1081.py b/tests/functional/u/used_before_assignment_issue1081.py deleted file mode 100644 index 0c59ccebe..000000000 --- a/tests/functional/u/used_before_assignment_issue1081.py +++ /dev/null @@ -1,40 +0,0 @@ -# pylint: disable=missing-docstring,invalid-name,too-few-public-methods, useless-object-inheritance - -x = 24 - - -def used_before_assignment_1(a): - if x == a: # [used-before-assignment] - for x in [1, 2]: # [redefined-outer-name] - pass - - -def used_before_assignment_2(a): - if x == a: # [used-before-assignment] - pass - x = 2 # [redefined-outer-name] - - -def used_before_assignment_3(a): - if x == a: # [used-before-assignment] - if x > 3: - x = 2 # [redefined-outer-name] - - -def not_used_before_assignment(a): - if x == a: - pass - - -def not_used_before_assignment_2(a): - x = 3 # [redefined-outer-name] - if x == a: - pass - - -def func(something): - return something ** 3 - - -class FalsePositive(object): - x = func(x) diff --git a/tests/functional/u/used_before_assignment_issue1081.txt b/tests/functional/u/used_before_assignment_issue1081.txt deleted file mode 100644 index 4d43c4ad2..000000000 --- a/tests/functional/u/used_before_assignment_issue1081.txt +++ /dev/null @@ -1,7 +0,0 @@ -used-before-assignment:7:7:used_before_assignment_1:Using variable 'x' before assignment -redefined-outer-name:8:12:used_before_assignment_1:Redefining name 'x' from outer scope (line 3) -used-before-assignment:13:7:used_before_assignment_2:Using variable 'x' before assignment -redefined-outer-name:15:4:used_before_assignment_2:Redefining name 'x' from outer scope (line 3) -used-before-assignment:19:7:used_before_assignment_3:Using variable 'x' before assignment -redefined-outer-name:21:12:used_before_assignment_3:Redefining name 'x' from outer scope (line 3) -redefined-outer-name:30:4:not_used_before_assignment_2:Redefining name 'x' from outer scope (line 3) diff --git a/tests/functional/u/used_before_assignment_issue853.py b/tests/functional/u/used_before_assignment_issue853.py deleted file mode 100644 index f8b412252..000000000 --- a/tests/functional/u/used_before_assignment_issue853.py +++ /dev/null @@ -1,23 +0,0 @@ -# pylint: disable=missing-docstring,bare-except,pointless-statement,superfluous-parens -def strangeproblem(): - try: - for _ in range(0, 4): - message = object() - print(type(message)) - finally: - message = object() - - -try: - MY_INT = 1 - print("MY_INT = %d" % MY_INT) -finally: - MY_INT = 2 - -try: - pass -except: - FALSE_POSITIVE = 1 - FALSE_POSITIVE # here pylint claims used-before-assignment -finally: - FALSE_POSITIVE = 2 # this line is needed to reproduce the issue diff --git a/tests/functional/u/used_before_assignment_nonlocal.py b/tests/functional/u/used_before_assignment_nonlocal.py deleted file mode 100644 index 5cbdd510c..000000000 --- a/tests/functional/u/used_before_assignment_nonlocal.py +++ /dev/null @@ -1,60 +0,0 @@ -"""Check for nonlocal and used-before-assignment""" -# pylint: disable=missing-docstring, unused-variable, no-init, too-few-public-methods - -__revision__ = 0 - -def test_ok(): - """ uses nonlocal """ - cnt = 1 - def wrap(): - nonlocal cnt - cnt = cnt + 1 - wrap() - -def test_fail(): - """ doesn't use nonlocal """ - cnt = 1 - def wrap(): - cnt = cnt + 1 # [used-before-assignment] - wrap() - -def test_fail2(): - """ use nonlocal, but for other variable """ - cnt = 1 - count = 1 - def wrap(): - nonlocal count - cnt = cnt + 1 # [used-before-assignment] - wrap() - -def test_fail3(arg: test_fail4): # [used-before-assignment] - """ Depends on `test_fail4`, in argument annotation. """ - return arg -# +1: [used-before-assignment, used-before-assignment] -def test_fail4(*args: test_fail5, **kwargs: undefined): - """ Depends on `test_fail5` and `undefined` in - variable and named arguments annotations. - """ - return args, kwargs - -def test_fail5()->undefined1: # [used-before-assignment] - """ Depends on `undefined1` in function return annotation. """ - -def undefined(): - """ no op """ - -def undefined1(): - """ no op """ - - -def nonlocal_in_ifexp(): - """bar""" - bug2 = True - def on_click(event): - """on_click""" - if event: - nonlocal bug2 - bug2 = not bug2 - on_click(True) - -nonlocal_in_ifexp() diff --git a/tests/functional/u/used_before_assignment_nonlocal.rc b/tests/functional/u/used_before_assignment_nonlocal.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/u/used_before_assignment_nonlocal.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/u/used_before_assignment_nonlocal.txt b/tests/functional/u/used_before_assignment_nonlocal.txt deleted file mode 100644 index 59aa0756d..000000000 --- a/tests/functional/u/used_before_assignment_nonlocal.txt +++ /dev/null @@ -1,6 +0,0 @@ -used-before-assignment:18:14:test_fail.wrap:Using variable 'cnt' before assignment -used-before-assignment:27:14:test_fail2.wrap:Using variable 'cnt' before assignment -used-before-assignment:30:20:test_fail3:Using variable 'test_fail4' before assignment -used-before-assignment:34:22:test_fail4:Using variable 'test_fail5' before assignment -used-before-assignment:34:44:test_fail4:Using variable 'undefined' before assignment -used-before-assignment:40:18:test_fail5:Using variable 'undefined1' before assignment diff --git a/tests/functional/u/used_prior_global_declaration.py b/tests/functional/u/used_prior_global_declaration.py deleted file mode 100644 index 079501022..000000000 --- a/tests/functional/u/used_prior_global_declaration.py +++ /dev/null @@ -1,39 +0,0 @@ -# pylint: disable=missing-docstring, pointless-statement, global-variable-not-assigned, global-statement - - -CONST = 1 - - -def test(): - CONST # [used-prior-global-declaration] - - global CONST - - -def other_test(): - CONST - - global SOMETHING - - -def other_test_1(): - global SOMETHING - - CONST - - -def other_test_2(): - CONST - - def inner(): - global CONST - - return inner - - -def other_test_3(): - def inner(): - return CONST - - global CONST - return inner diff --git a/tests/functional/u/used_prior_global_declaration.rc b/tests/functional/u/used_prior_global_declaration.rc deleted file mode 100644 index 0ba2b6333..000000000 --- a/tests/functional/u/used_prior_global_declaration.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.6 diff --git a/tests/functional/u/used_prior_global_declaration.txt b/tests/functional/u/used_prior_global_declaration.txt deleted file mode 100644 index 2354e0ef8..000000000 --- a/tests/functional/u/used_prior_global_declaration.txt +++ /dev/null @@ -1 +0,0 @@ -used-prior-global-declaration:8:4:test:Name 'CONST' is used prior to global declaration diff --git a/tests/functional/u/useless-import-alias.py b/tests/functional/u/useless-import-alias.py deleted file mode 100644 index c8ef8374d..000000000 --- a/tests/functional/u/useless-import-alias.py +++ /dev/null @@ -1,21 +0,0 @@ -# pylint: disable=unused-import, missing-docstring, invalid-name, reimported, import-error, wrong-import-order, no-name-in-module, relative-beyond-top-level -from collections import OrderedDict as OrderedDict # [useless-import-alias] -from collections import OrderedDict as o_dict -import os.path as path -import os.path as p -import foo.bar.foobar as foobar -import os -import os as OS -from sys import version -from . import bar as bar # [useless-import-alias] -from . import bar as Bar -from . import bar -from ..foo import bar as bar # [useless-import-alias] -from ..foo.bar import foobar as foobar # [useless-import-alias] -from ..foo.bar import foobar as anotherfoobar -from . import foo as foo, foo2 as bar2 # [useless-import-alias] -from . import foo as bar, foo2 as foo2 # [useless-import-alias] -from . import foo as bar, foo2 as bar2 -from foo.bar import foobar as foobar # [useless-import-alias] -from foo.bar import foobar as foo -from .foo.bar import f as foobar diff --git a/tests/functional/u/useless-import-alias.txt b/tests/functional/u/useless-import-alias.txt deleted file mode 100644 index bc99952ac..000000000 --- a/tests/functional/u/useless-import-alias.txt +++ /dev/null @@ -1,7 +0,0 @@ -useless-import-alias:2:0::Import alias does not rename original package -useless-import-alias:10:0::Import alias does not rename original package -useless-import-alias:13:0::Import alias does not rename original package -useless-import-alias:14:0::Import alias does not rename original package -useless-import-alias:16:0::Import alias does not rename original package -useless-import-alias:17:0::Import alias does not rename original package -useless-import-alias:19:0::Import alias does not rename original package diff --git a/tests/functional/u/useless/useless-import-alias.py b/tests/functional/u/useless/useless-import-alias.py new file mode 100644 index 000000000..c8ef8374d --- /dev/null +++ b/tests/functional/u/useless/useless-import-alias.py @@ -0,0 +1,21 @@ +# pylint: disable=unused-import, missing-docstring, invalid-name, reimported, import-error, wrong-import-order, no-name-in-module, relative-beyond-top-level +from collections import OrderedDict as OrderedDict # [useless-import-alias] +from collections import OrderedDict as o_dict +import os.path as path +import os.path as p +import foo.bar.foobar as foobar +import os +import os as OS +from sys import version +from . import bar as bar # [useless-import-alias] +from . import bar as Bar +from . import bar +from ..foo import bar as bar # [useless-import-alias] +from ..foo.bar import foobar as foobar # [useless-import-alias] +from ..foo.bar import foobar as anotherfoobar +from . import foo as foo, foo2 as bar2 # [useless-import-alias] +from . import foo as bar, foo2 as foo2 # [useless-import-alias] +from . import foo as bar, foo2 as bar2 +from foo.bar import foobar as foobar # [useless-import-alias] +from foo.bar import foobar as foo +from .foo.bar import f as foobar diff --git a/tests/functional/u/useless/useless-import-alias.txt b/tests/functional/u/useless/useless-import-alias.txt new file mode 100644 index 000000000..bc99952ac --- /dev/null +++ b/tests/functional/u/useless/useless-import-alias.txt @@ -0,0 +1,7 @@ +useless-import-alias:2:0::Import alias does not rename original package +useless-import-alias:10:0::Import alias does not rename original package +useless-import-alias:13:0::Import alias does not rename original package +useless-import-alias:14:0::Import alias does not rename original package +useless-import-alias:16:0::Import alias does not rename original package +useless-import-alias:17:0::Import alias does not rename original package +useless-import-alias:19:0::Import alias does not rename original package diff --git a/tests/functional/u/useless/useless_else_on_loop.py b/tests/functional/u/useless/useless_else_on_loop.py new file mode 100644 index 000000000..d686f4658 --- /dev/null +++ b/tests/functional/u/useless/useless_else_on_loop.py @@ -0,0 +1,103 @@ +"""Check for else branches on loops with break and return only.""" +from __future__ import print_function +__revision__ = 0 + +def test_return_for(): + """else + return is not accetable.""" + for i in range(10): + if i % 2: + return i + else: # [useless-else-on-loop] + print('math is broken') + return None + +def test_return_while(): + """else + return is not accetable.""" + while True: + return 1 + else: # [useless-else-on-loop] + print('math is broken') + return None + + +while True: + def short_fun(): + """A function with a loop.""" + for _ in range(10): + break +else: # [useless-else-on-loop] + print('or else!') + + +while True: + while False: + break +else: # [useless-else-on-loop] + print('or else!') + +for j in range(10): + pass +else: # [useless-else-on-loop] + print('fat chance') + for j in range(10): + break + + +def test_return_for2(): + """no false positive for break in else + + https://bitbucket.org/logilab/pylint/issue/117/useless-else-on-loop-false-positives + """ + for i in range(10): + for _ in range(i): + if i % 2: + break + else: + break + else: + print('great math') + + +def test_break_in_orelse_deep(): + """no false positive for break in else deeply nested + """ + for _ in range(10): + if 1 < 2: + for _ in range(3): + if 3 < 2: + break + else: + break + else: + return True + return False + + +def test_break_in_orelse_deep2(): + """should rise a useless-else-on-loop message, as the break statement is only + for the inner for loop + """ + for _ in range(10): + if 1 < 2: + for _ in range(3): + if 3 < 2: + break + else: + print("all right") + else: # [useless-else-on-loop] + return True + return False + + +def test_break_in_orelse_deep3(): + """no false positive for break deeply nested in else + """ + for _ in range(10): + for _ in range(3): + pass + else: + if 1 < 2: + break + else: + return True + return False diff --git a/tests/functional/u/useless/useless_else_on_loop.txt b/tests/functional/u/useless/useless_else_on_loop.txt new file mode 100644 index 000000000..dff8e318a --- /dev/null +++ b/tests/functional/u/useless/useless_else_on_loop.txt @@ -0,0 +1,6 @@ +useless-else-on-loop:10:4:test_return_for:Else clause on loop without a break statement +useless-else-on-loop:18:4:test_return_while:Else clause on loop without a break statement +useless-else-on-loop:28:0::Else clause on loop without a break statement +useless-else-on-loop:35:0::Else clause on loop without a break statement +useless-else-on-loop:40:0::Else clause on loop without a break statement +useless-else-on-loop:87:4:test_break_in_orelse_deep2:Else clause on loop without a break statement diff --git a/tests/functional/u/useless/useless_object_inheritance.py b/tests/functional/u/useless/useless_object_inheritance.py new file mode 100644 index 000000000..562c81f6a --- /dev/null +++ b/tests/functional/u/useless/useless_object_inheritance.py @@ -0,0 +1,27 @@ +"""Check if a class inherits from object. +In python3 every class implicitly inherits from object, therefore give refactoring message to + remove object from bases""" +# pylint: disable=no-init, invalid-name, missing-docstring, too-few-public-methods +# pylint: disable=inconsistent-mro +import abc + +class A(object): # [useless-object-inheritance] + pass + +class B: + pass + +class C(B, object): # [useless-object-inheritance] + pass + +class D(object, C, metaclass=abc.ABCMeta): # [useless-object-inheritance] + pass + +class E(D, C, object, metaclass=abc.ABCMeta): # [useless-object-inheritance] + pass + +class F(A): # positive test case + pass + +class G(B): # positive test case + pass diff --git a/tests/functional/u/useless/useless_object_inheritance.txt b/tests/functional/u/useless/useless_object_inheritance.txt new file mode 100644 index 000000000..1b18607fa --- /dev/null +++ b/tests/functional/u/useless/useless_object_inheritance.txt @@ -0,0 +1,4 @@ +useless-object-inheritance:8:0:A:Class 'A' inherits from object, can be safely removed from bases in python3 +useless-object-inheritance:14:0:C:Class 'C' inherits from object, can be safely removed from bases in python3 +useless-object-inheritance:17:0:D:Class 'D' inherits from object, can be safely removed from bases in python3 +useless-object-inheritance:20:0:E:Class 'E' inherits from object, can be safely removed from bases in python3 diff --git a/tests/functional/u/useless/useless_return.py b/tests/functional/u/useless/useless_return.py new file mode 100644 index 000000000..61aaebe7a --- /dev/null +++ b/tests/functional/u/useless/useless_return.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-self-use,bad-option-value, useless-object-inheritance +from __future__ import print_function + +def myfunc(): # [useless-return] + print('---- testing ---') + return + +class SomeClass(object): + def mymethod(self): # [useless-return] + print('---- testing ---') + return None + + # These are not emitted + def item_at(self): + return None diff --git a/tests/functional/u/useless/useless_return.txt b/tests/functional/u/useless/useless_return.txt new file mode 100644 index 000000000..9299b458a --- /dev/null +++ b/tests/functional/u/useless/useless_return.txt @@ -0,0 +1,2 @@ +useless-return:4:0:myfunc:Useless return at end of function or method +useless-return:9:4:SomeClass.mymethod:Useless return at end of function or method diff --git a/tests/functional/u/useless/useless_super_delegation.py b/tests/functional/u/useless/useless_super_delegation.py new file mode 100644 index 000000000..002c7eb03 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation.py @@ -0,0 +1,262 @@ +# pylint: disable=missing-docstring, no-member, no-self-use, bad-super-call +# pylint: disable=too-few-public-methods, unused-argument, invalid-name, too-many-public-methods +# pylint: disable=line-too-long, useless-object-inheritance, arguments-out-of-order +# pylint: disable=super-with-arguments, dangerous-default-value + +def not_a_method(param, param2): + return super(None, None).not_a_method(param, param2) + + +class SuperBase(object): + def with_default_arg(self, first, default_arg="only_in_super_base"): + pass + + def with_default_arg_bis(self, first, default_arg="only_in_super_base"): + pass + + def with_default_arg_ter(self, first, default_arg="will_be_changed"): + pass + + def with_default_arg_quad(self, first, default_arg="will_be_changed"): + pass + + +class Base(SuperBase): + + fake_method = not_a_method + + def something(self): + pass + + def with_default_argument(self, first, default_arg="default"): + pass + + def with_default_argument_bis(self, first, default_arg="default"): + pass + + def without_default_argument(self, first, second): + pass + + def with_default_argument_none(self, first, default_arg=None): + pass + + def without_default_argument2(self, first, second): + pass + + def with_default_argument_int(self, first, default_arg=42): + pass + + def with_default_argument_tuple(self, first, default_arg=()): + pass + + def with_default_argument_dict(self, first, default_arg={}): + pass + + def with_default_arg_ter(self, first, default_arg="has_been_changed"): + super().with_default_arg_ter(first, default_arg) + + def with_default_arg_quad(self, first, default_arg="has_been_changed"): + super().with_default_arg_quad(first, default_arg) + +class NotUselessSuper(Base): + + def multiple_statements(self): + first = 42 * 24 + return super().multiple_statements() + first + + def not_a_call(self): + return 1 + 2 + + def not_super_call(self): + return type(self).__class__ + + def not_super_attribute_access(self): + return super() + + def invalid_super_call(self): + return super(NotUselessSuper, 1).invalid_super_call() + + def other_invalid_super_call(self): + return super(2, 3, 4, 5).other_invalid_super_call() + + def different_name(self): + return super().something() + + def different_super_mro_pointer(self): + return super(Base, self).different_super_mro_pointer() + + def different_super_type(self): + return super(NotUselessSuper, NotUselessSuper).different_super_type() + + def other_different_super_type(self): + return super(NotUselessSuper, 1).other_different_super_type() + + def not_passing_param(self, first): + return super(NotUselessSuper, self).not_passing_param() + + def modifying_param(self, first): + return super(NotUselessSuper, self).modifying_param(first + 1) + + def transforming_param(self, first): + return super(NotUselessSuper, self).transforming_param(type(first)) + + def modifying_variadic(self, *args): + return super(NotUselessSuper, self).modifying_variadic(tuple(args)) + + def not_passing_keyword_variadics(self, *args, **kwargs): + return super(NotUselessSuper, self).not_passing_keyword_variadics(*args) + + def not_passing_default(self, first, second=None): + return super(NotUselessSuper, self).not_passing_default(first) + + def passing_only_a_handful(self, first, second, third, fourth): + return super(NotUselessSuper, self).passing_only_a_handful( + first, second) + + def not_the_same_order(self, first, second, third): + return super(NotUselessSuper, self).not_the_same_order(third, first, second) + + def no_kwargs_in_signature(self, key=None): + values = {'key': 'something'} + return super(NotUselessSuper, self).no_kwargs_in_signature(**values) + + def no_args_in_signature(self, first, second): + values = (first + 1, second + 2) + return super(NotUselessSuper, self).no_args_in_signature(*values) + + def variadics_with_multiple_keyword_arguments(self, **kwargs): + return super(NotUselessSuper, self).variadics_with_multiple_keyword_arguments( + first=None, + second=None, + **kwargs) + + def extraneous_keyword_params(self, none_ok=False): + super(NotUselessSuper, self).extraneous_keyword_params( + none_ok, + valid_values=[23, 42]) + + def extraneous_positional_args(self, **args): + super(NotUselessSuper, self).extraneous_positional_args( + 1, 2, **args) + + def with_default_argument(self, first, default_arg="other"): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument(first, default_arg) + + def without_default_argument(self, first, second=True): + # Not useless because in the base class there is not default value for second argument + super(NotUselessSuper, self).without_default_argument(first, second) + + def with_default_argument_none(self, first, default_arg='NotNone'): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument_none(first, default_arg) + + def without_default_argument2(self, first, second=None): + # Not useless because in the base class there is not default value for second argument + super(NotUselessSuper, self).without_default_argument2(first, second) + + def with_default_argument_int(self, first, default_arg="42"): + # Not useless because the default_arg is a string whereas in the base class it's an int + super(NotUselessSuper, self).with_default_argument_int(first, default_arg) + + def with_default_argument_tuple(self, first, default_arg=("42", "a")): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument_tuple(first, default_arg) + + def with_default_argument_dict(self, first, default_arg={'foo': 'bar'}): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument_dict(first, default_arg) + + def with_default_argument_bis(self, first, default_arg="default"): + # Although the default_arg is the same as in the base class, the call signature + # differs. Thus it is not useless. + super(NotUselessSuper, self).with_default_argument_bis(default_arg + "_argument") + + def fake_method(self, param2="other"): + super(NotUselessSuper, self).fake_method(param2) + + def with_default_arg(self, first, default_arg="only_in_super_base"): + # Not useless because the call of this method is different from the function signature + super(NotUselessSuper, self).with_default_arg(first, default_arg + "_and_here") + + def with_default_arg_bis(self, first, default_arg="default_changed"): + # Not useless because the default value is different from the SuperBase one + super(NotUselessSuper, self).with_default_arg_bis(first, default_arg) + + def with_default_arg_ter(self, first, default_arg="has_been_changed_again"): + # Not useless because the default value is different from the Base one + super(NotUselessSuper, self).with_default_arg_ter(first, default_arg) + + def with_default_arg_quad(self, first, default_arg="has_been_changed"): + # Not useless because the default value is the same as in the base but the + # call is different from the signature + super(NotUselessSuper, self).with_default_arg_quad(first, default_arg + "_and_modified") + + +class UselessSuper(Base): + + def equivalent_params(self): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params() + + def equivalent_params_1(self, first): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_1(first) + + def equivalent_params_2(self, *args): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_2(*args) + + def equivalent_params_3(self, *args, **kwargs): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_3(*args, **kwargs) + + def equivalent_params_4(self, first): # [useless-super-delegation] + super(UselessSuper, self).equivalent_params_4(first) + + def equivalent_params_5(self, first, *args): # [useless-super-delegation] + super(UselessSuper, self).equivalent_params_5(first, *args) + + def equivalent_params_6(self, first, *args, **kwargs): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_6(first, *args, **kwargs) + + def with_default_argument(self, first, default_arg="default"): # [useless-super-delegation] + # useless because the default value here is the same as in the base class + return super(UselessSuper, self).with_default_argument(first, default_arg) + + def without_default_argument(self, first, second): # [useless-super-delegation] + return super(UselessSuper, self).without_default_argument(first, second) + + def with_default_argument_none(self, first, default_arg=None): # [useless-super-delegation] + # useless because the default value here is the same as in the base class + super(UselessSuper, self).with_default_argument_none(first, default_arg) + + def with_default_argument_int(self, first, default_arg=42): # [useless-super-delegation] + super(UselessSuper, self).with_default_argument_int(first, default_arg) + + def with_default_argument_tuple(self, first, default_arg=()): # [useless-super-delegation] + super(UselessSuper, self).with_default_argument_tuple(first, default_arg) + + def with_default_argument_dict(self, first, default_arg={}): # [useless-super-delegation] + super(UselessSuper, self).with_default_argument_dict(first, default_arg) + + def __init__(self): # [useless-super-delegation] + super(UselessSuper, self).__init__() + + def with_default_arg(self, first, default_arg="only_in_super_base"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg(first, default_arg) + + def with_default_arg_bis(self, first, default_arg="only_in_super_base"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg_bis(first, default_arg) + + def with_default_arg_ter(self, first, default_arg="has_been_changed"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg_ter(first, default_arg) + + def with_default_arg_quad(self, first, default_arg="has_been_changed"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg_quad(first, default_arg) + + +def trigger_something(value_to_trigger): + pass + + +class NotUselessSuperDecorators(Base): + @trigger_something('value1') + def method_decorated(self): + super(NotUselessSuperDecorators, self).method_decorated() diff --git a/tests/functional/u/useless/useless_super_delegation.txt b/tests/functional/u/useless/useless_super_delegation.txt new file mode 100644 index 000000000..d2dae5603 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation.txt @@ -0,0 +1,18 @@ +useless-super-delegation:198:4:UselessSuper.equivalent_params:Useless super delegation in method 'equivalent_params' +useless-super-delegation:201:4:UselessSuper.equivalent_params_1:Useless super delegation in method 'equivalent_params_1' +useless-super-delegation:204:4:UselessSuper.equivalent_params_2:Useless super delegation in method 'equivalent_params_2' +useless-super-delegation:207:4:UselessSuper.equivalent_params_3:Useless super delegation in method 'equivalent_params_3' +useless-super-delegation:210:4:UselessSuper.equivalent_params_4:Useless super delegation in method 'equivalent_params_4' +useless-super-delegation:213:4:UselessSuper.equivalent_params_5:Useless super delegation in method 'equivalent_params_5' +useless-super-delegation:216:4:UselessSuper.equivalent_params_6:Useless super delegation in method 'equivalent_params_6' +useless-super-delegation:219:4:UselessSuper.with_default_argument:Useless super delegation in method 'with_default_argument' +useless-super-delegation:223:4:UselessSuper.without_default_argument:Useless super delegation in method 'without_default_argument' +useless-super-delegation:226:4:UselessSuper.with_default_argument_none:Useless super delegation in method 'with_default_argument_none' +useless-super-delegation:230:4:UselessSuper.with_default_argument_int:Useless super delegation in method 'with_default_argument_int' +useless-super-delegation:233:4:UselessSuper.with_default_argument_tuple:Useless super delegation in method 'with_default_argument_tuple' +useless-super-delegation:236:4:UselessSuper.with_default_argument_dict:Useless super delegation in method 'with_default_argument_dict' +useless-super-delegation:239:4:UselessSuper.__init__:Useless super delegation in method '__init__' +useless-super-delegation:242:4:UselessSuper.with_default_arg:Useless super delegation in method 'with_default_arg' +useless-super-delegation:245:4:UselessSuper.with_default_arg_bis:Useless super delegation in method 'with_default_arg_bis' +useless-super-delegation:248:4:UselessSuper.with_default_arg_ter:Useless super delegation in method 'with_default_arg_ter' +useless-super-delegation:251:4:UselessSuper.with_default_arg_quad:Useless super delegation in method 'with_default_arg_quad' diff --git a/tests/functional/u/useless/useless_super_delegation_py3.py b/tests/functional/u/useless/useless_super_delegation_py3.py new file mode 100644 index 000000000..b32ced873 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py3.py @@ -0,0 +1,43 @@ +# pylint: disable=missing-docstring, no-member, unused-argument, invalid-name,unused-variable +# pylint: disable=too-few-public-methods,wrong-import-position, useless-object-inheritance + +class NotUselessSuper(object): + + def not_passing_keyword_only(self, first, *, second): + return super().not_passing_keyword_only(first) + + def passing_keyword_only_with_modifications(self, first, *, second): + return super().passing_keyword_only_with_modifications( + first, second + 1) + + +class AlsoNotUselessSuper(NotUselessSuper): + def not_passing_keyword_only(self, first, *, second="second"): + return super().not_passing_keyword_only(first, second=second) + + +class UselessSuper(object): + + def useless(self, *, first): # [useless-super-delegation] + super().useless(first=first) + + +class Egg(): + def __init__(self, thing: object) -> None: + pass + +class Spam(Egg): + def __init__(self, thing: int) -> None: + super().__init__(thing) + +class Ham(Egg): + def __init__(self, thing: object) -> None: # [useless-super-delegation] + super().__init__(thing) + + +from typing import List + + +class Test: + def __init__(self, _arg: List[int]) -> None: + super().__init__() diff --git a/tests/functional/u/useless/useless_super_delegation_py3.rc b/tests/functional/u/useless/useless_super_delegation_py3.rc new file mode 100644 index 000000000..c093be204 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/tests/functional/u/useless/useless_super_delegation_py3.txt b/tests/functional/u/useless/useless_super_delegation_py3.txt new file mode 100644 index 000000000..3a1fdaa1a --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py3.txt @@ -0,0 +1,2 @@ +useless-super-delegation:21:4:UselessSuper.useless:Useless super delegation in method 'useless' +useless-super-delegation:34:4:Ham.__init__:Useless super delegation in method '__init__' diff --git a/tests/functional/u/useless/useless_super_delegation_py35.py b/tests/functional/u/useless/useless_super_delegation_py35.py new file mode 100644 index 000000000..16030f8a4 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py35.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-member,unused-argument, useless-object-inheritance + +class NotUselessSuper(object): + + def not_passing_all_params(self, first, *args, second=None, **kwargs): + return super().not_passing_all_params(*args, second, **kwargs) + + +class UselessSuper(object): + + def useless(self, first, *, second=None, **kwargs): # [useless-super-delegation] + return super().useless(first, second=second, **kwargs) diff --git a/tests/functional/u/useless/useless_super_delegation_py35.rc b/tests/functional/u/useless/useless_super_delegation_py35.rc new file mode 100644 index 000000000..71de8b630 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py35.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 diff --git a/tests/functional/u/useless/useless_super_delegation_py35.txt b/tests/functional/u/useless/useless_super_delegation_py35.txt new file mode 100644 index 000000000..672ce197e --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py35.txt @@ -0,0 +1 @@ +useless-super-delegation:11:4:UselessSuper.useless:Useless super delegation in method 'useless' diff --git a/tests/functional/u/useless/useless_super_delegation_py38.py b/tests/functional/u/useless/useless_super_delegation_py38.py new file mode 100644 index 000000000..ec402299f --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py38.py @@ -0,0 +1,17 @@ +# pylint: disable=missing-docstring,too-few-public-methods +from typing import Any + + +class Egg: + def __init__(self, first: Any, /, second: Any) -> None: + pass + + +class Spam(Egg): + def __init__(self, first: float, /, second: float) -> None: + super().__init__(first, second) + + +class Ham(Egg): + def __init__(self, first: Any, /, second: Any) -> None: # [useless-super-delegation] + super().__init__(first, second) diff --git a/tests/functional/u/useless/useless_super_delegation_py38.rc b/tests/functional/u/useless/useless_super_delegation_py38.rc new file mode 100644 index 000000000..85fc502b3 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py38.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.8 diff --git a/tests/functional/u/useless/useless_super_delegation_py38.txt b/tests/functional/u/useless/useless_super_delegation_py38.txt new file mode 100644 index 000000000..333444554 --- /dev/null +++ b/tests/functional/u/useless/useless_super_delegation_py38.txt @@ -0,0 +1 @@ +useless-super-delegation:16:4:Ham.__init__:Useless super delegation in method '__init__' diff --git a/tests/functional/u/useless_else_on_loop.py b/tests/functional/u/useless_else_on_loop.py deleted file mode 100644 index d686f4658..000000000 --- a/tests/functional/u/useless_else_on_loop.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Check for else branches on loops with break and return only.""" -from __future__ import print_function -__revision__ = 0 - -def test_return_for(): - """else + return is not accetable.""" - for i in range(10): - if i % 2: - return i - else: # [useless-else-on-loop] - print('math is broken') - return None - -def test_return_while(): - """else + return is not accetable.""" - while True: - return 1 - else: # [useless-else-on-loop] - print('math is broken') - return None - - -while True: - def short_fun(): - """A function with a loop.""" - for _ in range(10): - break -else: # [useless-else-on-loop] - print('or else!') - - -while True: - while False: - break -else: # [useless-else-on-loop] - print('or else!') - -for j in range(10): - pass -else: # [useless-else-on-loop] - print('fat chance') - for j in range(10): - break - - -def test_return_for2(): - """no false positive for break in else - - https://bitbucket.org/logilab/pylint/issue/117/useless-else-on-loop-false-positives - """ - for i in range(10): - for _ in range(i): - if i % 2: - break - else: - break - else: - print('great math') - - -def test_break_in_orelse_deep(): - """no false positive for break in else deeply nested - """ - for _ in range(10): - if 1 < 2: - for _ in range(3): - if 3 < 2: - break - else: - break - else: - return True - return False - - -def test_break_in_orelse_deep2(): - """should rise a useless-else-on-loop message, as the break statement is only - for the inner for loop - """ - for _ in range(10): - if 1 < 2: - for _ in range(3): - if 3 < 2: - break - else: - print("all right") - else: # [useless-else-on-loop] - return True - return False - - -def test_break_in_orelse_deep3(): - """no false positive for break deeply nested in else - """ - for _ in range(10): - for _ in range(3): - pass - else: - if 1 < 2: - break - else: - return True - return False diff --git a/tests/functional/u/useless_else_on_loop.txt b/tests/functional/u/useless_else_on_loop.txt deleted file mode 100644 index dff8e318a..000000000 --- a/tests/functional/u/useless_else_on_loop.txt +++ /dev/null @@ -1,6 +0,0 @@ -useless-else-on-loop:10:4:test_return_for:Else clause on loop without a break statement -useless-else-on-loop:18:4:test_return_while:Else clause on loop without a break statement -useless-else-on-loop:28:0::Else clause on loop without a break statement -useless-else-on-loop:35:0::Else clause on loop without a break statement -useless-else-on-loop:40:0::Else clause on loop without a break statement -useless-else-on-loop:87:4:test_break_in_orelse_deep2:Else clause on loop without a break statement diff --git a/tests/functional/u/useless_object_inheritance.py b/tests/functional/u/useless_object_inheritance.py deleted file mode 100644 index 562c81f6a..000000000 --- a/tests/functional/u/useless_object_inheritance.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Check if a class inherits from object. -In python3 every class implicitly inherits from object, therefore give refactoring message to - remove object from bases""" -# pylint: disable=no-init, invalid-name, missing-docstring, too-few-public-methods -# pylint: disable=inconsistent-mro -import abc - -class A(object): # [useless-object-inheritance] - pass - -class B: - pass - -class C(B, object): # [useless-object-inheritance] - pass - -class D(object, C, metaclass=abc.ABCMeta): # [useless-object-inheritance] - pass - -class E(D, C, object, metaclass=abc.ABCMeta): # [useless-object-inheritance] - pass - -class F(A): # positive test case - pass - -class G(B): # positive test case - pass diff --git a/tests/functional/u/useless_object_inheritance.txt b/tests/functional/u/useless_object_inheritance.txt deleted file mode 100644 index 1b18607fa..000000000 --- a/tests/functional/u/useless_object_inheritance.txt +++ /dev/null @@ -1,4 +0,0 @@ -useless-object-inheritance:8:0:A:Class 'A' inherits from object, can be safely removed from bases in python3 -useless-object-inheritance:14:0:C:Class 'C' inherits from object, can be safely removed from bases in python3 -useless-object-inheritance:17:0:D:Class 'D' inherits from object, can be safely removed from bases in python3 -useless-object-inheritance:20:0:E:Class 'E' inherits from object, can be safely removed from bases in python3 diff --git a/tests/functional/u/useless_return.py b/tests/functional/u/useless_return.py deleted file mode 100644 index 61aaebe7a..000000000 --- a/tests/functional/u/useless_return.py +++ /dev/null @@ -1,15 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods,no-self-use,bad-option-value, useless-object-inheritance -from __future__ import print_function - -def myfunc(): # [useless-return] - print('---- testing ---') - return - -class SomeClass(object): - def mymethod(self): # [useless-return] - print('---- testing ---') - return None - - # These are not emitted - def item_at(self): - return None diff --git a/tests/functional/u/useless_return.txt b/tests/functional/u/useless_return.txt deleted file mode 100644 index 9299b458a..000000000 --- a/tests/functional/u/useless_return.txt +++ /dev/null @@ -1,2 +0,0 @@ -useless-return:4:0:myfunc:Useless return at end of function or method -useless-return:9:4:SomeClass.mymethod:Useless return at end of function or method diff --git a/tests/functional/u/useless_super_delegation.py b/tests/functional/u/useless_super_delegation.py deleted file mode 100644 index 002c7eb03..000000000 --- a/tests/functional/u/useless_super_delegation.py +++ /dev/null @@ -1,262 +0,0 @@ -# pylint: disable=missing-docstring, no-member, no-self-use, bad-super-call -# pylint: disable=too-few-public-methods, unused-argument, invalid-name, too-many-public-methods -# pylint: disable=line-too-long, useless-object-inheritance, arguments-out-of-order -# pylint: disable=super-with-arguments, dangerous-default-value - -def not_a_method(param, param2): - return super(None, None).not_a_method(param, param2) - - -class SuperBase(object): - def with_default_arg(self, first, default_arg="only_in_super_base"): - pass - - def with_default_arg_bis(self, first, default_arg="only_in_super_base"): - pass - - def with_default_arg_ter(self, first, default_arg="will_be_changed"): - pass - - def with_default_arg_quad(self, first, default_arg="will_be_changed"): - pass - - -class Base(SuperBase): - - fake_method = not_a_method - - def something(self): - pass - - def with_default_argument(self, first, default_arg="default"): - pass - - def with_default_argument_bis(self, first, default_arg="default"): - pass - - def without_default_argument(self, first, second): - pass - - def with_default_argument_none(self, first, default_arg=None): - pass - - def without_default_argument2(self, first, second): - pass - - def with_default_argument_int(self, first, default_arg=42): - pass - - def with_default_argument_tuple(self, first, default_arg=()): - pass - - def with_default_argument_dict(self, first, default_arg={}): - pass - - def with_default_arg_ter(self, first, default_arg="has_been_changed"): - super().with_default_arg_ter(first, default_arg) - - def with_default_arg_quad(self, first, default_arg="has_been_changed"): - super().with_default_arg_quad(first, default_arg) - -class NotUselessSuper(Base): - - def multiple_statements(self): - first = 42 * 24 - return super().multiple_statements() + first - - def not_a_call(self): - return 1 + 2 - - def not_super_call(self): - return type(self).__class__ - - def not_super_attribute_access(self): - return super() - - def invalid_super_call(self): - return super(NotUselessSuper, 1).invalid_super_call() - - def other_invalid_super_call(self): - return super(2, 3, 4, 5).other_invalid_super_call() - - def different_name(self): - return super().something() - - def different_super_mro_pointer(self): - return super(Base, self).different_super_mro_pointer() - - def different_super_type(self): - return super(NotUselessSuper, NotUselessSuper).different_super_type() - - def other_different_super_type(self): - return super(NotUselessSuper, 1).other_different_super_type() - - def not_passing_param(self, first): - return super(NotUselessSuper, self).not_passing_param() - - def modifying_param(self, first): - return super(NotUselessSuper, self).modifying_param(first + 1) - - def transforming_param(self, first): - return super(NotUselessSuper, self).transforming_param(type(first)) - - def modifying_variadic(self, *args): - return super(NotUselessSuper, self).modifying_variadic(tuple(args)) - - def not_passing_keyword_variadics(self, *args, **kwargs): - return super(NotUselessSuper, self).not_passing_keyword_variadics(*args) - - def not_passing_default(self, first, second=None): - return super(NotUselessSuper, self).not_passing_default(first) - - def passing_only_a_handful(self, first, second, third, fourth): - return super(NotUselessSuper, self).passing_only_a_handful( - first, second) - - def not_the_same_order(self, first, second, third): - return super(NotUselessSuper, self).not_the_same_order(third, first, second) - - def no_kwargs_in_signature(self, key=None): - values = {'key': 'something'} - return super(NotUselessSuper, self).no_kwargs_in_signature(**values) - - def no_args_in_signature(self, first, second): - values = (first + 1, second + 2) - return super(NotUselessSuper, self).no_args_in_signature(*values) - - def variadics_with_multiple_keyword_arguments(self, **kwargs): - return super(NotUselessSuper, self).variadics_with_multiple_keyword_arguments( - first=None, - second=None, - **kwargs) - - def extraneous_keyword_params(self, none_ok=False): - super(NotUselessSuper, self).extraneous_keyword_params( - none_ok, - valid_values=[23, 42]) - - def extraneous_positional_args(self, **args): - super(NotUselessSuper, self).extraneous_positional_args( - 1, 2, **args) - - def with_default_argument(self, first, default_arg="other"): - # Not useless because the default_arg is different from the one in the base class - super(NotUselessSuper, self).with_default_argument(first, default_arg) - - def without_default_argument(self, first, second=True): - # Not useless because in the base class there is not default value for second argument - super(NotUselessSuper, self).without_default_argument(first, second) - - def with_default_argument_none(self, first, default_arg='NotNone'): - # Not useless because the default_arg is different from the one in the base class - super(NotUselessSuper, self).with_default_argument_none(first, default_arg) - - def without_default_argument2(self, first, second=None): - # Not useless because in the base class there is not default value for second argument - super(NotUselessSuper, self).without_default_argument2(first, second) - - def with_default_argument_int(self, first, default_arg="42"): - # Not useless because the default_arg is a string whereas in the base class it's an int - super(NotUselessSuper, self).with_default_argument_int(first, default_arg) - - def with_default_argument_tuple(self, first, default_arg=("42", "a")): - # Not useless because the default_arg is different from the one in the base class - super(NotUselessSuper, self).with_default_argument_tuple(first, default_arg) - - def with_default_argument_dict(self, first, default_arg={'foo': 'bar'}): - # Not useless because the default_arg is different from the one in the base class - super(NotUselessSuper, self).with_default_argument_dict(first, default_arg) - - def with_default_argument_bis(self, first, default_arg="default"): - # Although the default_arg is the same as in the base class, the call signature - # differs. Thus it is not useless. - super(NotUselessSuper, self).with_default_argument_bis(default_arg + "_argument") - - def fake_method(self, param2="other"): - super(NotUselessSuper, self).fake_method(param2) - - def with_default_arg(self, first, default_arg="only_in_super_base"): - # Not useless because the call of this method is different from the function signature - super(NotUselessSuper, self).with_default_arg(first, default_arg + "_and_here") - - def with_default_arg_bis(self, first, default_arg="default_changed"): - # Not useless because the default value is different from the SuperBase one - super(NotUselessSuper, self).with_default_arg_bis(first, default_arg) - - def with_default_arg_ter(self, first, default_arg="has_been_changed_again"): - # Not useless because the default value is different from the Base one - super(NotUselessSuper, self).with_default_arg_ter(first, default_arg) - - def with_default_arg_quad(self, first, default_arg="has_been_changed"): - # Not useless because the default value is the same as in the base but the - # call is different from the signature - super(NotUselessSuper, self).with_default_arg_quad(first, default_arg + "_and_modified") - - -class UselessSuper(Base): - - def equivalent_params(self): # [useless-super-delegation] - return super(UselessSuper, self).equivalent_params() - - def equivalent_params_1(self, first): # [useless-super-delegation] - return super(UselessSuper, self).equivalent_params_1(first) - - def equivalent_params_2(self, *args): # [useless-super-delegation] - return super(UselessSuper, self).equivalent_params_2(*args) - - def equivalent_params_3(self, *args, **kwargs): # [useless-super-delegation] - return super(UselessSuper, self).equivalent_params_3(*args, **kwargs) - - def equivalent_params_4(self, first): # [useless-super-delegation] - super(UselessSuper, self).equivalent_params_4(first) - - def equivalent_params_5(self, first, *args): # [useless-super-delegation] - super(UselessSuper, self).equivalent_params_5(first, *args) - - def equivalent_params_6(self, first, *args, **kwargs): # [useless-super-delegation] - return super(UselessSuper, self).equivalent_params_6(first, *args, **kwargs) - - def with_default_argument(self, first, default_arg="default"): # [useless-super-delegation] - # useless because the default value here is the same as in the base class - return super(UselessSuper, self).with_default_argument(first, default_arg) - - def without_default_argument(self, first, second): # [useless-super-delegation] - return super(UselessSuper, self).without_default_argument(first, second) - - def with_default_argument_none(self, first, default_arg=None): # [useless-super-delegation] - # useless because the default value here is the same as in the base class - super(UselessSuper, self).with_default_argument_none(first, default_arg) - - def with_default_argument_int(self, first, default_arg=42): # [useless-super-delegation] - super(UselessSuper, self).with_default_argument_int(first, default_arg) - - def with_default_argument_tuple(self, first, default_arg=()): # [useless-super-delegation] - super(UselessSuper, self).with_default_argument_tuple(first, default_arg) - - def with_default_argument_dict(self, first, default_arg={}): # [useless-super-delegation] - super(UselessSuper, self).with_default_argument_dict(first, default_arg) - - def __init__(self): # [useless-super-delegation] - super(UselessSuper, self).__init__() - - def with_default_arg(self, first, default_arg="only_in_super_base"): # [useless-super-delegation] - super(UselessSuper, self).with_default_arg(first, default_arg) - - def with_default_arg_bis(self, first, default_arg="only_in_super_base"): # [useless-super-delegation] - super(UselessSuper, self).with_default_arg_bis(first, default_arg) - - def with_default_arg_ter(self, first, default_arg="has_been_changed"): # [useless-super-delegation] - super(UselessSuper, self).with_default_arg_ter(first, default_arg) - - def with_default_arg_quad(self, first, default_arg="has_been_changed"): # [useless-super-delegation] - super(UselessSuper, self).with_default_arg_quad(first, default_arg) - - -def trigger_something(value_to_trigger): - pass - - -class NotUselessSuperDecorators(Base): - @trigger_something('value1') - def method_decorated(self): - super(NotUselessSuperDecorators, self).method_decorated() diff --git a/tests/functional/u/useless_super_delegation.txt b/tests/functional/u/useless_super_delegation.txt deleted file mode 100644 index d2dae5603..000000000 --- a/tests/functional/u/useless_super_delegation.txt +++ /dev/null @@ -1,18 +0,0 @@ -useless-super-delegation:198:4:UselessSuper.equivalent_params:Useless super delegation in method 'equivalent_params' -useless-super-delegation:201:4:UselessSuper.equivalent_params_1:Useless super delegation in method 'equivalent_params_1' -useless-super-delegation:204:4:UselessSuper.equivalent_params_2:Useless super delegation in method 'equivalent_params_2' -useless-super-delegation:207:4:UselessSuper.equivalent_params_3:Useless super delegation in method 'equivalent_params_3' -useless-super-delegation:210:4:UselessSuper.equivalent_params_4:Useless super delegation in method 'equivalent_params_4' -useless-super-delegation:213:4:UselessSuper.equivalent_params_5:Useless super delegation in method 'equivalent_params_5' -useless-super-delegation:216:4:UselessSuper.equivalent_params_6:Useless super delegation in method 'equivalent_params_6' -useless-super-delegation:219:4:UselessSuper.with_default_argument:Useless super delegation in method 'with_default_argument' -useless-super-delegation:223:4:UselessSuper.without_default_argument:Useless super delegation in method 'without_default_argument' -useless-super-delegation:226:4:UselessSuper.with_default_argument_none:Useless super delegation in method 'with_default_argument_none' -useless-super-delegation:230:4:UselessSuper.with_default_argument_int:Useless super delegation in method 'with_default_argument_int' -useless-super-delegation:233:4:UselessSuper.with_default_argument_tuple:Useless super delegation in method 'with_default_argument_tuple' -useless-super-delegation:236:4:UselessSuper.with_default_argument_dict:Useless super delegation in method 'with_default_argument_dict' -useless-super-delegation:239:4:UselessSuper.__init__:Useless super delegation in method '__init__' -useless-super-delegation:242:4:UselessSuper.with_default_arg:Useless super delegation in method 'with_default_arg' -useless-super-delegation:245:4:UselessSuper.with_default_arg_bis:Useless super delegation in method 'with_default_arg_bis' -useless-super-delegation:248:4:UselessSuper.with_default_arg_ter:Useless super delegation in method 'with_default_arg_ter' -useless-super-delegation:251:4:UselessSuper.with_default_arg_quad:Useless super delegation in method 'with_default_arg_quad' diff --git a/tests/functional/u/useless_super_delegation_py3.py b/tests/functional/u/useless_super_delegation_py3.py deleted file mode 100644 index b32ced873..000000000 --- a/tests/functional/u/useless_super_delegation_py3.py +++ /dev/null @@ -1,43 +0,0 @@ -# pylint: disable=missing-docstring, no-member, unused-argument, invalid-name,unused-variable -# pylint: disable=too-few-public-methods,wrong-import-position, useless-object-inheritance - -class NotUselessSuper(object): - - def not_passing_keyword_only(self, first, *, second): - return super().not_passing_keyword_only(first) - - def passing_keyword_only_with_modifications(self, first, *, second): - return super().passing_keyword_only_with_modifications( - first, second + 1) - - -class AlsoNotUselessSuper(NotUselessSuper): - def not_passing_keyword_only(self, first, *, second="second"): - return super().not_passing_keyword_only(first, second=second) - - -class UselessSuper(object): - - def useless(self, *, first): # [useless-super-delegation] - super().useless(first=first) - - -class Egg(): - def __init__(self, thing: object) -> None: - pass - -class Spam(Egg): - def __init__(self, thing: int) -> None: - super().__init__(thing) - -class Ham(Egg): - def __init__(self, thing: object) -> None: # [useless-super-delegation] - super().__init__(thing) - - -from typing import List - - -class Test: - def __init__(self, _arg: List[int]) -> None: - super().__init__() diff --git a/tests/functional/u/useless_super_delegation_py3.rc b/tests/functional/u/useless_super_delegation_py3.rc deleted file mode 100644 index c093be204..000000000 --- a/tests/functional/u/useless_super_delegation_py3.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.0 diff --git a/tests/functional/u/useless_super_delegation_py3.txt b/tests/functional/u/useless_super_delegation_py3.txt deleted file mode 100644 index 3a1fdaa1a..000000000 --- a/tests/functional/u/useless_super_delegation_py3.txt +++ /dev/null @@ -1,2 +0,0 @@ -useless-super-delegation:21:4:UselessSuper.useless:Useless super delegation in method 'useless' -useless-super-delegation:34:4:Ham.__init__:Useless super delegation in method '__init__' diff --git a/tests/functional/u/useless_super_delegation_py35.py b/tests/functional/u/useless_super_delegation_py35.py deleted file mode 100644 index 16030f8a4..000000000 --- a/tests/functional/u/useless_super_delegation_py35.py +++ /dev/null @@ -1,12 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods,no-member,unused-argument, useless-object-inheritance - -class NotUselessSuper(object): - - def not_passing_all_params(self, first, *args, second=None, **kwargs): - return super().not_passing_all_params(*args, second, **kwargs) - - -class UselessSuper(object): - - def useless(self, first, *, second=None, **kwargs): # [useless-super-delegation] - return super().useless(first, second=second, **kwargs) diff --git a/tests/functional/u/useless_super_delegation_py35.rc b/tests/functional/u/useless_super_delegation_py35.rc deleted file mode 100644 index 71de8b630..000000000 --- a/tests/functional/u/useless_super_delegation_py35.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.5 diff --git a/tests/functional/u/useless_super_delegation_py35.txt b/tests/functional/u/useless_super_delegation_py35.txt deleted file mode 100644 index 672ce197e..000000000 --- a/tests/functional/u/useless_super_delegation_py35.txt +++ /dev/null @@ -1 +0,0 @@ -useless-super-delegation:11:4:UselessSuper.useless:Useless super delegation in method 'useless' diff --git a/tests/functional/u/useless_super_delegation_py38.py b/tests/functional/u/useless_super_delegation_py38.py deleted file mode 100644 index ec402299f..000000000 --- a/tests/functional/u/useless_super_delegation_py38.py +++ /dev/null @@ -1,17 +0,0 @@ -# pylint: disable=missing-docstring,too-few-public-methods -from typing import Any - - -class Egg: - def __init__(self, first: Any, /, second: Any) -> None: - pass - - -class Spam(Egg): - def __init__(self, first: float, /, second: float) -> None: - super().__init__(first, second) - - -class Ham(Egg): - def __init__(self, first: Any, /, second: Any) -> None: # [useless-super-delegation] - super().__init__(first, second) diff --git a/tests/functional/u/useless_super_delegation_py38.rc b/tests/functional/u/useless_super_delegation_py38.rc deleted file mode 100644 index 85fc502b3..000000000 --- a/tests/functional/u/useless_super_delegation_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.8 diff --git a/tests/functional/u/useless_super_delegation_py38.txt b/tests/functional/u/useless_super_delegation_py38.txt deleted file mode 100644 index 333444554..000000000 --- a/tests/functional/u/useless_super_delegation_py38.txt +++ /dev/null @@ -1 +0,0 @@ -useless-super-delegation:16:4:Ham.__init__:Useless super delegation in method '__init__' diff --git a/tests/functional/u/using_constant_test.py b/tests/functional/u/using_constant_test.py deleted file mode 100644 index df7b56237..000000000 --- a/tests/functional/u/using_constant_test.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Verify if constant tests are used inside if statements.""" -# pylint: disable=invalid-name, missing-docstring,too-few-public-methods -# pylint: disable=no-init,expression-not-assigned, useless-object-inheritance -# pylint: disable=missing-parentheses-for-call-in-test, unnecessary-comprehension, condition-evals-to-constant - - -import collections - - -def function(): - yield - - -class Class(object): - - def method(self): - pass - - -instance = Class() - -if collections: # [using-constant-test] - pass - -# GenExpr -if (node for node in range(10)): # [using-constant-test] - pass - -if lambda: None: # [using-constant-test] - pass - -if function: # [using-constant-test] - pass - -if Class: # [using-constant-test] - pass - -if 2: # [using-constant-test] - pass - -if True: # [using-constant-test] - pass - -if '': # [using-constant-test] - pass - -if b'': # [using-constant-test] - pass - -if 2.0: # [using-constant-test] - pass - -if {}: # [using-constant-test] - pass - -if {1, 2, 3}: # [using-constant-test] - pass - -if (1, 2, 3): # [using-constant-test] - pass - -if (): # [using-constant-test] - pass - -# Generator -generator = function() -if generator: # [using-constant-test] - pass - -if 1 if 2 else 3: # [using-constant-test] - pass - -def test_comprehensions(): - [data for data in range(100) if abs] # [using-constant-test] - [data for data in range(100) if 1] # [using-constant-test] - (data for data in range(100) if abs) # [using-constant-test] - (data for data in range(100) if 1) # [using-constant-test] - {data for data in range(100) if abs} # [using-constant-test] - {data: 1 for data in range(100) if abs} # [using-constant-test] - - -# UnboundMethod / Function -if Class.method: # [using-constant-test] - pass - -# BoundMethod -if instance.method: # [using-constant-test] - pass - -# For these, we require to do inference, even though the result can be a -# constant value. For some of them, we could determine that the test -# is constant, such as 2 + 3, but the components of the BinOp -# can be anything else (2 + somefunccall). - -name = 42 -if name: - pass - -if 3 + 4: - pass - -if 3 and 4: - pass - -if not 3: - pass - -if instance.method(): - pass - -# pylint: disable=misplaced-comparison-constant -if 2 < 3: - pass - -if tuple((1, 2, 3)): - pass - -if dict(): - pass - -if tuple(): - pass - -if [1, 2, 3][:1]: - pass - -def test(*args): - if args: - return 42 - return None - -def test_good_comprehension_checks(): - [data for data in range(100)] - [data for data in range(100) if data] - [data for data in range(100) if abs(data)] - (data for data in range(100) if data) - (data for data in range(100) if abs(data)) - {data for data in range(100) if data} - {data for data in range(100) if abs(data)} - {data: 1 for data in range(100) if data} - {data: 1 for data in range(100)} diff --git a/tests/functional/u/using_constant_test.txt b/tests/functional/u/using_constant_test.txt deleted file mode 100644 index b3047955b..000000000 --- a/tests/functional/u/using_constant_test.txt +++ /dev/null @@ -1,24 +0,0 @@ -using-constant-test:22:0::Using a conditional statement with a constant value -using-constant-test:26:0::Using a conditional statement with a constant value -using-constant-test:29:0::Using a conditional statement with a constant value -using-constant-test:32:0::Using a conditional statement with a constant value -using-constant-test:35:0::Using a conditional statement with a constant value -using-constant-test:38:0::Using a conditional statement with a constant value -using-constant-test:41:0::Using a conditional statement with a constant value -using-constant-test:44:0::Using a conditional statement with a constant value -using-constant-test:47:0::Using a conditional statement with a constant value -using-constant-test:50:0::Using a conditional statement with a constant value -using-constant-test:53:0::Using a conditional statement with a constant value -using-constant-test:56:0::Using a conditional statement with a constant value -using-constant-test:59:0::Using a conditional statement with a constant value -using-constant-test:62:0::Using a conditional statement with a constant value -using-constant-test:67:0::Using a conditional statement with a constant value -using-constant-test:70:3::Using a conditional statement with a constant value -using-constant-test:74:0:test_comprehensions:Using a conditional statement with a constant value -using-constant-test:75:0:test_comprehensions:Using a conditional statement with a constant value -using-constant-test:76:0:test_comprehensions:Using a conditional statement with a constant value -using-constant-test:77:0:test_comprehensions:Using a conditional statement with a constant value -using-constant-test:78:0:test_comprehensions:Using a conditional statement with a constant value -using-constant-test:79:0:test_comprehensions:Using a conditional statement with a constant value -using-constant-test:83:0::Using a conditional statement with a constant value -using-constant-test:87:0::Using a conditional statement with a constant value diff --git a/tests/test_self.py b/tests/test_self.py index 954aa95d7..b3d8927b9 100644 --- a/tests/test_self.py +++ b/tests/test_self.py @@ -60,6 +60,9 @@ from pylint.utils import utils HERE = abspath(dirname(__file__)) CLEAN_PATH = re.escape(dirname(dirname(__file__)) + os.path.sep) +UNNECESSARY_LAMBDA = join( + HERE, "functional", "u", "unnecessary", "unnecessary_lambda.py" +) @contextlib.contextmanager @@ -285,17 +288,11 @@ class TestRunTC: def test_py3k_option(self): # Test that --py3k flag works. rc_code = 0 - self._runtest( - [join(HERE, "functional", "u", "unnecessary_lambda.py"), "--py3k"], - code=rc_code, - ) + self._runtest([UNNECESSARY_LAMBDA, "--py3k"], code=rc_code) def test_py3k_jobs_option(self): rc_code = 0 - self._runtest( - [join(HERE, "functional", "u", "unnecessary_lambda.py"), "--py3k", "-j 2"], - code=rc_code, - ) + self._runtest([UNNECESSARY_LAMBDA, "--py3k", "-j 2"], code=rc_code) def test_abbreviations_are_not_supported(self): expected = "no such option: --load-plugin" -- cgit v1.2.1