Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove old-style classes code, remove check for new-style class #9925

Merged
merged 7 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions doc/user_guide/checkers/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/9925.internal
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion pylint/checkers/classes/class_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 7 additions & 9 deletions pylint/checkers/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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(
Expand Down
100 changes: 46 additions & 54 deletions pylint/checkers/newstyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -72,55 +68,51 @@
):
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

Check warning on line 101 in pylint/checkers/newstyle.py

View check run for this annotation

Codecov / codecov/patch

pylint/checkers/newstyle.py#L100-L101

Added lines #L100 - L101 were not covered by tests

# 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

Expand Down
Original file line number Diff line number Diff line change
@@ -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"""
jacobtylerwalls marked this conversation as resolved.
Show resolved Hide resolved
"""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')
Expand All @@ -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]
Expand Down
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/functional/r/raising/raising_non_exception.txt
Original file line number Diff line number Diff line change
@@ -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
Loading