"abc" --- Abstract Base Classes
*******************************

**Code source:** Lib/abc.py

======================================================================

Le module fournit l'infrastructure pour définir les *classes mères
abstraites* (*Abstract Base Class* ou *ABC* en anglais) en Python, tel
qu'indiqué dans la **PEP 3119**; voir la PEP pour la raison de son
ajout à Python. (Voir également la **PEP 3141** et le module "numbers"
pour ce qui concerne la hiérarchie de types pour les nombres basés sur
les classes mères abstraites). Par la suite nous utiliserons
l'abréviation ABC (*Abstract Base Class*) pour désigner une classe
mère abstraite.

The "collections" module has some concrete classes that derive from
ABCs; these can, of course, be further derived. In addition, the
"collections.abc" submodule has some ABCs that can be used to test
whether a class or instance provides a particular interface, for
example, if it is *hashable* or if it is a *mapping*.

Ce module fournit la métaclasse "ABCMeta" pour définir les ABC ainsi
que la classe d'aide "ABC", cette dernière permettant de définir des
ABC en utilisant l'héritage :

class abc.ABC

   A helper class that has "ABCMeta" as its metaclass.  With this
   class, an abstract base class can be created by simply deriving
   from "ABC" avoiding sometimes confusing metaclass usage, for
   example:

      from abc import ABC

      class MyABC(ABC):
          pass

   Note that the type of "ABC" is still "ABCMeta", therefore
   inheriting from "ABC" requires the usual precautions regarding
   metaclass usage, as multiple inheritance may lead to metaclass
   conflicts. One may also define an abstract base class by passing
   the metaclass keyword and using "ABCMeta" directly, for example:

      from abc import ABCMeta

      class MyABC(metaclass=ABCMeta):
          pass

   Ajouté dans la version 3.4.

class abc.ABCMeta

   Métaclasse pour définir des classes mères abstraites (ABC).

   Utilisez cette métaclasse pour créer une ABC. Il est possible
   d'hériter d'une ABC directement, cette classe mère abstraite
   fonctionne alors comme une classe *mixin*. Vous pouvez également
   enregistrer une classe concrète sans lien (même une classe native)
   et des ABC comme "sous-classes virtuelles" -- celles-ci et leur
   descendantes seront considérées comme des sous-classes de la classe
   mère abstraite par la fonction native "issubclass()", mais les ABC
   enregistrées n'apparaitront pas dans leur ordre de résolution des
   méthodes (*MRO* pour *Method Resolution Order* en anglais). Les
   implémentations de méthodes définies par l'ABC ne seront pas
   appelable (pas même via "super()"). [1]

   Classes created with a metaclass of "ABCMeta" have the following
   method:

   register(subclass)

      Enregistrer *subclass* en tant que sous-classe virtuelle de
      cette ABC. Par exemple :

         from abc import ABC

         class MyABC(ABC):
             pass

         MyABC.register(tuple)

         assert issubclass(tuple, MyABC)
         assert isinstance((), MyABC)

      Modifié dans la version 3.3: Renvoie la sous-classe enregistrée
      pour permettre l'utilisation en tant que décorateur de classe.

      Modifié dans la version 3.4: To detect calls to "register()",
      you can use the "get_cache_token()" function.

   Vous pouvez également redéfinir cette méthode dans une ABC :

   __subclasshook__(subclass)

      (Doit être définie en tant que méthode de classe.)

      Check whether *subclass* is considered a subclass of this ABC.
      This means that you can customize the behavior of "issubclass()"
      further without the need to call "register()" on every class you
      want to consider a subclass of the ABC.  (This class method is
      called from the "__subclasscheck__()" method of the ABC.)

      This method should return "True", "False" or "NotImplemented".
      If it returns "True", the *subclass* is considered a subclass of
      this ABC. If it returns "False", the *subclass* is not
      considered a subclass of this ABC, even if it would normally be
      one.  If it returns "NotImplemented", the subclass check is
      continued with the usual mechanism.

   Pour une illustration de ces concepts, voir cet exemple de
   définition de ABC :

      class Foo:
          def __getitem__(self, index):
              ...
          def __len__(self):
              ...
          def get_iterator(self):
              return iter(self)

      class MyIterable(ABC):

          @abstractmethod
          def __iter__(self):
              while False:
                  yield None

          def get_iterator(self):
              return self.__iter__()

          @classmethod
          def __subclasshook__(cls, C):
              if cls is MyIterable:
                  if any("__iter__" in B.__dict__ for B in C.__mro__):
                      return True
              return NotImplemented

      MyIterable.register(Foo)

   The ABC "MyIterable" defines the standard iterable method,
   "__iter__()", as an abstract method.  The implementation given here
   can still be called from subclasses.  The "get_iterator()" method
   is also part of the "MyIterable" abstract base class, but it does
   not have to be overridden in non-abstract derived classes.

   The "__subclasshook__()" class method defined here says that any
   class that has an "__iter__()" method in its "__dict__" (or in that
   of one of its base classes, accessed via the "__mro__" list) is
   considered a "MyIterable" too.

   Finally, the last line makes "Foo" a virtual subclass of
   "MyIterable", even though it does not define an "__iter__()" method
   (it uses the old-style iterable protocol, defined in terms of
   "__len__()" and "__getitem__()").  Note that this will not make
   "get_iterator" available as a method of "Foo", so it is provided
   separately.

