:PROPERTIES:
:ID:       e30a1965-83c2-4015-92b5-dc4c8b9d82bf
:mtime:    20220217181714
:ctime:    20220217175257
:END:
#+title: Utiliser le nom d'une classe dans sa propre définition

* Introduction
Il arrive de devoir utiliser le nom d'une classe lors de l'annotation d'une de ses méthodes, notamment lorsque des
/classmethod/ sont utilisées pour retourner une nouvelle instance de la classe. Pour répondre à ce besoin, la [[https://www.python.org/dev/peps/pep-0563/][PEP563
(Postponed Evaluation of Annotations)]] a été rédigée/acceptée/implémentée. La modification consiste en la conversion des
annotations de méthodes en string :
 * Jusqu'à Python3.11, en ajoutant la ligne ~from __future__ import annotations~
 * Comportement par défaut à partir de la version 3.11.
   
* Howto
** Sans /Postponed Evaluation of Annotations/
#+BEGIN_SRC python :results output 
from typing import Type, TypeVar

DummyClassT = TypeVar('DummyClassT', bound='DummyClass')

class DummyClass:

    @classmethod
    def from_raw(cls: Type[DummyClassT], xml: str) -> DummyClassT:
        pass

print(DummyClass.from_raw.__annotations__)
#+END_SRC

#+RESULTS:
: {'cls': typing.Type[~DummyClassT], 'xml': <class 'str'>, 'return': ~DummyClassT}

** Avec /Postponed Evaluation of Annotations/
#+BEGIN_SRC python :results output 
from __future__ import annotations

class DummyClass:

    @classmethod
    def from_raw(cls, xml: str) -> DummyClass:
        pass

print(DummyClass.from_raw.__annotations__)
#+END_SRC

#+RESULTS:
: {'xml': 'str', 'return': 'DummyClass'}

* Références
 * [[https://gdevops.gitlab.io/tuto_python/versions/3.10.0/pep_0563/pep_0563.html]]
 * [[https://www.python.org/dev/peps/pep-0563/][PEP563 (Postponed Evaluation of Annotations)]]
 * [[https://bugs.python.org/issue38605][[typing] PEP 563: Postponed evaluation of annotations: enable it by default in Python 3.11]]
