RFC: patch_to property setters

The patch() and patch_to() decorators from fastcore.basics only create a getter method for a property. Setters and deleters are not supported.

I’d like to create a PR to add this functionality but it requires a change of the patch() and patch_to() signatures.

The current signatures are patch_to(cls, as_prop=False, cls_method=False) and patch(f=None, *, as_prop=False, cls_method=False).

I’ve been considering:

patch_to(cls, as_prop=False, cls_method=False, name=None)

Where as_prop can be a boolean or a string having one of the values “getter”, “setter”, “deleter”, boolean True being an alias for “getter”.

The argument name allows one to use an attribute name that differs from the function names.
When name is not used, the function name is used as the attribute name as in the current implementation.

I believe this approach has the least inpact on the current usage of patch and patch_to.

class Sample:
    def __init__(self, v):
        self.v = v

@patch_to(Sample, as_prop=True, name='val')
def get_v(self):
    '''controlled access to v'''
    return self.v

@patch_to(Sample, as_prop='setter', name='val')
def set_v(self, val):
    self.v = val

@patch_to(Sample, as_prop='deleter', name='val')
def del_v(self):
    self.v = None

s = Sample(10)
assert s.val == 10
s.val = 20
assert s.v == 20
del s.val
assert s.val is None

I welcome any comments on the proposed change.

Hello,

Your approach to adding setter and deleter support for patch() and patch_to() in fastcore.basics seems well thought out, especially with the idea of extending the as_prop argument to also handle “setter” and “deleter” functionality. Here’s a breakdown of the proposal and its potential impact:

Current Signatures:
patch(f=None, *, as_prop=False, cls_method=False)
patch_to(cls, as_prop=False, cls_method=False)
These signatures are focused on patching methods for property-like behavior (getter), but there’s no explicit support for setters or deleters.

Proposed Signature Changes:
patch_to(cls, as_prop=False, cls_method=False, name=None)

The introduction of name as an argument allows a function to be used as a property with a custom name, preserving backward compatibility if name is not supplied.
This approach makes the function name (getter) the default when name is not provided, aligning with the current behavior.
patch(f=None, *, as_prop=False, cls_method=False)

The signature for patch() is essentially unchanged but would support the same name argument for consistency. The as_prop flag would now be a bit more flexible, allowing values like True, “getter”, “setter”, and “deleter”.
This ensures that users who want to maintain the current behavior can still do so by setting as_prop=True or leaving it out entirely.
Best Regards
merry678