def prop(func=None, *,<EOL>field = _UNSET,<EOL>get: bool = True, set: bool = True, del_: bool = False,<EOL>default = _UNSET,<EOL>types: tuple = _UNSET):
def wrap(func):<EOL><INDENT>if not callable(func):<EOL><INDENT>raise TypeError<EOL><DEDENT>prop_name = func.__name__<EOL>key = field<EOL>if key is _UNSET:<EOL><INDENT>key = '<STR_LIT:_>' + prop_name<EOL><DEDENT>fget, fset, fdel = None, None, None<EOL>if get:<EOL><INDENT>def fget(self):<EOL><INDENT>try:<EOL><INDENT>return self.__dict__[key]<EOL><DEDENT>except KeyError:<EOL><INDENT>if default is not _UNSET:<EOL><INDENT>return default<EOL><DEDENT>raise AttributeError(f"<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>if set:<EOL><INDENT>def fset(self, val):<EOL><INDENT>if types is not _UNSET and not isinstance(val, types):<EOL><INDENT>if isinstance(types, tuple):<EOL><INDENT>types_name = tuple(x.__name__ for x in types)<EOL><DEDENT>else:<EOL><INDENT>types_name = types.__name__<EOL><DEDENT>raise TypeError(f'<STR_LIT>'<EOL>f'<STR_LIT>')<EOL><DEDENT>self.__dict__[key] = val<EOL><DEDENT><DEDENT>if del_:<EOL><INDENT>def fdel(self):<EOL><INDENT>del self.__dict__[key]<EOL><DEDENT><DEDENT>return property(fget, fset, fdel, func.__doc__)<EOL><DEDENT>return wrap(func) if func else wrap<EOL>
`prop` is a sugar for `property`.

``` py
@prop
def value(self):
    pass

# equals:

@property
def value(self):
    return self._value

@value.setter
def value(self, val):
    self._value = val
```