Larry Hastings wrote:
> On 8/11/21 2:48 AM, Jukka Lehtosalo wrote:
> > On Wed, Aug 11, 2021 at 10:32 AM Thomas Grainger <tagr...@gmail.com 
> > mailto:tagr...@gmail.com> wrote:
> > Larry Hastings wrote:
> > > On 8/11/21 12:02 AM, Thomas Grainger wrote:
> > > > I think as long as there's a test case for something like
> > > > @dataclass
> > > > class Node:
> > > >      global_node: ClassVar[Node | None]
> > > >      left: InitVar[Node | None]
> > > >      right: InitVar[None | None]
> > > >
> > > > the bug https://bugs.python.org/issue33453
> > <https://bugs.python.org/issue33453> and the current
> > implementation
> > https://github.com/python/cpython/blob/bfc2d5a5c4550ab3a2fadeb9459b4bd948ff6.
> > <https://github.com/python/cpython/blob/bfc2d5a5c4550ab3a2fadeb9459b4bd948ff6.>..
> > shows this is a tricky problem
> > > > The most straightforward workaround for this is to skip the
> > decorator
> > > syntax.  With PEP 649 active, this code should work:
> > > class Node:
> > >          global_node: ClassVar[Node | None]
> > >          left: InitVar[Node | None]
> > >          right: InitVar[None | None]
> > >     Node = dataclass(Node)
> > > //arry/
> > 
> > the decorator version simply has to work
> > 
> > 
> > 
> > I also think that it would be unfortunate if the decorator version 
> > wouldn't work. This is a pretty basic use case.
> > So, here's an idea, credit goes to Eric V. Smith.  What if we tweak how 
> decorators work, /juuuust sliiiightly/, so that they work like the 
> workaround code above?
> Specifically: currently, decorators are called just after the function 
> or class object is created, before it's bound to a variable.  But we 
> could change it so that we first bind the variable to the initial value, 
> then call the decorator, then rebind.  That is, this code:
> @dekor8
>     class C:
>          ...
> would become equivalent to this code:
> class C:
>          ...
>     C = dekorate(C)
> This seems like it would solve the class self-reference problem--the 
> "Node" example above--when PEP 649 is active.
> This approach shouldn't break reasonable existing code.  That said, this 
> change would be observable from Python, and pathological code could 
> notice and break.  For example:
> def ensure_Foo_is_a_class(o):
>          assert isinstance(Foo, type)
>          return o
> class Foo:
>          ...
> @ensure_Foo_is_a_class
>     def Foo():
>          ...
> This terrible code currently would not raise an assertion.  But if we 
> made the proposed change to the implementation of decorators, it would.  
> I doubt anybody does this sort of nonsense, I just wanted to fully flesh 
> out the topic.
> If this approach seems interesting, here's one wrinkle to iron out.  
> When an object has multiple decorators, would we want to re-bind after 
> each decorator call?  That is, would
> @dekor1
>     @dekor2
>     @dekor3
>     class C:
>          ...
> turn into approach A:
> class C:
>          ...
>     C = dekor1(dekor2(dekor3(C)))
> or approach B:
> class C:
>          ...
>     C = dekor3(C)
>     C = dekor2(C)
>     C = dekor1(C)
> I definitely think "approach B" makes more sense.
> //arry/


You mention that you wanted this to work also for non-type hint usage of 
annotations, and so a ForwardRef won't work. As such, would you also change 
this for function decorators so you can do this?

```
@decorator
@typing.no_type_check
def ham(spam: ham):
    ...

So it means:

```
def ham(spam: ham):
    ...
ham = typing.no_type_check(ham)
ham = decorator(ham)
```

Obviously it's meaningless as a type hint, hence the no_type_check opt out
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/OJKTIGCHNFTW224O6OM4NIZ3OZBK2YQI/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to