The "abc" module also provides the following decorator:

@abc.abstractmethod

   Un décorateur marquant les méthodes comme abstraites.

   Using this decorator requires that the class's metaclass is
   "ABCMeta" or is derived from it.  A class that has a metaclass
   derived from "ABCMeta" cannot be instantiated unless all of its
   abstract methods and properties are overridden.  The abstract
   methods can be called using any of the normal 'super' call
   mechanisms.  "abstractmethod()" may be used to declare abstract
   methods for properties and descriptors.

   Dynamically adding abstract methods to a class, or attempting to
   modify the abstraction status of a method or class once it is
   created, are only supported using the "update_abstractmethods()"
   function.  The "abstractmethod()" only affects subclasses derived
   using regular inheritance; "virtual subclasses" registered with the
   ABC's "register()" method are not affected.

   When "abstractmethod()" is applied in combination with other method
   descriptors, it should be applied as the innermost decorator, as
   shown in the following usage examples:

      class C(ABC):
          @abstractmethod
          def my_abstract_method(self, arg1):
              ...
          @classmethod
          @abstractmethod
          def my_abstract_classmethod(cls, arg2):
              ...
          @staticmethod
          @abstractmethod
          def my_abstract_staticmethod(arg3):
              ...

          @property
          @abstractmethod
          def my_abstract_property(self):
              ...
          @my_abstract_property.setter
          @abstractmethod
          def my_abstract_property(self, val):
              ...

          @abstractmethod
          def _get_x(self):
              ...
          @abstractmethod
          def _set_x(self, val):
              ...
          x = property(_get_x, _set_x)

   In order to correctly interoperate with the abstract base class
   machinery, the descriptor must identify itself as abstract using
   "__isabstractmethod__". In general, this attribute should be "True"
   if any of the methods used to compose the descriptor are abstract.
   For example, Python's built-in "property" does the equivalent of:

      class Descriptor:
          ...
          @property
          def __isabstractmethod__(self):
              return any(getattr(f, '__isabstractmethod__', False) for
                         f in (self._fget, self._fset, self._fdel))

   Note:

     Contrairement aux méthodes abstraites Java, ces méthodes
     abstraites peuvent être implémentées. Cette implémentation peut
     être appelée via le mécanisme "super()" depuis la classe qui la
     redéfinit. C'est typiquement utile pour y appeler *super* et
     ainsi coopérer correctement dans un environnement utilisant de
     l'héritage multiple.

