0

I am running the following code in Jupyter:

from typing import List

class dummy:
    def __init__(self, dum: List =[]):
        self.dum = dum

    @property
    def dum(self) -> List:
        return self.dum

    @dum.setter
    def dum(self, value: List) -> None:
        self.dum = value

When I run the following:

dummy(dum=[1,2,3])

The kernel dies without telling me much about the possible error. What is going on?

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
marcos
  • 134
  • 15
  • You shouldn't name your methods and attribute of a class the same name. `dum` is at the same time a method and an attribute, so `dummy().dum` is confusing. Renaming the attribute should solve the issue. – Thibault D. Dec 12 '22 at 16:07
  • Did the kernel dying tell you anything at all? If so, it would be helpful to post. Future searchers would more likely find this question with it in there. – tdelaney Dec 12 '22 at 16:08
  • It can be useful to run failing scripts from the command line to see what happens. Here you'd get `self.dum = value`, `RecursionError: maximum recursion depth exceeded`. – tdelaney Dec 12 '22 at 16:09

1 Answers1

4
@property
def dum(self) -> List:
    return self.dum

This creates an infinite recursion.

  • The attribute itself should have a different name. As per convention, it is usually the name of the property prefixed with an underscore.

  • While we are at it, default mutable arguments should be avoided.

  • mypy does not like implicit Optional annotations, so List = None should be Optional[List] = None.

from typing import List, Optional

class dummy:
    def __init__(self, dum: Optional[List] = None):
        self.dum = dum if dum is not None else []

    @property
    def dum(self) -> List:
        return self._dum

    @dum.setter
    def dum(self, value: List) -> None:
        self._dum = value
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • 1
    It's still OK to use the property in `__init__`, rather than working with `._dum` directly. (The `_num` attribute is, in some sense, an implementation detail of the *property*, not `dummy`.) It's also arguably better to still check if `dum is None`. A caller might have reason to pass an explicit empty list as an argument without wanting `__init__` to replace it with a *new* empty list. – chepner Dec 12 '22 at 16:09
  • @chepner totally agree, thanks – DeepSpace Dec 12 '22 at 16:15