7. Les instructions simples
***************************

Une instruction simple est contenue dans une seule ligne logique.
Plusieurs instructions simples peuvent être écrites sur une seule
ligne, séparées par des points-virgules. La syntaxe d'une instruction
simple est :

   simple_stmt ::= expression_stmt
                   | assert_stmt
                   | assignment_stmt
                   | augmented_assignment_stmt
                   | annotated_assignment_stmt
                   | pass_stmt
                   | del_stmt
                   | return_stmt
                   | yield_stmt
                   | raise_stmt
                   | break_stmt
                   | continue_stmt
                   | import_stmt
                   | future_stmt
                   | global_stmt
                   | nonlocal_stmt
                   | type_stmt


7.1. Les expressions
====================

Les expressions sont utilisées (généralement de manière interactive)
comme instructions pour calculer et écrire des valeurs, appeler une
procédure (une fonction dont le résultat renvoyé n'a pas d'importance
; en Python, les procédures renvoient la valeur "None"). D'autres
utilisations des expressions sont autorisées et parfois utiles. La
syntaxe pour une expression en tant qu'instruction est :

   expression_stmt ::= starred_expression

Ce genre d'instruction évalue la liste d'expressions (qui peut se
limiter à une seule expression).

En mode interactif, si la valeur n'est pas "None", elle est convertie
en chaîne en utilisant la fonction native "repr()" et la chaîne
résultante est écrite sur la sortie standard sur sa propre ligne. Si
le résultat est "None", rien n'est écrit ce qui est usuel pour les
appels de procédures.


7.2. Les assignations
=====================

Les assignations sont utilisées pour lier ou relier des noms à des
valeurs et modifier des attributs ou des éléments d'objets mutables :

   assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)
   target_list     ::= target ("," target)* [","]
   target          ::= identifier
                       | "(" [target_list] ")"
                       | "[" [target_list] "]"
                       | attributeref
                       | subscription
                       | slicing
                       | "*" target

Voir la section Primaires pour la définition des syntaxes de
*attributeref*, *subscription* et *slicing*.

Une assignation évalue la liste d'expressions (gardez en mémoire que
ce peut être une simple expression ou une liste dont les éléments sont
séparés par des virgules, cette dernière produisant un *n*-uplet) et
assigne l'unique objet résultant à chaque liste cible, de la gauche
vers la droite.

Une assignation est définie récursivement en fonction de la forme de
la cible (une liste). Quand la cible est une partie d'un objet mutable
(une référence à un attribut, une sélection ou une tranche), l'objet
mutable doit effectuer l'assignation au final et décider de sa
validité, voire lever une exception si l'assignation n'est pas
acceptable. Les règles suivies par les différents types et les
exceptions levées sont données dans les définitions des types d'objets
(voir la section Hiérarchie des types standards).

L'assignation d'un objet à une liste cible, optionnellement entourée
par des parenthèses ou des crochets, est définie récursivement comme
suit.

* Si la liste cible est une cible unique sans virgule de fin,
  optionnellement entre parenthèses, l'objet est assigné à cette
  cible.

* Sinon :

  * Si la liste cible contient une cible préfixée par un astérisque,
    appelée cible *étoilée* (*starred target* en anglais) : l'objet
    doit être un itérable avec au moins autant d'éléments qu'il y a de
    cibles dans la liste cible, moins un. Les premiers éléments de
    l'itérable sont assignés, de la gauche vers la droite, aux cibles
    avant la cible étoilée. Les éléments de queue de l'itérable sont
    assignés aux cibles après la cible étoilée. Une liste des éléments
    restants dans l'itérable est alors assignée à la cible étoilée
    (cette liste peut être vide).

  * Sinon : l'objet doit être un itérable avec le même nombre
    d'éléments qu'il y a de cibles dans la liste cible ; les éléments
    sont assignés, de la gauche vers la droite, vers les cibles
    correspondantes.

L'assignation d'un objet vers une cible unique est définie
récursivement comme suit.