The "abc" module also supports the following legacy decorators:

@abc.abstractclassmethod

   Ajouté dans la version 3.2.

   Obsolète depuis la version 3.3: Il est désormais possible
   d'utiliser "classmethod" avec "abstractmethod()", cela rend ce
   décorateur redondant.

   Sous-classe du décorateur natif "classmethod()" qui indique une
   méthode de classe ( "classmethod" ) abstraite. En dehors de cela,
   est similaire à "abstractmethod()".

   Ce cas spécial est obsolète car le décorateur "classmethod()" est
   désormais correctement identifié comme abstrait quand il est
   appliqué à une méthode abstraite :

      class C(ABC):
          @classmethod
          @abstractmethod
          def my_abstract_classmethod(cls, arg):
              ...

@abc.abstractstaticmethod

   Ajouté dans la version 3.2.

   Obsolète depuis la version 3.3: Il est désormais possible
   d'utiliser "staticmethod" avec "abstractmethod()", cela rend ce
   décorateur redondant.

   Sous-classe du décorateur natif "classmethod()" qui indique une
   méthode statique ( "staticmethod" ) abstraite. En dehors de cela,
   est similaire à "abstractmethod()".

   Ce cas spécial est obsolète car le décorateur "staticmethod()" est
   désormais correctement identifié comme abstrait quand appliqué à
   une méthode abstraite :

      class C(ABC):
          @staticmethod
          @abstractmethod
          def my_abstract_staticmethod(arg):
              ...

@abc.abstractproperty

   Obsolète depuis la version 3.3: Il est désormais possible
   d'utiliser "property", "property.getter()", "property.setter()" et
   "property.deleter()" avec "abstractmethod()", ce qui rend ce
   décorateur redondant.

   Sous-classe de "property()", qui indique une propriété abstraite.

   Ce cas spécial est obsolète car le décorateur "property()" est
   désormais correctement identifié comme abstrait quand appliqué à
   une méthode abstraite :

      class C(ABC):
          @property
          @abstractmethod
          def my_abstract_property(self):
              ...

   L'exemple ci-dessus définit une propriété en lecture seule. Vous
   pouvez également définir une propriété en lecture-écriture
   abstraite en indiquant une ou plusieurs des méthodes sous-jacentes
   comme abstraite :

      class C(ABC):
          @property
          def x(self):
              ...

          @x.setter
          @abstractmethod
          def x(self, val):
              ...

   Si seuls certains composants sont abstraits, seuls ces composants
   abstraits nécessitent d'être mis à jour pour créer une propriété
   concrète dans une sous-classe :

      class D(C):
          @C.x.setter
          def x(self, val):
              ...

The "abc" module also provides the following functions:

abc.get_cache_token()

   Renvoie le jeton de cache ( *cache token*) de l'ABC.

   Le jeton est un objet opaque (qui implémente le test d'égalité) qui
   identifie la version actuelle du cache de l'ABC pour les sous-
   classes virtuelles. Le jeton change avec chaque appel à
   "ABCMeta.register()" sur n'importe quelle ABC.

   Ajouté dans la version 3.4.

abc.update_abstractmethods(cls)

   Recalcule l'état d'abstraction de la classe. Il est nécessaire
   d'appeler cette fonction si les méthodes abstraites d'une classe
   sont ajoutées ou modifiées après la création de la classe. C'est
   notamment le cas dans les décorateurs de classe.

   Pour permettre une utilisation en tant que décorateur, cette
   fonction renvoie *cls*.

   Ne fait rien si *cls* n'est pas une instance de "ABCMeta".

   Note:

     Cette fonction suppose que les classes mères de *cls* ont vu leur
     état recalculé, et ne fait rien pour recalculer celui des classes
     filles.

   Ajouté dans la version 3.10.

-[ Notes ]-

[1] Les développeurs C++ noteront que le concept Python de classe mère
    virtuelle ( *virtual base class* ) n'est pas le même que celui de
    C++.
