Skip to content

Instantly share code, notes, and snippets.

@adamchainz
Forked from willmcgugan/typed_property.py
Created October 18, 2021 10:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamchainz/412d6bcad3232c6edaf69f9e4b741713 to your computer and use it in GitHub Desktop.
Save adamchainz/412d6bcad3232c6edaf69f9e4b741713 to your computer and use it in GitHub Desktop.
A descriptor that permits a different type in the setter
from __future__ import annotations
from typing import NamedTuple, cast, overload
class ConsoleDimensions(NamedTuple):
width: int
height: int
class Size:
def __set_name__(self, owner: type[object], name: str) -> None:
self.name = name
@overload
def __get__(self, obj: None, objtype: None) -> Size:
...
@overload
def __get__(self, obj: object, objtype: type[object]) -> ConsoleDimensions:
...
def __get__(
self, obj: object | None, objtype: type[object] | None = None
) -> Size | ConsoleDimensions:
if obj is None:
return self
return cast(ConsoleDimensions, obj.__dict__[self.name])
def __set__(self, obj: object, value: ConsoleDimensions | tuple[int, int]) -> None:
if isinstance(value, tuple):
value = ConsoleDimensions(*value)
obj.__dict__[self.name] = value
class Console:
size = Size()
def __init__(self) -> None:
self.size = ConsoleDimensions(80, 25)
console = Console()
print(console.size)
console.size = (10, 20)
print(console.size)
console.size = ConsoleDimensions(3, 4)
print(console.size)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment