"zipfile" — Travailler avec des archives ZIP
********************************************

**Source code:** Lib/zipfile.py

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

Le format de fichier ZIP est une archive et un standard de compression
couramment utilisés. Ce module fournit des outils pour créer, écrire,
ajouter des données à et lister un fichier ZIP. L'utilisation avancée
de ce module requiert une certaine compréhension du format, comme
défini dans PKZIP Application Note.

Ce module ne gère pas pour l'instant les fichiers ZIP multi-disque. Il
gère les fichiers ZIP qui utilisent les extensions ZIP64 (c'est-à-dire
des fichiers d'une taille supérieure à 4 Go). Il gère le chiffrement
d'archives ZIP chiffrées, mais il ne peut pas pour l'instant créer de
fichier chiffré. Le déchiffrement est extrêmement lent car il est
implémenté uniquement en Python plutôt qu'en C.

Le module définit les éléments suivants :

exception zipfile.BadZipFile

   Erreur levée en cas de fichier ZIP non valide.

   Nouveau dans la version 3.2.

exception zipfile.BadZipfile

   Alias de "BadZipFile", pour la compatibilité avec les versions de
   Python précédentes.

   Obsolète depuis la version 3.2.

exception zipfile.LargeZipFile

   Erreur levée quand un fichier ZIP nécessite la fonctionnalité ZIP64
   mais qu'elle n'a pas été activée.

class zipfile.ZipFile

   Classe pour lire et écrire des fichiers ZIP. Voir la section Objets
   ZipFile pour les détails du constructeur.

class zipfile.Path

   Class that implements a subset of the interface provided by
   "pathlib.Path", including the full
   "importlib.resources.abc.Traversable" interface.

   Nouveau dans la version 3.8.

class zipfile.PyZipFile

   Classe pour créer des archives ZIP contenant des bibliothèques
   Python.

class zipfile.ZipInfo(filename='NoName', date_time=(1980, 1, 1, 0, 0, 0))

   Classe utilisée pour représenter les informations d'un membre d'une
   archive. Les instances de cette classe sont retournées par les
   méthodes  "getinfo()" et "infolist()" des objets "ZipFile". La
   plupart des utilisateurs du module "zipfile" n'ont pas besoin de
   créer ces instances mais d'utiliser celles créées par ce module.
   *filename* doit être le nom complet du membre de l'archive et
   *date_time* doit être un sextuplet  décrivant la date de dernière
   modification du fichier ; les champs sont décrits dans la section
   Objets ZipInfo.

zipfile.is_zipfile(filename)

   Retourne "True" si *filename* est un fichier ZIP valide basé sur
   son nombre magique, sinon retourne "False". *filename* peut aussi
   être un fichier ou un objet fichier-compatible.

   Modifié dans la version 3.1: Gestion des objets fichier et fichier-
   compatibles.

zipfile.ZIP_STORED

   Constante numérique pour un membre d'une archive décompressée.

zipfile.ZIP_DEFLATED

   Constante numérique pour la méthode habituelle de compression de
   ZIP. Nécessite le module "zlib".

zipfile.ZIP_BZIP2

   Constante numérique pour la méthode de compressions BZIP2.
   Nécessite le module "bz2".

   Nouveau dans la version 3.3.

zipfile.ZIP_LZMA

   Constante numérique pour la méthode de compressions LZMA. Nécessite
   le module "lzma".

   Nouveau dans la version 3.3.

   Note:

     La spécification du format de fichier ZIP inclut la gestion de la
     compression BZIP2 depuis 2001 et LZMA depuis 2006. Néanmoins,
     certains outils (comme certaines versions de Python) ne gèrent
     pas ces méthodes de compression et peuvent soit totalement
     refuser de traiter le fichier ZIP soit ne pas extraire certains
     fichiers.

Voir aussi:

  PKZIP Application Note
     Documentation sur le format de fichier ZIP par Phil Katz,
     créateur du format et des algorithmes utilisés.

  Info-ZIP Home Page
     Informations sur les programmes et les bibliothèques de
     développement d'archivage ZIP du projet Info-ZIP.


Objets ZipFile
==============

class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True, metadata_encoding=None)

   Ouvre un fichier ZIP, où *file* peut être un chemin vers un fichier
   (une chaîne de caractères), un objet fichier-compatible ou un objet
   chemin-compatible *path-like object*.

   Le paramètre *mode* doit être "r" pour lire un fichier existant,
   "w" pour tronquer et écrire un nouveau fichier, "a" pour ajouter
   des données à la fin d'un fichier existant ou "x" pour créer et
   écrire exclusivement un nouveau fichier. Si *mode* est à "x" et
   *file* fait référence à un fichier existant, une exception
   "FileExistsError" est levée. Si *mode* est à "a" et *file* fait
   référence à un fichier ZIP existant, alors des fichiers
   supplémentaires y seront ajoutés. Si *file* ne fait pas référence à
   un fichier ZIP, alors une nouvelle archive ZIP est ajoutée au
   fichier, afin de prévoir le cas d'ajouter une archive ZIP à un
   autre fichier (comme par exemple "python.exe"). Si *mode* est à "r"
   ou "a", le fichier doit être navigable.

   Le paramètre *compression* est la méthode de compression ZIP à
   utiliser lors de l'écriture de l'archive et doit être défini à
   "ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2" ou "ZIP_LZMA" ; les
   valeurs non reconnues lèveront une exception "NotImplementedError".
   Si "ZIP_DEFLATED", "ZIP_BZIP2" ou "ZIP_LZMA" est spécifié mais le
   module correspondant ("zlib", "bz2" ou "lzma") n'est pas
   disponible, une exception "RuntimeError" est levée. Est défini par
   défaut à "ZIP_STORED".

   Si *allowZip64* est à "True" (par défaut), *zipfile* crée des
   fichiers ZIP utilisant les extensions ZIP64 quand le fichier ZIP
   est plus grand que 4 Go. S'il est à "False", "zipfile" lève une
   exception quand le fichier ZIP nécessiterait les extensions ZIP64.

   Le paramètre *compresslevel* contrôle le niveau de compression à
   utiliser lors de l'écriture des fichiers dans l'archive. Avec
   "ZIP_STORED" ou "ZIP_LZMA", cela est sans effet. Avec
   "ZIP_DEFLATED" les entiers de "0" à "9" sont acceptés (voir "zlib"
   pour plus d'informations). Avec "ZIP_BZIP2" les entiers de "1" à
   "9" sont acceptés (voir "bz2" pour plus d'informations).

   Les fichiers ZIP plus anciens que le 1er janvier 1980 sont
   autorisés lorsque l'argument *strict_timestamps* vaut "False",
   moyennant de les voir datés du 1er janvier 1980. De même pour les
   fichiers datés d'après le 31 décembre 2107 qui voient leur
   horodatage fixé au 31 décembre 2107.

   When mode is "'r'", *metadata_encoding* may be set to the name of a
   codec, which will be used to decode metadata such as the names of
   members and ZIP comments.

   Si le fichier est créé avec le mode "'w'", "'x'" ou "'a'" et
   ensuite "fermé" sans ajouter de fichiers à l'archive, la structure
   appropriée pour un fichier archive ZIP vide sera écrite dans le
   fichier.

   *ZipFile* est aussi un gestionnaire de contexte et gère ainsi la
   déclaration "with". Dans l'exemple, *myzip* est fermé à la fin de
   la déclaration "with" --- même si une exception est levée :

      with ZipFile('spam.zip', 'w') as myzip:
          myzip.write('eggs.txt')

   Note:

     *metadata_encoding* is an instance-wide setting for the ZipFile.
     It is not currently possible to set this on a per-member
     basis.This attribute is a workaround for legacy implementations
     which produce archives with names in the current locale encoding
     or code page (mostly on Windows).  According to the .ZIP
     standard, the encoding of metadata may be specified to be either
     IBM code page (default) or UTF-8 by a flag in the archive header.
     That flag takes precedence over *metadata_encoding*, which is a
     Python-specific extension.

   Modifié dans la version 3.2: Ajout de la possibilité d'utiliser
   "ZipFile" comme un gestionnaire de contexte.

   Modifié dans la version 3.3: Ajout de la gestion de la compression
   "bzip2" et "lzma".

   Modifié dans la version 3.4: Les extensions ZIP64 sont activées par
   défaut.

   Modifié dans la version 3.5: Ajout de la gestion de l'écriture dans
   des flux non navigables. Ajout de la gestion du mode "x".

   Modifié dans la version 3.6: Auparavant, une simple exception
   "RuntimeError" était levée pour des valeurs de compression non
   reconnues.

   Modifié dans la version 3.6.2: Le paramètre *file* accepte un objet
   fichier-compatible *path-like object*.

   Modifié dans la version 3.7: Ajout du paramètre *compresslevel*.

   Modifié dans la version 3.8: The *strict_timestamps* keyword-only
   parameter.

   Modifié dans la version 3.11: Added support for specifying member
   name encoding for reading metadata in the zipfile's directory and
   file headers.

ZipFile.close()

   Ferme l'archive. Vous devez appeler "close()" avant de terminer
   votre programme ou des informations essentielles n'y seront pas
   enregistrées.

ZipFile.getinfo(name)

   Retourne un objet "ZipInfo" avec les informations du membre *name*
   de l'archive. Appeler "getinfo()" pour un nom non contenu dans
   l'archive lève une exception "KeyError".

ZipFile.infolist()

   Retourne une liste contenant un objet "ZipInfo" pour chaque membre
   de l'archive. Les objets ont le même ordre que leurs entrées dans
   le fichier ZIP présent sur disque s'il s'agissait d'une archive
   préexistante.

ZipFile.namelist()

   Retourne une liste des membres de l'archive indexés par leur nom.

ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)

   Access a member of the archive as a binary file-like object.
   *name* can be either the name of a file within the archive or a
   "ZipInfo" object.  The *mode* parameter, if included, must be "'r'"
   (the default) or "'w'".  *pwd* is the password used to decrypt
   encrypted ZIP files as a "bytes" object.

   "open()" est aussi un gestionnaire de contexte et gère ainsi la
   déclaration "with" :

      with ZipFile('spam.zip') as myzip:
          with myzip.open('eggs.txt') as myfile:
              print(myfile.read())

   With *mode* "'r'" the file-like object ("ZipExtFile") is read-only
   and provides the following methods: "read()", "readline()",
   "readlines()", "seek()", "tell()", "__iter__()", "__next__()".
   These objects can operate independently of the ZipFile.

   Avec "mode='w'" un descripteur de fichier en écriture est retourné,
   gérant la méthode "write()". Quand le descripteur d'un fichier
   inscriptible est ouvert, tenter de lire ou écrire d'autres fichiers
   dans le fichier ZIP lève une exception "ValueError".

   Lors de l'écriture d'un fichier, si la taille du fichier n'est pas
   connue mais peut être supérieure à 2 GiO, spécifiez
   "force_zip64=True" afin de vous assurer que le format d'en-tête est
   capable de supporter des fichiers volumineux. Si la taille du
   fichier est connue à l'avance, instanciez un objet "ZipInfo" avec
   l'attribut "file_size" défini et utilisez-le en tant que paramètre
   *name*.

   Note:

     Les méthodes "open()", "read()" et "extract()" peuvent prendre un
     nom de fichier ou un objet "ZipInfo". Cela est appréciable
     lorsqu'on essaie de lire un fichier ZIP qui contient des membres
     avec des noms en double.

   Modifié dans la version 3.6: Suppression de la gestion de
   "mode='U'".  Utilisez "io.TextIOWrapper" pour lire des fichiers
   texte compressés en mode *universal newlines*.

   Modifié dans la version 3.6: "ZipFile.open()" can now be used to
   write files into the archive with the "mode='w'" option.

   Modifié dans la version 3.6: Appeler "open()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

ZipFile.extract(member, path=None, pwd=None)

   Extract a member from the archive to the current working directory;
   *member* must be its full name or a "ZipInfo" object.  Its file
   information is extracted as accurately as possible.  *path*
   specifies a different directory to extract to.  *member* can be a
   filename or a "ZipInfo" object. *pwd* is the password used for
   encrypted files as a "bytes" object.

   Retourne le chemin normalisé créé (un dossier ou un nouveau
   fichier).

   Note:

     Si le nom de fichier d'un membre est un chemin absolu, le
     disque/partage UNC et les (anti)slashes de départ seront
     supprimés, par exemple "///foo/bar" devient "foo/bar" sous Unix
     et "C:\foo\bar" devient "foo\bar" sous Windows. Et tous les
     composants "".."" dans le nom de fichier d'un membre seront
     supprimés, par exemple "../../foo../../ba..r" devient
     "foo../ba..r". Sous Windows les caractères illégaux (":", "<",
     ">", "|", """, "?" et "*") sont remplacés par un *underscore*
     ("_").

   Modifié dans la version 3.6: Appeler "extract()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

   Modifié dans la version 3.6.2: Le paramètre *path* accepte un objet
   chemin-compatible *path-like object*.

ZipFile.extractall(path=None, members=None, pwd=None)

   Extract all members from the archive to the current working
   directory.  *path* specifies a different directory to extract to.
   *members* is optional and must be a subset of the list returned by
   "namelist()".  *pwd* is the password used for encrypted files as a
   "bytes" object.

   Avertissement:

     N'extrayez jamais d'archives depuis des sources non fiables sans
     inspection préalable. Il est possible que des fichiers soient
     créés en dehors de *path*, par exemple des membres qui ont des
     chemins de fichier absolus commençant par ""/"" ou des noms de
     fichier avec deux points "".."".  Ce module essaie de prévenir
     ceci. Voir la note de "extract()".

   Modifié dans la version 3.6: Appeler "extractall()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

   Modifié dans la version 3.6.2: Le paramètre *path* accepte un objet
   chemin-compatible *path-like object*.

ZipFile.printdir()

   Affiche la liste des contenus de l'archive sur "sys.stdout".

ZipFile.setpassword(pwd)

   Set *pwd* (a "bytes" object) as default password to extract
   encrypted files.

ZipFile.read(name, pwd=None)

   Return the bytes of the file *name* in the archive.  *name* is the
   name of the file in the archive, or a "ZipInfo" object.  The
   archive must be open for read or append. *pwd* is the password used
   for encrypted files as a "bytes" object and, if specified,
   overrides the default password set with "setpassword()". Calling
   "read()" on a ZipFile that uses a compression method other than
   "ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2" or "ZIP_LZMA" will raise
   a "NotImplementedError". An error will also be raised if the
   corresponding compression module is not available.

   Modifié dans la version 3.6: Appeler "read()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

ZipFile.testzip()

   Lit tous les fichiers de l'archive et vérifie leurs sommes CRC et
   leurs en-têtes. Retourne le nom du premier fichier mauvais ou
   retourne "None" sinon.

   Modifié dans la version 3.6: Appeler "testzip()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)

   Écrit le fichier nommé *filename* dans l'archive, lui donnant
   *arcname* comme nom dans l'archive (par défaut, *arcname* prend la
   même valeur que *filename* mais sans lettre de disque et séparateur
   de chemin en première position). Si donné, *compress_type* écrase
   la valeur donnée pour le paramètre *compression* au constructeur
   pour la nouvelle entrée. De la même manière, *compression* écrase
   le constructeur si donné. L'archive doit être ouverte avec le mode
   "'w'", "'x'" ou "'a'".

   Note:

     The ZIP file standard historically did not specify a metadata
     encoding, but strongly recommended CP437 (the original IBM PC
     encoding) for interoperability.  Recent versions allow use of
     UTF-8 (only).  In this module, UTF-8 will automatically be used
     to write the member names if they contain any non-ASCII
     characters.  It is not possible to write member names in any
     encoding other than ASCII or UTF-8.

   Note:

     Les noms d'archive doivent être relatifs à la racine de
     l'archive, c'est-à-dire qu'ils ne doivent pas commencer par un
     séparateur de chemin.

   Note:

     Si "arcname" (ou "filename" si "arcname" n'est pas donné)
     contient un octet nul, le nom du fichier dans l'archive sera
     tronqué à l'octet nul.

   Note:

     A leading slash in the filename may lead to the archive being
     impossible to open in some zip programs on Windows systems.

   Modifié dans la version 3.6: Appeler "write()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)

   Écrit un fichier dans l'archive. Le contenu est *data*, qui peut
   être soit une instance de "str" ou une instance de "bytes" ; s'il
   s'agit d'une "str", il est encodé en UTF-8 au préalable.
   *zinfo_or_arcname* est soit le nom de fichier qu'il sera donné dans
   l'archive, soit une instance de "ZipInfo". Si c'est une instance,
   au moins le nom de fichier, la date et l'heure doivent être donnés.
   S'il s'agit d'un nom, la date et l'heure sont définies sur la date
   et l'heure actuelles. L'archive doit être ouverte avec le mode
   "'w'", "'x'" ou "'a'".

   Si donné, *compress_type* écrase la valeur donnée pour le paramètre
   *compression* au constructeur de la nouvelle entrée ou dans le
   paramètre *zinfo_or_arcname* (si c'est une instance de "ZipInfo").
   De la même manière, *compresslevel* le constructeur si donné.

   Note:

     Lorsque l'on passe une instance de "ZipInfo" dans le paramètre
     *zinfo_or_arcname*, la méthode de compression utilisée sera celle
     spécifiée dans le membre *compress_type* de l'instance "ZipInfo"
     donnée. Par défaut, le constructeur de la classe "ZipInfo"
     définit ce membre à "ZIP_STORED".

   Modifié dans la version 3.2: L'argument *compress_type*.

   Modifié dans la version 3.6: Appeler "writestr()" sur un fichier
   ZipFile fermé lève une erreur "ValueError". Précédemment, une
   erreur "RuntimeError" était levée.

ZipFile.mkdir(zinfo_or_directory, mode=511)

   Create a directory inside the archive.  If *zinfo_or_directory* is
   a string, a directory is created inside the archive with the mode
   that is specified in the *mode* argument. If, however,
   *zinfo_or_directory* is a "ZipInfo" instance then the *mode*
   argument is ignored.

   The archive must be opened with mode "'w'", "'x'" or "'a'".

   Nouveau dans la version 3.11.

Les attributs suivants sont aussi disponibles :

ZipFile.filename

   Nom du fichier ZIP.

ZipFile.debug

   Le niveau d'affichage de *debug* à utiliser. Peut être défini de
   "0" (par défaut, pas d'affichage) à "3" (affichage le plus bavard).
   Les informations de débogage sont affichées sur "sys.stdout".

ZipFile.comment

   Le commentaire associé au fichier ZIP en tant qu'objet "bytes". Si
   vous affectez un commentaire à une instance de "ZipFile" créée avec
   le mode "'w'", "'x'" ou "'a'", il ne doit pas dépasser 65535
   octets. Les commentaires plus longs que cette taille seront
   tronqués.


Objets *Path*
=============

class zipfile.Path(root, at='')

   Construit un objet *Path* depuis le fichier ZIP *root* (qui peut
   être une instance de "ZipFile" ou tout ce qui sera accepté par le
   paramètre *file* du constructeur de "ZipFile").

   "at" indique la position de ce *Path* dans l'archive ZIP, par
   exemple ""dir/file.txt"", ""dir/"", ou """". Par défaut c'est une
   chaine vide, indiquant la racine de l'archive.

Les objets "Path" de "zipfile" exposent les fonctionnalités suivantes
des objets de "pathlib.Path" :

Path objects are traversable using the "/" operator or "joinpath".

Path.name

   Le dernier segment du chemin.

Path.open(mode='r', *, pwd, **)

   Appelle "ZipFile.open()" sur ce chemin. Il est possible d'ouvrir en
   lecture ou en écriture, au format texte ou binaire, via les modes
   "'r'", "'w'", "'rb'" et "'wb'". Les arguments positionnels et
   nommés sont passés à la classe "io.TextIOWrapper" lors d'une
   ouverture au format texte, ils sont ignorés autrement. "pwd" est le
   paramètre "pwd" de "ZipFile.open()".

   Modifié dans la version 3.9: prise en charge des modes texte et
   binaire pour "open". Le mode texte est maintenant le mode par
   défaut.

   Modifié dans la version 3.11.2: The "encoding" parameter can be
   supplied as a positional argument without causing a "TypeError". As
   it could in 3.9. Code needing to be compatible with unpatched 3.10
   and 3.11 versions must pass all "io.TextIOWrapper" arguments,
   "encoding" included, as keywords.

Path.iterdir()

   Énumère le contenu du dossier actuel.

Path.is_dir()

   Renvoie "True" si ce chemin pointe sur un dossier.

Path.is_file()

   Renvoie "True" si ce chemin pointe sur un fichier.

Path.exists()

   Renvoie "True" si le chemin pointe sur un fichier ou un dossier de
   l'archive ZIP

Path.suffix

   The file extension of the final component.

   Nouveau dans la version 3.11: Added "Path.suffix" property.

Path.stem

   The final path component, without its suffix.

   Nouveau dans la version 3.11: Added "Path.stem" property.

Path.suffixes

   A list of the path’s file extensions.

   Nouveau dans la version 3.11: Added "Path.suffixes" property.

Path.read_text(*, **)

   Lit le fichier au format texte. Les arguments positionnels et
   nommés sont passés à "io.TextIOWrapper" (sauf "buffer", qui est
   imposé par le contexte)

   Modifié dans la version 3.11.2: The "encoding" parameter can be
   supplied as a positional argument without causing a "TypeError". As
   it could in 3.9. Code needing to be compatible with unpatched 3.10
   and 3.11 versions must pass all "io.TextIOWrapper" arguments,
   "encoding" included, as keywords.

Path.read_bytes()

   Lit le fichier en mode binaire, renvoyant un objet *bytes*.

Path.joinpath(*other)

   Return a new Path object with each of the *other* arguments joined.
   The following are equivalent:

      >>> Path(...).joinpath('child').joinpath('grandchild')
      >>> Path(...).joinpath('child', 'grandchild')
      >>> Path(...) / 'child' / 'grandchild'

   Modifié dans la version 3.10: Prior to 3.10, "joinpath" was
   undocumented and accepted exactly one parameter.

The zipp project provides backports of the latest path object
functionality to older Pythons. Use "zipp.Path" in place of
"zipfile.Path" for early access to changes.


Objets *PyZipFile*
==================

Le constructeur de "PyZipFile" prend les mêmes paramètres que le
constructeur de "ZipFile" avec un paramètre additionnel *optimize*.

class zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=-1)

   Modifié dans la version 3.2: Added the *optimize* parameter.

   Modifié dans la version 3.4: Les extensions ZIP64 sont activées par
   défaut.

   Les instances ont une méthode supplémentaire par rapport aux objets
   "ZipFile" :

   writepy(pathname, basename='', filterfunc=None)

      Cherche les fichiers "*.py" et ajoute le fichier correspondant à
      l'archive.

      Si le paramètre *optimize* du constructeur de "PyZipFile" n'a
      pas été donné ou est à "-1", le fichier correspondant est un
      fichier "*.pyc", à compiler si nécessaire.

      Si le paramètre *optimize* du constructeur de "PyZipFile" est à
      "0", "1" ou "2", ne sont ajoutés dans l'archive que les fichiers
      avec ce niveau d'optimisation (voir "compile()"), à compiler si
      nécessaire.

      Si *pathname* est un fichier, le chemin de fichier doit terminer
      par  ".py" et uniquement le fichier ("*.pyc" correspondant) est
      ajouté au niveau le plus haut (sans information de chemin). Si
      *pathname* est un fichier ne terminant pas par ".py", une
      exception "RuntimeError" est levée. Si c'est un répertoire et
      que le répertoire n'est pas un répertoire de paquet, alors tous
      les fichiers  "*.pyc" sont ajoutés à la racine. Si le répertoire
      est un répertoire de paquet, alors tous les "*.pyc" sont ajoutés
      sous le nom du paquet en tant que chemin, et s'il y a des sous-
      répertoires qui sont des répertoires de paquet, ils sont tous
      ajoutés récursivement dans un ordre trié.

      *basename* n'est sensé être utilisé qu'en interne.

      *filterfunc*, si donné, doit être une fonction prenant une seule
      chaîne de caractères en argument. Il lui sera passé chaque
      chemin (incluant chaque chemin de fichier complet individuel)
      avant d'être ajouté à l'archive. Si *filterfunc* retourne une
      valeur fausse, le chemin n'est pas ajouté et si c'est un
      répertoire son contenu est ignoré. Par exemple, si nos fichiers
      de test sont tous soit dans des répertoires "test" ou commencent
      par "test_", nous pouvons utiliser une fonction *filterfunc*
      pour les exclure :

         >>> zf = PyZipFile('myprog.zip')
         >>> def notests(s):
         ...     fn = os.path.basename(s)
         ...     return (not (fn == 'test' or fn.startswith('test_')))
         >>> zf.writepy('myprog', filterfunc=notests)

      La méthode "writepy()" crée des archives avec des noms de
      fichier comme suit :

         string.pyc                   # Top level name
         test/__init__.pyc            # Package directory
         test/testall.pyc             # Module test.testall
         test/bogus/__init__.pyc      # Subpackage directory
         test/bogus/myfile.pyc        # Submodule test.bogus.myfile

      Modifié dans la version 3.4: Added the *filterfunc* parameter.

      Modifié dans la version 3.6.2: Le paramètre *pathname* accepte
      un objet chemin-compatible *path-like object*.

      Modifié dans la version 3.7: La récursion trie les entrées de
      dossier.


Objets *ZipInfo*
================

Des instances de la classe "ZipInfo" sont retournées par les méthodes
"getinfo()" et "infolist()" des objets "ZipFile". Chaque objet stocke
des informations sur un seul membre de l'archive ZIP.

Il y a une méthode de classe pour créer une instance de "ZipInfo" pour
un fichier du système de fichiers :

classmethod ZipInfo.from_file(filename, arcname=None, *, strict_timestamps=True)

   Construit une instance de "ZipInfo" pour le fichier du système de
   fichiers, en préparation de l'ajouter à un fichier ZIP.

   *filename* doit être un chemin vers un fichier ou un répertoire
   dans le système de fichiers.

   Si *arcname* est spécifié, il est utilisé en tant que nom dans
   l'archive. Si *arcname* n'est pas spécifié, le nom sera le même que
   *filename* mais sans lettre de disque et sans séparateur de chemin
   en première position.

   Les fichiers ZIP plus anciens que le 1er janvier 1980 sont
   autorisés lorsque l'argument *strict_timestamps* vaut "False",
   moyennant de les voir datés du 1er janvier 1980. De même pour les
   fichiers datés d'après le 31 décembre 2107 qui voient leur
   horodatage fixé au 31 décembre 2107.

   Nouveau dans la version 3.6.

   Modifié dans la version 3.6.2: Le paramètre  *filename* accepte un
   objet chemin-compatible *path-like object*.

   Modifié dans la version 3.8: Added the *strict_timestamps* keyword-
   only parameter.

Les instances ont les méthodes et attributs suivants :

ZipInfo.is_dir()

   Retourne "True" si le membre d'archive est un répertoire.

   Utilise le nom de l'entrée : les répertoires doivent toujours se
   terminer par "/".

   Nouveau dans la version 3.6.

ZipInfo.filename

   Nom du fichier dans l'archive.

ZipInfo.date_time

   Date et heure de dernière modification pour le membre de l'archive.
   *Tuple* de six valeurs :

   +---------+----------------------------+
   | Index   | Valeur                     |
   |=========|============================|
   | "0"     | Année (>= 1980)            |
   +---------+----------------------------+
   | "1"     | Mois (indexé à partir de   |
   |         | 1)                         |
   +---------+----------------------------+
   | "2"     | Jour du mois (indexé à     |
   |         | partir de 1)               |
   +---------+----------------------------+
   | "3"     | Heures (indexées à partir  |
   |         | de 0)                      |
   +---------+----------------------------+
   | "4"     | Minutes (indexées à partir |
   |         | de 0)                      |
   +---------+----------------------------+
   | "5"     | Secondes (indexées à       |
   |         | partir de 0)               |
   +---------+----------------------------+

   Note:

     Le format de fichier ZIP ne gère pas les horodatages avant 1980.

ZipInfo.compress_type

   Type de compression du membre d'archive.

ZipInfo.comment

   Commentaire pour le membre d'archive individuel en tant qu'objet
   "bytes".

ZipInfo.extra

   Données du champ d'extension. La documentation PKZIP Application
   Note contient quelques commentaires sur la structure interne des
   données contenues dans cet objet "bytes".

ZipInfo.create_system

   Système ayant créé l'archive ZIP.

ZipInfo.create_version

   Version de PKZIP ayant créé l'archive ZIP.

ZipInfo.extract_version

   Version de PKZIP nécessaire à l'extraction de l'archive ZIP.

ZipInfo.reserved

   Doit être à zéro.

ZipInfo.flag_bits

   Bits d'options ZIP.

ZipInfo.volume

   Numéro de volume de l'entête du fichier.

ZipInfo.internal_attr

   Attributs internes.

ZipInfo.external_attr

   Attributs de fichier externes.

ZipInfo.header_offset

   Longueur de l'entête du fichier en octets.

ZipInfo.CRC

   CRC-32 du fichier décompressé.

ZipInfo.compress_size

   Taille des données décompressées.

ZipInfo.file_size

   Taille du fichier décompressé.


Interface en ligne de commande
==============================

Le module "zipfile" fournit une interface en ligne de commande simple
pour interagir avec des archives ZIP.

Si vous voulez créer une nouvelle archive ZIP, spécifiez son nom après
l'option "-c" et listez ensuite le(s) nom(s) de fichier à inclure :

   $ python -m zipfile -c monty.zip spam.txt eggs.txt

Passer un répertoire est aussi possible :

   $ python -m zipfile -c monty.zip life-of-brian_1979/

Si vous voulez extraire une archive ZIP dans un répertoire donné,
utilisez l'option "-e" :

   $ python -m zipfile -e monty.zip target-dir/

Pour une liste des fichiers dans une archive ZIP, utilisez l'option
"-l" :

   $ python -m zipfile -l monty.zip


Options de la ligne de commande
-------------------------------

-l <zipfile>
--list <zipfile>

   Liste les fichiers dans un fichier ZIP *zipfile*.

-c <zipfile> <source1> ... <sourceN>
--create <zipfile> <source1> ... <sourceN>

   Crée un fichier ZIP *zipfile* à partir des fichiers *source*.

-e <zipfile> <output_dir>
--extract <zipfile> <output_dir>

   Extrait le fichier ZIP *zipfile* vers le répertoire cible
   *output_dir*.

-t <zipfile>
--test <zipfile>

   Teste si le fichier zip est valide.

--metadata-encoding <encoding>

   Specify encoding of member names for "-l", "-e" and "-t".

   Nouveau dans la version 3.11.


Problèmes de décompression
==========================

L'extraction d'une archive ZIP par le module *zipfile* peut échouer
pour les raisons listées ci-dessous.


À cause du fichier lui-même
---------------------------

La décompression peut échouer à cause d'un mot de passe ou d'une somme
de contrôle CRC incorrectes. Elle peut aussi échouer si le format, la
méthode de compression, ou de chiffrement n'est pas implémenté.


Limitations du système de fichiers
----------------------------------

Dépasser les limites du système de fichiers peut faire échouer la
décompression. Ces limites peuvent concerner les caractères licites
pour un nom de fichier, la longueur du nom du fichier ou du chemin, la
taille d'un fichier, le nombre de fichiers, etc.


Ressources limitées
-------------------

Le manque de mémoire ou d'espace disque peut mener à un échec de
décompression. Par exemple, une bombe de décompression (ZIP bomb),
décompressés avec *zifile* peut remplir l'espace disque.


Interruption
------------

Une interruption durant la décompression, en utilisant *control-C* ou
en tuant le processus, peut mener à une décompression partielle de
l'archive.


Comportements par défaut de l'extraction
----------------------------------------

Ne pas connaître le comportement d'extraction par défaut peut causer
des résultats inattendus. Par exemple, lors de l'extraction d'une même
archive deux fois, les fichiers sont écrasés sans prévenir.
