On Thu, May 27, 2021 at 11:09 AM Matt del Valle <[email protected]>
wrote:

>
>> I'm not the OP, but the way I understand the proposal __decoration_call__
> is only invoked when you actually *use an object to decorate something*.
> That means that a decorator factory will just invoke __call__ as normal,
> because it's nothing but a convenient way to generate a decorator. It is
> not itself a decorator, nor is it used to actually decorate anything. To
> illustrate this point we can separate it out across several lines:
>
> @factory("foo")
> def bar():
>     pass
>
>
> Can be rewritten as:
>
> decorator = factory("foo")
>
> @decorator
> def bar():
>     pass
>
>
> So __decorator_call__ will only be invoked on the object that gets
> returned from `factory("foo")`, not on `factory`.
>

Correct.


> It seems to me that this proposal means that we can't even tell which of
>> the two protocols (classic decoration, or new `__decoration_call__`
>> style decoration) without digging into the implementation of the
>> decorator.
>>
>> To be precise, the problem here as reader isn't so much the fact that I
>> don't know whether the object is called using the `__call__` protocol or
>> the new-style `__decorator_call__` protocol, but the fact that I can't
>> tell whether the calls will involve the name being passed or not.
>>
>
>
> The OP mentioned a default implementation for __decoration_call__ of:
>
> def  __decoration_call__(self, func, by_name):
>     if func is None:
>         return self(by_name)
>     return self(func)
>
>
> Such that you can assume that the decorator will *always* receive the
> name, but may choose to discard it and not make use of it if it doesn't
> implement the __decoration_call__ interface and instead opts to use default
> implementation which falls back on __call__.
>

Yes but I am on the fence as to whether this default implementation (I
suppose it would live on the object class?) should be considered or not. It
would certainly provide a lot of functionality "out-of-the-box".

For decorated functions the name can always be pulled out of the function
> object as normal even when using __call__, but to make use of the name in a
> decorated assignment statement the decorator would have to override
> __decoration_call__.
>
>
> At this point I will say that I may be putting words into OPs mouth, and
> would be happy to be corrected if I've misunderstood.
>

Nah you got it.


> One final point I've just thought of is that Ricky suggested that when no
> value is assigned to a name that the object reference be `None`. But I
> don't think that works, because it becomes indistinguishable from when
> `None` is explicitly assigned. We would need some sentinel value instead of
> `None` to remove ambiguity in this situation:
>
>
> from somewhere import NOTSET
>
>
> @decorate
> foo: int
>
> def __decoration_call__(self, obj, names, annotation):
>     print(obj is None)    # False
>     print(obj is NOTSET)  # True
>
> @decorate
> foo: int = None
>
>
> def __decoration_call__(self, obj, names, annotation):
>     print(obj is None)    # True
>     print(obj is NOTSET)  # False
>
>
>
Bikesheddable, but I don't know why having these two be equivalent:

@decorator var
@decorator var = None

..would be a problem. Having an implied default of None for var above makes
sense to my brain. Do you have an example in mind where you think it would
create a problem?


---
Ricky.

"I've never met a Kentucky man who wasn't either thinking about going home
or actually going home." - Happy Chandler
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/V5PENKCPAGWOFVQKGFGYK666RSD6VLDU/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to