13.4. "lzma" — Compression via l'algorithme LZMA
************************************************

Nouveau dans la version 3.3.

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

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

Ce module fournit des classes et des fonctions utiles pour compresser
et décompresser des données en utilisant l'algorithme de compression
LZMA. Ce module inclut aussi aussi une interface prenant en charge les
fichiers ".xz" et son format originel ".lzma" utilisés par
l'utilitaire **xz**, ainsi que les flux bruts compressés.

L'interface disponible par ce module ressemble en de nombreux points à
celle du module "bz2". Cependant, notez que la "LZMAFile" n'est pas
*thread-safe*, comme l'est la "bz2.BZ2File". Donc, si vous souhaitez
utiliser une seule instance de "LZMAFile" pour plusieurs fils, il sera
alors nécessaire de la protéger avec un verrou (*lock*).

exception lzma.LZMAError

   Cette exception est levée dès lors qu'une erreur survient pendant
   la compression ou la décompression, ou pendant l'initialisation de
   l'état de la compression/décompression.


13.4.1. Lire et écrire des fichiers compressés
==============================================

lzma.open(filename, mode="rb", *, format=None, check=-1, preset=None, filters=None, encoding=None, errors=None, newline=None)

   Ouvre un fichier compressé sous LZMA en mode binaire ou texte,
   retourne un *file object*.

   L'argument *nom de fichier* peut être soit le nom d'un fichier à
   créer (donné pour "str", "bytes" ou un objet *path-like*), dont le
   fichier nommé reste ouvert, ou soit un objet fichier existant à
   lire ou à écrire.

   L'argument *mode* peut être n'importe quel argument suivant :
   ""r"", ""rb"", ""w"", ""wb"", ""x"", ""xb"", ""a"" ou ""ab"" pour
   le mode binaire, ou ""rt"", ""wt"", ""xt"", ou ""at"" pour le mode
   texte. La valeur par défaut est ""rb"".

   Quand un fichier est ouvert pour le lire, les arguments *format* et
   *filters* ont les mêmes significations que pour la
   "LZMADecompressor". Par conséquent, les arguments *check* et
   *preset* ne devront pas être sollicités.

   Dès ouverture d'un fichier pour l'écriture, les arguments *format*,
   *check*, *preset* et *filters* ont le même sens que dans la
   "LZMACompressor".

   Pour le mode binaire, cette fonction équivaut à la "LZMAFile"
   constructor: "LZMAFile(filename, mode, ...)". Dans ce cas précis,
   les arguments *encoding*, *errors* et *newline* ne sont pas
   accessibles.

   Pour le mode texte, un objet de "LZMAFile" est créé, et enveloppé
   dans une instance de "io.TextIOWrapper" avec son encodage
   spécifique, son gestionnaire d'erreur, et ses signes pour les
   renvois à la ligne.

   Modifié dans la version 3.4: Support ajouté pour les modes ""x"",
   ""xb"" and ""xt"".

   Modifié dans la version 3.6: Accepte un *path-like object*.

