None: self._name = name def __str__(self): return("Er" /> None: self._name = name def __str__(self): return("Er" /> None: self._name = name def __str__(self): return("Er"/>

Python: VSCode does not show docstring for inherited exceptions

41 Views Asked by At
class CustomNamedException(Exception):
    """Example docstring here."""

    def __init__(self, name) -> None:
        self._name = name

    def __str__(self):
        return("Error message.")

My exception above does not show the docstring when I use the class in VSCode, what appears in the info box is instead Common base class for all exceptions.

Screenshot:

enter image description here

Seems redundant to include the base class docstring instead of the actual exception when I call it. I want Example docstring here. to display instead. Am I missing something?

UPDATE: The docstring for __init__() instead actually appears if I give it one:

enter image description here

Is this basically the intended behaviour? Are docstrings ignored when you inherit from the BaseException class unless you put it in __init__()?

1

There are 1 best solutions below

0
starball On

I can't speak for whether this is intentional or not, but here's what the behaviour seems to be:

class BaseClass:
    """BaseClass docstring"""
    def __init__():
        """BaseClass __init__ docstring"""
        pass
class DerivedClass(BaseClass):
    """DerivedClass docstring"""
    def __init__():
        """DerivedClass __init__ docstring""" # <-
        pass
DerivedClass() # DerivedClass __init__ docstring
class BaseClass:
    """BaseClass docstring"""
    def __init__():
        """BaseClass __init__ docstring""" # <-
        pass
class DerivedClass(BaseClass):
    """DerivedClass docstring"""
    def __init__():
        # """DerivedClass __init__ docstring""" # commented out
        pass
DerivedClass() # BaseClass __init__ docstring
class BaseClass:
    """BaseClass docstring"""
    def __init__():
        # """BaseClass __init__ docstring""" # commented out
        pass
class DerivedClass(BaseClass):
    """DerivedClass docstring""" # <-
    def __init__():
        # """DerivedClass __init__ docstring""" # commented out
        pass
DerivedClass() # DerivedClass docstring
class BaseClass:
    """BaseClass docstring"""
    def __init__():
        # """BaseClass __init__ docstring""" # commented out
        pass
class DerivedClass(BaseClass):
    # """DerivedClass docstring""" # commented out
    def __init__():
        # """DerivedClass __init__ docstring""" # commented out
        pass
DerivedClass() # N/A

It's not quite that it's not showing the derived class' docstring. It's that it's looking for a docstring on __init__, and not finding it, first falls back to the base class' __init__ docstring if that exists (and in the case of the question post, it did).

I do agree this could be awkward according to taste, and I imagine it could be problematic if the derived class' constructor has a very different signature than the base class, but I don't think this is a necessarily terrible design either / I can kind of empathize with this choice of behaviour.