[Python-ideas] PEP 563 and expensive backwards compatibility

Lukasz Langa lukasz at langa.pl
Wed Sep 13 22:29:24 EDT 2017


> On Sep 13, 2017, at 9:44 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> 
> On 14 September 2017 at 09:43, Lukasz Langa <lukasz at langa.pl> wrote:
>>> On Sep 13, 2017, at 6:37 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>> That way, during the "from __future__ import lazy_annotations" period,
>>> folks will have clearer guidance on how to explicitly opt-in to eager
>>> evaluation via function and class decorators.
>> 
>> I like this idea! For classes it would have to be a function that you call post factum. The way class decorators are implemented, they cannot evaluate annotations that contain forward references. For example:
>> 
>> class Tree:
>>    left: Tree
>>    right: Tree
>> 
>>    def __init__(self, left: Tree, right: Tree):
>>        self.left = left
>>        self.right = right
>> 
>> This is true today, get_type_hints() called from within a class decorator will fail on this class. However, a function performing postponed evaluation can do this without issue. If a class decorator knew what name a class is about to get, that would help. But that's a different PEP and I'm not writing that one ;-)
> 
> The class decorator case is indeed a bit more complicated, but there
> are a few tricks available to create a forward-reference friendly
> evaluation environment.

Using cls.__name__ and the ChainMap is clever, I like it. It might prove useful for Eric's data classes later. However, there's more to forward references than self-references:

class A:
    b: B

class B:
    ...

In this scenario evaluation of A's annotations has to happen after the module is fully loaded. This is the general case. No magic decorator will solve this.

The general solution is running eval() later, when the namespace is fully populated. I do agree with you that a default implementation of a typing-agnostic variant of `get_type_hints()` would be nice. If anything, implementing this might better surface limitations of postponed annotations. That function won't be recursive though as your example. And I'll leave converting the function to a decorator as an exercise for the reader, especially given the forward referencing caveats.

- Ł

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170913/11b51b83/attachment-0001.sig>


More information about the Python-ideas mailing list