Skip to content

Instantly share code, notes, and snippets.

@karbachinsky
Last active September 19, 2023 10:23
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save karbachinsky/cc5164b77b09170edce7e67e57f1636c to your computer and use it in GitHub Desktop.
Save karbachinsky/cc5164b77b09170edce7e67e57f1636c to your computer and use it in GitHub Desktop.
from dataclasses import dataclass
from typing import Optional
from functools import wraps
def optional_chaining(_class):
class Wrapper(_class):
class NoneStub:
def __getattr__(self, name):
return self.__class__()
def __eq__(self, v):
return v is None
def __lt__(self, v):
return False
def __bool__(self, v):
return False
def __str__(self):
return 'None'
def __getattr__(self, name: str):
if name[-1] == "ʔ":
value = getattr(self, name[:-1], None)
if value is not None:
return value
return self.NoneStub()
else:
return getattr(self, name)
return Wrapper
@dataclass
class Foo:
x = 1
y = 2
@optional_chaining
class Bar:
def __init__(self, foo: Optional[Foo] = None):
self.foo = foo
if __name__ == "__main__":
b = Bar(foo=Foo())
print(b.fooʔ.x) # 1
b = Bar()
print(b.fooʔ.x) # None
@rmortes
Copy link

rmortes commented Feb 15, 2023

Gosh this feels illegal, I LOVE IT

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