Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Bug: raising a nested error class causes spurious ‘member is not assignable’ error #1968

Description

@sietse

First off, thank you all for the delightful mypy tool. I really enjoy it every day I use it. ^_^

As for the bug report, mypy gives a spurious error in this scenario:

I have a class Shift with, nested inside it, the exception class
Shift.AlreadyCovered. The Shift.cover() method, which is annotated to
return None, will raise self.AlreadyCovered under certain circumstances. A
mypy check then complains that Member "AlreadyCovered" is not assignable.
See cover1 in the example below.

Mypy does not give an error in these variants:

  • a method is not annotated to return None (cover2)
  • a method raises an exception defined outside the current class (cover3)
  • a method raises an exception defined outside the current class via a
    reference defined inside the current class. (cover4)

Minimal example of the error:

class Shift:

    # A nested exception class defined inside the current class
    class AlreadyCovered(Exception):
        pass
    # If a method is annotated to return None, then raising the nested
    # exception class gives a mypy error
    #     x.py: note: In member "cover1" of class "Shift":
    #     x.py:11: error: Member "AlreadyCovered" is not assignable
    def cover1(self) -> None:
        raise self.AlreadyCovered  # <-- ERROR HERE

The variants that don't raise errors:

# An exception class defined outside the main (Shift) class
class OuterAlreadyCovered(Exception):
    pass

class Shift:

    # A nested exception class defined inside the current class
    class AlreadyCovered(Exception):
        pass

    # If a method is not annotated to return None, then mypy is okay
    # with raising the nested exception class
    def cover2(self):
        raise self.AlreadyCovered

    # Raising an exception defined outside the current class is fine.
    def cover3(self) -> None:
        raise OuterAlreadyCovered

    # Raising a reference defined inside the current class to an
    # exception defined outside the class is fine.
    def cover4(self) -> None:
        raise self.BorrowedAlreadyCovered

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions