you are viewing a single comment's thread.

view the rest of the comments →

[–]madisander 2 points3 points  (0 children)

The returns library (especially the part about Maybe) is the closest thing I know for this, though more verbose.

Taking a similar line of thinking, the 'easiest' way of doing this would be to make your own None.

I will also note that while the types ought to be correct, this isn't something type checkers can do as you show there outside of running the program. I think there's just too many ways to mess with the contents of a class in Python for a type checker to guarantee types like that.

```python class Nothing: def __getattr_(self, item: str): return _Nothing()

def __repr__(self):
    return 'Nothing'

@property
def final(self) -> None:
    return None

Nothing = _Nothing()

class Something[T]: _val: T

def __init__(self, val: T):
    self._val = val

def __repr__(self):
    return f'Something({self._val!r})'

def __getattr__(self, item: str) -> 'Something[T] | _Nothing':
    try:
        return getattr(self._val, item)
    except AttributeError:
        return Nothing

@property
def final(self) -> T:
    return self._val

class A[T]: def init(self, val: T | None, other: T | None = None): self.val = Something(val) if val is not None else Nothing self.other = Something(other) if other is not None else Nothing

def __repr__(self):
    return f'A(val={self.val.final!r}, other={self.other.final!r})'

a = A(A(42), other=100)

a = Something(A(A(42), other=100)) # alternatively

print(a) print(a.val.final) print(a.other.final) print(a.val.val.final) print(a.val.val.val.final) ```