* Si la cible est une variable (un nom) :

  * si le nom n'apparaît pas dans une instruction "global" ou
    "nonlocal" (respectivement) du bloc de code courant, le nom est
    lié à l'objet dans l'espace courant des noms locaux ;

  * sinon le nom est lié à l'objet dans l'espace des noms globaux ou
    dans un espace de nommage plus large déterminé par "nonlocal",
    respectivement.

  Le lien du nom est modifié si le nom était déjà lié. Ceci peut faire
  que le compteur de références de l'objet auquel le nom était
  précédemment lié tombe à zéro, entrainant la dé-allocation de
  l'objet et l'appel de son destructeur (s'il existe).

* Si la cible est une référence à un attribut : l'expression primaire
  de la référence est évaluée. Elle doit produire un objet avec des
  attributs que l'on peut assigner : si ce n'est pas le cas, une
  "TypeError" est levée. Python demande alors à cet objet d'assigner
  l'attribut donné ; si ce n'est pas possible, une exception est levée
  (habituellement, mais pas nécessairement, "AttributeError").

  Note : si l'objet est une instance de classe et que la référence à
  l'attribut apparaît des deux côtés de l'opérateur d'assignation,
  l'expression « à droite », "a.x" peut accéder soit à l'attribut
  d'instance ou (si cet attribut d'instance n'existe pas) à l'attribut
  de classe. L'expression cible « à gauche » "a.x" est toujours
  définie comme un attribut d'instance, en le créant si nécessaire.
  Ainsi, les deux occurrences de "a.x" ne font pas nécessairement
  référence au même attribut : si l'expression « à droite » fait
  référence à un attribut de classe, l'expression « à gauche » crée un
  nouvel attribut d'instance comme cible de l'assignation :

     class Cls:
         x = 3             # class variable
     inst = Cls()
     inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3

  Cette description ne s'applique pas nécessairement aux attributs des
  descripteurs, telles que les propriétés créées avec "property()".

* Si la cible est une sélection : l'expression primaire de la
  référence est évaluée. Elle doit produire soit un objet séquence
  mutable (telle qu'une liste) ou un objet tableau de correspondances
  (tel qu'un dictionnaire). Ensuite, l'expression de la sélection est
  évaluée.

  Si la primaire est un objet séquence mutable (telle qu'une liste),
  la sélection doit produire un entier. S'il est négatif, la longueur
  de la séquence lui est ajoutée. La valeur résultante doit être un
  entier positif ou nul, plus petit que la longueur de la séquence, et
  Python demande à la séquence d'assigner l'objet à l'élément se
  trouvant à cet indice. Si l'indice est hors limites, une
  "IndexError" est levée (une assignation à une sélection dans une
  séquence ne peut pas ajouter de nouveaux éléments à une liste).

  Si la primaire est un objet tableau de correspondances (tel qu'un
  dictionnaire), la sélection doit être d'un type compatible avec le
  type des clés ; Python demande alors au tableau de correspondances
  de créer un couple clé-valeur qui associe la sélection à l'objet
  assigné. Ceci peut remplacer une correspondance déjà existante pour
  une clé donnée ou insérer un nouveau couple clé-valeur.

  For user-defined objects, the "__setitem__()" method is called with
  appropriate arguments.

* Si la cible est une tranche : l'expression primaire de la référence
  est évaluée. Elle doit produire un objet séquence mutable (telle
  qu'une liste). L'objet assigné doit être un objet séquence du même
  type. Ensuite, les expressions de la borne inférieure et de la borne
  supérieure sont évaluées, dans la mesure où elles sont spécifiées
  (les valeurs par défaut sont zéro et la longueur de la séquence).
  Les bornes doivent être des entiers. Si une borne est négative, la
  longueur de la séquence lui est ajoutée. Les bornes résultantes sont
  coupées pour être dans l'intervalle zéro -- longueur de la séquence,
  inclus. Finalement, Python demande à l'objet séquence de remplacer
  la tranche avec les éléments de la séquence à assigner. La longueur
  de la tranche peut être différente de la longueur de la séquence à
  assigner, ce qui modifie alors la longueur de la séquence cible, si
  celle-ci le permet.

Dans l'implémentation actuelle, la syntaxe pour les cibles est
similaire à celle des expressions. Toute syntaxe invalide est rejetée
pendant la phase de génération de code, ce qui produit des messages
d'erreurs moins détaillés.

Bien que la définition de l'assignation implique que le passage entre
le côté gauche et le côté droit soient « simultanés » (par exemple,
"a, b = b, a" permute les deux variables), le passage *à l'intérieur*
des collections de variables que l'on assigne intervient de la gauche
vers la droite, ce qui peut entraîner quelques confusions. Par
exemple, le programme suivant affiche "[0, 2]" :

   x = [0, 1]
   i = 0
   i, x[i] = 1, 2         # i is updated, then x[i] is updated
   print(x)

Voir aussi:

  **PEP 3132** -- dépaquetage étendu d'itérable
     Spécification de la fonctionnalité "*cible".


7.2.1. Les assignations augmentées
----------------------------------

Une assignation augmentée est la combinaison, dans une seule
instruction, d'une opération binaire et d'une assignation :

   augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)
   augtarget                 ::= identifier | attributeref | subscription | slicing
   augop                     ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
                                 | ">>=" | "<<=" | "&=" | "^=" | "|="

Voir la section Primaires pour la définition des syntaxes des trois
derniers symboles.

Une assignation augmentée évalue la cible (qui, au contraire des
assignations normales, ne peut pas être un dépaquetage) et la liste
d'expressions, effectue l'opération binaire (spécifique au type
d'assignation) sur les deux opérandes et assigne le résultat à la
cible originale. La cible n'est évaluée qu'une seule fois.

An augmented assignment statement like "x += 1" can be rewritten as "x
= x + 1" to achieve a similar, but not exactly equal effect. In the
augmented version, "x" is only evaluated once. Also, when possible,
the actual operation is performed *in-place*, meaning that rather than
creating a new object and assigning that to the target, the old object
is modified instead.

Au contraire des assignations normales, les assignations augmentées
évaluent la partie gauche *avant* d'évaluer la partie droite. Par
exemple, "a[i] += f(x)" commence par s'intéresser à "a[i]", puis
Python évalue "f(x)", effectue l'addition et, enfin, écrit le résultat
dans "a[i]".

À l'exception de l'assignation de *n*-uplets et de cibles multiples
dans une seule instruction, l'assignation effectuée par une
assignation augmentée est traitée de la même manière qu'une
assignation normale. De même, à l'exception du comportement possible
*sur place*, l'opération binaire effectuée par assignation augmentée
est la même que les opérations binaires normales.

Pour les cibles qui sont des références à des attributs, la même mise
en garde sur les attributs de classe et d'instances s'applique que
pour les assignations normales.


7.2.2. Les assignations annotées
--------------------------------

Une assignation *annotée* est la combinaison, dans une seule
instruction, d'une annotation de variable ou d'attribut et d'une
assignation optionnelle :

   annotated_assignment_stmt ::= augtarget ":" expression
                                 ["=" (starred_expression | yield_expression)]

La différence avec une assignation normale (voir ci-dessus) est qu'une
seule cible est autorisée.

The assignment target is considered "simple" if it consists of a
single name that is not enclosed in parentheses. For simple assignment
targets, if in class or module scope, the annotations are evaluated
and stored in a special class or module attribute "__annotations__"
that is a dictionary mapping from variable names (mangled if private)
to evaluated annotations. This attribute is writable and is
automatically created at the start of class or module body execution,
if annotations are found statically.

If the assignment target is not simple (an attribute, subscript node,
or parenthesized name), the annotation is evaluated if in class or
module scope, but not stored.

Si le nom est annoté dans la portée d'une fonction, alors ce nom est
local à cette portée. Les annotations ne sont jamais évaluées et
stockées dans les portées des fonctions.

If the right hand side is present, an annotated assignment performs
the actual assignment before evaluating annotations (where
applicable). If the right hand side is not present for an expression
target, then the interpreter evaluates the target except for the last
"__setitem__()" or "__setattr__()" call.

Voir aussi:

  **PEP 526** -- Syntaxe pour les annotations de variables
     La proposition qui a ajouté la syntaxe pour annoter les types de
     variables (y compris les variables de classe et les variables
     d'instance), au lieu de les exprimer par le biais de
     commentaires.

  **PEP 484** -- Indices de type
     La proposition qui a ajouté le module "typing" pour fournir une
     syntaxe standard pour les annotations de type qui peuvent être
     utilisées dans les outils d'analyse statique et les
     environnements de développement intégrés (*EDI*).

Modifié dans la version 3.8: Dorénavant, côté droit des assignations
annotées, peuvent figurer les mêmes expressions que pour les
assignations normales. Auparavant, certaines expressions (comme des
*n*-uplets sans parenthèse englobante) généraient des erreurs de
syntaxe.


7.3. L'instruction "assert"
===========================

Les instructions "assert" sont une manière pratique d'insérer des
tests de débogage au sein d'un programme :

   assert_stmt ::= "assert" expression ["," expression]

La forme la plus simple, "assert expression", est équivalente à :

   if __debug__:
       if not expression: raise AssertionError

La forme étendue, "assert expression1, expression2", est équivalente à
:

   if __debug__:
       if not expression1: raise AssertionError(expression2)

These equivalences assume that "__debug__" and "AssertionError" refer
to the built-in variables with those names.  In the current
implementation, the built-in variable "__debug__" is "True" under
normal circumstances, "False" when optimization is requested (command
line option "-O").  The current code generator emits no code for an
"assert" statement when optimization is requested at compile time.
Note that it is unnecessary to include the source code for the
expression that failed in the error message; it will be displayed as
part of the stack trace.

Assigner vers "__debug__" est illégal. La valeur de cette variable
native est déterminée au moment où l'interpréteur démarre.


7.4. L'instruction "pass"
=========================

   pass_stmt ::= "pass"

"pass" est une opération vide --- quand elle est exécutée, rien ne se
passe. Elle est utile comme bouche-trou lorsqu'une instruction est
syntaxiquement requise mais qu'aucun code ne doit être exécuté. Par
exemple :

   def f(arg): pass    # a function that does nothing (yet)

   class C: pass       # a class with no methods (yet)


7.5. L'instruction "del"
========================

   del_stmt ::= "del" target_list

La suppression est récursivement définie de la même manière que
l'assignation. Plutôt que de détailler cela de manière approfondie,
voici quelques indices.

La suppression d'une liste cible (*target_list* dans la grammaire ci-
dessus) supprime récursivement chaque cible, de la gauche vers la
droite.

Deletion of a name removes the binding of that name from the local or
global namespace, depending on whether the name occurs in a "global"
statement in the same code block.  Trying to delete an unbound name
raises a "NameError" exception.

La suppression d'une référence à un attribut, une sélection ou une
tranche est passée à l'objet primaire concerné : la suppression d'une
tranche est en général équivalente à l'assignation d'une tranche vide
du type adéquat (mais ceci est au final déterminé par l'objet que l'on
tranche).

Modifié dans la version 3.2: Auparavant, il était illégal de supprimer
un nom dans l'espace des noms locaux si celui-ci apparaissait comme
variable libre dans un bloc imbriqué.


7.6. L'instruction "return"
===========================

   return_stmt ::= "return" [expression_list]

"return" ne peut être placée qu'à l'intérieur d'une définition de
fonction, pas à l'intérieur d'une définition de classe.

Si une liste d'expressions (*expression_list* dans la grammaire ci-
dessus) est présente, elle est évaluée, sinon "None" est utilisée
comme valeur par défaut.

"return" quitte l'appel à la fonction courante avec la liste
d'expressions (ou "None") comme valeur de retour.

Quand "return" fait sortir d'une instruction "try" avec une clause
"finally", cette clause "finally" est exécutée avant de réellement
quitter la fonction.

Dans une fonction génératrice, l'instruction "return" indique que le
générateur est terminé et provoque la levée d'une "StopIteration". La
valeur de retour (s'il y en a une) est utilisée comme argument pour
construire l'exception "StopIteration" et devient l'attribut
"StopIteration.value".

Dans une fonction génératrice asynchrone, une instruction "return"
vide indique que le générateur asynchrone est terminé et provoque la
levée d'une "StopAsyncIteration". Une instruction "return" non vide
est une erreur de syntaxe dans une fonction génératrice asynchrone.


7.7. L'instruction "yield"
==========================

   yield_stmt ::= yield_expression

A "yield" statement is semantically equivalent to a yield expression.
The "yield" statement can be used to omit the parentheses that would
otherwise be required in the equivalent yield expression statement.
For example, the yield statements

   yield <expr>
   yield from <expr>

sont équivalentes aux instructions expressions *yield* :

   (yield <expr>)
   (yield from <expr>)

Yield expressions and statements are only used when defining a
*generator* function, and are only used in the body of the generator
function.  Using "yield" in a function definition is sufficient to
cause that definition to create a generator function instead of a
normal function.

Pour tous les détails sur la sémantique de "yield", reportez-vous à la
section Expressions yield.


7.8. L'instruction "raise"
==========================

   raise_stmt ::= "raise" [expression ["from" expression]]

Si aucune expression n'est présente, "raise" propage l'exception en
cours de traitement, aussi dénommée *exception active*. Si aucune
exception n'est active, une exception "RuntimeError" est levée,
indiquant que c'est une erreur.

Sinon, "raise" évalue la première expression en tant qu'objet
exception. Ce doit être une sous-classe ou une instance de
"BaseException". Si c'est une classe, l'instance de l'exception est
obtenue en instanciant la classe sans argument (au moment voulu).

Le *type* de l'exception est la classe de l'instance de l'exception,
la *value* est l'instance elle-même.

A traceback object is normally created automatically when an exception
is raised and attached to it as the "__traceback__" attribute. You can
create an exception and set your own traceback in one step using the
"with_traceback()" exception method (which returns the same exception
instance, with its traceback set to its argument), like so:

   raise Exception("foo occurred").with_traceback(tracebackobj)

The "from" clause is used for exception chaining: if given, the second
*expression* must be another exception class or instance. If the
second expression is an exception instance, it will be attached to the
raised exception as the "__cause__" attribute (which is writable). If
the expression is an exception class, the class will be instantiated
and the resulting exception instance will be attached to the raised
exception as the "__cause__" attribute. If the raised exception is not
handled, both exceptions will be printed:

   >>> try:
   ...     print(1 / 0)
   ... except Exception as exc:
   ...     raise RuntimeError("Something bad happened") from exc
   ...
   Traceback (most recent call last):
     File "<stdin>", line 2, in <module>
       print(1 / 0)
             ~~^~~
   ZeroDivisionError: division by zero

   The above exception was the direct cause of the following exception:

   Traceback (most recent call last):
     File "<stdin>", line 4, in <module>
       raise RuntimeError("Something bad happened") from exc
   RuntimeError: Something bad happened

A similar mechanism works implicitly if a new exception is raised when
an exception is already being handled.  An exception may be handled
when an "except" or "finally" clause, or a "with" statement, is used.
The previous exception is then attached as the new exception's
"__context__" attribute:

   >>> try:
   ...     print(1 / 0)
   ... except:
   ...     raise RuntimeError("Something bad happened")
   ...
   Traceback (most recent call last):
     File "<stdin>", line 2, in <module>
       print(1 / 0)
             ~~^~~
   ZeroDivisionError: division by zero

   During handling of the above exception, another exception occurred:

   Traceback (most recent call last):
     File "<stdin>", line 4, in <module>
       raise RuntimeError("Something bad happened")
   RuntimeError: Something bad happened

Exception chaining can be explicitly suppressed by specifying "None"
in the "from" clause:

   >>> try:
   ...     print(1 / 0)
   ... except:
   ...     raise RuntimeError("Something bad happened") from None
   ...
   Traceback (most recent call last):
     File "<stdin>", line 4, in <module>
   RuntimeError: Something bad happened

Des informations complémentaires sur les exceptions sont disponibles
dans la section Exceptions et sur la gestion des exceptions dans la
section L'instruction try.

Modifié dans la version 3.3: "None" est dorénavant autorisée en tant
que "Y" dans "raise X from Y".Added the "__suppress_context__"
attribute to suppress automatic display of the exception context.

Modifié dans la version 3.11: si la trace d'appels de l'exception
active est modifiée dans une clause "except", une instruction "raise"
postérieure lève à nouveau l'exception avec la trace modifiée.
Auparavant, l'exception était levée à nouveau avec la trace qu'elle
avait au moment de son interception.


7.9. L'instruction "break"
==========================

   break_stmt ::= "break"

Une instruction "break" ne peut apparaître qu'à l'intérieur d'une
boucle "for" ou "while", mais pas dans une définition de fonction ou
de classe à l'intérieur de cette boucle.

Elle termine la boucle la plus imbriquée, shuntant l'éventuelle clause
"else" de la boucle.

Si une boucle "for" est terminée par un "break", la cible qui contrôle
la boucle garde sa valeur.

Quand "break" passe le contrôle en dehors d'une instruction "try" qui
comporte une clause "finally", cette clause "finally" est exécutée
avant de quitter la boucle.


7.10. L'instruction "continue"
==============================

   continue_stmt ::= "continue"

L'instruction "continue" ne peut apparaître qu'à l'intérieur d'une
boucle "for" ou "while", mais pas dans une définition de fonction ou
de classe à l'intérieur de cette boucle. Elle fait continuer le flot
d'exécution au prochain cycle de la boucle la plus imbriquée.

Quand "continue" passe le contrôle en dehors d'une instruction "try"
qui comporte une clause "finally", cette clause "finally" est exécutée
avant de commencer le cycle suivant de la boucle.


7.11. L'instruction "import"
============================

   import_stmt     ::= "import" module ["as" identifier] ("," module ["as" identifier])*
                       | "from" relative_module "import" identifier ["as" identifier]
                       ("," identifier ["as" identifier])*
                       | "from" relative_module "import" "(" identifier ["as" identifier]
                       ("," identifier ["as" identifier])* [","] ")"
                       | "from" relative_module "import" "*"
   module          ::= (identifier ".")* identifier
   relative_module ::= "."* module | "."+

L'instruction de base *import* (sans clause "from") est exécutée en
deux étapes :

1. trouve un module, le charge et l'initialise si nécessaire

2. définit un ou des noms (*name* dans la grammaire ci-dessus) dans
   l'espace des noms locaux de la portée où l'instruction "import"
   apparaît.

Quand l'instruction contient plusieurs clauses (séparées par des
virgules), les deux étapes sont menées séparément pour chaque clause,
comme si les clauses étaient séparées dans des instructions
d'importations individuelles.

Les détails de la première étape, de recherche et de chargement des
modules, sont décrits largement dans la section relative au système
d'importation, qui décrit également les différents types de paquets et
modules qui peuvent être importés, de même que les points d'entrée
pouvant être utilisés pour personnaliser le système d'importation.
Notez que des erreurs dans cette étape peuvent indiquer soit que le
module n'a pas été trouvé, soit qu'une erreur s'est produite lors de
l'initialisation du module, ce qui comprend l'exécution du code du
module.

Si le module requis est bien récupéré, il est mis à disposition de
l'espace de nommage local suivant l'une des trois façons suivantes :

* Si le nom du module est suivi par "as", alors le nom suivant "as"
  est directement lié au module importé.

* si aucun autre nom n'est spécifié et que le module en cours
  d'importation est un module de niveau le plus haut, le nom du module
  est lié dans l'espace des noms locaux au module importé ;

* si le module en cours d'importation n'est *pas* un module de plus
  haut niveau, alors le nom du paquet de plus haut niveau qui contient
  ce module est lié dans l'espace des noms locaux au paquet de plus
  haut niveau. Vous pouvez accéder au module importé en utilisant son
  nom pleinement qualifié et non directement.

La forme "from" utilise un processus un peu plus complexe :

1. trouve le module spécifié dans la clause "from", le charge et
   l'initialise si nécessaire ;

2. pour chaque nom spécifié dans les clauses "import" :

   1. vérifie si le module importé possède un attribut avec ce nom ;

   2. si non, essaie d'importer un sous-module avec ce nom puis
      vérifie si le module importé possède lui-même cet attribut ;

   3. si l'attribut n'est pas trouvé, une "ImportError" est levée.

   4. sinon, une référence à cette valeur est stockée dans l'espace
      des noms locaux, en utilisant le nom de la clause "as" si elle
      est présente, sinon en utilisant le nom de l'attribut.

Exemples :

   import foo                 # foo imported and bound locally
   import foo.bar.baz         # foo, foo.bar, and foo.bar.baz imported, foo bound locally
   import foo.bar.baz as fbb  # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb
   from foo.bar import baz    # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz
   from foo import attr       # foo imported and foo.attr bound as attr

Si la liste des noms est remplacée par une étoile ("'*'"), tous les
noms publics définis dans le module sont liés dans l'espace des noms
locaux de la portée où apparaît l'instruction "import".

Les *noms publics* définis par un module sont déterminés en cherchant
dans l'espace de nommage du module une variable nommée "__all__" ; Si
elle est définie, elle doit être une séquence de chaînes désignant les
noms définis ou importés par ce module. Les noms donnés dans "__all__"
sont tous considérés publics et doivent exister. Si "__all__" n'est
pas définie, l'ensemble des noms publics contient tous les noms
trouvés dans l'espace des noms du module qui ne commencent pas par un
caractère souligné ("_"). "__all__" doit contenir toute l'API
publique. Elle est destinée à éviter l'exportation accidentelle
d'éléments qui ne font pas partie de l'API (tels que des modules de
bibliothèques qui ont été importés et utilisés à l'intérieur du
module).

La forme d'*import* avec astérisque --- "from module import *" --- est
autorisée seulement au niveau du module. Si vous essayez de l'utiliser
dans une définition de classe ou de fonction, cela lève une
"SyntaxError".

Quand vous spécifiez les modules à importer, vous n'avez pas besoin de
spécifier les noms absolus des modules. Quand un module ou un paquet
est contenu dans un autre paquet, il est possible d'effectuer une
importation relative à l'intérieur du même paquet de plus haut niveau
sans avoir à mentionner le nom du paquet. En utilisant des points en
entête du module ou du paquet spécifié après "from", vous pouvez
spécifier combien de niveaux vous souhaitez remonter dans la
hiérarchie du paquet courant sans spécifier de nom exact. Un seul
point en tête signifie le paquet courant où se situe le module qui
effectue l'importation. Deux points signifient de remonter d'un
niveau. Trois points, remonter de deux niveaux et ainsi de suite.
Ainsi, si vous exécutez "from . import mod" dans un module du paquet
"pkg", vous importez finalement "pkg.mod". Et si vous exécutez "from
..souspkg2 import mod" depuis "pkg.souspkg1", vous importez finalement
"pkg.souspkg2.mod". La spécification des importations relatives se
situe dans la section Importations relatives au paquet.

"importlib.import_module()" est fournie pour gérer les applications
qui déterminent dynamiquement les modules à charger.

Lève un évènement d'audit avec les arguments "module", "filename",
"sys.path", "sys.meta_path", "sys.path_hooks".


7.11.1. L'instruction future
----------------------------

Une *instruction future* est une directive à l'attention du
compilateur afin qu'un module particulier soit compilé en utilisant
une syntaxe ou une sémantique qui sera disponible dans une future
version de Python où cette fonctionnalité est devenue un standard.

L'instruction *future* a vocation à faciliter les migrations vers les
futures versions de Python qui introduisent des changements
incompatibles au langage. Cela permet l'utilisation de nouvelles
fonctionnalités module par module avant qu'une version n'officialise
cette fonctionnalité comme un standard.

   future_stmt ::= "from" "__future__" "import" feature ["as" identifier]
                   ("," feature ["as" identifier])*
                   | "from" "__future__" "import" "(" feature ["as" identifier]
                   ("," feature ["as" identifier])* [","] ")"
   feature     ::= identifier

Une instruction *future* doit apparaître en haut du module. Les seules
lignes autorisées avant une instruction *future* sont :

* la chaîne de documentation du module (si elle existe),

* des commentaires,

* des lignes vides et

* d'autres instructions *future*.

La seule fonctionnalité qui nécessite l'utilisation de l'instruction
"future" est "annotations" (voir la **PEP 563**).

Toutes les fonctionnalités (*feature* dans la grammaire ci-dessus)
autorisées par l'instruction "future" sont toujours reconnues par
Python 3. Cette liste comprend "absolute_import", "division",
"generators", "generator_stop", "unicode_literals", "print_function",
"nested_scopes" et "with_statement". Elles sont toutes redondantes car
elles sont de toute manière activées ; elles ne sont conservées que
par souci de compatibilité descendante.

Une instruction *future* est reconnue et traitée spécialement au
moment de la compilation : les modifications à la sémantique des
constructions de base sont souvent implémentées en générant un code
différent. Il peut même arriver qu'une nouvelle fonctionnalité ait une
syntaxe incompatible (tel qu'un nouveau mot réservé) ; dans ce cas, le
compilateur a besoin d'analyser le module de manière différente. De
telles décisions ne peuvent pas être différées au moment de
l'exécution.

Pour une version donnée, le compilateur sait quelles fonctionnalités
ont été définies et lève une erreur à la compilation si une
instruction *future* contient une fonctionnalité qui lui est inconnue.

La sémantique à l'exécution est la même que pour toute autre
instruction d'importation : il existe un module standard "__future__",
décrit plus loin, qui est importé comme les autres au moment où
l'instruction *future* est exécutée.

La sémantique particulière à l'exécution dépend des fonctionnalités
apportées par l'instruction *future*.

Notez que l'instruction suivante est tout à fait normale :

   import __future__ [as name]

Ce n'est pas une instruction *future* ; c'est une instruction
d'importation ordinaire qui n'a aucune sémantique particulière ou
restriction de syntaxe.

Code compiled by calls to the built-in functions "exec()" and
"compile()" that occur in a module "M" containing a future statement
will, by default, use the new syntax or semantics associated with the
future statement.  This can be controlled by optional arguments to
"compile()" --- see the documentation of that function for details.

Une instruction *future* entrée à l'invite de l'interpréteur
interactif est effective pour le reste de la session de
l'interpréteur. Si l'interpréteur est démarré avec l'option "-i",
qu'un nom de script est passé pour être exécuté et que ce script
contient une instruction *future*, elle est effective pour la session
interactive qui démarre après l'exécution du script.

Voir aussi:

  **PEP 236** — retour vers le "__future__"
     La proposition originale pour le mécanisme de "__future__".


7.12. L'instruction "global"
============================

   global_stmt ::= "global" identifier ("," identifier)*

The "global" statement causes the listed identifiers to be interpreted
as globals. It would be impossible to assign to a global variable
without "global", although free variables may refer to globals without
being declared global.

The "global" statement applies to the entire current scope (module,
function body or class definition). A "SyntaxError" is raised if a
variable is used or assigned to prior to its global declaration in the
scope.

At the module level, all variables are global, so a "global" statement
has no effect. However, variables must still not be used or assigned
to prior to their "global" declaration. This requirement is relaxed in
the interactive prompt (*REPL*).

**Note pour les programmeurs :** "global" est une directive à
l'attention de l'analyseur syntaxique. Elle s'applique uniquement au
code analysé en même temps que l'instruction "global". En particulier,
une instruction "global" contenue dans une chaîne ou un objet code
fourni à la fonction native "exec()" n'affecte pas le code *contenant*
cet appel et le code contenu dans un telle chaîne n'est pas affecté
par une instruction "global" placée dans le code contenant l'appel. Il
en est de même pour les fonctions "eval()" et "compile()".


7.13. L'instruction "nonlocal"
==============================

   nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

When the definition of a function or class is nested (enclosed) within
the definitions of other functions, its nonlocal scopes are the local
scopes of the enclosing functions. The "nonlocal" statement causes the
listed identifiers to refer to names previously bound in nonlocal
scopes. It allows encapsulated code to rebind such nonlocal
identifiers.  If a name is bound in more than one nonlocal scope, the
nearest binding is used. If a name is not bound in any nonlocal scope,
or if there is no nonlocal scope, a "SyntaxError" is raised.

The "nonlocal" statement applies to the entire scope of a function or
class body. A "SyntaxError" is raised if a variable is used or
assigned to prior to its nonlocal declaration in the scope.

Voir aussi:

  **PEP 3104** -- Accès à des noms en dehors de la portée locale
     Les spécifications pour l'instruction "nonlocal".

**Programmer's note:** "nonlocal" is a directive to the parser and
applies only to code parsed along with it.  See the note for the
"global" statement.


7.14. The "type" statement
==========================

   type_stmt ::= 'type' identifier [type_params] "=" expression

The "type" statement declares a type alias, which is an instance of
"typing.TypeAliasType".

For example, the following statement creates a type alias:

   type Point = tuple[float, float]

This code is roughly equivalent to:

   annotation-def VALUE_OF_Point():
       return tuple[float, float]
   Point = typing.TypeAliasType("Point", VALUE_OF_Point())

"annotation-def" indicates an annotation scope, which behaves mostly
like a function, but with several small differences.

The value of the type alias is evaluated in the annotation scope. It
is not evaluated when the type alias is created, but only when the
value is accessed through the type alias's "__value__" attribute (see
Lazy evaluation). This allows the type alias to refer to names that
are not yet defined.

Type aliases may be made generic by adding a type parameter list after
the name. See Generic type aliases for more.

"type" is a soft keyword.

Ajouté dans la version 3.12.

Voir aussi:

  **PEP 695** - Type Parameter Syntax
     Introduced the "type" statement and syntax for generic classes
     and functions.
