Randolf Scholz <randolf.sch...@gmail.com> added the comment: Dear Raymond,
I think decorator chaining is a very useful concept. At the very least, if all decorators are functional (following the `functools.wraps` recipe), things work out great -- we even get associativity of function composition if things are done properly! The question is: can we get similar behaviour when allowing decoration with stateful objects, i.e. classes? This seems a lot more difficult. At the very least, in the case of `@classmethod` I think one can formulate a straightforward desiderata: ### Expectation - `classmethod(property)` should still be a `property`! - More generally: `classmethod(decorated)` should always be a subclass of `decorated`! Using your pure-python versions of property / classmethod from <https://docs.python.org/3.9/howto/descriptor.html>, I was able to write down a variant of `classmethod` that works mostly as expected in conjunction with `property`. The main idea is rewrite the `classmethod` to dynamically be a subclass of whatever it wrapped; roughly: ```python def ClassMethod(func): class Wrapped(type(func)): def __get__(self, obj, cls=None): if cls is None: cls = type(obj) if hasattr(type(self.__func__), '__get__'): return self.__func__.__get__(cls) return MethodType(self.__func__, cls) return Wrapped(func) ``` I attached a full MWE. Unfortunately, this doesn't fix the `help` bug, though it is kind of weird because the decorated class-property now correctly shows up under the "Readonly properties" section. Maybe `help` internally checks `isinstance(cls.func, property)` at some point instead of `isinstance(cls.__dict__["func"], property)`? ### Some further Proposals / Ideas 1. Decorators could always have an attribute that points to whatever object they wrapped. For the sake of argument, let's take `__func__`. ⟹ raise Error when typing `@decorator` if `not hasattr(decorated, "__func__")` ⟹ Regular functions/methods should probably by default have `__func__` as a pointer to themselves? ⟹ This could hae several subsidiary benefits, for example, currently, how would you implement a pair of decorators `@print_args_and_kwargs` and `@time_execution` such that both of them only apply to the base function, no matter the order in which they are decorating it? The proposed `__func__` convention would make this very easy, almost trivial. 2. `type.__setattr__` could support checking if `attr` already exists and has `__set__` implemented. ⟹ This would allow true class-properties with `getter`, `setter` and `deleter`. I provide a MWE here: <https://mail.google.com/mail/u/0/#label/Python+Ideas/FMfcgzGlkPRbJVRkHHtkRPhMCxNsFHpl> 3. I think an argument can be made that it would be really, really cool if `@` could become a general purpose function composition operator? ⟹ This is already kind of what it is doing with decorators ⟹ This is already exacltly what it is doing in numpy -- matrix multiplication \*is\* the composition of linear functions. ⟹ In fact this is a frequently requested feature on python-ideas! ⟹ But here is probably the wrong place to discuss this. ---------- Added file: https://bugs.python.org/file50344/ClassPropertyIdea.py _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue45356> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com