diff --git a/doc/user_guide/checkers/features.rst b/doc/user_guide/checkers/features.rst index fd7f07d716..3c92594e42 100644 --- a/doc/user_guide/checkers/features.rst +++ b/doc/user_guide/checkers/features.rst @@ -474,9 +474,8 @@ Exceptions checker Messages :raising-bad-type (E0702): *Raising %s while only classes or instances are allowed* Used when something which is neither a class nor an instance is raised (i.e. a `TypeError` will be raised). -:raising-non-exception (E0710): *Raising a new style class which doesn't inherit from BaseException* - Used when a new style class which doesn't inherit from BaseException is - raised. +:raising-non-exception (E0710): *Raising a class which doesn't inherit from BaseException* + Used when a class which doesn't inherit from BaseException is raised. :misplaced-bare-raise (E0704): *The raise statement is not inside an except clause* Used when a bare raise is not used inside an except clause. This generates an error, since there are no active exceptions to be reraised. An exception to diff --git a/doc/whatsnew/fragments/9925.internal b/doc/whatsnew/fragments/9925.internal new file mode 100644 index 0000000000..145fe4a947 --- /dev/null +++ b/doc/whatsnew/fragments/9925.internal @@ -0,0 +1,3 @@ +Remove old-style classes (Python 2) code and remove check for new-style class since everything is new-style in Python 3. Updated doc for exception checker to remove reference to new style class. + +Refs #9925 diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index ced5048eb1..0caeeadcdf 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -1778,7 +1778,7 @@ def _check_in_slots(self, node: nodes.AssignAttr) -> None: klass = inferred._proxied if not has_known_bases(klass): return - if "__slots__" not in klass.locals or not klass.newstyle: + if "__slots__" not in klass.locals: return # If `__setattr__` is defined on the class, then we can't reason about # what will happen when assigning to an attribute. diff --git a/pylint/checkers/exceptions.py b/pylint/checkers/exceptions.py index 688dc829a0..a503000560 100644 --- a/pylint/checkers/exceptions.py +++ b/pylint/checkers/exceptions.py @@ -92,10 +92,9 @@ def _is_raising(body: list[nodes.NodeNG]) -> bool: {"old_names": [("E0703", "bad-exception-context")]}, ), "E0710": ( - "Raising a new style class which doesn't inherit from BaseException", + "Raising a class which doesn't inherit from BaseException", "raising-non-exception", - "Used when a new style class which doesn't inherit from " - "BaseException is raised.", + "Used when a class which doesn't inherit from BaseException is raised.", ), "E0711": ( "NotImplemented raised - should raise NotImplementedError", @@ -262,12 +261,11 @@ def visit_instance(self, instance: objects.ExceptionInstance) -> None: def visit_classdef(self, node: nodes.ClassDef) -> None: if not utils.inherit_from_std_ex(node) and utils.has_known_bases(node): - if node.newstyle: - self._checker.add_message( - "raising-non-exception", - node=self._node, - confidence=INFERENCE, - ) + self._checker.add_message( + "raising-non-exception", + node=self._node, + confidence=INFERENCE, + ) def visit_tuple(self, _: nodes.Tuple) -> None: self._checker.add_message( diff --git a/pylint/checkers/newstyle.py b/pylint/checkers/newstyle.py index 0c2c559fe8..920c8cc41e 100644 --- a/pylint/checkers/newstyle.py +++ b/pylint/checkers/newstyle.py @@ -12,11 +12,7 @@ from astroid import nodes from pylint.checkers import BaseChecker -from pylint.checkers.utils import ( - has_known_bases, - node_frame_class, - only_required_for_messages, -) +from pylint.checkers.utils import node_frame_class, only_required_for_messages from pylint.typing import MessageDefinitionTuple if TYPE_CHECKING: @@ -72,55 +68,51 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None: ): continue - # super should not be used on an old style class - if klass.newstyle or not has_known_bases(klass): - # super first arg should not be the class - if not call.args: - continue - - # calling super(type(self), self) can lead to recursion loop - # in derived classes - arg0 = call.args[0] - if ( - isinstance(arg0, nodes.Call) - and isinstance(arg0.func, nodes.Name) - and arg0.func.name == "type" - ): - self.add_message("bad-super-call", node=call, args=("type",)) - continue - - # calling super(self.__class__, self) can lead to recursion loop - # in derived classes - if ( - len(call.args) >= 2 - and isinstance(call.args[1], nodes.Name) - and call.args[1].name == "self" - and isinstance(arg0, nodes.Attribute) - and arg0.attrname == "__class__" - ): - self.add_message( - "bad-super-call", node=call, args=("self.__class__",) - ) - continue - - try: - supcls = call.args and next(call.args[0].infer(), None) - except astroid.InferenceError: - continue - - # If the supcls is in the ancestors of klass super can be used to skip - # a step in the mro() and get a method from a higher parent - if klass is not supcls and all(i != supcls for i in klass.ancestors()): - name = None - # if supcls is not Uninferable, then supcls was inferred - # and use its name. Otherwise, try to look - # for call.args[0].name - if supcls: - name = supcls.name - elif call.args and hasattr(call.args[0], "name"): - name = call.args[0].name - if name: - self.add_message("bad-super-call", node=call, args=(name,)) + # super first arg should not be the class + if not call.args: + continue + + # calling super(type(self), self) can lead to recursion loop + # in derived classes + arg0 = call.args[0] + if ( + isinstance(arg0, nodes.Call) + and isinstance(arg0.func, nodes.Name) + and arg0.func.name == "type" + ): + self.add_message("bad-super-call", node=call, args=("type",)) + continue + + # calling super(self.__class__, self) can lead to recursion loop + # in derived classes + if ( + len(call.args) >= 2 + and isinstance(call.args[1], nodes.Name) + and call.args[1].name == "self" + and isinstance(arg0, nodes.Attribute) + and arg0.attrname == "__class__" + ): + self.add_message("bad-super-call", node=call, args=("self.__class__",)) + continue + + try: + supcls = call.args and next(call.args[0].infer(), None) + except astroid.InferenceError: + continue + + # If the supcls is in the ancestors of klass super can be used to skip + # a step in the mro() and get a method from a higher parent + if klass is not supcls and all(i != supcls for i in klass.ancestors()): + name = None + # if supcls is not Uninferable, then supcls was inferred + # and use its name. Otherwise, try to look + # for call.args[0].name + if supcls: + name = supcls.name + elif call.args and hasattr(call.args[0], "name"): + name = call.args[0].name + if name: + self.add_message("bad-super-call", node=call, args=(name,)) visit_asyncfunctiondef = visit_functiondef diff --git a/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.py b/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.py index aa37a45306..3189fb8f44 100644 --- a/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.py +++ b/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.py @@ -1,17 +1,13 @@ # pylint:disable=too-few-public-methods,import-error,missing-docstring, not-callable, import-outside-toplevel -"""test pb with exceptions and old/new style classes""" +"""test pb with exceptions and classes""" class ValidException(Exception): """Valid Exception.""" -class OldStyleClass: - """Not an exception.""" - class NewStyleClass: """Not an exception.""" - def good_case(): """raise""" raise ValidException('hop') @@ -31,22 +27,10 @@ def good_case3(): 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] diff --git a/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.txt b/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.txt index f2ccd8a052..863e5baf37 100644 --- a/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.txt +++ b/tests/functional/i/invalid/invalid_exceptions/invalid_exceptions_raised.txt @@ -1,11 +1,9 @@ -raising-non-exception:38:4:38:30:bad_case0:Raising a new style class which doesn't inherit from BaseException:INFERENCE -raising-non-exception:42:4:42:25:bad_case1:Raising a new style class which doesn't inherit from BaseException:INFERENCE -raising-non-exception:48:4:48:30:bad_case2:Raising a new style class which doesn't inherit from BaseException:INFERENCE -raising-non-exception:52:4:52:23:bad_case3:Raising a new style class which doesn't inherit from BaseException:INFERENCE -notimplemented-raised:56:4:56:31:bad_case4:NotImplemented raised - should raise NotImplementedError:HIGH -raising-bad-type:60:4:60:11:bad_case5:Raising int while only classes or instances are allowed:INFERENCE -raising-bad-type:64:4:64:14:bad_case6:Raising NoneType while only classes or instances are allowed:INFERENCE -raising-non-exception:68:4:68:14:bad_case7:Raising a new style class which doesn't inherit from BaseException:INFERENCE -raising-non-exception:72:4:72:15:bad_case8:Raising a new style class which doesn't inherit from BaseException:INFERENCE -raising-non-exception:76:4:76:14:bad_case9:Raising a new style class which doesn't inherit from BaseException:INFERENCE -raising-bad-type:110:4:110:18:bad_case10:Raising str while only classes or instances are allowed:INFERENCE +raising-non-exception:32:4:32:25:bad_case1:Raising a class which doesn't inherit from BaseException:INFERENCE +raising-non-exception:36:4:36:23:bad_case3:Raising a class which doesn't inherit from BaseException:INFERENCE +notimplemented-raised:40:4:40:31:bad_case4:NotImplemented raised - should raise NotImplementedError:HIGH +raising-bad-type:44:4:44:11:bad_case5:Raising int while only classes or instances are allowed:INFERENCE +raising-bad-type:48:4:48:14:bad_case6:Raising NoneType while only classes or instances are allowed:INFERENCE +raising-non-exception:52:4:52:14:bad_case7:Raising a class which doesn't inherit from BaseException:INFERENCE +raising-non-exception:56:4:56:15:bad_case8:Raising a class which doesn't inherit from BaseException:INFERENCE +raising-non-exception:60:4:60:14:bad_case9:Raising a class which doesn't inherit from BaseException:INFERENCE +raising-bad-type:94:4:94:18:bad_case10:Raising str while only classes or instances are allowed:INFERENCE diff --git a/tests/functional/r/raising/raising_non_exception.txt b/tests/functional/r/raising/raising_non_exception.txt index 5cab168463..86c4f70b1a 100644 --- a/tests/functional/r/raising/raising_non_exception.txt +++ b/tests/functional/r/raising/raising_non_exception.txt @@ -1 +1 @@ -raising-non-exception:13:0:13:22::Raising a new style class which doesn't inherit from BaseException:INFERENCE +raising-non-exception:13:0:13:22::Raising a class which doesn't inherit from BaseException:INFERENCE