# 13.5. `zipfile` — Travailler avec des archives ZIP

Code source : 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.``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 tuple contenant six champs qui décrit 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.

## 13.5.1. Objets ZipFile

class `zipfile.``ZipFile`(file, mode='r', compression=ZIP_STORED, allowZip64=True)

  Open a ZIP file, where file can be a path to a file (a string), a file-like object or a path-like object. The mode parameter should be `'r'` to read an existing file, `'w'` to truncate and write a new file, `'a'` to append to an existing file, or `'x'` to exclusively create and write a new file. If mode is `'x'` and file refers to an existing file, a `FileExistsError` will be raised. If mode is `'a'` and file refers to an existing ZIP file, then additional files are added to it. If file does not refer to a ZIP file, then a new ZIP archive is appended to the file. This is meant for adding a ZIP archive to another file (such as `python.exe`). If mode is `'a'` and the file does not exist at all, it is created. If mode is `'r'` or `'a'`, the file should be seekable. compression is the ZIP compression method to use when writing the archive, and should be `ZIP_STORED`, `ZIP_DEFLATED`, `ZIP_BZIP2` or `ZIP_LZMA`; unrecognized values will cause `NotImplementedError` to be raised. If `ZIP_DEFLATED`, `ZIP_BZIP2` or `ZIP_LZMA` is specified but the corresponding module (`zlib`, `bz2` or `lzma`) is not available, `RuntimeError` is raised. The default is `ZIP_STORED`. If allowZip64 is `True` (the default) zipfile will create ZIP files that use the ZIP64 extensions when the zipfile is larger than 4 GiB. If it is false `zipfile` will raise an exception when the ZIP file would require ZIP64 extensions.

  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 is also a context manager and therefore supports the `with` statement. In the example, myzip is closed after the `with` statement’s suite is finished—even if an exception occurs:

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

  Nouveau 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.

`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)

  Accède un membre de l’archive en tant qu’objet fichier-compatible binaire. name peut être soit le nom d’un fichier au sein de l’archive soit un objet `ZipInfo`. Le paramètre mode, si inclus, doit être défini à `'r'` (valeur par défaut) ou `'w'`. pwd est le mot de passe utilisé pour déchiffrer des fichiers ZIP chiffrés.

  `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()`, `__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: La méthode `open()` peut désormais être utilisée pour écrire des fichiers dans l’archive avec l’option `mode='w'`.

  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)

  Extrait un membre de l’archive dans le répertoire courant ; member doit être son nom complet ou un objet `ZipInfo`. Ses propriétés de fichier sont extraites le plus fidèlement possible. path spécifie un répertoire différent où l’extraire. member peut être un nom de fichier ou un objet `ZipInfo`. pwd est le mot de passe utilisé pour les fichiers chiffrés.

  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)

  Extrait tous les membres de l’archive dans le répertoire courant. path spécifie un dossier de destination différent. members est optionnel et doit être un sous-ensemble de la liste retournée par `namelist()`. pwd est le mot de passe utilisé pour les fichiers chiffrés.

  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)

  Définit pwd comme mot de passe par défait pour extraire des fichiers chiffrés.

`ZipFile.``read`(name, pwd=None)

  Retourne les octets du fichier name dans l’archive. name est le nom du fichier dans l’archive ou un objet `ZipInfo`. L’archive doit être ouverte en mode lecture ou ajout de données. pwd est le mot de passe utilisé pour les fichiers chiffrés et, si spécifié, écrase le mot de passe par défaut défini avec `setpassword()`. Appeler `read()` sur un fichier ZipFile qui utilise une méthode de compression différente de `ZIP_STORED`, `ZIP_DEFLATED`, `ZIP_BZIP2` ou `ZIP_LZMA` lève une erreur `NotImplementedError`. Une erreur est également levée si le module de compression n’est pas disponible.

  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: Calling `testzip()` on a closed ZipFile will raise a `ValueError`. Previously, a `RuntimeError` was raised.

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

  Write the file named filename to the archive, giving it the archive name arcname (by default, this will be the same as filename, but without a drive letter and with leading path separators removed). If given, compress_type overrides the value given for the compression parameter to the constructor for the new entry. The archive must be open with mode `'w'`, `'x'` or `'a'`.

  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.

  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])

  Write a file into the archive. The contents is data, which may be either a `str` or a `bytes` instance; if it is a `str`, it is encoded as UTF-8 first. zinfo_or_arcname is either the file name it will be given in the archive, or a `ZipInfo` instance. If it’s an instance, at least the filename, date, and time must be given. If it’s a name, the date and time is set to the current date and time. The archive must be opened with mode `'w'`, `'x'` or `'a'`.

  If given, compress_type overrides the value given for the compression parameter to the constructor for the new entry, or in the zinfo_or_arcname (if that is a `ZipInfo` instance).

  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.

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`

  The comment associated with the ZIP file as a `bytes` object. If assigning a comment to a `ZipFile` instance created with mode `'w'`, `'x'` or `'a'`, it should be no longer than 65535 bytes. Comments longer than this will be truncated.

## 13.5.2. 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)

  Nouveau dans la version 3.2: Le paramètre optimize.

  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.

    If pathname is a file, the filename must end with `.py`, and just the (corresponding `*.pyc`) file is added at the top level (no path information). If pathname is a file that does not end with `.py`, a `RuntimeError` will be raised. If it is a directory, and the directory is not a package directory, then all the files `*.pyc` are added at the top level. If the directory is a package directory, then all `*.pyc` are added under the package name as a file path, and if any subdirectories are package directories, all of these are added recursively.

    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

    Nouveau dans la version 3.4: Le paramètre filterfunc.

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

## 13.5.3. 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)

  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.

  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.

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`

  Comment for the individual archive member as a `bytes` object.

`ZipInfo.``extra`

  Expansion field data. The PKZIP Application Note contains some comments on the internal structure of the data contained in this `bytes` object.

`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é.

## 13.5.4. 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

### 13.5.4.1. Options de la ligne de commande

`-l``<zipfile>`

  Liste les fichiers dans un fichier ZIP zipfile.

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

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

`-e``<zipfile> <output_dir>`

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

`-t``<zipfile>`

  Teste si le fichier zip est valide.