class lzma.LZMAFile(filename=None, mode="r", *, format=None, check=-1, preset=None, filters=None)

   Ouvre un fichier LZMA compressé en mode binaire.

   An "LZMAFile" can wrap an already-open *file object*, or operate
   directly on a named file. The *filename* argument specifies either
   the file object to wrap, or the name of the file to open (as a
   "str", "bytes" or *path-like* object). When wrapping an existing
   file object, the wrapped file will not be closed when the
   "LZMAFile" is closed.

   L'argument *mode* peut être soit ""r"" pour la lecture (défaut),
   ""w"" pour la ré-écriture, ""x"" pour la création exclusive, ou
   ""a"" pour l'insertion. Elles epuvent aussi être écrites de la
   façon suivante : ""rb"", ""wb"", ""xb"" et ""ab"" respectivement.

   Si l'argument *filename* est un objet fichier (plutôt qu'un nom de
   fichier courant), un mode``"w"`` ne tronquera aucunement le
   fichier, et sera équivalent à ""a"".

   Dès l'ouverture d'un fichier pour être lu, le fichier d'entrée peut
   être le résultat d'une concaténation de plusieurs flux distincts et
   compressés. Ceux-ci sont décodés de manière transparente en un seul
   flux logique.

   Quand un fichier est ouvert pour le lire, les arguments *format* et
   *filters* ont les mêmes significations que pour la
   "LZMADecompressor". Par conséquent, les arguments *check* et
   *preset* ne devront pas être sollicités.

   Dès ouverture d'un fichier pour l'écriture, les arguments *format*,
   *check*, *preset* et *filters* ont le même sens que dans la
   "LZMACompressor".

   La "LZMAFile" supporte tous les attributs précisés dans
   "io.BufferedIOBase", sauf "detach()" et "truncate()". Le "with" et
   son itération sont également supportés.

   Les méthodes suivantes sont aussi disponibles :

   peek(size=-1)

      Renvoie la donnée en mémoire-tampon sans progression de la
      position du fichier. Au moins un octet de donnée sera renvoyé,
      jusqu'à ce que l'EOF soit atteinte. Le nombre exact d'octets
      renvoyés demeure indéterminé (l'argument *taille* est ignoré).

      Note:

        Alors que l'exécution de "peek()" ne change pas la position du
        fichier de la classe  "LZMAFile", la position de l'objet
        sous-jacent peut être modifiée (ex. : si la classe "LZMAFile"
        est construite en lui transmettant un fichier-objet comme
        *filename*).

   Modifié dans la version 3.4: Support ajouté pour les modes ""x""
   and ""xb"".

   Modifié dans la version 3.5: La méthode "read()" accepte maintenant
   un argument "None".

   Modifié dans la version 3.6: Accepte un *path-like object*.


13.4.2. Compresser et décompresser une donnée en mémoire
========================================================

class lzma.LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)

   Créé un objet compresseur, qui peut être utilisé pour compresser
   incrémentalement une donnée.

   Pour une façon plus adaptée de compresser un seul extrait de
   donnée, voir "compress()".

   L'argument *format* définit quel format de conteneur sera mis en
   œuvre. Les valeurs possibles sont :

   * "FORMAT_XZ": Le format du  conteneur ".xz".
        C'est le format par défaut.

   * "FORMAT_ALONE": L'ancien format du conteneur ".lzma".
        Ce format est davantage limité que ".xz" --il ne supporte pas
        les vérifications d'intégrité ou les filtres multiples.

   * "FORMAT_RAW": Un flux de données brut, n'utilisant aucun format
     de conteneur.
        Ce format spécifique ne prend pas en charge les vérifications
        d'intégrité et exige systématiquement la définition d'une
        chaîne de filtrage personnalisée (à la fois pour la
        compression et la décompression). Par ailleurs, les données
        compressées par ce biais ne peuvent pas être décompressées par
        l'usage de "FORMAT_AUTO" (voir :  "LZMADecompressor").

   L'argument *check* détermine le type de vérification d'intégrité à
   exploiter avec la donnée compressée. Cette vérification est
   déclenchée lors de la décompression, pour garantir que la donnée
   n'a pas été corrompue. Les valeurs possibles sont :

   * "CHECK_NONE": Pas de vérification d'intégrité. C'est la valeur
     par défaut (et la seule valeur acceptable) pour "FORMAT_ALONE" et
     "FORMAT_RAW".

   * "CHECK_CRC32": Vérification par Redondance Cyclique 32-bit
     (*Cyclic Redundancy Check*).

   * "CHECK_CRC64": Vérification par Redondance Cyclique 64-bit
     (*Cyclic Redundancy Check*). Valeur par défaut pour "FORMAT_XZ".

   * "CHECK_SHA256": Algorithme de Hachage Sécurisé 256-bit (*Secure
     Hash Algorithm*).

   Si le type de vérification n'est pas supporté par le système, une
   erreur de type "LZMAError" est levée.

   Les réglages de compression peuvent être définis soit comme un
   pré-réglage de niveau de compression (avec l'argument *preset*) ;
   soit de façon détaillée comme une chaîne particulière de filtres
   (avec l'argument *filters*).

   L'argument *preset* (s'il est fourni) doit être un entier compris
   entre *0`* et "9" (inclus), éventuellement relié à OR avec la
   constante "PRESET_EXTREME". Si aucun *preset* ni *filters* ne ont
   définis, le comportement par défaut consiste à utiliser la
   "PRESET_DEFAULT" (niveau par défaut : "6"). Des pré-réglages plus
   élevés entraîne une sortie plus petite, mais rend le processus de
   compression plus lent.

   Note:

     En plus d'être plus gourmande en CPU, la compression avec des
     préréglages plus élevés nécessite beaucoup plus de mémoire (et
     produit des résultats qui nécessitent plus de mémoire pour
     décompresser). Par exemple, avec le préréglage "9", l'objet d'une
     "LZMACompressor" peut dépasser largement les 800 Mo. Pour cette
     raison, il est généralement préférable de respecter le préréglage
     par défaut.

   L'argument *filters* (s'il est défini) doit être un critère de la
   chaîne de filtrage. Voir Préciser des chaînes de filtre
   personnalisées pour plus de précisions.

   compress(data)

      Une *data* compressée (un objet "bytes"), renvoie un objet
      "bytes" contenant une donnée compressée pour au moins une partie
      de l'entrée. Certaine *data* peuvent être mise en tampon, pour
      être utiliser lors de prochains appels par "compress()" et
      "flush()". La donnée renvoyée pourra être concaténée avec la
      sortie d'appels précédents vers la méthode "compress()".

   flush()

      Conclut l'opération de compression, en renvoyant l'objet "bytes"
      constitué de toutes les données stockées dans les tampons
      interne du compresseur.

      Le compresseur ne pourra pas être sollicité après l'appel de
      cette méthode.

class lzma.LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)

   Créé un objet de décompression, pour décompresser de façon
   incrémentale une donnée.

   Pour un moyen plus pratique de décompresser un flux compressé
   complet en une seule fois, voir "decompress()".

   L'argument *format* spécifie le format du conteneur à utiliser. La
   valeur par défaut est "FORMAT_AUTO" pouvant à la fois décompresser
   les fichiers ".xz" and ".lzma". D'autres valeurs sont possibles
   comme "FORMAT_XZ", "FORMAT_ALONE", et "FORMAT_RAW".

   L'argument *memlimit* spécifie une limite (en octets) sur la
   quantité de mémoire que le décompresseur peut utiliser. Lorsque cet
   argument est utilisé, la décompression échouera avec une
   "LZMAError" s'il n'est pas possible de décompresser l'entrée dans
   la limite mémoire disponible.

   L'argument *filters* spécifie la chaîne de filtrage utilisée pour
   créer le flux décompressé. Cet argument est requis si *format* est
   "FORMAT_RAW", mais ne doit pas être utilisé pour d'autres formats.
   Voir Préciser des chaînes de filtre personnalisées pour plus
   d'informations sur les chaînes de filtrage.

   Note:

     Cette classe ne gère pas de manière transparente les entrées
     contenant plusieurs flux compressés, contrairement à
     "decompress()" et "LZMAFile". Pour décompresser une entrée multi-
     flux avec  "LZMADecompressor", vous devez créer un nouveau
     décompresseur à chaque flux.

   decompress(data, max_length=-1)

      Décompresse *data* (un *bytes-like object*), renvoyant une
      donnée non compressée en tant que chaîne d'octets. Certaines de
      ces *data* peuvent être mises en interne en tampon, pour un
      usage lors d'appels ultérieurs par la méthode "decompress()". La
      donnée renvoyée doit être concaténée avec la sortie des appels
      précédents à la méthode "decompress()".

      Si *max_length* est positif, renvoie au plus *max_length* octets
      de données compressées. Si la limite est atteinte et que
      d'autres sorties peuvent être produites, l'attribut
      "needs_input" est positionné sur "False". Dans ce cas, lors de
      l'appel suivant à la méthode "decompress()", vous pouvez fournir
      "b''" dans *data* afin d'obtenir la suite de la sortie.

      Si toutes les données entrées ont été décompressées et renvoyées
      (soit parce qu'il y avait moins de *max_length* octets, ou parce
      que *max_length* était négatif), l'attribut "needs_input" sera
      configuré sur "True".

      Essayer de décompresser des données après que la fin du flux
      soit atteinte lève une erreur *EOFError*. Toute donnée trouvée
      après la fin du flux est ignorée et sauvegardée dans l'attribut
      "unused_data".

      Modifié dans la version 3.5: Ajout du paramètre *max_length*.

   check

      L'ID de la vérification d'intégrité exploité par le flux
      entrant. Il s'agit de "CHECK_UNKNOWN" tant que ce flux a été
      décodé pour déterminer quel type de vérification d'intégrité à
      été utilisé.

   eof

      "True" si le marqueur de fin de flux a été atteint.

   unused_data

      Donnée trouvée après la fin du flux compressé.

      Avant d'atteindre la fin du flux, ce sera "b""".

   needs_input

      "False" si la méthode "decompress()" peut fournir plus de
      données décompressées avant l'acquisition d'une nouvelle entrée
      non compressée.

      Nouveau dans la version 3.5.

lzma.compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None)

   *data* compressée (un objet "bytes"), renvoyant une donnée
   compressée comme un objet "bytes".

   Voir "LZMACompressor" ci-dessus pour une description des arguments
   *format*, *check*, *preset* and *filters*.

lzma.decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None)

   Décopresse *data* (un objet "bytes" ), et retourne la donnée
   décompressée sous la forme d'un objet "bytes".

   Si *data* est le résultat de la concaténation de plusieurs
   fluxcompressés et distincts , il les décompresse tous, et retourne
   les résultats concaténés.

   Voir "LZMADecompressor" ci-dessus pour une description des
   arguments *format*, *memlimit* et *filters*.


13.4.3. Divers
==============

lzma.is_check_supported(check)

   Renvoie vrai si le contrôle d'intégrité donné est supporté par le
   système.

   "CHECK_NONE" et "CHECK_CRC32" sont toujours suppportés.
   "CHECK_CRC64" et "CHECK_SHA256" peuvent être indisponibles si vous
   utlisez une version de **liblzma** compilée avec des possibilités
   restreintes.


13.4.4. Préciser des chaînes de filtre personnalisées
=====================================================

Une chaîne de filtres est une séquence de dictionnaires, où chaque
dictionnaire contient l'ID et les options pour chaque filtre. Le
moindre dictionnaire contient la clé ""id"" et peut aussicontenir
d'autres clés pour préciser chaque options relative au filtre déclaré.
Les ID valides des filtres sont définies comme suit :

* Filtres de compression:
     * "FILTER_LZMA1" (à utiliser avec "FORMAT_ALONE")

     * "FILTER_LZMA2" (à utiliser avec "FORMAT_XZ" et "FORMAT_RAW")

* Filtre Delta:
     * "FILTER_DELTA"

* Filtres Branch-Call-Jump (BCJ):
     * "FILTER_X86"

     * "FILTER_IA64"

     * "FILTER_ARM"

     * "FILTER_ARMTHUMB"

     * "FILTER_POWERPC"

     * "FILTER_SPARC"

Une chaîne de filtres peut contenir jusqu'à 4 filtres, et ne peut pas
être vide. Le dernier filtre de cette chaîne devra être un filtre de
compression, et tous les autres doivent être des filtres delta ou BCJ.

Les filtres de compression contiennent les options suivantes (définies
comme entrées additionnelles dans le dictionnaire qui représente le
filtre) :

   * "preset": Un pré-réglage à exploiter comme une source de valeurs
     par défaut pour les options qui ne sont pas explicitement
     définies.

   * "dict_size": La taille du dictionnaire en octets. Comprise entre
     4 Ko et 1.5 Go (inclus).

   * "lc": Nombre de bits dans le contexte litéral.

   * "lp": Nombre de bits dans la position litérale. La somme "lc +
     lp" devra être au moins 4.

   * "pb": Nombre de bits à cette position ; au moins 4.

   * "mode": "MODE_FAST" ou "MODE_NORMAL".

   * "nice_len": Ce qui devra être pris en compte comme "longueur
     appréciable" pour une recherche. Il devra être 273 ou moins.

   * "mf": Quel type d'index de recherche à utiliser -- "MF_HC3",
     "MF_HC4", "MF_BT2", "MF_BT3", ou "MF_BT4".

   * "depth": Profondeur maximum de la recherche, utilisée par l'index
     de recherche. 0 (défaut) signifie une sélection automatique basée
     sur des options de filtres différents.

Le filtre delta stocke les différences entre octets, induisant
davantage d'entrées répétitives pour le compresseur, selon les
circonstances. Il support une option, "dist". Ce paramètre définit la
distance entre les octets à soustraire. Par défaut : 1, soit la
différence entre des octets adjacents.

Les filtres BCJ sont conçus pour être appliqués sur du langage
machine. Ils convertissent les branches relatives, les appels et les
sauts dans le code à des fins d'adressage strict, dans le but
d'augmenter la redondance mise en jeu par le compresseur. Ils ne
supportent qu'une seule option : "start_offset", pour définir
l'adresse où sera déclenché le début de la donnée d'entrée. Par défaut
: 0.


13.4.5. Exemples
================

Lire un fichier compressé:

   import lzma
   with lzma.open("file.xz") as f:
       file_content = f.read()

Créer un fichier compressé:

   import lzma
   data = b"Insert Data Here"
   with lzma.open("file.xz", "w") as f:
       f.write(data)

Compresser des données en mémoire:

   import lzma
   data_in = b"Insert Data Here"
   data_out = lzma.compress(data_in)

Compression incrémentale:

   import lzma
   lzc = lzma.LZMACompressor()
   out1 = lzc.compress(b"Some data\n")
   out2 = lzc.compress(b"Another piece of data\n")
   out3 = lzc.compress(b"Even more data\n")
   out4 = lzc.flush()
   # Concatenate all the partial results:
   result = b"".join([out1, out2, out3, out4])

Ecrire des données compressées dans un fichier préalablement ouvert:

   import lzma
   with open("file.xz", "wb") as f:
       f.write(b"This data will not be compressed\n")
       with lzma.open(f, "w") as lzf:
           lzf.write(b"This *will* be compressed\n")
       f.write(b"Not compressed\n")

Créer un fichier compressé en utilisant une chaîne de filtre
personnalisée:

   import lzma
   my_filters = [
       {"id": lzma.FILTER_DELTA, "dist": 5},
       {"id": lzma.FILTER_LZMA2, "preset": 7 | lzma.PRESET_EXTREME},
   ]
   with lzma.open("file.xz", "w", filters=my_filters) as f:
       f.write(b"blah blah blah")
